<commit_before>const React = require('react');
const ReactDom = require('react-dom');
const Radium = require('radium');

const d3 = require('d3');
const moment = require('moment');
const numeral = require('numeral');

const StyleConstants = require('../constants/Style');

class TimeBasedLineChart extends React.Component {
  constructor (props) {
    super(props);

    const adjustedWidth = this.props.width - this.props.margin.right - this.props.margin.left;
    const adjustedHeight = this.props.height - this.props.margin.top - this.props.margin.bottom;

    this.state = {
      adjustedHeight,
      adjustedWidth
    };
  }

  componentDidMount () {
    this.setState({
      chartEl: ReactDom.findDOMNode(this.refs.chart)
    });
  }

  componentWillReceiveProps (newProps) {
    if (newProps.height !== null || newProps.width !== null || newProps.margin !== null) {
      const height = newProps.height || this.props.height;
      const width = newProps.width || this.props.width;
      const margin = newProps.margin || this.props.margin;

      const adjustedWidth = width - margin.right - margin.left;
      const adjustedHeight = height - margin.top - margin.bottom;

      this.setState({
        adjustedHeight,
        adjustedWidth
      });
    }
  }

  _getAreaBelowZero (data) {
    const area = d3.svg.area()
      .x(d => {
        const currentDate = moment.unix(d.timeStamp).startOf(this.props.rangeType).unix();

        return this._getXScaleValue(currentDate);
      })
      .y0(this.state.adjustedHeight - 10)
      .y1(this._getYScaleValue(0));

    return area(data);
  }

  _getFlatLine (data) {
    const flatLine = d3.svg.line()
      .x(d => {
        const currentDate = moment.unix(d.timeStamp).startOf(this.props.rangeType).unix();

        return this._getXScaleValue(currentDate);
      })
      .y(this.state.adjustedHeight);

    return flatLine(data);
  }

  _getLine (data) {
    const line = d3.svg.line()
      .x(d => {
        const currentDate = moment.unix(d.timeStamp).startOf(this.props.rangeType).unix();

        return this._getXScaleValue(currentDate);
      })
      .y(d => {
        return this._getYScaleValue(d.value);
      });

    return line(data);
  }

  _getSliceMiddle () {
    return this._getSliceWidth() / 2;
  }

  _getSliceWidth () {
    return Math.floor(this.state.adjustedWidth / this.props.data.length);
  }

  _getSplitData () {
    const future = [];
    const past = [];

    this.props.data.forEach(item => {
      const currentDate = moment.unix(item.timeStamp).startOf(this.props.rangeType);

      if (currentDate.isBefore(moment.unix(this.props.breakPointDate), this.props.rangeType)) {
        past.push(item);
      }

      if (currentDate.isAfter(moment.unix(this.props.breakPointDate), this.props.rangeType)) {
        future.push(item);
      }

      if (currentDate.isSame(moment.unix(this.props.breakPointDate), this.props.rangeType)) {
        past.push(item);
        future.push(item);
      }
    });

    return [past, future];
  }

  _getYAxisTicks (data, numTicks = 4) {
    const maxValue = d3.max(this.props.data, d => {
      const value = d.above ? d.value + d.above : d.value + 1000;
      const multiplier = value < 0 ? -1000 : 1000;

      return Math.ceil(value / multiplier) * multiplier;
    });

    let minValue = d3.min(this.props.data, d => {
      const value = d.below ? d.value + d.below : d.value - 1000;
      const multiplier = value < 0 ? -1000 : 1000;

      return Math.ceil(value / multiplier) * multiplier;
    });

    minValue = minValue > 0 ? 0 : minValue;

    const ticks = [maxValue, minValue];
    const interval = (maxValue - minValue) / numTicks;

    for (let current = minValue; current < maxValue; current += interval) {
      ticks.push(current);
    }

    if (this.props.alwaysShowZeroYTick) {
      if (ticks.indexOf(0) === -1) {
        ticks.push(0);
      }
    }

    return ticks;
  }

  _getXScaleFunction () {
    let maxDate = this.props.data[this.props.data.length - 1].timeStamp;
    let minDate = this.props.data[0].timeStamp;

    maxDate = moment.unix(maxDate).endOf(this.props.rangeType).unix();
    minDate = moment.unix(minDate).startOf(this.props.rangeType).unix();

    return d3.time.scale()
      .range([0, this.state.adjustedWidth])
      .domain([minDate, maxDate]);
  }

  _getXScaleValue (value) {
    const xScale = this._getXScaleFunction();

    return xScale(value);
  }

  _getYScaleFunction () {<commit_msg>dont render zero axis if to close to another tick<commit_after>const React = require('react');
const ReactDom = require('react-dom');
const Radium = require('radium');

const d3 = require('d3');
const moment = require('moment');
const numeral = require('numeral');

const StyleConstants = require('../constants/Style');

class TimeBasedLineChart extends React.Component {
  constructor (props) {
    super(props);

    const adjustedWidth = this.props.width - this.props.margin.right - this.props.margin.left;
    const adjustedHeight = this.props.height - this.props.margin.top - this.props.margin.bottom;

    this.state = {
      adjustedHeight,
      adjustedWidth
    };
  }

  componentDidMount () {
    this.setState({
      chartEl: ReactDom.findDOMNode(this.refs.chart)
    });
  }

  componentWillReceiveProps (newProps) {
    if (newProps.height !== null || newProps.width !== null || newProps.margin !== null) {
      const height = newProps.height || this.props.height;
      const width = newProps.width || this.props.width;
      const margin = newProps.margin || this.props.margin;

      const adjustedWidth = width - margin.right - margin.left;
      const adjustedHeight = height - margin.top - margin.bottom;

      this.setState({
        adjustedHeight,
        adjustedWidth
      });
    }
  }

  _getAreaBelowZero (data) {
    const area = d3.svg.area()
      .x(d => {
        const currentDate = moment.unix(d.timeStamp).startOf(this.props.rangeType).unix();

        return this._getXScaleValue(currentDate);
      })
      .y0(this.state.adjustedHeight - 10)
      .y1(this._getYScaleValue(0));

    return area(data);
  }

  _getFlatLine (data) {
    const flatLine = d3.svg.line()
      .x(d => {
        const currentDate = moment.unix(d.timeStamp).startOf(this.props.rangeType).unix();

        return this._getXScaleValue(currentDate);
      })
      .y(this.state.adjustedHeight);

    return flatLine(data);
  }

  _getLine (data) {
    const line = d3.svg.line()
      .x(d => {
        const currentDate = moment.unix(d.timeStamp).startOf(this.props.rangeType).unix();

        return this._getXScaleValue(currentDate);
      })
      .y(d => {
        return this._getYScaleValue(d.value);
      });

    return line(data);
  }

  _getSliceMiddle () {
    return this._getSliceWidth() / 2;
  }

  _getSliceWidth () {
    return Math.floor(this.state.adjustedWidth / this.props.data.length);
  }

  _getSplitData () {
    const future = [];
    const past = [];

    this.props.data.forEach(item => {
      const currentDate = moment.unix(item.timeStamp).startOf(this.props.rangeType);

      if (currentDate.isBefore(moment.unix(this.props.breakPointDate), this.props.rangeType)) {
        past.push(item);
      }

      if (currentDate.isAfter(moment.unix(this.props.breakPointDate), this.props.rangeType)) {
        future.push(item);
      }

      if (currentDate.isSame(moment.unix(this.props.breakPointDate), this.props.rangeType)) {
        past.push(item);
        future.push(item);
      }
    });

    return [past, future];
  }

  _getYAxisTicks (data, numTicks = 4) {
    const maxValue = d3.max(this.props.data, d => {
      const value = d.above ? d.value + d.above : d.value + 1000;
      const multiplier = value < 0 ? -1000 : 1000;

      return Math.ceil(value / multiplier) * multiplier;
    });

    let minValue = d3.min(this.props.data, d => {
      const value = d.below ? d.value + d.below : d.value - 1000;
      const multiplier = value < 0 ? -1000 : 1000;

      return Math.ceil(value / multiplier) * multiplier;
    });

    minValue = minValue > 0 ? 0 : minValue;

    const ticks = [maxValue, minValue];
    const interval = (maxValue - minValue) / numTicks;

    for (let current = minValue; current < maxValue; current += interval) {
      ticks.push(current);
    }

    if (this.props.alwaysShowZeroYTick) {
      if (ticks.indexOf(0) === -1) {
        let shouldAddZeroToTicks = true;

        ticks.forEach(tick => {
          if ((tick <= 1000 && tick > 0) || (tick >= -1000 && tick < 0)) {
            shouldAddZeroToTicks = false;
          }
        });

        if (shouldAddZeroToTicks) {
          ticks.push(0);
        }
      }
    }

    return ticks;
  }

  _getXScaleFunction () {
    let maxDate = this.props.data[this.props.data.length - 1].timeStamp;
    let minDate = this.props.data[0].timeStamp;

    maxDate = moment.unix(maxDate).endOf(this.props.rangeType).unix();
    minDate = moment.unix(minDate).startOf(this.props.rangeType).unix();

    return d3.time.scale()
      .range([0, this.state.adjustedWidth])
      .domain([minDate, maxDate]);
  }

  _getXScaleValue (value) {
    const xScale = this._getXScaleFunction();

    return xScale(value);
  }

  _getYScaleFunction () {
{'fraction_non_alphanumeric': 0.14240984668538112, 'fraction_numerical': 0.011660548477650615, 'mean_word_length': 2.6482867270578967, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 22, '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': '2475310', 'n_tokens_mistral': 3148, 'n_tokens_neox': 2962, 'n_words': 548}