<commit_before>(function() {
  window.shared || (window.shared = {});
  var dom = window.shared.ReactHelpers.dom;
  var createEl = window.shared.ReactHelpers.createEl;
  var merge = window.shared.ReactHelpers.merge;
  var QuadConverter = window.shared.QuadConverter;

  var ProfileChartSettings = window.ProfileChartSettings;
  var HighchartsWrapper = window.shared.HighchartsWrapper;

  // Component for all charts in the profile page.
  window.shared.ProfileChart = React.createClass({
    displayName: 'ProfileChart',

    propTypes: {
      quadSeries: React.PropTypes.arrayOf( // you can plot multiple series on the same graph
        React.PropTypes.shape({
          name: React.PropTypes.string.isRequired, // e.g. 'Scaled score'
          data: React.PropTypes.array.isRequired // [year, month, date, value] quads
        })
      ),
      titleText: React.PropTypes.string.isRequired, // e.g. 'MCAS scores, last 4 years'
      yAxis: React.PropTypes.object.isRequired, // options for rendering the y-axis
      student: React.PropTypes.object.isRequired
    },

    getDefaultProps: function() {
      var now = moment.utc().toDate();
      // TODO(kr) align to school year?
      // The intent of fixing this date range is that when staff are looking at profile of different students,
      // the scales are consistent (and not changing between 3 mos and 6 years depending on the student's record,
      // since that's easy to miss and misinterpret.
      var intervalBack = [4, 'years'];

      return {
        now: now,
        intervalBack: intervalBack,
        timestampRange: {
          min: moment(now).subtract(4, 'years').toDate().getTime(),
          max: now.getTime(),
        }
      };
    },

    render: function() {
      return createEl(HighchartsWrapper, merge(this.baseOptions(), {
        series: this.props.quadSeries.map(function(obj){
          return {
            name: obj.name,
            data: obj.data ? _.map(obj.data, QuadConverter.toPair): []
          }
        }),
        yAxis: this.props.yAxis
      }));
    },

    getPositionsForYearStarts: function(){
      var result = {};
      var current = moment();
      var current_grade = parseInt(this.props.student.grade);
      var n = 48;

      n -= (current.month() + 1);
      current.dayOfYear(1);

      result[current.valueOf()] = current.year().toString() + "<br>" + "<b>" + "Grade " + current_grade.toString() + "</b>";

      // Take 12-month jumps backwards until we can't anymore.
      while (n - 12 > 0){
        current.subtract(1, 'year');
        n -= 12;
        current_grade -= 1;

        result[current.valueOf()] = current.year().toString() + "<br>" + "<b>" +
          (current_grade != 0 ? "Grade " + current_grade.toString() + "</b>" : "");
      }

      return result;
    },

    baseOptions: function() {
      var positionsForYearStarts = this.getPositionsForYearStarts();
<commit_msg>Moving towards making profile_chart.js use pure functions so it's easier to test.<commit_after>(function() {
  window.shared || (window.shared = {});
  var dom = window.shared.ReactHelpers.dom;
  var createEl = window.shared.ReactHelpers.createEl;
  var merge = window.shared.ReactHelpers.merge;
  var QuadConverter = window.shared.QuadConverter;

  var ProfileChartSettings = window.ProfileChartSettings;
  var HighchartsWrapper = window.shared.HighchartsWrapper;

  // Component for all charts in the profile page.
  window.shared.ProfileChart = React.createClass({
    displayName: 'ProfileChart',

    propTypes: {
      quadSeries: React.PropTypes.arrayOf( // you can plot multiple series on the same graph
        React.PropTypes.shape({
          name: React.PropTypes.string.isRequired, // e.g. 'Scaled score'
          data: React.PropTypes.array.isRequired // [year, month, date, value] quads
        })
      ),
      titleText: React.PropTypes.string.isRequired, // e.g. 'MCAS scores, last 4 years'
      yAxis: React.PropTypes.object.isRequired, // options for rendering the y-axis
      student: React.PropTypes.object.isRequired
    },

    getDefaultProps: function() {
      var now = moment.utc().toDate();
      // TODO(kr) align to school year?
      // The intent of fixing this date range is that when staff are looking at profile of different students,
      // the scales are consistent (and not changing between 3 mos and 6 years depending on the student's record,
      // since that's easy to miss and misinterpret.
      var intervalBack = [4, 'years'];

      return {
        now: now,
        intervalBack: intervalBack,
        timestampRange: {
          min: moment(now).subtract(4, 'years').toDate().getTime(),
          max: now.getTime(),
        }
      };
    },

    render: function() {
      return createEl(HighchartsWrapper, merge(this.baseOptions(), {
        series: this.props.quadSeries.map(function(obj){
          return {
            name: obj.name,
            data: obj.data ? _.map(obj.data, QuadConverter.toPair): []
          }
        }),
        yAxis: this.props.yAxis
      }));
    },

    getPositionsForYearStarts: function(n, d, current_grade){
      var result = {};
      var current = d;

      n -= (current.month() + 1);
      current.dayOfYear(1);

      result[current.valueOf()] = current.year().toString() + "<br>" + "<b>" + "Grade " + current_grade.toString() + "</b>";

      // Take 12-month jumps backwards until we can't anymore.
      while (n - 12 > 0){
        current.subtract(1, 'year');
        n -= 12;
        current_grade -= 1;

        result[current.valueOf()] = current.year().toString() + "<br>" + "<b>" +
          (current_grade != 0 ? "Grade " + current_grade.toString() + "</b>" : "");
      }

      return result;
    },

    baseOptions: function() {
      var positionsForYearStarts = this.getPositionsForYearStarts(48, moment.utc(), parseInt(this.props.student.grade));

{'fraction_non_alphanumeric': 0.13242784380305603, 'fraction_numerical': 0.0064516129032258064, 'mean_word_length': 2.546658639373871, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, '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': '6716413', 'n_tokens_mistral': 1745, 'n_tokens_neox': 1685, 'n_words': 443}