• Jump To … +
    ChartMain.js core.js index.js internal.js internalArea.js internalBar.js internalBarLeft.js internalDonutChart.js internalLine.js internalScatter.js internalWaffle.js AreaChart.js BarChart.js BarChartLeft.js DonutChart.js LineChart.js ScatterChart.js WaffleChart.js charts.js data.js errors.js themes.js utils.js
  • internalLine.js

  • ¶
    /*
    This is required for d3 to load.
    */
    /*  global d3  */
    
    import utils from '../utils/utils';
    
    const InternalLine = {
  • ¶

    Updates the chart’s style on the element

      /*
      @private
      @function styleChart
      @description Updates the chart's style on the element
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      styleChart(context) {
        context.element.select('svg')
            .style('font-family', context.getFontStyle)
            .attr('font-size', context.getFontSize)
            .append('text')
            .attr('class', 'title')
            .attr('x', context.getChartWidth * 0.5)
            .attr('y', 20)
            .text(context.getTitle);
    
        return context;
      },
  • ¶

    Builds up the line

      /*
      @private
      @function buildLine
      @description Builds up the line
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      buildLine(context) {
  • ¶

    Build the d3 line using by mapping the x and y values to the data

        context.line = d3.svg.line()
            .x((d) => { return context.xScale(d.x); })
            .y((d) => { return context.yScale(d.y); });
    
        return context;
      },
  • ¶

    Builds up the y-axis

      /*
      @private
      @function buildYAxis
      @description Builds up the y-axis
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      buildYAxis(context) {
        context.svg.append('g')
                 .attr('class', 'y axis')
                 .call(context.yAxis)
                 .append('text')
                 .attr('transform', 'rotate(-90)')
                 .attr('y', -45)
                 .attr('x', -context.getMargins.bottom * 2)
                 .attr('dy', '.4em')
                 .style('text-anchor', 'end')
                 .text(context.getyAxisLabel);
    
        return context;
      },
  • ¶

    Updates and rebuilds the y-axis

      /*
      @private
      @function updateYAxis
      @description Updates and rebuilds the y-axis
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      updateYAxis(context) {
  • ¶

    Updated the y-axis on chart by rebuilding it. Used when properties on a chart are changed and require a rebuild.

        context.element
               .select('svg')
               .selectAll('g .y.axis')
               .call(context.yAxis);
    
        context.element.select('.y-axis-label')
               .attr('class', 'y-axis-label')
               .attr('transform', 'rotate(-90)')
               .attr('y', -45)
               .attr('x', -context.getMargins.bottom * 2)
               .attr('dy', '.4em')
               .style('text-anchor', 'end')
               .text(context.getyAxisLabel);
    
        return context;
      },
  • ¶

    Sets the x-scale according to the data

      /*
      @private
      @function setXScale
      @description Sets the x-scale according to the data
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
      setXScale(context) {
        context.setxAxisLabel = context.xColumnName;
        context.xScale = d3.time.scale()
                        .range([0, context.getChartWidth]);
        context.xScale.domain(
          [d3.min(context.data, d => { return d3.min(d.values, v => {return v[context.xColumnName]; }); }),
          d3.max(context.data, d => { return d3.max(d.values, v => {return v[context.xColumnName]; }); })]);
    
        return context;
      },
  • ¶

    Sets the y-scale according to the data

      /*
      @private
      @function setYScale
      @description Sets the y-scale according to the data
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
      setYScale(context) {
        context.setyAxisLabel = 'Default Label';
        context.yScale = d3.scale.linear()
                        .range([context.getChartHeight, 0]);
    
        context.yScale.domain(
          [d3.min(context.data, d => { return d3.min(d.values, v => {return v[d.name]; }); }),
          d3.max(context.data, d => { return d3.max(d.values, v => {return v[d.name]; }); })]);
    
        return context;
      },
  • ¶

    Builds the actual chart components with data

      /*
      @private
      @function buildChartComponents
      @description Builds the actual chart components with data
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
       */
    
      buildChartComponents(context) {
        const groups = context.svg.selectAll('.line')
        .data(context.data)
        .enter()
        .append('g');
    
        const lines = groups.append('path')
                            .attr('class', 'line');
    
        let k = context.data[0].values.length;
        const length = k;
        d3.timer(() => {
          if (k > 0) {
            k -= 7;
            lines.attr('d', (d) => {
              return context.line(d.values.map(v => {
                return { x: v[context.xColumnName], y: v[d.name] };
              }).slice(0, length - k)); });
          } else {
            return true;
          }
        });
    
        lines.on('mouseover', (d, i) => {
          context.element.selectAll('.line')
          .style('opacity', (data, index) => {
            if (index !== i) {
              return 0.25;
            }
            return 1;
          });
          context.tooltip.transition()
           .duration(200)
           .style('display', 'block')
           .style('opacity', 0.9);
          context.tooltip
           .html(() => {
             return `${context.xColumnName}: ${context.xScale.invert(d3.event.pageX - context.getMargins.left - context.getMargins.right).toLocaleString()}\
             ${d.name}: ${context.yScale.invert(d3.event.pageY - context.getMargins.top - context.getMargins.bottom).toFixed(3)}`;
           })
           .style('left', (d3.event.pageX + 'px'))
           .style('top', (d3.event.pageY + 'px'));
        });
    
        lines.on('mouseout', () => {
          context.tooltip.transition().delay(1000).style('opacity', 0).style('display', 'none');
          context.element.selectAll('.line').transition().delay(1000).style('opacity', 1.0);
        });
    
        return context;
      },
  • ¶

    Rebuilds the line on the chart

      /*
      @private
      @function updateChartComponents
      @description Rebuilds the line on the chart
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      updateChartComponents(context) {
        context.svg.select('.line').remove();
        context.svg.append('path')
                .datum(context.data)
                .attr('class', 'line')
                .style({
                  fill: 'none',
                  stroke: context.getColors[0],
                  'stroke-width': 'crispEdges',
                })
                .attr('d', context.line);
    
        return context;
      },
  • ¶

    Updates color of bar chart after initial render

      /*
      @private
      @function updateColors
      @description Updates color of bar chart after initial render
      @@param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      updateColors(context) {
        context.svg.selectAll('.line')
            .style({
              fill: 'none',
              'stroke-width': 'crispEdges',
            })
            .style('stroke', (d, i) => {
              return context.getColors[i];
            });
    
        return context;
      },
  • ¶

    Converts the data needed for the chart

      /*
      @private
      @function convertData
      @description Converts the data needed for the chart
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      convertData(context) {
        context.data = utils.parseTimeData(context.data, context.xColumnName, context._dateFormat);
        const list = [];
        const dataWorker = (i, columns) => {
          list.push({
            name: columns[i],
            values: context.data.map(val => {
              return { [context.xColumnName]: val[context.xColumnName], [columns[i]]: Number(val[columns[i]]) };
            }),
          });
        };
        const columns = utils.getColumnNames(context.data);
        for (let i = 0; i < columns.length; i++) {
          if (columns[i] !== context.xColumnName && utils.isLinear(context.data, columns[i])) {
            dataWorker(i, columns);
          }
        }
        context.data = list;
    
        return context;
      },
  • ¶

    Sets the column names

      /*
      @private
      @function setColumnNames
      @description Sets the column names
      @param {Object} context (chart instance)
      @returns {Object} context (chart instance)
      */
    
      setColumnNames(context) {
        context.xColumnName = utils.getFirstTimeColumn(context.data, context._dateFormat);
    
        return context;
      },
  • ¶

    Sets the tick format for xAxis

      /*
      @private
      @function setTickFormat
      @description Sets the tick format for xAxis
      @param {Object} context Chart object
      @param {String} tickFormat a format specifier
      */
    
      setTickFormat(context, tickFormat) {
        context.xAxis
        .tickFormat(d3.time.format(tickFormat));
      },
  • ¶

    Sets the tick count for xAxis

      /*
      @private
      @function setTickCount
      @description Sets the tick count for xAxis
      @param {Object} context Chart object
      @param {String} tickCount A count for the number of ticks
      @param {String} countBy countBy What interval ticks should count e.g. by month, year, minute
      */
    
      setTickCount(context, tickCount, countBy) {
        context.xAxis
        .ticks(d3.time[countBy], tickCount);
      },
    
    };
    
    export default InternalLine;