<commit_before>import { ResponsiveBar } from '@nivo/bar'
import Legend from './legend'
import { scaleOrdinal } from 'd3-scale'
import { CSSTransition } from 'react-transition-group';

class NivoBarChart extends React.Component {

  setUpData = () => {
    const {data, services, serviceMap} = this.props.cost

    // init data to have allways 12 months with all services
    let resultData = {}
    let now = new Date()
    for (let i = 0; i <= 11; i++) {
      let past = new Date(now)
      past.setMonth(now.getMonth() - i)
      let date = past.getFullYear() + '/' + (past.getMonth()+1) // +1 to get the month from 1-12
      resultData[date] = {date: date}
      resultData[date]["rawData"] = []
      services.map(i => resultData[date][i] = 0)
    }

    // add prices per service and add to total per month
    data.map(i => {
      let date = i.year + "/" + i.month
      if (resultData[date]) {
        if (services.includes(serviceMap[i.service])){
          resultData[date][serviceMap[i.service]] += i.price_loc + i.price_sec
          resultData[date]["rawData"].push(i)
        }
      }
    })
    return resultData
  }

  // Remove keys to have just an array of objects
  // Reverse array to go from the past to the present
  getData = () => {
    const data = this.setUpData()
    let resultArray = Object.keys(data).map(i => data[i])
    return resultArray.reverse()
  }

  onClickRect = (recData) => {
    const data = this.setUpData()
    let rawData = data[recData.indexValue]["rawData"]
    this.props.onClick({date: recData.indexValue, rawData: rawData})
  }

  getServiceByColor = (color) => {
    const colorScale = scaleOrdinal()
      .domain(this.props.cost.services)
      .range(this.props.colors)
    let colorIndex = colorScale.range().indexOf(color)
    return colorScale.domain()[colorIndex]
  }

  rectBarComponent = ({ x, y, width, height, color, data, onClick, tooltip, showTooltip, hideTooltip}) => {
    const {clickService,clickedBar} = this.props
    let service = this.getServiceByColor(color)
    const handleTooltip = e => showTooltip(this.customTooltip(data, color), e)

    let newY = (service === clickService) ? 240-height : y
    let opacity = (clickService !== "all" && service !== clickService) ? 0 : 1
    opacity = (opacity == 1 && clickedBar!== "none" && data.indexValue !== clickedBar) ? 0.5 : opacity

    // hide hideTooltip
    if (opacity == 0) {
      return <rect width={width} height={height} x={x} y={newY} fill={color} opacity={opacity} onClick={() => onClick(data)}/>
    }

    return <rect width={width} height={height} x={x} y={newY} fill={color} opacity={opacity} onClick={() => onClick(data)}
              onMouseEnter={handleTooltip}
              onMouseMove={handleTooltip}
              onMouseLeave={hideTooltip}/>
  }

  customTooltip = (node, color) => (
      <div className="customTooltip">
          <span style={{ fontWeight: 500 }}>Service</span>
          <span><i className="fa fa-square header-square" style={{color: color}}/> {node.id}</span>
          <span style={{ fontWeight: 500 }}>Value</span>
          <span>{node.value}</span>
      </div>
  )

  render() {
    const {data,services,isFetching,serviceMap} = this.props.cost
    return (
      <React.Fragment>
        {isFetching &&
          <div>
            Loading
            <span className="spinner"/>
          </div>
        }
        {data && data.length == 0 &&
          <div>
            No data available for this project.
          </div>
        }
        {data && data.length > 0 && services && serviceMap &&
          <div className="row">
            <div className="col-sm-10 col-xs-10">
              <div className="barChart">
                <ResponsiveBar
                  data={this.getData()}
                  colors={this.props.colors}
                  margin={{<commit_msg>[cost report]:  2 digits after the comma with euro char on mouseover<commit_after>import { ResponsiveBar } from '@nivo/bar'
import Legend from './legend'
import { scaleOrdinal } from 'd3-scale'
import { CSSTransition } from 'react-transition-group';

class NivoBarChart extends React.Component {

  setUpData = () => {
    const {data, services, serviceMap} = this.props.cost

    // init data to have allways 12 months with all services
    let resultData = {}
    let now = new Date()
    for (let i = 0; i <= 11; i++) {
      let past = new Date(now)
      past.setMonth(now.getMonth() - i)
      let date = past.getFullYear() + '/' + (past.getMonth()+1) // +1 to get the month from 1-12
      resultData[date] = {date: date}
      resultData[date]["rawData"] = []
      services.map(i => resultData[date][i] = 0)
    }

    // add prices per service and add to total per month
    data.map(i => {
      let date = i.year + "/" + i.month
      if (resultData[date]) {
        if (services.includes(serviceMap[i.service])){
          resultData[date][serviceMap[i.service]] += i.price_loc + i.price_sec
          resultData[date]["rawData"].push(i)
        }
      }
    })
    return resultData
  }

  // Remove keys to have just an array of objects
  // Reverse array to go from the past to the present
  getData = () => {
    const data = this.setUpData()
    let resultArray = Object.keys(data).map(i => data[i])
    return resultArray.reverse()
  }

  onClickRect = (recData) => {
    const data = this.setUpData()
    let rawData = data[recData.indexValue]["rawData"]
    this.props.onClick({date: recData.indexValue, rawData: rawData})
  }

  getServiceByColor = (color) => {
    const colorScale = scaleOrdinal()
      .domain(this.props.cost.services)
      .range(this.props.colors)
    let colorIndex = colorScale.range().indexOf(color)
    return colorScale.domain()[colorIndex]
  }

  rectBarComponent = ({ x, y, width, height, color, data, onClick, tooltip, showTooltip, hideTooltip}) => {
    const {clickService,clickedBar} = this.props
    let service = this.getServiceByColor(color)
    const handleTooltip = e => showTooltip(this.customTooltip(data, color), e)

    let newY = (service === clickService) ? 240-height : y
    let opacity = (clickService !== "all" && service !== clickService) ? 0 : 1
    opacity = (opacity == 1 && clickedBar!== "none" && data.indexValue !== clickedBar) ? 0.5 : opacity

    // hide hideTooltip
    if (opacity == 0) {
      return <rect width={width} height={height} x={x} y={newY} fill={color} opacity={opacity} onClick={() => onClick(data)}/>
    }

    return <rect width={width} height={height} x={x} y={newY} fill={color} opacity={opacity} onClick={() => onClick(data)}
              onMouseEnter={handleTooltip}
              onMouseMove={handleTooltip}
              onMouseLeave={hideTooltip}/>
  }

  customTooltip = (node, color) => {
    let cost = parseFloat(node.value).toFixed(2)
    return (<div className="customTooltip">
        <span style={{ fontWeight: 500 }}>Service</span>
        <span><i className="fa fa-square header-square" style={{color: color}}/> {node.id}</span>
        <span style={{ fontWeight: 500 }}>Value</span>
        <span>{cost} €</span>
    </div>)
  }

  render() {
    const {data,services,isFetching,serviceMap} = this.props.cost
    return (
      <React.Fragment>
        {isFetching &&
          <div>
            Loading
            <span className="spinner"/>
          </div>
        }
        {data && data.length == 0 &&
          <div>
            No data available for this project.
          </div>
        }
        {data && data.length > 0 && services && serviceMap &&
          <div className="row">
            <div className="col-sm-10 col-xs-10">
              <div className="barChart">
                <ResponsiveBar
                  data={this.getData()}
                  colors={this.props.colors}
                  margin={{
{'fraction_non_alphanumeric': 0.14928818776452482, 'fraction_numerical': 0.008721303065281518, 'mean_word_length': 2.5445454545454544, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 73, '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': '4891782', 'n_tokens_mistral': 2426, 'n_tokens_neox': 2370, 'n_words': 591}