-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
Copy pathprepareDefaultData.js
156 lines (137 loc) · 4.71 KB
/
prepareDefaultData.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { isNil, extend, each, includes, map, sortBy } from "lodash";
import chooseTextColorForBackground from "@/lib/chooseTextColorForBackground";
import { ColorPaletteArray } from "@/visualizations/ColorPalette";
import { cleanNumber, normalizeValue, getSeriesAxis } from "./utils";
function getSeriesColor(seriesOptions, seriesIndex) {
return seriesOptions.color || ColorPaletteArray[seriesIndex % ColorPaletteArray.length];
}
function getHoverInfoPattern(options) {
const hasX = /{{\s*@@x\s*}}/.test(options.textFormat);
const hasName = /{{\s*@@name\s*}}/.test(options.textFormat);
let result = "text";
if (!hasX) result += "+x";
if (!hasName) result += "+name";
return result;
}
function prepareBarSeries(series, options) {
series.type = "bar";
if (options.showDataLabels) {
series.textposition = "inside";
}
return series;
}
function prepareLineSeries(series, options) {
series.mode = "lines" + (options.showDataLabels ? "+text" : "");
return series;
}
function prepareAreaSeries(series, options) {
series.mode = "lines" + (options.showDataLabels ? "+text" : "");
series.fill = options.series.stacking ? "tonexty" : "tozeroy";
return series;
}
function prepareScatterSeries(series, options) {
series.type = "scatter";
series.mode = "markers" + (options.showDataLabels ? "+text" : "");
return series;
}
function prepareBubbleSeries(series, options, { seriesColor, data }) {
series.mode = "markers";
series.marker = {
color: seriesColor,
size: map(data, i => i.size),
};
return series;
}
function prepareBoxSeries(series, options, { seriesColor }) {
series.type = "box";
series.mode = "markers";
series.boxpoints = "outliers";
series.hoverinfo = false;
series.marker = {
color: seriesColor,
size: 3,
};
if (options.showpoints) {
series.boxpoints = "all";
series.jitter = 0.3;
series.pointpos = -1.8;
}
return series;
}
function prepareSeries(series, options, additionalOptions) {
const { hoverInfoPattern, index } = additionalOptions;
const seriesOptions = extend({ type: options.globalSeriesType, yAxis: 0 }, options.seriesOptions[series.name]);
const seriesColor = getSeriesColor(seriesOptions, index);
const seriesYAxis = getSeriesAxis(series, options);
// Sort by x - `Map` preserves order of items
const data = options.sortX ? sortBy(series.data, d => normalizeValue(d.x, options.xAxis.type)) : series.data;
// For bubble/scatter charts `y` may be any (similar to `x`) - numeric is only bubble size;
// for other types `y` is always number
const cleanYValue = includes(["bubble", "scatter"], seriesOptions.type)
? normalizeValue
: v => {
v = cleanNumber(v);
return options.missingValuesAsZero && isNil(v) ? 0.0 : v;
};
const sourceData = new Map();
const xValues = [];
const yValues = [];
const yErrorValues = [];
each(data, row => {
const x = normalizeValue(row.x, options.xAxis.type); // number/datetime/category
const y = cleanYValue(row.y, seriesYAxis === "y2" ? options.yAxis[1].type : options.yAxis[0].type); // depends on series type!
const yError = cleanNumber(row.yError); // always number
const size = cleanNumber(row.size); // always number
sourceData.set(x, {
x,
y,
yError,
size,
yPercent: null, // will be updated later
row,
});
xValues.push(x);
yValues.push(y);
yErrorValues.push(yError);
});
const plotlySeries = {
visible: true,
hoverinfo: hoverInfoPattern,
x: xValues,
y: yValues,
error_y: {
array: yErrorValues,
color: seriesColor,
},
name: seriesOptions.name || series.name,
marker: { color: seriesColor },
insidetextfont: {
color: chooseTextColorForBackground(seriesColor),
},
yaxis: seriesYAxis,
sourceData,
};
additionalOptions = { ...additionalOptions, seriesColor, data };
switch (seriesOptions.type) {
case "column":
return prepareBarSeries(plotlySeries, options, additionalOptions);
case "line":
return prepareLineSeries(plotlySeries, options, additionalOptions);
case "area":
return prepareAreaSeries(plotlySeries, options, additionalOptions);
case "scatter":
return prepareScatterSeries(plotlySeries, options, additionalOptions);
case "bubble":
return prepareBubbleSeries(plotlySeries, options, additionalOptions);
case "box":
return prepareBoxSeries(plotlySeries, options, additionalOptions);
default:
return plotlySeries;
}
}
export default function prepareDefaultData(seriesList, options) {
const additionalOptions = {
hoverInfoPattern: getHoverInfoPattern(options),
};
return map(seriesList, (series, index) => prepareSeries(series, options, { ...additionalOptions, index }));
}