multiple_time_series.js 3.5 KB
Newer Older
1
import _ from 'underscore';
2 3 4 5 6 7
import { scaleLinear, scaleTime } from 'd3-scale';
import { line, area, curveLinear } from 'd3-shape';
import { extent, max } from 'd3-array';
import { timeMinute } from 'd3-time';

const d3 = { scaleLinear, scaleTime, line, area, curveLinear, extent, max, timeMinute };
8

9 10 11 12 13 14 15
const defaultColorPalette = {
  blue: ['#1f78d1', '#8fbce8'],
  orange: ['#fc9403', '#feca81'],
  red: ['#db3b21', '#ed9d90'],
  green: ['#1aaa55', '#8dd5aa'],
  purple: ['#6666c4', '#d1d1f0'],
};
16

17
const defaultColorOrder = ['blue', 'orange', 'red', 'green', 'purple'];
18

M
Mike Greiling 已提交
19 20
const defaultStyleOrder = ['solid', 'dashed', 'dotted'];

21
function queryTimeSeries(query, graphWidth, graphHeight, graphHeightOffset, xDom, yDom, lineStyle) {
22 23 24 25 26 27
  let usedColors = [];

  function pickColor(name) {
    let pick;
    if (name && defaultColorPalette[name]) {
      pick = name;
28
    } else {
29 30 31 32 33 34 35
      const unusedColors = _.difference(defaultColorOrder, usedColors);
      if (unusedColors.length > 0) {
        pick = unusedColors[0];
      } else {
        usedColors = [];
        pick = defaultColorOrder[0];
      }
36
    }
37 38
    usedColors.push(pick);
    return defaultColorPalette[pick];
39
  }
40

M
Mike Greiling 已提交
41
  return query.result.map((timeSeries, timeSeriesNumber) => {
J
Jose Ivan Vargas 已提交
42
    let metricTag = '';
43 44
    let lineColor = '';
    let areaColor = '';
45

46
    const timeSeriesScaleX = d3.scaleTime()
47 48
      .range([0, graphWidth - 70]);

49
    const timeSeriesScaleY = d3.scaleLinear()
50 51
      .range([graphHeight - graphHeightOffset, 0]);

52
    timeSeriesScaleX.domain(xDom);
53
    timeSeriesScaleX.ticks(d3.timeMinute, 60);
54
    timeSeriesScaleY.domain(yDom);
55

56 57
    const defined = d => !isNaN(d.value) && d.value != null;

58
    const lineFunction = d3.line()
59
      .defined(defined)
60
      .curve(d3.curveLinear) // d3 v4 uses curbe instead of interpolate
61 62 63
      .x(d => timeSeriesScaleX(d.time))
      .y(d => timeSeriesScaleY(d.value));

64
    const areaFunction = d3.area()
65
      .defined(defined)
66
      .curve(d3.curveLinear)
67 68
      .x(d => timeSeriesScaleX(d.time))
      .y0(graphHeight - graphHeightOffset)
69
      .y1(d => timeSeriesScaleY(d.value));
70

71
    const timeSeriesMetricLabel = timeSeries.metric[Object.keys(timeSeries.metric)[0]];
M
Mike Greiling 已提交
72
    const seriesCustomizationData = query.series != null &&
73 74 75
      _.findWhere(query.series[0].when, { value: timeSeriesMetricLabel });

    if (seriesCustomizationData) {
76 77
      metricTag = seriesCustomizationData.value || timeSeriesMetricLabel;
      [lineColor, areaColor] = pickColor(seriesCustomizationData.color);
J
Jose Ivan Vargas 已提交
78
    } else {
79 80
      metricTag = timeSeriesMetricLabel || `series ${timeSeriesNumber + 1}`;
      [lineColor, areaColor] = pickColor();
81 82
    }

83
    if (query.track) {
84
      metricTag += ` - ${query.track}`;
85 86
    }

87 88 89 90 91
    return {
      linePath: lineFunction(timeSeries.values),
      areaPath: areaFunction(timeSeries.values),
      timeSeriesScaleX,
      values: timeSeries.values,
M
Mike Greiling 已提交
92
      lineStyle,
93 94
      lineColor,
      areaColor,
95
      metricTag,
96 97 98
    };
  });
}
M
Mike Greiling 已提交
99 100

export default function createTimeSeries(queries, graphWidth, graphHeight, graphHeightOffset) {
101 102 103 104
  const allValues = queries.reduce((allQueryResults, query) => allQueryResults.concat(
    query.result.reduce((allResults, result) => allResults.concat(result.values), []),
  ), []);

105 106
  const xDom = d3.extent(allValues, d => d.time);
  const yDom = [0, d3.max(allValues.map(d => d.value))];
M
Mike Greiling 已提交
107 108 109 110

  return queries.reduce((series, query, index) => {
    const lineStyle = defaultStyleOrder[index % defaultStyleOrder.length];
    return series.concat(
111
      queryTimeSeries(query, graphWidth, graphHeight, graphHeightOffset, xDom, yDom, lineStyle),
M
Mike Greiling 已提交
112 113 114
    );
  }, []);
}