<commit_before>import d3 from 'd3'
import _ from 'lodash'

function d3Time(){
const node = document.createElement('div');
const width = 700,
      height = 300;

const svg = d3.select(node).append('svg')
  .attr('width', width)
  .attr('height', height)
  .style('overflow', 'visible');

const nest = (content) => {
  // creates a key from content.created_at object 'YYYYMMDD'
  let timeKey = (v) =>
    Number(`${v.created_at.years}${('0' + v.created_at.months).slice(-2)}${('0' + v.created_at.date).slice(-2)}`);
  return d3.nest()
    .key((d) => timeKey(d))
    .sortKeys(d3.ascending)
    .entries(content)
    .reduce((curr,d) => {
      // if(d.values.length < 4)
      //   return curr;
      return [].concat(curr, { key: d.key,
        values: d.values.reduce((curr, v, i) => {
          let pushVal = (nest, val) => {
            curr[nest].t += val;
            curr[nest].avg = curr[nest].t / (i + 1);
            curr[nest].values.push({ content: v, value: val });
          };

          let s = v.sentiment;
          let value = ( s.score * s.comparative ) / ( s.words.length * 5 );
          s.comparative < 0 ? pushVal('negative', -value) : pushVal('positive', value);

          return curr;
        },{ negative:{ values:[], avg:0, t:0}, positive:{ values:[], avg:0, t:0} })
      });
    },[]);
};

const Map = (content) => {

  let d = nest(content);

  let xRange = d3.extent(d,(val) => Number(val.key));

  let yMax = d3.max(d,(val) => val.values.positive.avg);
  let yMin = d3.min(d,(val) => val.values.negative.avg);
  let yRangeMax = Math.max(Math.abs(yMin),yMax);

  let Maxim = d.reduce((curr,val,i) => {
    let pos = val.values.positive.avg;
    let neg = val.values.negative.avg;
    curr.positive = (curr.positive === null && pos === yMax) ? i : curr.positive;
    curr.negative = (curr.negative === null && neg === yMin) ? i : curr.negative;
    return curr;
  }, {positive: null, negative: null});

  let Y = (v) => d3.scale.linear().domain([-yRangeMax,yRangeMax]).range([height, 0])(v);
  // let X = (v) => d3.scale.linear().domain(xRange).range([0, width])(v);
  let X = (v) => d3.scale.linear().domain([0,d.length-1]).range([0, width])(v);

  let Area = d3.svg.area()
    .x((d,i) => X(i))
    .y0((d,i) => Y(d.values.negative.avg))
    .y1((d,i) => Y(d.values.positive.avg))
    .interpolate('monotone')(d);

  // let Mean = d3.mean(d,(val) => val[0]);
  // let Dev = d3.deviation(d,(val) => val[0]);

  // let R = (v) =>  3 + d3.scale.sqrt().domain(yRange).range([1,13])(Math.abs(v));
  // let Color = (v) => d3.scale.linear().domain([-xRangeMax,xRangeMax]).range(['#f80', '#08f'])(v);

  return {
    d: d,

    // c: Color,
    // r: R,
    x: X,
    y: Y,

    area: Area,
    maxim: Maxim,

    xRange: xRange,
    yRange: [yMin,yMax],
    yRangeMax: yRangeMax
    // mean: Mean,
    // dev: Dev
  }
};

const markers = (m) => {

  return [{
    x1: m.maxim.negative - m.d.length/7,
    x2: m.maxim.negative + m.d.length/7,
    y: m.yRange[0],
    class: 'time-min'
  },{
    x1: 0 - m.d.length/7,
    x2: m.d.length + m.d.length/7,
    y: 0,
    class: 'time-zero'
  },{
    x1: m.maxim.positive - m.d.length/7,
    x2: m.maxim.positive + m.d.length/7,
    y: m.yRange[1],
    class: 'time-max'
  }]
};

const append = {
  data: (timeLine,m) => {
    let timeData = timeLine.append('g').attr('class','time-data');

    return timeData.append('path')
      .attr('d', m.area)
      .attr('fill', 'url(#gradient)')
      .style('opacity', 'url(#opacity)');
  },
  markers: (timeLine,m) => {<commit_msg>[fix] zero horizontal axis width now evenly extends from time-line<commit_after>import d3 from 'd3'
import _ from 'lodash'

function d3Time(){
const node = document.createElement('div');
const width = 700,
      height = 300;

const svg = d3.select(node).append('svg')
  .attr('width', width)
  .attr('height', height)
  .style('overflow', 'visible');

const nest = (content) => {
  // creates a key from content.created_at object 'YYYYMMDD'
  let timeKey = (v) =>
    Number(`${v.created_at.years}${('0' + v.created_at.months).slice(-2)}${('0' + v.created_at.date).slice(-2)}`);
  return d3.nest()
    .key((d) => timeKey(d))
    .sortKeys(d3.ascending)
    .entries(content)
    .reduce((curr,d) => {
      // if(d.values.length < 4)
      //   return curr;
      return [].concat(curr, { key: d.key,
        values: d.values.reduce((curr, v, i) => {
          let pushVal = (nest, val) => {
            curr[nest].t += val;
            curr[nest].avg = curr[nest].t / (i + 1);
            curr[nest].values.push({ content: v, value: val });
          };

          let s = v.sentiment;
          let value = ( s.score * s.comparative ) / ( s.words.length * 5 );
          s.comparative < 0 ? pushVal('negative', -value) : pushVal('positive', value);

          return curr;
        },{ negative:{ values:[], avg:0, t:0}, positive:{ values:[], avg:0, t:0} })
      });
    },[]);
};

const Map = (content) => {

  let d = nest(content);

  let xRange = d3.extent(d,(val) => Number(val.key));

  let yMax = d3.max(d,(val) => val.values.positive.avg);
  let yMin = d3.min(d,(val) => val.values.negative.avg);
  let yRangeMax = Math.max(Math.abs(yMin),yMax);

  let Maxim = d.reduce((curr,val,i) => {
    let pos = val.values.positive.avg;
    let neg = val.values.negative.avg;
    curr.positive = (curr.positive === null && pos === yMax) ? i : curr.positive;
    curr.negative = (curr.negative === null && neg === yMin) ? i : curr.negative;
    return curr;
  }, {positive: null, negative: null});

  let Y = (v) => d3.scale.linear().domain([-yRangeMax,yRangeMax]).range([height, 0])(v);
  // let X = (v) => d3.scale.linear().domain(xRange).range([0, width])(v);
  let X = (v) => d3.scale.linear().domain([0,d.length-1]).range([0, width])(v);

  let Area = d3.svg.area()
    .x((d,i) => X(i))
    .y0((d,i) => Y(d.values.negative.avg))
    .y1((d,i) => Y(d.values.positive.avg))
    .interpolate('monotone')(d);

  // let Mean = d3.mean(d,(val) => val[0]);
  // let Dev = d3.deviation(d,(val) => val[0]);

  // let R = (v) =>  3 + d3.scale.sqrt().domain(yRange).range([1,13])(Math.abs(v));
  // let Color = (v) => d3.scale.linear().domain([-xRangeMax,xRangeMax]).range(['#f80', '#08f'])(v);

  return {
    d: d,

    // c: Color,
    // r: R,
    x: X,
    y: Y,

    area: Area,
    maxim: Maxim,

    xRange: xRange,
    yRange: [yMin,yMax],
    yRangeMax: yRangeMax
    // mean: Mean,
    // dev: Dev
  }
};

const markers = (m) => {

  return [{
    x1: m.maxim.negative - m.d.length/7,
    x2: m.maxim.negative + m.d.length/7,
    y: m.yRange[0],
    class: 'time-min'
  },{
    x1: 0 - (m.d.length)/7,
    x2: (m.d.length-1) + m.d.length/7,
    y: 0,
    class: 'time-zero'
  },{
    x1: m.maxim.positive - m.d.length/7,
    x2: m.maxim.positive + m.d.length/7,
    y: m.yRange[1],
    class: 'time-max'
  }]
};

const append = {
  data: (timeLine,m) => {
    let timeData = timeLine.append('g').attr('class','time-data');

    return timeData.append('path')
      .attr('d', m.area)
      .attr('fill', 'url(#gradient)')
      .style('opacity', 'url(#opacity)');
  },
  markers: (timeLine,m) => {
{'fraction_non_alphanumeric': 0.2243042931058593, 'fraction_numerical': 0.019158159697944342, 'mean_word_length': 2.6157735085945397, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 51, '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': '2628014', 'n_tokens_mistral': 2896, 'n_tokens_neox': 2791, 'n_words': 549}