<commit_before>/** @jsx React.DOM */

var React = require('react'),
    _ = require('lodash'),
    moment = require('moment');

var Maths = require('bd-stampy/utils/Maths');
var Legend = require('./Legend.jsx');

var _MAX_TICKS = 10;

var Line = React.createClass({
    displayName: 'Line',
    propTypes: {         
        data: React.PropTypes.array
    },
    getDefaultProps: function() {
        return {
            data: [],
            colors: [],
            tickInterval: 1,
            yAxisLabel: null,
            padding: 0
        };
    },
    getInitialState: function() {
        return {
            width: 0,
            height: 300
        };
    },
    componentDidMount: function() {
        this.setState({width: this.refs.graphContent.getDOMNode().clientWidth});
    },
    getY: function(val, MAX) {
        var h = this.state.height - this.props.padding;
        return h - ((val / MAX) * h);
    },
    getX: function(val, numberOfTicks) {
        var padding = this.props.padding;
        var w = this.state.width - padding;
        var xSpacer = w / numberOfTicks;

        return (val * xSpacer) + padding;
    },
    getComputedValues: function(data, tickInterval) {
        // TODO: Refactor this function and add tests!!
        data = data || this.props.data;
        tickInterval = tickInterval || this.props.tickInterval;

        var _values = _.chain(data)
                            .map(function(s) {
                                return s.map(function(d) {
                                    return d.value;
                                });
                            })
                            .flatten()
                            .remove(null)
                            .value();

        var extent = Maths.extent(_values);
        
        var max = extent[1] || 0;
        var roundToNearest = tickInterval;
        var roundMax = Math.ceil(max / roundToNearest) * roundToNearest;

        var numberOfTicks = roundMax / tickInterval;

        if (numberOfTicks > _MAX_TICKS) {
            var nextTickInterval = tickInterval * 2;
            
            // To avoid going over the yMax
            if (this.props.yMax && roundMax > this.props.yMax) {
                if (this.props.tickInterval === 1 || this.props.tickInterval % 2 === 0) {
                    nextTickInterval = 5;
                }
                else {
                    nextTickInterval = 1;
                }
            }

            // Keep increasing the tickInterval until we get less than the _MAX_TICKS ticks
            return this.getComputedValues(data, nextTickInterval);
        }


        // More calcs
        var yRange = [],
            height = this.state.height - this.props.padding;

        if (numberOfTicks > 0) {
            yRange = Maths.tickRange(numberOfTicks, 0, roundMax);
        }

        var ySpacer = height / yRange.length;

        var yPadding = 0,
            diff = (yRange.length - 1) * ySpacer;

        if (diff < height) {
            yPadding = height - diff;
        }


        // X Calcs
        var xRange = this.getXLabels(this.props.data[0][0].date, this.props.data[0][this.props.data[0].length - 1].date);
        var xSpacer = (this.state.width - this.props.padding) / xRange.length;

        return {
            min: extent[0] || 0,
            max: roundMax,
            numberOfTicks: numberOfTicks,
            ySpacer: ySpacer,
            yPadding: yPadding,
            yRange: yRange,
            xRange: xRange,
            xSpacer: xSpacer
        };
    },
    getPath: function(series, MAX) {
        if (!series || series.length === 0) {
            return 'M0,0';
        }

        var _this = this;

        var path = _.chain(series)
                        .map(function(d, i) {
                            return {
                                x: _this.getX(i, series.length),
                                y: _this.getY(d.value, MAX)
                            };
                        })
                        .map(function(d, i) {
                            var c = i === 0 ? 'M' : 'L';

                            return c + [d.x, d.y].join(',');
                        })
                        .value();

        return path.join(' ');
    },
    getXLabels: function(firstDate, lastDate) {
        firstDate = moment(new Date(firstDate));
        lastDate = moment(new Date(lastDate));

        var interval = lastDate.diff(firstDate, 'months'),
            labels = [],<commit_msg>Convert date format to YYYYMMDD<commit_after>/** @jsx React.DOM */

var React = require('react'),
    _ = require('lodash'),
    moment = require('moment');

var Maths = require('bd-stampy/utils/Maths');
var Legend = require('./Legend.jsx');

var _MAX_TICKS = 10;

var Line = React.createClass({
    displayName: 'Line',
    propTypes: {         
        data: React.PropTypes.array
    },
    getDefaultProps: function() {
        return {
            data: [],
            colors: [],
            tickInterval: 1,
            yAxisLabel: null,
            padding: 0
        };
    },
    getInitialState: function() {
        return {
            width: 0,
            height: 300
        };
    },
    componentDidMount: function() {
        this.setState({width: this.refs.graphContent.getDOMNode().clientWidth});
    },
    getY: function(val, MAX) {
        var h = this.state.height - this.props.padding;
        return h - ((val / MAX) * h);
    },
    getX: function(val, numberOfTicks) {
        var padding = this.props.padding;
        var w = this.state.width - padding;
        var xSpacer = w / numberOfTicks;

        return (val * xSpacer) + padding;
    },
    getComputedValues: function(data, tickInterval) {
        // TODO: Refactor this function and add tests!!
        data = data || this.props.data;
        tickInterval = tickInterval || this.props.tickInterval;

        var _values = _.chain(data)
                            .map(function(s) {
                                return s.map(function(d) {
                                    return d.value;
                                });
                            })
                            .flatten()
                            .remove(null)
                            .value();

        var extent = Maths.extent(_values);
        
        var max = extent[1] || 0;
        var roundToNearest = tickInterval;
        var roundMax = Math.ceil(max / roundToNearest) * roundToNearest;

        var numberOfTicks = roundMax / tickInterval;

        if (numberOfTicks > _MAX_TICKS) {
            var nextTickInterval = tickInterval * 2;
            
            // To avoid going over the yMax
            if (this.props.yMax && roundMax > this.props.yMax) {
                if (this.props.tickInterval === 1 || this.props.tickInterval % 2 === 0) {
                    nextTickInterval = 5;
                }
                else {
                    nextTickInterval = 1;
                }
            }

            // Keep increasing the tickInterval until we get less than the _MAX_TICKS ticks
            return this.getComputedValues(data, nextTickInterval);
        }


        // More calcs
        var yRange = [],
            height = this.state.height - this.props.padding;

        if (numberOfTicks > 0) {
            yRange = Maths.tickRange(numberOfTicks, 0, roundMax);
        }

        var ySpacer = height / yRange.length;

        var yPadding = 0,
            diff = (yRange.length - 1) * ySpacer;

        if (diff < height) {
            yPadding = height - diff;
        }


        // X Calcs
        var xRange = this.getXLabels(this.props.data[0][0].date, this.props.data[0][this.props.data[0].length - 1].date);
        var xSpacer = (this.state.width - this.props.padding) / xRange.length;

        return {
            min: extent[0] || 0,
            max: roundMax,
            numberOfTicks: numberOfTicks,
            ySpacer: ySpacer,
            yPadding: yPadding,
            yRange: yRange,
            xRange: xRange,
            xSpacer: xSpacer
        };
    },
    getPath: function(series, MAX) {
        if (!series || series.length === 0) {
            return 'M0,0';
        }

        var _this = this;

        var path = _.chain(series)
                        .map(function(d, i) {
                            return {
                                x: _this.getX(i, series.length),
                                y: _this.getY(d.value, MAX)
                            };
                        })
                        .map(function(d, i) {
                            var c = i === 0 ? 'M' : 'L';

                            return c + [d.x, d.y].join(',');
                        })
                        .value();

        return path.join(' ');
    },
    getXLabels: function(firstDate, lastDate) {
        firstDate = moment(firstDate, 'YYYYMMDD');
        lastDate = moment(lastDate, 'YYYYMMDD');

        var interval = lastDate.diff(firstDate, 'months'),
            labels = [],
{'fraction_non_alphanumeric': 0.11528268551236749, 'fraction_numerical': 0.006846289752650177, 'mean_word_length': 1.2911712623324059, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '724047', 'n_tokens_mistral': 2620, 'n_tokens_neox': 2494, 'n_words': 566}