<commit_before>import numeral from 'numeral'
import React from 'react'
import { Environment } from 'rt-system'
import { PNLChartModel } from '../model/pnlChartModel'
import { PositionsChartModel } from '../model/positionsChartModel'
import AnalyticsBarChart from './AnalyticsBarChart'
import PositionsBubbleChart from './positions-chart/PositionsBubbleChart'

import { CurrencyPair } from 'rt-types'
import PNLChart from './pnlChart/PNLChart'

import { ConnectionOverlay, PopoutIcon } from 'rt-components'
import { ThemeProvider } from 'rt-theme'
import { AnalyticsStyle, BubbleChart, Chart, Controls, Header, LastPosition, PopoutButton, Title } from './styled'

export interface CurrencyPairs {
  [id: string]: CurrencyPair
}

export interface Props {
  tornOff: boolean
  isConnected: boolean
  currencyPairs: CurrencyPairs
  pnlChartModel?: PNLChartModel
  positionsChartModel?: PositionsChartModel
  onMount?: () => void
  onPopoutClick?: () => void
}

const RESIZE_EVENT = 'resize'

export default class Analytics extends React.Component<Props> {
  private handleResize = () => this.forceUpdate()

  componentDidMount() {
    if (this.props.onMount) {
      this.props.onMount()
    }
  }

  // Resizing the window is causing the nvd3 chart to resize incorrectly. This forces a render when the window resizes
  componentWillMount() {
    window.addEventListener(RESIZE_EVENT, this.handleResize)
  }

  componentWillUnmount() {
    window.removeEventListener(RESIZE_EVENT, this.handleResize)
  }

  render() {
    const { tornOff, isConnected, currencyPairs, pnlChartModel, positionsChartModel, onPopoutClick } = this.props

    if (!isConnected) {
      return <ConnectionOverlay>Analytics Disconnected</ConnectionOverlay>
    }

    const lastPos = (pnlChartModel && pnlChartModel.lastPos) || 0
    const lastPosition = lastPositionWithDirection(lastPos)

    return (
      <ThemeProvider theme={theme => theme.analytics}>
        <AnalyticsStyle>
          <Header>
            {!Environment.isRunningInIE() &&
              !tornOff && (
                <Controls>
                  <PopoutButton onClick={onPopoutClick}>
                    <PopoutIcon width={0.8125} height={0.75} />
                  </PopoutButton>
                </Controls>
              )}
            <Title>Analytics</Title>
          </Header>
          <LastPosition color={lastPosition.color}>USD {lastPosition.formattedLastPos}</LastPosition>
          <Chart>{pnlChartModel && <PNLChart {...pnlChartModel} />}</Chart>
          {positionsChartModel &&
            positionsChartModel.seriesData.length !== 0 && (
              <React.Fragment>
                <Title>Positions</Title>
                <BubbleChart>
                  <PositionsBubbleChart data={positionsChartModel.seriesData} currencyPairs={currencyPairs} />
                </BubbleChart>
                <Title>Profit and Loss</Title>
                <AnalyticsBarChart
                  chartData={positionsChartModel.seriesData}
                  currencyPairs={currencyPairs}
                  isPnL={true}
                />
              </React.Fragment>
            )}
        </AnalyticsStyle>
      </ThemeProvider>
    )
  }
}

function lastPositionWithDirection(lastPos: number) {
  let formattedLastPos = numeral(lastPos).format()
  let color = ''
  if (lastPos > 0) {
    color = 'green'
    formattedLastPos = '+' + formattedLastPos
  }
  if (lastPos < 0) {
    color = 'red'
    formattedLastPos = '-' + formattedLastPos
  }
  return { color, formattedLastPos }
}<commit_msg>ARTP-241 Analytics Double Minus<commit_after>import numeral from 'numeral'
import React from 'react'
import { Environment } from 'rt-system'
import { PNLChartModel } from '../model/pnlChartModel'
import { PositionsChartModel } from '../model/positionsChartModel'
import AnalyticsBarChart from './AnalyticsBarChart'
import PositionsBubbleChart from './positions-chart/PositionsBubbleChart'

import { CurrencyPair } from 'rt-types'
import PNLChart from './pnlChart/PNLChart'

import { ConnectionOverlay, PopoutIcon } from 'rt-components'
import { ThemeProvider } from 'rt-theme'
import { AnalyticsStyle, BubbleChart, Chart, Controls, Header, LastPosition, PopoutButton, Title } from './styled'

export interface CurrencyPairs {
  [id: string]: CurrencyPair
}

export interface Props {
  tornOff: boolean
  isConnected: boolean
  currencyPairs: CurrencyPairs
  pnlChartModel?: PNLChartModel
  positionsChartModel?: PositionsChartModel
  onMount?: () => void
  onPopoutClick?: () => void
}

const RESIZE_EVENT = 'resize'

export default class Analytics extends React.Component<Props> {
  private handleResize = () => this.forceUpdate()

  componentDidMount() {
    if (this.props.onMount) {
      this.props.onMount()
    }
  }

  // Resizing the window is causing the nvd3 chart to resize incorrectly. This forces a render when the window resizes
  componentWillMount() {
    window.addEventListener(RESIZE_EVENT, this.handleResize)
  }

  componentWillUnmount() {
    window.removeEventListener(RESIZE_EVENT, this.handleResize)
  }

  render() {
    const { tornOff, isConnected, currencyPairs, pnlChartModel, positionsChartModel, onPopoutClick } = this.props

    if (!isConnected) {
      return <ConnectionOverlay>Analytics Disconnected</ConnectionOverlay>
    }

    const lastPos = (pnlChartModel && pnlChartModel.lastPos) || 0
    const lastPosition = lastPositionWithDirection(lastPos)

    return (
      <ThemeProvider theme={theme => theme.analytics}>
        <AnalyticsStyle>
          <Header>
            {!Environment.isRunningInIE() &&
              !tornOff && (
                <Controls>
                  <PopoutButton onClick={onPopoutClick}>
                    <PopoutIcon width={0.8125} height={0.75} />
                  </PopoutButton>
                </Controls>
              )}
            <Title>Analytics</Title>
          </Header>
          <LastPosition color={lastPosition.color}>USD {lastPosition.formattedLastPos}</LastPosition>
          <Chart>{pnlChartModel && <PNLChart {...pnlChartModel} />}</Chart>
          {positionsChartModel &&
            positionsChartModel.seriesData.length !== 0 && (
              <React.Fragment>
                <Title>Positions</Title>
                <BubbleChart>
                  <PositionsBubbleChart data={positionsChartModel.seriesData} currencyPairs={currencyPairs} />
                </BubbleChart>
                <Title>Profit and Loss</Title>
                <AnalyticsBarChart
                  chartData={positionsChartModel.seriesData}
                  currencyPairs={currencyPairs}
                  isPnL={true}
                />
              </React.Fragment>
            )}
        </AnalyticsStyle>
      </ThemeProvider>
    )
  }
}

function lastPositionWithDirection(lastPos: number) {
  let formattedLastPos = numeral(lastPos).format()
  let color = ''
  if (lastPos > 0) {
    color = 'green'
    formattedLastPos = '+' + formattedLastPos
  }
  if (lastPos < 0) {
    color = 'red'
    formattedLastPos = formattedLastPos
  }
  return { color, formattedLastPos }
}
{'fraction_non_alphanumeric': 0.1061586051743532, 'fraction_numerical': 0.004077615298087739, 'mean_word_length': 2.771474019088017, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5826336', 'n_tokens_mistral': 2054, 'n_tokens_neox': 1971, 'n_words': 427}