@deephaven/chart 0.38.1-beta.3 → 0.38.1-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,12 +5,10 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
5
5
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
6
6
  import Log from '@deephaven/log';
7
7
  import { TableUtils } from '@deephaven/jsapi-utils';
8
- import dh from '@deephaven/jsapi-shim';
9
8
  import set from 'lodash.set';
10
9
  import { assertNotNull } from '@deephaven/utils';
11
10
  import ChartTheme from "./ChartTheme.js";
12
11
  var log = Log.module('ChartUtils');
13
- var DAYS = Object.freeze(dh.calendar.DayOfWeek.values());
14
12
  var BUSINESS_COLUMN_TYPE = 'io.deephaven.time.DateTime';
15
13
  var MILLIS_PER_HOUR = 3600000;
16
14
  var NANOS_PER_MILLI = 1000000;
@@ -27,168 +25,6 @@ function isRangedPlotlyAxis(value) {
27
25
  return value != null && value.range != null && (value.autorange === false || value.autorange === undefined);
28
26
  }
29
27
  class ChartUtils {
30
- /**
31
- * Converts the Iris plot style into a plotly chart type
32
- * @param plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle
33
- * @param isBusinessTime If the plot is using business time for an axis
34
- */
35
- static getPlotlyChartType(plotStyle, isBusinessTime) {
36
- switch (plotStyle) {
37
- case dh.plot.SeriesPlotStyle.SCATTER:
38
- // scattergl mode is more performant, but doesn't support the rangebreaks we need for businessTime calendars
39
- return !isBusinessTime ? 'scattergl' : 'scatter';
40
- case dh.plot.SeriesPlotStyle.LINE:
41
- // There is also still some artifacting bugs with scattergl: https://github.com/plotly/plotly.js/issues/3522
42
- // The artifacting only occurs on line plots, which we can draw with fairly decent performance using SVG paths
43
- // Once the above plotly issue is fixed, scattergl should be used here (when !isBusinessTime)
44
- return 'scatter';
45
- case dh.plot.SeriesPlotStyle.BAR:
46
- case dh.plot.SeriesPlotStyle.STACKED_BAR:
47
- return 'bar';
48
- case dh.plot.SeriesPlotStyle.PIE:
49
- return 'pie';
50
- case dh.plot.SeriesPlotStyle.TREEMAP:
51
- return 'treemap';
52
- case dh.plot.SeriesPlotStyle.HISTOGRAM:
53
- return 'histogram';
54
- case dh.plot.SeriesPlotStyle.OHLC:
55
- return 'ohlc';
56
- default:
57
- return undefined;
58
- }
59
- }
60
-
61
- /**
62
- * Converts the Iris plot style into a plotly chart mode
63
- * @param plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle.*
64
- * @param areLinesVisible Whether lines are visible or not
65
- * @param areShapesVisible Whether shapes are visible or not
66
- */
67
- static getPlotlyChartMode(plotStyle, areLinesVisible, areShapesVisible) {
68
- var modes = new Set();
69
- switch (plotStyle) {
70
- case dh.plot.SeriesPlotStyle.SCATTER:
71
- // Default to only showing shapes in scatter plots
72
- if (areLinesVisible !== null && areLinesVisible !== void 0 ? areLinesVisible : false) {
73
- modes.add(ChartUtils.MODE_LINES);
74
- }
75
- if (areShapesVisible !== null && areShapesVisible !== void 0 ? areShapesVisible : true) {
76
- modes.add(ChartUtils.MODE_MARKERS);
77
- }
78
- break;
79
- case dh.plot.SeriesPlotStyle.LINE:
80
- // Default to only showing lines in line series
81
- if (areLinesVisible !== null && areLinesVisible !== void 0 ? areLinesVisible : true) {
82
- modes.add(ChartUtils.MODE_LINES);
83
- }
84
- if (areShapesVisible !== null && areShapesVisible !== void 0 ? areShapesVisible : false) {
85
- modes.add(ChartUtils.MODE_MARKERS);
86
- }
87
- break;
88
- default:
89
- break;
90
- }
91
- return modes.size > 0 ? [...modes].join('+') : undefined;
92
- }
93
-
94
- /**
95
- * Get the property to set on the series data for plotly
96
- * @param plotStyle The plot style of the series
97
- * @param sourceType The source type for the series
98
- */
99
- static getPlotlyProperty(plotStyle, sourceType) {
100
- switch (plotStyle) {
101
- case dh.plot.SeriesPlotStyle.PIE:
102
- switch (sourceType) {
103
- case dh.plot.SourceType.X:
104
- return 'labels';
105
- case dh.plot.SourceType.Y:
106
- return 'values';
107
- default:
108
- break;
109
- }
110
- break;
111
- case dh.plot.SeriesPlotStyle.OHLC:
112
- switch (sourceType) {
113
- case dh.plot.SourceType.TIME:
114
- return 'x';
115
- default:
116
- break;
117
- }
118
- break;
119
- case dh.plot.SeriesPlotStyle.TREEMAP:
120
- switch (sourceType) {
121
- case dh.plot.SourceType.X:
122
- return 'ids';
123
- case dh.plot.SourceType.Y:
124
- return 'values';
125
- case dh.plot.SourceType.LABEL:
126
- return 'labels';
127
- case dh.plot.SourceType.PARENT:
128
- return 'parents';
129
- case dh.plot.SourceType.COLOR:
130
- return 'marker.colors';
131
- default:
132
- break;
133
- }
134
- break;
135
- default:
136
- break;
137
- }
138
- switch (sourceType) {
139
- case dh.plot.SourceType.X:
140
- return 'x';
141
- case dh.plot.SourceType.Y:
142
- return 'y';
143
- case dh.plot.SourceType.Z:
144
- return 'z';
145
- case dh.plot.SourceType.X_LOW:
146
- return 'xLow';
147
- case dh.plot.SourceType.X_HIGH:
148
- return 'xHigh';
149
- case dh.plot.SourceType.Y_LOW:
150
- return 'yLow';
151
- case dh.plot.SourceType.Y_HIGH:
152
- return 'yHigh';
153
- case dh.plot.SourceType.TIME:
154
- return 'time';
155
- case dh.plot.SourceType.OPEN:
156
- return 'open';
157
- case dh.plot.SourceType.HIGH:
158
- return 'high';
159
- case dh.plot.SourceType.LOW:
160
- return 'low';
161
- case dh.plot.SourceType.CLOSE:
162
- return 'close';
163
- case dh.plot.SourceType.SHAPE:
164
- return 'shape';
165
- case dh.plot.SourceType.SIZE:
166
- return 'size';
167
- case dh.plot.SourceType.LABEL:
168
- return 'label';
169
- case dh.plot.SourceType.COLOR:
170
- return 'color';
171
- case dh.plot.SourceType.PARENT:
172
- return 'parent';
173
- case dh.plot.SourceType.HOVER_TEXT:
174
- return 'hovertext';
175
- case dh.plot.SourceType.TEXT:
176
- return 'text';
177
- default:
178
- throw new Error("Unrecognized source type: ".concat(sourceType));
179
- }
180
- }
181
- static getPlotlySeriesOrientation(series) {
182
- var _sources$, _sources$$axis;
183
- var {
184
- sources
185
- } = series;
186
- if (sources.length === 2 && ((_sources$ = sources[0]) === null || _sources$ === void 0 ? void 0 : (_sources$$axis = _sources$.axis) === null || _sources$$axis === void 0 ? void 0 : _sources$$axis.type) === dh.plot.AxisType.Y) {
187
- return ChartUtils.ORIENTATION.HORIZONTAL;
188
- }
189
- return ChartUtils.ORIENTATION.VERTICAL;
190
- }
191
-
192
28
  /**
193
29
  * Generate the plotly error bar data from the passed in data.
194
30
  * Iris passes in the values as absolute, plotly needs them as relative.
@@ -208,20 +44,6 @@ class ChartUtils {
208
44
  arrayminus
209
45
  };
210
46
  }
211
- static getPlotlyDateFormat(formatter, columnType, formatPattern) {
212
- var tickformat = formatPattern == null ? undefined : formatPattern.replace('%', '%%').replace(/S{9}/g, '%9f').replace(/S{8}/g, '%8f').replace(/S{7}/g, '%7f').replace(/S{6}/g, '%6f').replace(/S{5}/g, '%5f').replace(/S{4}/g, '%4f').replace(/S{3}/g, '%3f').replace(/S{2}/g, '%2f').replace(/S{1}/g, '%1f').replace(/y{4}/g, '%Y').replace(/y{2}/g, '%y').replace(/M{4}/g, '%B').replace(/M{3}/g, '%b').replace(/M{2}/g, '%m').replace(/M{1}/g, '%-m').replace(/E{4,}/g, '%A').replace(/E{1,}/g, '%a').replace(/d{2}/g, '%d').replace(/([^%]|^)d{1}/g, '$1%-d').replace(/H{2}/g, '%H').replace(/h{2}/g, '%I').replace(/h{1}/g, '%-I').replace(/m{2}/g, '%M').replace(/s{2}/g, '%S').replace("'T'", 'T').replace(' z', ''); // timezone added as suffix if necessary
213
-
214
- var ticksuffix;
215
- var dataFormatter = formatter === null || formatter === void 0 ? void 0 : formatter.getColumnTypeFormatter(columnType);
216
- if (dataFormatter != null && isDateTimeColumnFormatter(dataFormatter) && dataFormatter.dhTimeZone != null && dataFormatter.showTimeZone) {
217
- ticksuffix = dh.i18n.DateTimeFormat.format(' z', new Date(), dataFormatter.dhTimeZone);
218
- }
219
- return {
220
- tickformat,
221
- ticksuffix,
222
- automargin: true
223
- };
224
- }
225
47
  static convertNumberPrefix(prefix) {
226
48
  return prefix.replace(/\u00A4\u00A4/g, 'USD').replace(/\u00A4/g, '$');
227
49
  }
@@ -260,42 +82,6 @@ class ChartUtils {
260
82
  };
261
83
  }
262
84
 
263
- /**
264
- * Gets the plotly axis formatting information from the source passed in
265
- * @param source The Source to get the formatter information from
266
- * @param formatter The current formatter for formatting data
267
- */
268
- static getPlotlyAxisFormat(source) {
269
- var formatter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
270
- var {
271
- axis,
272
- columnType
273
- } = source;
274
- var {
275
- formatPattern
276
- } = axis;
277
- var axisFormat = null;
278
- if (TableUtils.isDateType(columnType)) {
279
- axisFormat = ChartUtils.getPlotlyDateFormat(formatter, columnType, formatPattern);
280
- axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, true);
281
- } else if (TableUtils.isNumberType(columnType)) {
282
- axisFormat = ChartUtils.getPlotlyNumberFormat(formatter, columnType, formatPattern);
283
- axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, false);
284
- }
285
- if (axis.formatType === dh.plot.AxisFormatType.CATEGORY) {
286
- if (axisFormat) {
287
- axisFormat.type = 'category';
288
- } else {
289
- axisFormat = {
290
- type: 'category',
291
- tickformat: undefined,
292
- ticksuffix: undefined
293
- };
294
- }
295
- }
296
- return axisFormat;
297
- }
298
-
299
85
  /**
300
86
  * Adds tick spacing for an axis that has gapBetweenMajorTicks defined.
301
87
  *
@@ -354,34 +140,457 @@ class ChartUtils {
354
140
  if (settings != null && settings.hiddenSeries != null && settings.hiddenSeries.includes(name)) {
355
141
  return 'legendonly';
356
142
  }
357
- return true;
143
+ return true;
144
+ }
145
+
146
+ /**
147
+ * Get hidden labels array from chart settings
148
+ * @param settings Chart settings
149
+ * @returns Array of hidden series names
150
+ */
151
+ static getHiddenLabels(settings) {
152
+ if (settings !== null && settings !== void 0 && settings.hiddenSeries) {
153
+ return [...settings.hiddenSeries];
154
+ }
155
+ return [];
156
+ }
157
+
158
+ /**
159
+ * Create a default series data object. Apply styling to the object afterward.
160
+ * @returns A simple series data object with no styling
161
+ */
162
+ static makeSeriesData(type, mode, name, showLegend) {
163
+ var orientation = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ChartUtils.ORIENTATION.VERTICAL;
164
+ return {
165
+ type,
166
+ mode,
167
+ name,
168
+ orientation,
169
+ showlegend: showLegend !== null && showLegend !== void 0 ? showLegend : undefined
170
+ };
171
+ }
172
+
173
+ /**
174
+ * Get the Plotly marker symbol for the provided Deephaven shape
175
+ * Deephaven shapes: https://deephaven.io/enterprise/docs/plotting/visual-formatting/#point-formatting
176
+ * Plotly shapes: https://plotly.com/javascript/reference/scattergl/#scattergl-marker-symbol
177
+ * Table of plotly shapes: https://plotly.com/python/marker-style/#custom-marker-symbols
178
+ * @param deephavenShape Deephaven shape to get the marker symbol for
179
+ */
180
+ static getMarkerSymbol(deephavenShape) {
181
+ switch (deephavenShape) {
182
+ case 'SQUARE':
183
+ return 'square';
184
+ case 'CIRCLE':
185
+ return 'circle';
186
+ case 'DIAMOND':
187
+ return 'diamond';
188
+ case 'UP_TRIANGLE':
189
+ return 'triangle-up';
190
+ case 'DOWN_TRIANGLE':
191
+ return 'triangle-down';
192
+ case 'RIGHT_TRIANGLE':
193
+ return 'triangle-right';
194
+ case 'LEFT_TRIANGLE':
195
+ return 'triangle-left';
196
+ // There don't seem to be any plotly equivalents for ellipse or rectangles
197
+ // Rectangles could be `line-ew`, `line-ns`, or `hourglass` and `bowtie` instead?
198
+ // Ellipse could be `asterisk` or `diamond-wide` instead?
199
+ // Just throw an error, we've already got a bunch of types.
200
+ case 'ELLIPSE':
201
+ case 'HORIZONTAL_RECTANGLE':
202
+ case 'VERTICAL_RECTANGLE':
203
+ default:
204
+ throw new Error("Unrecognized shape ".concat(deephavenShape));
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Get all axes for a given `Figure`. Iterates through all charts axes and concatenates them.
210
+ * @param figure Figure to get all axes for
211
+ */
212
+ static getAllAxes(figure) {
213
+ return figure.charts.reduce((axes, chart) => [...axes, ...chart.axes], []);
214
+ }
215
+
216
+ /**
217
+ * Retrieve the chart that contains the passed in series from the figure
218
+ * @param figure The figure to retrieve the chart from
219
+ * @param series The series to get the chart for
220
+ */
221
+ static getChartForSeries(figure, series) {
222
+ var {
223
+ charts
224
+ } = figure;
225
+ for (var i = 0; i < charts.length; i += 1) {
226
+ var _chart = charts[i];
227
+ for (var j = 0; j < _chart.series.length; j += 1) {
228
+ if (series === _chart.series[j]) {
229
+ return _chart;
230
+ }
231
+ }
232
+ }
233
+ return null;
234
+ }
235
+
236
+ /**
237
+ * Get an object mapping axis to their ranges
238
+ * @param layout The plotly layout object to get the ranges from
239
+ * @returns An object mapping the axis name to it's range
240
+ */
241
+ static getLayoutRanges(layout) {
242
+ var ranges = {};
243
+ var keys = Object.keys(layout).filter(key => key.indexOf('axis') >= 0);
244
+ for (var i = 0; i < keys.length; i += 1) {
245
+ var key = keys[i];
246
+ var value = layout[key];
247
+ if (isRangedPlotlyAxis(value)) {
248
+ // Only want to add the range if it's not autoranged
249
+ ranges[key] = [...value.range];
250
+ }
251
+ }
252
+ return ranges;
253
+ }
254
+ static getAxisLayoutProperty(axisProperty, axisIndex) {
255
+ var axisIndexString = axisIndex > 0 ? "".concat(axisIndex + 1) : '';
256
+ return "".concat(axisProperty !== null && axisProperty !== void 0 ? axisProperty : '', "axis").concat(axisIndexString);
257
+ }
258
+
259
+ /**
260
+ * Converts an open or close period to a declimal. e.g '09:30" to 9.5
261
+ *
262
+ * @param period the open or close value of the period
263
+ */
264
+ static periodToDecimal(period) {
265
+ var values = period.split(':');
266
+ return Number(values[0]) + Number(values[1]) / 60;
267
+ }
268
+
269
+ /**
270
+ * Groups an array and returns a map
271
+ * @param array The object to group
272
+ * @param property The property name to group by
273
+ * @returns A map containing the items grouped by their values for the property
274
+ */
275
+ static groupArray(array, property) {
276
+ return array.reduce((result, item) => {
277
+ var _result$get;
278
+ var key = item[property];
279
+ var group = (_result$get = result.get(key)) !== null && _result$get !== void 0 ? _result$get : [];
280
+ group.push(item);
281
+ result.set(key, group);
282
+ return result;
283
+ }, new Map());
284
+ }
285
+
286
+ /**
287
+ * Parses the colorway property of a theme and returns an array of colors
288
+ * Theme could have a single string with space separated colors or an array of strings representing the colorway
289
+ * @param theme The theme to get colorway from
290
+ * @returns Colorway array for the theme
291
+ */
292
+ static getColorwayFromTheme() {
293
+ var theme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChartTheme;
294
+ var colorway = [];
295
+ if (theme.colorway) {
296
+ if (Array.isArray(theme.colorway)) {
297
+ colorway = theme.colorway;
298
+ } else if (typeof theme.colorway === 'string') {
299
+ colorway = theme.colorway.split(' ');
300
+ } else {
301
+ log.warn("Unable to handle colorway property: ".concat(theme.colorway));
302
+ }
303
+ }
304
+ return colorway;
305
+ }
306
+ static titleFromSettings(settings) {
307
+ var {
308
+ series,
309
+ xAxis,
310
+ title = "".concat((series !== null && series !== void 0 ? series : []).join(', '), " by ").concat(xAxis)
311
+ } = settings;
312
+ return title;
313
+ }
314
+ constructor(dh) {
315
+ _defineProperty(this, "dh", void 0);
316
+ _defineProperty(this, "daysOfWeek", void 0);
317
+ this.dh = dh;
318
+ this.daysOfWeek = Object.freeze(dh.calendar.DayOfWeek.values());
319
+ }
320
+
321
+ /**
322
+ * Retrieve the axis formats from the provided figure.
323
+ * Currently defaults to just the x/y axes.
324
+ * @param figure The figure to get the axis formats for
325
+ * @param formatter The formatter to use when getting the axis format
326
+ * @returns A map of axis layout property names to axis formats
327
+ */
328
+ getAxisFormats(figure, formatter) {
329
+ var _this = this;
330
+ var axisFormats = new Map();
331
+ var nullFormat = {
332
+ tickformat: null,
333
+ ticksuffix: null
334
+ };
335
+ var allAxes = ChartUtils.getAllAxes(figure);
336
+ var axisTypeMap = ChartUtils.groupArray(allAxes, 'type');
337
+ var {
338
+ charts
339
+ } = figure;
340
+ for (var i = 0; i < charts.length; i += 1) {
341
+ var _chart2 = charts[i];
342
+ for (var j = 0; j < _chart2.series.length; j += 1) {
343
+ var series = _chart2.series[j];
344
+ var {
345
+ sources
346
+ } = series;
347
+ var axisSources = sources.filter(source => source.axis);
348
+ var _loop = function _loop() {
349
+ var source = axisSources[k];
350
+ var {
351
+ axis
352
+ } = source;
353
+ var {
354
+ type: axisType
355
+ } = axis;
356
+ var typeAxes = axisTypeMap.get(axisType);
357
+ assertNotNull(typeAxes);
358
+ var axisIndex = typeAxes.indexOf(axis);
359
+ var axisProperty = _this.getAxisPropertyName(axisType);
360
+ if (axisProperty != null) {
361
+ var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
362
+ if (axisFormats.has(axisLayoutProperty)) {
363
+ log.debug("".concat(axisLayoutProperty, " already added."));
364
+ } else {
365
+ log.debug("Adding ".concat(axisLayoutProperty, " to axisFormats."));
366
+ var axisFormat = _this.getPlotlyAxisFormat(source, formatter);
367
+ if (axisFormat === null) {
368
+ axisFormats.set(axisLayoutProperty, nullFormat);
369
+ } else {
370
+ axisFormats.set(axisLayoutProperty, axisFormat);
371
+ var {
372
+ businessCalendar
373
+ } = axis;
374
+ if (businessCalendar != null) {
375
+ var rangebreaks = [];
376
+ var {
377
+ businessPeriods,
378
+ businessDays,
379
+ holidays,
380
+ timeZone: calendarTimeZone
381
+ } = businessCalendar;
382
+ var typeFormatter = formatter === null || formatter === void 0 ? void 0 : formatter.getColumnTypeFormatter(BUSINESS_COLUMN_TYPE);
383
+ var formatterTimeZone;
384
+ if (isDateTimeColumnFormatter(typeFormatter)) {
385
+ formatterTimeZone = typeFormatter.dhTimeZone;
386
+ }
387
+ var timeZoneDiff = formatterTimeZone ? (calendarTimeZone.standardOffset - formatterTimeZone.standardOffset) / 60 : 0;
388
+ if (holidays.length > 0) {
389
+ rangebreaks.push(..._this.createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone));
390
+ }
391
+ businessPeriods.forEach(period => rangebreaks.push({
392
+ pattern: 'hour',
393
+ bounds: [ChartUtils.periodToDecimal(period.close) + timeZoneDiff, ChartUtils.periodToDecimal(period.open) + timeZoneDiff]
394
+ }));
395
+ // If there are seven business days, then there is no weekend
396
+ if (businessDays.length < _this.daysOfWeek.length) {
397
+ _this.createBoundsFromDays(businessDays).forEach(weekendBounds => rangebreaks.push({
398
+ pattern: 'day of week',
399
+ bounds: weekendBounds
400
+ }));
401
+ }
402
+ axisFormat.rangebreaks = rangebreaks;
403
+ }
404
+ if (axisFormats.size === _chart2.axes.length) {
405
+ return {
406
+ v: axisFormats
407
+ };
408
+ }
409
+ }
410
+ }
411
+ }
412
+ };
413
+ for (var k = 0; k < axisSources.length; k += 1) {
414
+ var _ret = _loop();
415
+ if (typeof _ret === "object") return _ret.v;
416
+ }
417
+ }
418
+ }
419
+ return axisFormats;
420
+ }
421
+
422
+ /**
423
+ * Converts the Iris plot style into a plotly chart type
424
+ * @param plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle
425
+ * @param isBusinessTime If the plot is using business time for an axis
426
+ */
427
+ getPlotlyChartType(plotStyle, isBusinessTime) {
428
+ var {
429
+ dh
430
+ } = this;
431
+ switch (plotStyle) {
432
+ case dh.plot.SeriesPlotStyle.SCATTER:
433
+ // scattergl mode is more performant, but doesn't support the rangebreaks we need for businessTime calendars
434
+ return !isBusinessTime ? 'scattergl' : 'scatter';
435
+ case dh.plot.SeriesPlotStyle.LINE:
436
+ // There is also still some artifacting bugs with scattergl: https://github.com/plotly/plotly.js/issues/3522
437
+ // The artifacting only occurs on line plots, which we can draw with fairly decent performance using SVG paths
438
+ // Once the above plotly issue is fixed, scattergl should be used here (when !isBusinessTime)
439
+ return 'scatter';
440
+ case dh.plot.SeriesPlotStyle.BAR:
441
+ case dh.plot.SeriesPlotStyle.STACKED_BAR:
442
+ return 'bar';
443
+ case dh.plot.SeriesPlotStyle.PIE:
444
+ return 'pie';
445
+ case dh.plot.SeriesPlotStyle.TREEMAP:
446
+ return 'treemap';
447
+ case dh.plot.SeriesPlotStyle.HISTOGRAM:
448
+ return 'histogram';
449
+ case dh.plot.SeriesPlotStyle.OHLC:
450
+ return 'ohlc';
451
+ default:
452
+ return undefined;
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Converts the Iris plot style into a plotly chart mode
458
+ * @param plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle.*
459
+ * @param areLinesVisible Whether lines are visible or not
460
+ * @param areShapesVisible Whether shapes are visible or not
461
+ */
462
+ getPlotlyChartMode(plotStyle, areLinesVisible, areShapesVisible) {
463
+ var {
464
+ dh
465
+ } = this;
466
+ var modes = new Set();
467
+ switch (plotStyle) {
468
+ case dh.plot.SeriesPlotStyle.SCATTER:
469
+ // Default to only showing shapes in scatter plots
470
+ if (areLinesVisible !== null && areLinesVisible !== void 0 ? areLinesVisible : false) {
471
+ modes.add(ChartUtils.MODE_LINES);
472
+ }
473
+ if (areShapesVisible !== null && areShapesVisible !== void 0 ? areShapesVisible : true) {
474
+ modes.add(ChartUtils.MODE_MARKERS);
475
+ }
476
+ break;
477
+ case dh.plot.SeriesPlotStyle.LINE:
478
+ // Default to only showing lines in line series
479
+ if (areLinesVisible !== null && areLinesVisible !== void 0 ? areLinesVisible : true) {
480
+ modes.add(ChartUtils.MODE_LINES);
481
+ }
482
+ if (areShapesVisible !== null && areShapesVisible !== void 0 ? areShapesVisible : false) {
483
+ modes.add(ChartUtils.MODE_MARKERS);
484
+ }
485
+ break;
486
+ default:
487
+ break;
488
+ }
489
+ return modes.size > 0 ? [...modes].join('+') : undefined;
490
+ }
491
+
492
+ /**
493
+ * Get the property to set on the series data for plotly
494
+ * @param plotStyle The plot style of the series
495
+ * @param sourceType The source type for the series
496
+ */
497
+ getPlotlyProperty(plotStyle, sourceType) {
498
+ var {
499
+ dh
500
+ } = this;
501
+ switch (plotStyle) {
502
+ case dh.plot.SeriesPlotStyle.PIE:
503
+ switch (sourceType) {
504
+ case dh.plot.SourceType.X:
505
+ return 'labels';
506
+ case dh.plot.SourceType.Y:
507
+ return 'values';
508
+ default:
509
+ break;
510
+ }
511
+ break;
512
+ case dh.plot.SeriesPlotStyle.OHLC:
513
+ switch (sourceType) {
514
+ case dh.plot.SourceType.TIME:
515
+ return 'x';
516
+ default:
517
+ break;
518
+ }
519
+ break;
520
+ case dh.plot.SeriesPlotStyle.TREEMAP:
521
+ switch (sourceType) {
522
+ case dh.plot.SourceType.X:
523
+ return 'ids';
524
+ case dh.plot.SourceType.Y:
525
+ return 'values';
526
+ case dh.plot.SourceType.LABEL:
527
+ return 'labels';
528
+ case dh.plot.SourceType.PARENT:
529
+ return 'parents';
530
+ case dh.plot.SourceType.COLOR:
531
+ return 'marker.colors';
532
+ default:
533
+ break;
534
+ }
535
+ break;
536
+ default:
537
+ break;
538
+ }
539
+ switch (sourceType) {
540
+ case dh.plot.SourceType.X:
541
+ return 'x';
542
+ case dh.plot.SourceType.Y:
543
+ return 'y';
544
+ case dh.plot.SourceType.Z:
545
+ return 'z';
546
+ case dh.plot.SourceType.X_LOW:
547
+ return 'xLow';
548
+ case dh.plot.SourceType.X_HIGH:
549
+ return 'xHigh';
550
+ case dh.plot.SourceType.Y_LOW:
551
+ return 'yLow';
552
+ case dh.plot.SourceType.Y_HIGH:
553
+ return 'yHigh';
554
+ case dh.plot.SourceType.TIME:
555
+ return 'time';
556
+ case dh.plot.SourceType.OPEN:
557
+ return 'open';
558
+ case dh.plot.SourceType.HIGH:
559
+ return 'high';
560
+ case dh.plot.SourceType.LOW:
561
+ return 'low';
562
+ case dh.plot.SourceType.CLOSE:
563
+ return 'close';
564
+ case dh.plot.SourceType.SHAPE:
565
+ return 'shape';
566
+ case dh.plot.SourceType.SIZE:
567
+ return 'size';
568
+ case dh.plot.SourceType.LABEL:
569
+ return 'label';
570
+ case dh.plot.SourceType.COLOR:
571
+ return 'color';
572
+ case dh.plot.SourceType.PARENT:
573
+ return 'parent';
574
+ case dh.plot.SourceType.HOVER_TEXT:
575
+ return 'hovertext';
576
+ case dh.plot.SourceType.TEXT:
577
+ return 'text';
578
+ default:
579
+ throw new Error("Unrecognized source type: ".concat(sourceType));
580
+ }
358
581
  }
359
-
360
- /**
361
- * Get hidden labels array from chart settings
362
- * @param settings Chart settings
363
- * @returns Array of hidden series names
364
- */
365
- static getHiddenLabels(settings) {
366
- if (settings !== null && settings !== void 0 && settings.hiddenSeries) {
367
- return [...settings.hiddenSeries];
582
+ getPlotlySeriesOrientation(series) {
583
+ var _sources$, _sources$$axis;
584
+ var {
585
+ dh
586
+ } = this;
587
+ var {
588
+ sources
589
+ } = series;
590
+ if (sources.length === 2 && ((_sources$ = sources[0]) === null || _sources$ === void 0 ? void 0 : (_sources$$axis = _sources$.axis) === null || _sources$$axis === void 0 ? void 0 : _sources$$axis.type) === dh.plot.AxisType.Y) {
591
+ return ChartUtils.ORIENTATION.HORIZONTAL;
368
592
  }
369
- return [];
370
- }
371
-
372
- /**
373
- * Create a default series data object. Apply styling to the object afterward.
374
- * @returns A simple series data object with no styling
375
- */
376
- static makeSeriesData(type, mode, name, showLegend) {
377
- var orientation = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ChartUtils.ORIENTATION.VERTICAL;
378
- return {
379
- type,
380
- mode,
381
- name,
382
- orientation,
383
- showlegend: showLegend !== null && showLegend !== void 0 ? showLegend : undefined
384
- };
593
+ return ChartUtils.ORIENTATION.VERTICAL;
385
594
  }
386
595
 
387
596
  /**
@@ -392,7 +601,7 @@ class ChartUtils {
392
601
  * @param theme The theme properties for the plot. See ChartTheme.js for an example
393
602
  * @returns The series data (trace) object for use with plotly.
394
603
  */
395
- static makeSeriesDataFromSeries(series, axisTypeMap, seriesVisibility) {
604
+ makeSeriesDataFromSeries(series, axisTypeMap, seriesVisibility) {
396
605
  var showLegend = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
397
606
  var theme = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : ChartTheme;
398
607
  var {
@@ -410,15 +619,15 @@ class ChartUtils {
410
619
  var _source$axis;
411
620
  return (_source$axis = source.axis) === null || _source$axis === void 0 ? void 0 : _source$axis.businessCalendar;
412
621
  });
413
- var type = ChartUtils.getChartType(plotStyle, isBusinessTime);
414
- var mode = ChartUtils.getPlotlyChartMode(plotStyle, isLinesVisible !== null && isLinesVisible !== void 0 ? isLinesVisible : undefined, isShapesVisible !== null && isShapesVisible !== void 0 ? isShapesVisible : undefined);
415
- var orientation = ChartUtils.getPlotlySeriesOrientation(series);
622
+ var type = this.getChartType(plotStyle, isBusinessTime);
623
+ var mode = this.getPlotlyChartMode(plotStyle, isLinesVisible !== null && isLinesVisible !== void 0 ? isLinesVisible : undefined, isShapesVisible !== null && isShapesVisible !== void 0 ? isShapesVisible : undefined);
624
+ var orientation = this.getPlotlySeriesOrientation(series);
416
625
  var seriesData = ChartUtils.makeSeriesData(type, mode, name, showLegend, orientation);
417
- ChartUtils.addSourcesToSeriesData(seriesData, plotStyle, sources, axisTypeMap);
418
- ChartUtils.addStylingToSeriesData(seriesData, plotStyle, theme, lineColor, shapeColor, shape, shapeSize, seriesVisibility);
626
+ this.addSourcesToSeriesData(seriesData, plotStyle, sources, axisTypeMap);
627
+ this.addStylingToSeriesData(seriesData, plotStyle, theme, lineColor, shapeColor, shape, shapeSize, seriesVisibility);
419
628
  return seriesData;
420
629
  }
421
- static addSourcesToSeriesData(seriesDataParam, plotStyle, sources, axisTypeMap) {
630
+ addSourcesToSeriesData(seriesDataParam, plotStyle, sources, axisTypeMap) {
422
631
  var seriesData = seriesDataParam;
423
632
  for (var k = 0; k < sources.length; k += 1) {
424
633
  var source = sources[k];
@@ -426,9 +635,9 @@ class ChartUtils {
426
635
  axis: _axis,
427
636
  type: sourceType
428
637
  } = source;
429
- var dataAttributeName = ChartUtils.getPlotlyProperty(plotStyle, sourceType);
638
+ var dataAttributeName = this.getPlotlyProperty(plotStyle, sourceType);
430
639
  set(seriesData, dataAttributeName, []);
431
- var axisProperty = _axis != null ? ChartUtils.getAxisPropertyName(_axis.type) : null;
640
+ var axisProperty = _axis != null ? this.getAxisPropertyName(_axis.type) : null;
432
641
  if (axisProperty != null) {
433
642
  var axes = axisTypeMap.get(_axis.type);
434
643
  if (axes) {
@@ -439,13 +648,16 @@ class ChartUtils {
439
648
  }
440
649
  }
441
650
  }
442
- static addStylingToSeriesData(seriesDataParam, plotStyle) {
651
+ addStylingToSeriesData(seriesDataParam, plotStyle) {
443
652
  var theme = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ChartTheme;
444
653
  var lineColor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
445
654
  var shapeColor = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
446
655
  var shape = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null;
447
656
  var shapeSize = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : null;
448
657
  var seriesVisibility = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
658
+ var {
659
+ dh
660
+ } = this;
449
661
  var seriesData = seriesDataParam;
450
662
  // Add some empty objects so we can fill them in later with details without checking for existence
451
663
  seriesData.marker = {
@@ -531,231 +743,58 @@ class ChartUtils {
531
743
  seriesData.visible = seriesVisibility;
532
744
  }
533
745
  }
534
-
535
- /**
536
- * Get the Plotly marker symbol for the provided Deephaven shape
537
- * Deephaven shapes: https://deephaven.io/enterprise/docs/plotting/visual-formatting/#point-formatting
538
- * Plotly shapes: https://plotly.com/javascript/reference/scattergl/#scattergl-marker-symbol
539
- * Table of plotly shapes: https://plotly.com/python/marker-style/#custom-marker-symbols
540
- * @param deephavenShape Deephaven shape to get the marker symbol for
541
- */
542
- static getMarkerSymbol(deephavenShape) {
543
- switch (deephavenShape) {
544
- case 'SQUARE':
545
- return 'square';
546
- case 'CIRCLE':
547
- return 'circle';
548
- case 'DIAMOND':
549
- return 'diamond';
550
- case 'UP_TRIANGLE':
551
- return 'triangle-up';
552
- case 'DOWN_TRIANGLE':
553
- return 'triangle-down';
554
- case 'RIGHT_TRIANGLE':
555
- return 'triangle-right';
556
- case 'LEFT_TRIANGLE':
557
- return 'triangle-left';
558
- // There don't seem to be any plotly equivalents for ellipse or rectangles
559
- // Rectangles could be `line-ew`, `line-ns`, or `hourglass` and `bowtie` instead?
560
- // Ellipse could be `asterisk` or `diamond-wide` instead?
561
- // Just throw an error, we've already got a bunch of types.
562
- case 'ELLIPSE':
563
- case 'HORIZONTAL_RECTANGLE':
564
- case 'VERTICAL_RECTANGLE':
565
- default:
566
- throw new Error("Unrecognized shape ".concat(deephavenShape));
567
- }
568
- }
569
-
570
- /**
571
- * Retrieve the axis formats from the provided figure.
572
- * Currently defaults to just the x/y axes.
573
- * @param figure The figure to get the axis formats for
574
- * @param formatter The formatter to use when getting the axis format
575
- * @returns A map of axis layout property names to axis formats
576
- */
577
- static getAxisFormats(figure, formatter) {
578
- var axisFormats = new Map();
579
- var nullFormat = {
580
- tickformat: null,
581
- ticksuffix: null
582
- };
583
- var allAxes = ChartUtils.getAllAxes(figure);
584
- var axisTypeMap = ChartUtils.groupArray(allAxes, 'type');
746
+ getChartType(plotStyle, isBusinessTime) {
585
747
  var {
586
- charts
587
- } = figure;
588
- for (var i = 0; i < charts.length; i += 1) {
589
- var _chart = charts[i];
590
- for (var j = 0; j < _chart.series.length; j += 1) {
591
- var series = _chart.series[j];
592
- var {
593
- sources
594
- } = series;
595
- var axisSources = sources.filter(source => source.axis);
596
- var _loop = function _loop() {
597
- var source = axisSources[k];
598
- var {
599
- axis
600
- } = source;
601
- var {
602
- type: axisType
603
- } = axis;
604
- var typeAxes = axisTypeMap.get(axisType);
605
- assertNotNull(typeAxes);
606
- var axisIndex = typeAxes.indexOf(axis);
607
- var axisProperty = ChartUtils.getAxisPropertyName(axisType);
608
- if (axisProperty != null) {
609
- var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
610
- if (axisFormats.has(axisLayoutProperty)) {
611
- log.debug("".concat(axisLayoutProperty, " already added."));
612
- } else {
613
- log.debug("Adding ".concat(axisLayoutProperty, " to axisFormats."));
614
- var axisFormat = ChartUtils.getPlotlyAxisFormat(source, formatter);
615
- if (axisFormat === null) {
616
- axisFormats.set(axisLayoutProperty, nullFormat);
617
- } else {
618
- axisFormats.set(axisLayoutProperty, axisFormat);
619
- var {
620
- businessCalendar
621
- } = axis;
622
- if (businessCalendar != null) {
623
- var rangebreaks = [];
624
- var {
625
- businessPeriods,
626
- businessDays,
627
- holidays,
628
- timeZone: calendarTimeZone
629
- } = businessCalendar;
630
- var typeFormatter = formatter === null || formatter === void 0 ? void 0 : formatter.getColumnTypeFormatter(BUSINESS_COLUMN_TYPE);
631
- var formatterTimeZone;
632
- if (isDateTimeColumnFormatter(typeFormatter)) {
633
- formatterTimeZone = typeFormatter.dhTimeZone;
634
- }
635
- var timeZoneDiff = formatterTimeZone ? (calendarTimeZone.standardOffset - formatterTimeZone.standardOffset) / 60 : 0;
636
- if (holidays.length > 0) {
637
- rangebreaks.push(...ChartUtils.createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone));
638
- }
639
- businessPeriods.forEach(period => rangebreaks.push({
640
- pattern: 'hour',
641
- bounds: [ChartUtils.periodToDecimal(period.close) + timeZoneDiff, ChartUtils.periodToDecimal(period.open) + timeZoneDiff]
642
- }));
643
- // If there are seven business days, then there is no weekend
644
- if (businessDays.length < DAYS.length) {
645
- ChartUtils.createBoundsFromDays(businessDays).forEach(weekendBounds => rangebreaks.push({
646
- pattern: 'day of week',
647
- bounds: weekendBounds
648
- }));
649
- }
650
- axisFormat.rangebreaks = rangebreaks;
651
- }
652
- if (axisFormats.size === _chart.axes.length) {
653
- return {
654
- v: axisFormats
655
- };
656
- }
657
- }
658
- }
659
- }
660
- };
661
- for (var k = 0; k < axisSources.length; k += 1) {
662
- var _ret = _loop();
663
- if (typeof _ret === "object") return _ret.v;
664
- }
665
- }
666
- }
667
- return axisFormats;
668
- }
669
- static getChartType(plotStyle, isBusinessTime) {
748
+ dh
749
+ } = this;
670
750
  switch (plotStyle) {
671
751
  case dh.plot.SeriesPlotStyle.HISTOGRAM:
672
752
  // When reading data from the `Figure`, it already provides bins and values, so rather than using
673
753
  // plot.ly to calculate the bins and sum values, just convert it to a bar chart
674
754
  return 'bar';
675
755
  default:
676
- return ChartUtils.getPlotlyChartType(plotStyle, isBusinessTime);
677
- }
678
- }
679
-
680
- /**
681
- * Return the plotly axis property name
682
- * @param axisType The axis type to get the property name for
683
- */
684
- static getAxisPropertyName(axisType) {
685
- switch (axisType) {
686
- case dh.plot.AxisType.X:
687
- return 'x';
688
- case dh.plot.AxisType.Y:
689
- return 'y';
690
- default:
691
- return null;
692
- }
693
- }
694
-
695
- /**
696
- * Returns the plotly "side" value for the provided axis position
697
- * @param axisPosition The Iris AxisPosition of the axis
698
- */
699
- static getAxisSide(axisPosition) {
700
- switch (axisPosition) {
701
- case dh.plot.AxisPosition.BOTTOM:
702
- return 'bottom';
703
- case dh.plot.AxisPosition.TOP:
704
- return 'top';
705
- case dh.plot.AxisPosition.LEFT:
706
- return 'left';
707
- case dh.plot.AxisPosition.RIGHT:
708
- return 'right';
709
- default:
710
- return undefined;
756
+ return this.getPlotlyChartType(plotStyle, isBusinessTime);
711
757
  }
712
758
  }
713
-
714
- /**
715
- * Get all axes for a given `Figure`. Iterates through all charts axes and concatenates them.
716
- * @param figure Figure to get all axes for
717
- */
718
- static getAllAxes(figure) {
719
- return figure.charts.reduce((axes, chart) => [...axes, ...chart.axes], []);
720
- }
721
-
722
- /**
723
- * Retrieve the chart that contains the passed in series from the figure
724
- * @param figure The figure to retrieve the chart from
725
- * @param series The series to get the chart for
726
- */
727
- static getChartForSeries(figure, series) {
728
- var {
729
- charts
730
- } = figure;
731
- for (var i = 0; i < charts.length; i += 1) {
732
- var _chart2 = charts[i];
733
- for (var j = 0; j < _chart2.series.length; j += 1) {
734
- if (series === _chart2.series[j]) {
735
- return _chart2;
736
- }
737
- }
759
+
760
+ /**
761
+ * Return the plotly axis property name
762
+ * @param axisType The axis type to get the property name for
763
+ */
764
+ getAxisPropertyName(axisType) {
765
+ var {
766
+ dh
767
+ } = this;
768
+ switch (axisType) {
769
+ case dh.plot.AxisType.X:
770
+ return 'x';
771
+ case dh.plot.AxisType.Y:
772
+ return 'y';
773
+ default:
774
+ return null;
738
775
  }
739
- return null;
740
776
  }
741
777
 
742
778
  /**
743
- * Get an object mapping axis to their ranges
744
- * @param layout The plotly layout object to get the ranges from
745
- * @returns An object mapping the axis name to it's range
779
+ * Returns the plotly "side" value for the provided axis position
780
+ * @param axisPosition The Iris AxisPosition of the axis
746
781
  */
747
- static getLayoutRanges(layout) {
748
- var ranges = {};
749
- var keys = Object.keys(layout).filter(key => key.indexOf('axis') >= 0);
750
- for (var i = 0; i < keys.length; i += 1) {
751
- var key = keys[i];
752
- var value = layout[key];
753
- if (isRangedPlotlyAxis(value)) {
754
- // Only want to add the range if it's not autoranged
755
- ranges[key] = [...value.range];
756
- }
782
+ getAxisSide(axisPosition) {
783
+ var {
784
+ dh
785
+ } = this;
786
+ switch (axisPosition) {
787
+ case dh.plot.AxisPosition.BOTTOM:
788
+ return 'bottom';
789
+ case dh.plot.AxisPosition.TOP:
790
+ return 'top';
791
+ case dh.plot.AxisPosition.LEFT:
792
+ return 'left';
793
+ case dh.plot.AxisPosition.RIGHT:
794
+ return 'right';
795
+ default:
796
+ return undefined;
757
797
  }
758
- return ranges;
759
798
  }
760
799
 
761
800
  /**
@@ -767,7 +806,7 @@ class ChartUtils {
767
806
  * @param plotHeight Height of the plot in pixels
768
807
  * @param theme Theme used for displaying the plot
769
808
  */
770
- static updateFigureAxes(layoutParam, figure, chartAxisRangeParser) {
809
+ updateFigureAxes(layoutParam, figure, chartAxisRangeParser) {
771
810
  var plotWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
772
811
  var plotHeight = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
773
812
  var theme = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : ChartTheme;
@@ -776,13 +815,16 @@ class ChartUtils {
776
815
  for (var i = 0; i < figure.charts.length; i += 1) {
777
816
  var _chart3 = figure.charts[i];
778
817
  var axisRangeParser = chartAxisRangeParser === null || chartAxisRangeParser === void 0 ? void 0 : chartAxisRangeParser(_chart3);
779
- var bounds = ChartUtils.getChartBounds(figure, _chart3, plotWidth, plotHeight);
780
- ChartUtils.updateLayoutAxes(layout, _chart3.axes, figureAxes, plotWidth, plotHeight, bounds, axisRangeParser, theme);
818
+ var bounds = this.getChartBounds(figure, _chart3, plotWidth, plotHeight);
819
+ this.updateLayoutAxes(layout, _chart3.axes, figureAxes, plotWidth, plotHeight, bounds, axisRangeParser, theme);
781
820
  }
782
- ChartUtils.removeStaleAxes(layout, figureAxes);
821
+ this.removeStaleAxes(layout, figureAxes);
783
822
  }
784
- static getChartBounds(figure, chart, plotWidth, plotHeight) {
823
+ getChartBounds(figure, chart, plotWidth, plotHeight) {
785
824
  var _axisPositionMap$get;
825
+ var {
826
+ dh
827
+ } = this;
786
828
  var {
787
829
  cols,
788
830
  rows
@@ -820,6 +862,62 @@ class ChartUtils {
820
862
  }
821
863
  return bounds;
822
864
  }
865
+ getPlotlyDateFormat(formatter, columnType, formatPattern) {
866
+ var {
867
+ dh
868
+ } = this;
869
+ var tickformat = formatPattern == null ? undefined : formatPattern.replace('%', '%%').replace(/S{9}/g, '%9f').replace(/S{8}/g, '%8f').replace(/S{7}/g, '%7f').replace(/S{6}/g, '%6f').replace(/S{5}/g, '%5f').replace(/S{4}/g, '%4f').replace(/S{3}/g, '%3f').replace(/S{2}/g, '%2f').replace(/S{1}/g, '%1f').replace(/y{4}/g, '%Y').replace(/y{2}/g, '%y').replace(/M{4}/g, '%B').replace(/M{3}/g, '%b').replace(/M{2}/g, '%m').replace(/M{1}/g, '%-m').replace(/E{4,}/g, '%A').replace(/E{1,}/g, '%a').replace(/d{2}/g, '%d').replace(/([^%]|^)d{1}/g, '$1%-d').replace(/H{2}/g, '%H').replace(/h{2}/g, '%I').replace(/h{1}/g, '%-I').replace(/m{2}/g, '%M').replace(/s{2}/g, '%S').replace("'T'", 'T').replace(' z', ''); // timezone added as suffix if necessary
870
+
871
+ var ticksuffix;
872
+ var dataFormatter = formatter === null || formatter === void 0 ? void 0 : formatter.getColumnTypeFormatter(columnType);
873
+ if (dataFormatter != null && isDateTimeColumnFormatter(dataFormatter) && dataFormatter.dhTimeZone != null && dataFormatter.showTimeZone) {
874
+ ticksuffix = dh.i18n.DateTimeFormat.format(' z', new Date(), dataFormatter.dhTimeZone);
875
+ }
876
+ return {
877
+ tickformat,
878
+ ticksuffix,
879
+ automargin: true
880
+ };
881
+ }
882
+
883
+ /**
884
+ * Gets the plotly axis formatting information from the source passed in
885
+ * @param source The Source to get the formatter information from
886
+ * @param formatter The current formatter for formatting data
887
+ */
888
+ getPlotlyAxisFormat(source) {
889
+ var formatter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
890
+ var {
891
+ dh
892
+ } = this;
893
+ var {
894
+ axis,
895
+ columnType
896
+ } = source;
897
+ var {
898
+ formatPattern
899
+ } = axis;
900
+ var axisFormat = null;
901
+ if (TableUtils.isDateType(columnType)) {
902
+ axisFormat = this.getPlotlyDateFormat(formatter, columnType, formatPattern);
903
+ axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, true);
904
+ } else if (TableUtils.isNumberType(columnType)) {
905
+ axisFormat = ChartUtils.getPlotlyNumberFormat(formatter, columnType, formatPattern);
906
+ axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, false);
907
+ }
908
+ if (axis.formatType === dh.plot.AxisFormatType.CATEGORY) {
909
+ if (axisFormat) {
910
+ axisFormat.type = 'category';
911
+ } else {
912
+ axisFormat = {
913
+ type: 'category',
914
+ tickformat: undefined,
915
+ ticksuffix: undefined
916
+ };
917
+ }
918
+ }
919
+ return axisFormat;
920
+ }
823
921
 
824
922
  /**
825
923
  * Updates the axes positions and sizes in the layout object provided.
@@ -834,7 +932,7 @@ class ChartUtils {
834
932
  * @param bounds The bounds for this set of axes
835
933
  * @param axisRangeParser A function to retrieve the range parser for a given axis
836
934
  */
837
- static updateLayoutAxes(layoutParam, chartAxes, figureAxes) {
935
+ updateLayoutAxes(layoutParam, chartAxes, figureAxes) {
838
936
  var plotWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
839
937
  var plotHeight = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
840
938
  var bounds = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
@@ -845,6 +943,9 @@ class ChartUtils {
845
943
  };
846
944
  var axisRangeParser = arguments.length > 6 ? arguments[6] : undefined;
847
945
  var theme = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : ChartTheme;
946
+ var {
947
+ dh
948
+ } = this;
848
949
  var xAxisSize = plotWidth > 0 ? Math.max(ChartUtils.MIN_AXIS_SIZE, Math.min(ChartUtils.AXIS_SIZE_PX / plotHeight, ChartUtils.MAX_AXIS_SIZE)) : ChartUtils.DEFAULT_AXIS_SIZE;
849
950
  var yAxisSize = plotHeight > 0 ? Math.max(ChartUtils.MIN_AXIS_SIZE, Math.min(ChartUtils.AXIS_SIZE_PX / plotWidth, ChartUtils.MAX_AXIS_SIZE)) : ChartUtils.DEFAULT_AXIS_SIZE;
850
951
  var layout = layoutParam;
@@ -854,7 +955,7 @@ class ChartUtils {
854
955
  var figureAxisTypeMap = ChartUtils.groupArray(figureAxes, 'type');
855
956
  for (var j = 0; j < axisTypes.length; j += 1) {
856
957
  var axisType = axisTypes[j];
857
- var axisProperty = ChartUtils.getAxisPropertyName(axisType);
958
+ var axisProperty = this.getAxisPropertyName(axisType);
858
959
  if (axisProperty != null) {
859
960
  var typeAxes = axisTypeMap.get(axisType);
860
961
  var figureTypeAxes = figureAxisTypeMap.get(axisType);
@@ -867,11 +968,11 @@ class ChartUtils {
867
968
  var figureAxisIndex = figureTypeAxes.indexOf(_axis2);
868
969
  var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, figureAxisIndex);
869
970
  if (layout[axisLayoutProperty] == null) {
870
- layout[axisLayoutProperty] = ChartUtils.makeLayoutAxis(axisType, theme);
971
+ layout[axisLayoutProperty] = this.makeLayoutAxis(axisType, theme);
871
972
  }
872
973
  var layoutAxis = layout[axisLayoutProperty];
873
974
  if (layoutAxis != null) {
874
- ChartUtils.updateLayoutAxis(layoutAxis, _axis2, chartAxisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds);
975
+ this.updateLayoutAxis(layoutAxis, _axis2, chartAxisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds);
875
976
  var {
876
977
  range: _range,
877
978
  autorange
@@ -895,7 +996,7 @@ class ChartUtils {
895
996
  * @param layoutParam Layout object to remove stale axes from
896
997
  * @param axes All axes in the figure
897
998
  */
898
- static removeStaleAxes(layoutParam, axes) {
999
+ removeStaleAxes(layoutParam, axes) {
899
1000
  var layout = layoutParam;
900
1001
  var figureAxisTypeMap = ChartUtils.groupArray(axes, 'type');
901
1002
  var figureAxisTypes = [...figureAxisTypeMap.keys()];
@@ -905,7 +1006,7 @@ class ChartUtils {
905
1006
  assertNotNull(typeAxes);
906
1007
  var axisIndex = typeAxes.length;
907
1008
  // Delete any axes that may no longer exist
908
- var axisProperty = ChartUtils.getAxisPropertyName(axisType);
1009
+ var axisProperty = this.getAxisPropertyName(axisType);
909
1010
  if (axisProperty != null) {
910
1011
  var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
911
1012
  while (layout[axisLayoutProperty] != null) {
@@ -916,10 +1017,6 @@ class ChartUtils {
916
1017
  }
917
1018
  }
918
1019
  }
919
- static getAxisLayoutProperty(axisProperty, axisIndex) {
920
- var axisIndexString = axisIndex > 0 ? "".concat(axisIndex + 1) : '';
921
- return "".concat(axisProperty !== null && axisProperty !== void 0 ? axisProperty : '', "axis").concat(axisIndexString);
922
- }
923
1020
 
924
1021
  /**
925
1022
  * Updates the layout axis object in place
@@ -930,8 +1027,11 @@ class ChartUtils {
930
1027
  * @param axisSize The size of each axis in percent
931
1028
  * @param bounds The bounds of the axes domains
932
1029
  */
933
- static updateLayoutAxis(layoutAxisParam, axis, axisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds) {
1030
+ updateLayoutAxis(layoutAxisParam, axis, axisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds) {
934
1031
  var _axis$label;
1032
+ var {
1033
+ dh
1034
+ } = this;
935
1035
  var isYAxis = axis.type === dh.plot.AxisType.Y;
936
1036
  var axisSize = isYAxis ? yAxisSize : xAxisSize;
937
1037
  var layoutAxis = layoutAxisParam;
@@ -948,10 +1048,10 @@ class ChartUtils {
948
1048
  if (axis.log) {
949
1049
  layoutAxis.type = 'log';
950
1050
  }
951
- layoutAxis.side = ChartUtils.getAxisSide(axis.position);
1051
+ layoutAxis.side = this.getAxisSide(axis.position);
952
1052
  if (axisIndex > 0) {
953
- var _ChartUtils$getAxisPr, _axisPositionMap$get2;
954
- layoutAxis.overlaying = (_ChartUtils$getAxisPr = ChartUtils.getAxisPropertyName(axis.type)) !== null && _ChartUtils$getAxisPr !== void 0 ? _ChartUtils$getAxisPr : undefined;
1053
+ var _this$getAxisProperty, _axisPositionMap$get2;
1054
+ layoutAxis.overlaying = (_this$getAxisProperty = this.getAxisPropertyName(axis.type)) !== null && _this$getAxisProperty !== void 0 ? _this$getAxisProperty : undefined;
955
1055
  var positionAxes = (_axisPositionMap$get2 = axisPositionMap.get(axis.position)) !== null && _axisPositionMap$get2 !== void 0 ? _axisPositionMap$get2 : [];
956
1056
  var sideIndex = positionAxes.indexOf(axis);
957
1057
  if (sideIndex > 0) {
@@ -981,16 +1081,6 @@ class ChartUtils {
981
1081
  }
982
1082
  }
983
1083
 
984
- /**
985
- * Converts an open or close period to a declimal. e.g '09:30" to 9.5
986
- *
987
- * @param period the open or close value of the period
988
- */
989
- static periodToDecimal(period) {
990
- var values = period.split(':');
991
- return Number(values[0]) + Number(values[1]) / 60;
992
- }
993
-
994
1084
  /**
995
1085
  * Creates range break bounds for plotly from business days.
996
1086
  * For example a standard business week of ['MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY']
@@ -999,14 +1089,14 @@ class ChartUtils {
999
1089
  *
1000
1090
  * @param businessDays the days to display on the x-axis
1001
1091
  */
1002
- static createBoundsFromDays(businessDays) {
1003
- var businessDaysInt = businessDays.map(day => DAYS.indexOf(day));
1004
- var nonBusinessDaysInt = DAYS.filter(day => !businessDays.includes(day)).map(day => DAYS.indexOf(day));
1092
+ createBoundsFromDays(businessDays) {
1093
+ var businessDaysInt = businessDays.map(day => this.daysOfWeek.indexOf(day));
1094
+ var nonBusinessDaysInt = this.daysOfWeek.filter(day => !businessDays.includes(day)).map(day => this.daysOfWeek.indexOf(day));
1005
1095
  // These are the days when business reopens (e.g. Monday after a weekend)
1006
1096
  var reopenDays = new Set();
1007
1097
  nonBusinessDaysInt.forEach(closed => {
1008
- for (var i = closed + 1; i < closed + DAYS.length; i += 1) {
1009
- var adjustedDay = i % DAYS.length;
1098
+ for (var i = closed + 1; i < closed + this.daysOfWeek.length; i += 1) {
1099
+ var adjustedDay = i % this.daysOfWeek.length;
1010
1100
  if (businessDaysInt.includes(adjustedDay)) {
1011
1101
  reopenDays.add(adjustedDay);
1012
1102
  break;
@@ -1016,8 +1106,8 @@ class ChartUtils {
1016
1106
  var boundsArray = [];
1017
1107
  // For each reopen day, find the furthest previous closed day
1018
1108
  reopenDays.forEach(open => {
1019
- for (var i = open - 1; i > open - DAYS.length; i -= 1) {
1020
- var adjustedDay = i < 0 ? i + DAYS.length : i;
1109
+ for (var i = open - 1; i > open - this.daysOfWeek.length; i -= 1) {
1110
+ var adjustedDay = i < 0 ? i + this.daysOfWeek.length : i;
1021
1111
  if (businessDaysInt.includes(adjustedDay)) {
1022
1112
  var closedDay = (adjustedDay + 1) % 7;
1023
1113
  boundsArray.push([closedDay, open]);
@@ -1035,14 +1125,14 @@ class ChartUtils {
1035
1125
  * @param calendarTimeZone the time zone for the business calendar
1036
1126
  * @param formatterTimeZone the time zone for the formatter
1037
1127
  */
1038
- static createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone) {
1128
+ createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone) {
1039
1129
  var fullHolidays = [];
1040
1130
  var partialHolidays = [];
1041
1131
  holidays.forEach(holiday => {
1042
1132
  if (holiday.businessPeriods.length > 0) {
1043
- partialHolidays.push(...ChartUtils.createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone));
1133
+ partialHolidays.push(...this.createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone));
1044
1134
  } else {
1045
- fullHolidays.push(ChartUtils.createFullHoliday(holiday, calendarTimeZone, formatterTimeZone));
1135
+ fullHolidays.push(this.createFullHoliday(holiday, calendarTimeZone, formatterTimeZone));
1046
1136
  }
1047
1137
  });
1048
1138
  return [{
@@ -1057,8 +1147,8 @@ class ChartUtils {
1057
1147
  * @param calendarTimeZone the time zone for the business calendar
1058
1148
  * @param formatterTimeZone the time zone for the formatter
1059
1149
  */
1060
- static createFullHoliday(holiday, calendarTimeZone, formatterTimeZone) {
1061
- return ChartUtils.adjustDateForTimeZone("".concat(holiday.date.toString(), " 00:00:00.000000"), calendarTimeZone, formatterTimeZone);
1150
+ createFullHoliday(holiday, calendarTimeZone, formatterTimeZone) {
1151
+ return this.adjustDateForTimeZone("".concat(holiday.date.toString(), " 00:00:00.000000"), calendarTimeZone, formatterTimeZone);
1062
1152
  }
1063
1153
 
1064
1154
  /**
@@ -1069,7 +1159,7 @@ class ChartUtils {
1069
1159
  * @param calendarTimeZone the time zone for the business calendar
1070
1160
  * @param formatterTimeZone the time zone for the formatter
1071
1161
  */
1072
- static createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone) {
1162
+ createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone) {
1073
1163
  // If a holiday has business periods {open1, close1} and {open2, close2}
1074
1164
  // This will generate range breaks for:
1075
1165
  // closed from 00:00 to open1
@@ -1089,7 +1179,7 @@ class ChartUtils {
1089
1179
  var endClose = closedPeriods[i + 1];
1090
1180
  // Skip over any periods where start and close are the same (zero hours)
1091
1181
  if (startClose !== endClose) {
1092
- var values = [ChartUtils.adjustDateForTimeZone("".concat(dateString, " ").concat(startClose, ":00.000000"), calendarTimeZone, formatterTimeZone)];
1182
+ var values = [this.adjustDateForTimeZone("".concat(dateString, " ").concat(startClose, ":00.000000"), calendarTimeZone, formatterTimeZone)];
1093
1183
  var dvalue = MILLIS_PER_HOUR * (ChartUtils.periodToDecimal(endClose) - ChartUtils.periodToDecimal(startClose));
1094
1184
  rangeBreaks.push({
1095
1185
  values,
@@ -1107,35 +1197,77 @@ class ChartUtils {
1107
1197
  * @param calendarTimeZone the time zone for the business calendar
1108
1198
  * @param formatterTimeZone the time zone for the formatter
1109
1199
  */
1110
- static adjustDateForTimeZone(dateString, calendarTimeZone, formatterTimeZone) {
1200
+ adjustDateForTimeZone(dateString, calendarTimeZone, formatterTimeZone) {
1111
1201
  if (formatterTimeZone && formatterTimeZone.standardOffset !== calendarTimeZone.standardOffset) {
1112
- return ChartUtils.unwrapValue(ChartUtils.wrapValue(dateString, BUSINESS_COLUMN_TYPE, calendarTimeZone), formatterTimeZone);
1202
+ return this.unwrapValue(this.wrapValue(dateString, BUSINESS_COLUMN_TYPE, calendarTimeZone), formatterTimeZone);
1113
1203
  }
1114
1204
  return dateString;
1115
1205
  }
1116
1206
 
1117
1207
  /**
1118
- * Groups an array and returns a map
1119
- * @param array The object to group
1120
- * @param property The property name to group by
1121
- * @returns A map containing the items grouped by their values for the property
1208
+ * Creates the Figure settings from the Chart Builder settings
1209
+ * This should be deprecated at some point, and have Chart Builder create the figure settings directly.
1210
+ * This logic will still need to exist to translate existing charts, but could be part of a migration script
1211
+ * to translate the data.
1212
+ * Change when we decide to add more functionality to the Chart Builder.
1213
+ * @param settings The chart builder settings
1214
+ * @param settings.title The title for this figure
1215
+ * @param settings.xAxis The name of the column to use for the x-axis
1216
+ * @param settings.series The name of the columns to use for the series of this figure
1217
+ * @param settings.type The plot style for this figure
1122
1218
  */
1123
- static groupArray(array, property) {
1124
- return array.reduce((result, item) => {
1125
- var _result$get;
1126
- var key = item[property];
1127
- var group = (_result$get = result.get(key)) !== null && _result$get !== void 0 ? _result$get : [];
1128
- group.push(item);
1129
- result.set(key, group);
1130
- return result;
1131
- }, new Map());
1219
+ makeFigureSettings(settings, table) {
1220
+ var {
1221
+ dh
1222
+ } = this;
1223
+ var {
1224
+ series,
1225
+ xAxis: settingsAxis,
1226
+ type
1227
+ } = settings;
1228
+ var title = ChartUtils.titleFromSettings(settings);
1229
+ var xAxis = {
1230
+ formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1231
+ type: "".concat(dh.plot.AxisType.X),
1232
+ position: "".concat(dh.plot.AxisPosition.BOTTOM)
1233
+ };
1234
+ var yAxis = {
1235
+ formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1236
+ type: "".concat(dh.plot.AxisType.Y),
1237
+ position: "".concat(dh.plot.AxisPosition.LEFT)
1238
+ };
1239
+ return {
1240
+ charts: [{
1241
+ chartType: "".concat(dh.plot.ChartType.XY),
1242
+ axes: [xAxis, yAxis],
1243
+ series: (series !== null && series !== void 0 ? series : []).map(name => ({
1244
+ plotStyle: "".concat(type),
1245
+ name,
1246
+ dataSources: [{
1247
+ type: "".concat(dh.plot.SourceType.X),
1248
+ columnName: settingsAxis !== null && settingsAxis !== void 0 ? settingsAxis : '',
1249
+ axis: xAxis,
1250
+ table
1251
+ }, {
1252
+ type: "".concat(dh.plot.SourceType.Y),
1253
+ columnName: name,
1254
+ axis: yAxis,
1255
+ table
1256
+ }]
1257
+ }))
1258
+ }],
1259
+ title
1260
+ };
1132
1261
  }
1133
1262
 
1134
1263
  /**
1135
1264
  * Unwraps a value provided from API to a value plotly can understand
1136
1265
  * Eg. Unwraps DateWrapper, LongWrapper objects.
1137
1266
  */
1138
- static unwrapValue(value, timeZone) {
1267
+ unwrapValue(value, timeZone) {
1268
+ var {
1269
+ dh
1270
+ } = this;
1139
1271
  if (value != null) {
1140
1272
  if (isDateWrapper(value)) {
1141
1273
  return dh.i18n.DateTimeFormat.format(ChartUtils.DATE_FORMAT, value, timeZone);
@@ -1153,8 +1285,11 @@ class ChartUtils {
1153
1285
  * @param columnType The type of column this value is from
1154
1286
  * @param timeZone The time zone if applicable
1155
1287
  */
1156
- static wrapValue(value, columnType) {
1288
+ wrapValue(value, columnType) {
1157
1289
  var timeZone = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
1290
+ var {
1291
+ dh
1292
+ } = this;
1158
1293
  if (TableUtils.isDateType(columnType) && typeof value === 'string') {
1159
1294
  // Need to limit the format to the actual length of the string range set in plotly
1160
1295
  // Otherwise parse will fail
@@ -1177,8 +1312,11 @@ class ChartUtils {
1177
1312
  }
1178
1313
  return value;
1179
1314
  }
1180
- static makeLayoutAxis(type) {
1315
+ makeLayoutAxis(type) {
1181
1316
  var theme = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ChartTheme;
1317
+ var {
1318
+ dh
1319
+ } = this;
1182
1320
  var axis = {
1183
1321
  automargin: true,
1184
1322
  gridcolor: theme.gridcolor,
@@ -1212,29 +1350,11 @@ class ChartUtils {
1212
1350
  }
1213
1351
  return axis;
1214
1352
  }
1215
-
1216
- /**
1217
- * Parses the colorway property of a theme and returns an array of colors
1218
- * Theme could have a single string with space separated colors or an array of strings representing the colorway
1219
- * @param theme The theme to get colorway from
1220
- * @returns Colorway array for the theme
1221
- */
1222
- static getColorwayFromTheme() {
1223
- var theme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChartTheme;
1224
- var colorway = [];
1225
- if (theme.colorway) {
1226
- if (Array.isArray(theme.colorway)) {
1227
- colorway = theme.colorway;
1228
- } else if (typeof theme.colorway === 'string') {
1229
- colorway = theme.colorway.split(' ');
1230
- } else {
1231
- log.warn("Unable to handle colorway property: ".concat(theme.colorway));
1232
- }
1233
- }
1234
- return colorway;
1235
- }
1236
- static makeDefaultLayout() {
1353
+ makeDefaultLayout() {
1237
1354
  var theme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ChartTheme;
1355
+ var {
1356
+ dh
1357
+ } = this;
1238
1358
  var layout = _objectSpread(_objectSpread({}, theme), {}, {
1239
1359
  autosize: true,
1240
1360
  colorway: ChartUtils.getColorwayFromTheme(theme),
@@ -1255,8 +1375,8 @@ class ChartUtils {
1255
1375
  }
1256
1376
  },
1257
1377
  margin: _objectSpread({}, ChartUtils.DEFAULT_MARGIN),
1258
- xaxis: ChartUtils.makeLayoutAxis(dh.plot.AxisType.X, theme),
1259
- yaxis: ChartUtils.makeLayoutAxis(dh.plot.AxisType.Y, theme)
1378
+ xaxis: this.makeLayoutAxis(dh.plot.AxisType.X, theme),
1379
+ yaxis: this.makeLayoutAxis(dh.plot.AxisType.Y, theme)
1260
1380
  });
1261
1381
  layout.datarevision = 0;
1262
1382
  return layout;
@@ -1266,72 +1386,14 @@ class ChartUtils {
1266
1386
  * Hydrate settings from a JSONable object
1267
1387
  * @param settings Dehydrated settings
1268
1388
  */
1269
- static hydrateSettings(settings) {
1389
+ hydrateSettings(settings) {
1390
+ var {
1391
+ dh
1392
+ } = this;
1270
1393
  return _objectSpread(_objectSpread({}, settings), {}, {
1271
1394
  type: settings.type != null ? dh.plot.SeriesPlotStyle[settings.type] : undefined
1272
1395
  });
1273
1396
  }
1274
- static titleFromSettings(settings) {
1275
- var {
1276
- series,
1277
- xAxis,
1278
- title = "".concat((series !== null && series !== void 0 ? series : []).join(', '), " by ").concat(xAxis)
1279
- } = settings;
1280
- return title;
1281
- }
1282
-
1283
- /**
1284
- * Creates the Figure settings from the Chart Builder settings
1285
- * This should be deprecated at some point, and have Chart Builder create the figure settings directly.
1286
- * This logic will still need to exist to translate existing charts, but could be part of a migration script
1287
- * to translate the data.
1288
- * Change when we decide to add more functionality to the Chart Builder.
1289
- * @param settings The chart builder settings
1290
- * @param settings.title The title for this figure
1291
- * @param settings.xAxis The name of the column to use for the x-axis
1292
- * @param settings.series The name of the columns to use for the series of this figure
1293
- * @param settings.type The plot style for this figure
1294
- */
1295
- static makeFigureSettings(settings, table) {
1296
- var {
1297
- series,
1298
- xAxis: settingsAxis,
1299
- type
1300
- } = settings;
1301
- var title = ChartUtils.titleFromSettings(settings);
1302
- var xAxis = {
1303
- formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1304
- type: "".concat(dh.plot.AxisType.X),
1305
- position: "".concat(dh.plot.AxisPosition.BOTTOM)
1306
- };
1307
- var yAxis = {
1308
- formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1309
- type: "".concat(dh.plot.AxisType.Y),
1310
- position: "".concat(dh.plot.AxisPosition.LEFT)
1311
- };
1312
- return {
1313
- charts: [{
1314
- chartType: "".concat(dh.plot.ChartType.XY),
1315
- axes: [xAxis, yAxis],
1316
- series: (series !== null && series !== void 0 ? series : []).map(name => ({
1317
- plotStyle: "".concat(type),
1318
- name,
1319
- dataSources: [{
1320
- type: "".concat(dh.plot.SourceType.X),
1321
- columnName: settingsAxis !== null && settingsAxis !== void 0 ? settingsAxis : '',
1322
- axis: xAxis,
1323
- table
1324
- }, {
1325
- type: "".concat(dh.plot.SourceType.Y),
1326
- columnName: name,
1327
- axis: yAxis,
1328
- table
1329
- }]
1330
- }))
1331
- }],
1332
- title
1333
- };
1334
- }
1335
1397
  }
1336
1398
  _defineProperty(ChartUtils, "DEFAULT_AXIS_SIZE", 0.15);
1337
1399
  _defineProperty(ChartUtils, "MIN_AXIS_SIZE", 0.025);