@deephaven/chart 0.5.0 → 0.5.2-lessredux.14

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.
@@ -2,1318 +2,1232 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
2
2
 
3
3
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
4
4
 
5
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
6
-
7
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
8
-
9
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
-
11
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
12
-
13
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
14
-
15
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
16
-
17
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
18
-
19
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
20
-
21
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
22
-
23
- function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
24
-
25
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
26
-
27
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28
-
29
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
30
-
31
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
32
-
33
5
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
34
6
 
35
7
  import Log from '@deephaven/log';
36
8
  import { TableUtils } from '@deephaven/iris-grid';
37
9
  import dh from '@deephaven/jsapi-shim';
38
- import ChartTheme from './ChartTheme';
10
+ import ChartTheme from "./ChartTheme.js";
39
11
  var log = Log.module('ChartUtils');
40
12
  var DAYS = Object.freeze(dh.calendar.DayOfWeek.values());
41
13
  var BUSINESS_COLUMN_TYPE = 'io.deephaven.db.tables.utils.DBDateTime';
42
14
  var MILLIS_PER_HOUR = 3600000;
43
15
  var NANOS_PER_MILLI = 1000000;
44
16
 
45
- var ChartUtils = /*#__PURE__*/function () {
46
- function ChartUtils() {
47
- _classCallCheck(this, ChartUtils);
17
+ class ChartUtils {
18
+ /**
19
+ * Converts the Iris plot style into a plotly chart type
20
+ * @param {String} plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle
21
+ * @param {boolean} isBusinessTime If the plot is using business time for an axis
22
+ */
23
+ static getPlotlyChartType(plotStyle, isBusinessTime) {
24
+ switch (plotStyle) {
25
+ case dh.plot.SeriesPlotStyle.SCATTER:
26
+ // scattergl mode is more performant, but doesn't support the rangebreaks we need for businessTime calendars
27
+ return !isBusinessTime ? 'scattergl' : 'scatter';
28
+
29
+ case dh.plot.SeriesPlotStyle.LINE:
30
+ // There is also still some artifacting bugs with scattergl: https://github.com/plotly/plotly.js/issues/3522
31
+ // The artifacting only occurs on line plots, which we can draw with fairly decent performance using SVG paths
32
+ // Once the above plotly issue is fixed, scattergl should be used here (when !isBusinessTime)
33
+ return 'scatter';
34
+
35
+ case dh.plot.SeriesPlotStyle.BAR:
36
+ case dh.plot.SeriesPlotStyle.STACKED_BAR:
37
+ return 'bar';
38
+
39
+ case dh.plot.SeriesPlotStyle.PIE:
40
+ return 'pie';
41
+
42
+ case dh.plot.SeriesPlotStyle.HISTOGRAM:
43
+ return 'histogram';
44
+
45
+ case dh.plot.SeriesPlotStyle.OHLC:
46
+ return 'ohlc';
47
+
48
+ default:
49
+ return null;
50
+ }
48
51
  }
52
+ /**
53
+ * Converts the Iris plot style into a plotly chart mode
54
+ * @param {String} plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle.*
55
+ */
49
56
 
50
- _createClass(ChartUtils, null, [{
51
- key: "getPlotlyChartType",
52
- value:
53
- /**
54
- * Converts the Iris plot style into a plotly chart type
55
- * @param {String} plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle
56
- * @param {boolean} isBusinessTime If the plot is using business time for an axis
57
- */
58
- function getPlotlyChartType(plotStyle, isBusinessTime) {
59
- switch (plotStyle) {
60
- case dh.plot.SeriesPlotStyle.SCATTER:
61
- // scattergl mode is more performant, but doesn't support the rangebreaks we need for businessTime calendars
62
- return !isBusinessTime ? 'scattergl' : 'scatter';
63
-
64
- case dh.plot.SeriesPlotStyle.LINE:
65
- // There is also still some artifacting bugs with scattergl: https://github.com/plotly/plotly.js/issues/3522
66
- // The artifacting only occurs on line plots, which we can draw with fairly decent performance using SVG paths
67
- // Once the above plotly issue is fixed, scattergl should be used here (when !isBusinessTime)
68
- return 'scatter';
69
-
70
- case dh.plot.SeriesPlotStyle.BAR:
71
- case dh.plot.SeriesPlotStyle.STACKED_BAR:
72
- return 'bar';
73
-
74
- case dh.plot.SeriesPlotStyle.PIE:
75
- return 'pie';
76
-
77
- case dh.plot.SeriesPlotStyle.HISTOGRAM:
78
- return 'histogram';
79
-
80
- case dh.plot.SeriesPlotStyle.OHLC:
81
- return 'ohlc';
82
-
83
- default:
84
- return null;
85
- }
86
- }
87
- /**
88
- * Converts the Iris plot style into a plotly chart mode
89
- * @param {String} plotStyle The plotStyle to use, see dh.plot.SeriesPlotStyle.*
90
- */
91
-
92
- }, {
93
- key: "getPlotlyChartMode",
94
- value: function getPlotlyChartMode(plotStyle) {
95
- switch (plotStyle) {
96
- case dh.plot.SeriesPlotStyle.SCATTER:
97
- return 'markers';
98
-
99
- case dh.plot.SeriesPlotStyle.LINE:
100
- return 'lines';
101
-
102
- default:
103
- return null;
104
- }
105
- }
106
- /**
107
- * Get the property to set on the series data for plotly
108
- * @param {dh.plot.SeriesPlotStyle} plotStyle The plot style of the series
109
- * @param {dh.plot.SourceType} sourceType The source type for the series
110
- */
111
-
112
- }, {
113
- key: "getPlotlyProperty",
114
- value: function getPlotlyProperty(plotStyle, sourceType) {
115
- switch (plotStyle) {
116
- case dh.plot.SeriesPlotStyle.PIE:
117
- switch (sourceType) {
118
- case dh.plot.SourceType.X:
119
- return 'labels';
120
-
121
- case dh.plot.SourceType.Y:
122
- return 'values';
123
-
124
- default:
125
- break;
126
- }
127
57
 
128
- break;
58
+ static getPlotlyChartMode(plotStyle) {
59
+ switch (plotStyle) {
60
+ case dh.plot.SeriesPlotStyle.SCATTER:
61
+ return 'markers';
129
62
 
130
- case dh.plot.SeriesPlotStyle.OHLC:
131
- switch (sourceType) {
132
- case dh.plot.SourceType.TIME:
133
- return 'x';
63
+ case dh.plot.SeriesPlotStyle.LINE:
64
+ return 'lines';
134
65
 
135
- default:
136
- break;
137
- }
66
+ default:
67
+ return null;
68
+ }
69
+ }
70
+ /**
71
+ * Get the property to set on the series data for plotly
72
+ * @param {dh.plot.SeriesPlotStyle} plotStyle The plot style of the series
73
+ * @param {dh.plot.SourceType} sourceType The source type for the series
74
+ */
138
75
 
139
- break;
140
76
 
141
- default:
142
- break;
143
- }
77
+ static getPlotlyProperty(plotStyle, sourceType) {
78
+ switch (plotStyle) {
79
+ case dh.plot.SeriesPlotStyle.PIE:
80
+ switch (sourceType) {
81
+ case dh.plot.SourceType.X:
82
+ return 'labels';
144
83
 
145
- switch (sourceType) {
146
- case dh.plot.SourceType.X:
147
- return 'x';
84
+ case dh.plot.SourceType.Y:
85
+ return 'values';
148
86
 
149
- case dh.plot.SourceType.Y:
150
- return 'y';
87
+ default:
88
+ break;
89
+ }
151
90
 
152
- case dh.plot.SourceType.Z:
153
- return 'z';
91
+ break;
154
92
 
155
- case dh.plot.SourceType.X_LOW:
156
- return 'xLow';
93
+ case dh.plot.SeriesPlotStyle.OHLC:
94
+ switch (sourceType) {
95
+ case dh.plot.SourceType.TIME:
96
+ return 'x';
157
97
 
158
- case dh.plot.SourceType.X_HIGH:
159
- return 'xHigh';
98
+ default:
99
+ break;
100
+ }
160
101
 
161
- case dh.plot.SourceType.Y_LOW:
162
- return 'yLow';
102
+ break;
163
103
 
164
- case dh.plot.SourceType.Y_HIGH:
165
- return 'yHigh';
104
+ default:
105
+ break;
106
+ }
166
107
 
167
- case dh.plot.SourceType.TIME:
168
- return 'time';
108
+ switch (sourceType) {
109
+ case dh.plot.SourceType.X:
110
+ return 'x';
169
111
 
170
- case dh.plot.SourceType.OPEN:
171
- return 'open';
112
+ case dh.plot.SourceType.Y:
113
+ return 'y';
172
114
 
173
- case dh.plot.SourceType.HIGH:
174
- return 'high';
115
+ case dh.plot.SourceType.Z:
116
+ return 'z';
175
117
 
176
- case dh.plot.SourceType.LOW:
177
- return 'low';
118
+ case dh.plot.SourceType.X_LOW:
119
+ return 'xLow';
178
120
 
179
- case dh.plot.SourceType.CLOSE:
180
- return 'shape';
121
+ case dh.plot.SourceType.X_HIGH:
122
+ return 'xHigh';
181
123
 
182
- case dh.plot.SourceType.SIZE:
183
- return 'size';
124
+ case dh.plot.SourceType.Y_LOW:
125
+ return 'yLow';
184
126
 
185
- case dh.plot.SourceType.LABEL:
186
- return 'label';
127
+ case dh.plot.SourceType.Y_HIGH:
128
+ return 'yHigh';
187
129
 
188
- case dh.plot.SourceType.COLOR:
189
- return 'color';
130
+ case dh.plot.SourceType.TIME:
131
+ return 'time';
190
132
 
191
- default:
192
- throw new Error('Unrecognized source type', sourceType);
193
- }
194
- }
195
- }, {
196
- key: "getPlotlySeriesOrientation",
197
- value: function getPlotlySeriesOrientation(series) {
198
- var sources = series.sources;
133
+ case dh.plot.SourceType.OPEN:
134
+ return 'open';
199
135
 
200
- if (sources.length === 2 && sources[0].axis.type === dh.plot.AxisType.Y) {
201
- return ChartUtils.ORIENTATION.HORIZONTAL;
202
- }
136
+ case dh.plot.SourceType.HIGH:
137
+ return 'high';
203
138
 
204
- return ChartUtils.ORIENTATION.VERTICAL;
205
- }
206
- /**
207
- * Generate the plotly error bar data from the passed in data.
208
- * Iris passes in the values as absolute, plotly needs them as relative.
209
- * @param {Array[Number]} x The main data array
210
- * @param {Array[Number]} xLow The absolute low values
211
- * @param {Array[Number]} xHigh
212
- *
213
- * @returns {Object} The error_x object required by plotly, or null if none is required
214
- */
215
-
216
- }, {
217
- key: "getPlotlyErrorBars",
218
- value: function getPlotlyErrorBars(x, xLow, xHigh) {
219
- var array = xHigh.map(function (value, i) {
220
- return value - x[i];
221
- });
222
- var arrayminus = xLow.map(function (value, i) {
223
- return x[i] - value;
224
- });
225
- return {
226
- type: 'data',
227
- symmetric: false,
228
- array: array,
229
- arrayminus: arrayminus
230
- };
231
- }
232
- }, {
233
- key: "getPlotlyDateFormat",
234
- value: function getPlotlyDateFormat(formatter, columnType, formatPattern) {
235
- var tickformat = formatPattern == null ? null : 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
139
+ case dh.plot.SourceType.LOW:
140
+ return 'low';
236
141
 
237
- var ticksuffix = null;
238
- var dataFormatter = formatter.getColumnTypeFormatter(columnType);
142
+ case dh.plot.SourceType.CLOSE:
143
+ return 'shape';
239
144
 
240
- if (dataFormatter.dhTimeZone != null && dataFormatter.showTimeZone) {
241
- ticksuffix = dh.i18n.DateTimeFormat.format(' z', new Date(), dataFormatter.dhTimeZone);
242
- }
145
+ case dh.plot.SourceType.SIZE:
146
+ return 'size';
243
147
 
244
- return {
245
- tickformat: tickformat,
246
- ticksuffix: ticksuffix,
247
- automargin: true
248
- };
249
- }
250
- }, {
251
- key: "convertNumberPrefix",
252
- value: function convertNumberPrefix(prefix) {
253
- return prefix.replace(/\u00A4\u00A4/g, 'USD').replace(/\u00A4/g, '$');
254
- }
255
- }, {
256
- key: "getPlotlyNumberFormat",
257
- value: function getPlotlyNumberFormat(formatter, columnType, formatPattern) {
258
- if (!formatPattern) {
259
- return null;
260
- } // We translate java formatting: https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html
261
- // Into d3 number formatting: https://github.com/d3/d3-format
262
- // We can't translate number formatting exactly, but should be able to translate the most common cases
263
- // First split it into the subpatterns; currently only handling the positive subpattern, ignoring the rest
264
-
265
-
266
- var subpatterns = formatPattern.split(';');
267
-
268
- var _subpatterns$0$match = subpatterns[0].match(/^([^#,0.]*)([#,]*)([0,]*)(\.?)(0*)(#*)(E?0*)(%?)(.*)/),
269
- _subpatterns$0$match2 = _slicedToArray(_subpatterns$0$match, 10),
270
- prefix = _subpatterns$0$match2[1],
271
- placeholderDigits = _subpatterns$0$match2[2],
272
- zeroDigits = _subpatterns$0$match2[3],
273
- decimalDigits = _subpatterns$0$match2[5],
274
- optionalDecimalDigits = _subpatterns$0$match2[6],
275
- numberType = _subpatterns$0$match2[7],
276
- percentSign = _subpatterns$0$match2[8],
277
- suffix = _subpatterns$0$match2[9];
278
-
279
- var paddingLength = zeroDigits.replace(',', '').length;
280
- var isCommaSeparated = placeholderDigits.indexOf(',') >= 0 || zeroDigits.indexOf(',') >= 0;
281
- var comma = isCommaSeparated ? ',' : '';
282
- var plotlyNumberType = numberType ? 'e' : 'f';
283
- var type = percentSign || plotlyNumberType;
284
- var decimalLength = decimalDigits.length + optionalDecimalDigits.length; // IDS-4565 Plotly uses an older version of d3 which doesn't support the trim option or negative brackets
285
- // If plotly updates it's d3 version, this should be re-enabled
286
- // const trimOption = optionalDecimalDigits.length > 0 ? '~' : '';
287
-
288
- var trimOption = '';
289
- var tickformat = "0".concat(paddingLength).concat(comma, ".").concat(decimalLength).concat(trimOption).concat(type);
290
- var tickprefix = ChartUtils.convertNumberPrefix(prefix); // prefix and suffix are processed the same
291
-
292
- var ticksuffix = ChartUtils.convertNumberPrefix(suffix);
293
- return {
294
- tickformat: tickformat,
295
- tickprefix: tickprefix,
296
- ticksuffix: ticksuffix,
297
- automargin: true
298
- };
148
+ case dh.plot.SourceType.LABEL:
149
+ return 'label';
150
+
151
+ case dh.plot.SourceType.COLOR:
152
+ return 'color';
153
+
154
+ default:
155
+ throw new Error('Unrecognized source type', sourceType);
299
156
  }
300
- /**
301
- * Gets the plotly axis formatting information from the source passed in
302
- * @param {dh.plot.Source} source The Source to get the formatter information from
303
- * @param {Formatter} formatter The current formatter for formatting data
304
- */
305
-
306
- }, {
307
- key: "getPlotlyAxisFormat",
308
- value: function getPlotlyAxisFormat(source) {
309
- var formatter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
310
- var axis = source.axis,
311
- columnType = source.columnType;
312
- var formatPattern = axis.formatPattern;
313
- var axisFormat = null;
314
-
315
- if (TableUtils.isDateType(columnType)) {
316
- axisFormat = ChartUtils.getPlotlyDateFormat(formatter, columnType, formatPattern);
317
- axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, true);
318
- } else if (TableUtils.isNumberType(columnType)) {
319
- axisFormat = ChartUtils.getPlotlyNumberFormat(formatter, columnType, formatPattern);
320
- axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, false);
321
- }
157
+ }
322
158
 
323
- if (axis.formatType === dh.plot.AxisFormatType.CATEGORY) {
324
- if (axisFormat) {
325
- axisFormat.type = 'category';
326
- } else {
327
- axisFormat = {
328
- type: 'category',
329
- tickformat: null,
330
- ticksuffix: null
331
- };
332
- }
333
- }
159
+ static getPlotlySeriesOrientation(series) {
160
+ var {
161
+ sources
162
+ } = series;
334
163
 
335
- return axisFormat;
164
+ if (sources.length === 2 && sources[0].axis.type === dh.plot.AxisType.Y) {
165
+ return ChartUtils.ORIENTATION.HORIZONTAL;
336
166
  }
337
- /**
338
- * Adds tick spacing for an axis that has gapBetweenMajorTicks defined.
339
- *
340
- * @param {object} axisFormat the current axis format, may be null
341
- * @param {object} axis the current axis
342
- * @param {boolean} isDateType indicates if the columns is a date type
343
- */
344
-
345
- }, {
346
- key: "addTickSpacing",
347
- value: function addTickSpacing(axisFormat, axis, isDateType) {
348
- var gapBetweenMajorTicks = axis.gapBetweenMajorTicks;
349
-
350
- if (gapBetweenMajorTicks > 0) {
351
- var updatedFormat = axisFormat || {};
352
- var tickSpacing = gapBetweenMajorTicks;
353
-
354
- if (isDateType) {
355
- // Need to convert from nanoseconds to milliseconds
356
- tickSpacing = gapBetweenMajorTicks / NANOS_PER_MILLI;
357
- }
358
167
 
359
- if (axis.log) {
360
- tickSpacing = Math.log(tickSpacing);
361
- } // Note that tickmode defaults to 'auto'
168
+ return ChartUtils.ORIENTATION.VERTICAL;
169
+ }
170
+ /**
171
+ * Generate the plotly error bar data from the passed in data.
172
+ * Iris passes in the values as absolute, plotly needs them as relative.
173
+ * @param {Array[Number]} x The main data array
174
+ * @param {Array[Number]} xLow The absolute low values
175
+ * @param {Array[Number]} xHigh
176
+ *
177
+ * @returns {Object} The error_x object required by plotly, or null if none is required
178
+ */
179
+
180
+
181
+ static getPlotlyErrorBars(x, xLow, xHigh) {
182
+ var array = xHigh.map((value, i) => value - x[i]);
183
+ var arrayminus = xLow.map((value, i) => x[i] - value);
184
+ return {
185
+ type: 'data',
186
+ symmetric: false,
187
+ array,
188
+ arrayminus
189
+ };
190
+ }
362
191
 
192
+ static getPlotlyDateFormat(formatter, columnType, formatPattern) {
193
+ var tickformat = formatPattern == null ? null : 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
363
194
 
364
- updatedFormat.tickmode = 'linear';
365
- updatedFormat.dtick = tickSpacing;
366
- return updatedFormat;
367
- }
195
+ var ticksuffix = null;
196
+ var dataFormatter = formatter.getColumnTypeFormatter(columnType);
368
197
 
369
- return axisFormat;
198
+ if (dataFormatter.dhTimeZone != null && dataFormatter.showTimeZone) {
199
+ ticksuffix = dh.i18n.DateTimeFormat.format(' z', new Date(), dataFormatter.dhTimeZone);
370
200
  }
371
- /**
372
- * Retrieve the data source for a given axis in a chart
373
- * @param {dh.plot.Chart} chart The chart to get the source for
374
- * @param {dh.plot.Axis} axis The axis to find the source for
375
- * @returns {dh.plot.Source} The first source matching this axis
376
- */
377
-
378
- }, {
379
- key: "getSourceForAxis",
380
- value: function getSourceForAxis(chart, axis) {
381
- for (var i = 0; i < chart.series.length; i += 1) {
382
- var series = chart.series[i];
383
-
384
- for (var j = 0; j < series.sources.length; j += 1) {
385
- var source = series.sources[j];
386
-
387
- if (source.axis === axis) {
388
- return source;
389
- }
390
- }
391
- }
392
201
 
202
+ return {
203
+ tickformat,
204
+ ticksuffix,
205
+ automargin: true
206
+ };
207
+ }
208
+
209
+ static convertNumberPrefix(prefix) {
210
+ return prefix.replace(/\u00A4\u00A4/g, 'USD').replace(/\u00A4/g, '$');
211
+ }
212
+
213
+ static getPlotlyNumberFormat(formatter, columnType, formatPattern) {
214
+ if (!formatPattern) {
393
215
  return null;
216
+ } // We translate java formatting: https://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html
217
+ // Into d3 number formatting: https://github.com/d3/d3-format
218
+ // We can't translate number formatting exactly, but should be able to translate the most common cases
219
+ // First split it into the subpatterns; currently only handling the positive subpattern, ignoring the rest
220
+
221
+
222
+ var subpatterns = formatPattern.split(';');
223
+ var [, prefix, placeholderDigits, zeroDigits,, decimalDigits, optionalDecimalDigits, numberType, percentSign, suffix] = subpatterns[0].match(/^([^#,0.]*)([#,]*)([0,]*)(\.?)(0*)(#*)(E?0*)(%?)(.*)/);
224
+ var paddingLength = zeroDigits.replace(',', '').length;
225
+ var isCommaSeparated = placeholderDigits.indexOf(',') >= 0 || zeroDigits.indexOf(',') >= 0;
226
+ var comma = isCommaSeparated ? ',' : '';
227
+ var plotlyNumberType = numberType ? 'e' : 'f';
228
+ var type = percentSign || plotlyNumberType;
229
+ var decimalLength = decimalDigits.length + optionalDecimalDigits.length; // IDS-4565 Plotly uses an older version of d3 which doesn't support the trim option or negative brackets
230
+ // If plotly updates it's d3 version, this should be re-enabled
231
+ // const trimOption = optionalDecimalDigits.length > 0 ? '~' : '';
232
+
233
+ var trimOption = '';
234
+ var tickformat = "0".concat(paddingLength).concat(comma, ".").concat(decimalLength).concat(trimOption).concat(type);
235
+ var tickprefix = ChartUtils.convertNumberPrefix(prefix); // prefix and suffix are processed the same
236
+
237
+ var ticksuffix = ChartUtils.convertNumberPrefix(suffix);
238
+ return {
239
+ tickformat,
240
+ tickprefix,
241
+ ticksuffix,
242
+ automargin: true
243
+ };
244
+ }
245
+ /**
246
+ * Gets the plotly axis formatting information from the source passed in
247
+ * @param {dh.plot.Source} source The Source to get the formatter information from
248
+ * @param {Formatter} formatter The current formatter for formatting data
249
+ */
250
+
251
+
252
+ static getPlotlyAxisFormat(source) {
253
+ var formatter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
254
+ var {
255
+ axis,
256
+ columnType
257
+ } = source;
258
+ var {
259
+ formatPattern
260
+ } = axis;
261
+ var axisFormat = null;
262
+
263
+ if (TableUtils.isDateType(columnType)) {
264
+ axisFormat = ChartUtils.getPlotlyDateFormat(formatter, columnType, formatPattern);
265
+ axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, true);
266
+ } else if (TableUtils.isNumberType(columnType)) {
267
+ axisFormat = ChartUtils.getPlotlyNumberFormat(formatter, columnType, formatPattern);
268
+ axisFormat = ChartUtils.addTickSpacing(axisFormat, axis, false);
394
269
  }
395
- /**
396
- * Get visibility setting for the series object
397
- * @param {string} name The series name to get the visibility for
398
- * @param {object} settings Chart settings
399
- * @returns {boolean|string} True for visible series and 'legendonly' for hidden
400
- */
401
-
402
- }, {
403
- key: "getSeriesVisibility",
404
- value: function getSeriesVisibility(name, settings) {
405
- var _settings$hiddenSerie;
406
-
407
- if (settings !== null && settings !== void 0 && (_settings$hiddenSerie = settings.hiddenSeries) !== null && _settings$hiddenSerie !== void 0 && _settings$hiddenSerie.includes(name)) {
408
- return 'legendonly';
409
- }
410
270
 
411
- return true;
271
+ if (axis.formatType === dh.plot.AxisFormatType.CATEGORY) {
272
+ if (axisFormat) {
273
+ axisFormat.type = 'category';
274
+ } else {
275
+ axisFormat = {
276
+ type: 'category',
277
+ tickformat: null,
278
+ ticksuffix: null
279
+ };
280
+ }
412
281
  }
413
- /**
414
- * Get hidden labels array from chart settings
415
- * @param {object} settings Chart settings
416
- * @returns {string[]} Array of hidden series names
417
- */
418
-
419
- }, {
420
- key: "getHiddenLabels",
421
- value: function getHiddenLabels(settings) {
422
- if (settings !== null && settings !== void 0 && settings.hiddenSeries) {
423
- return _toConsumableArray(settings.hiddenSeries);
282
+
283
+ return axisFormat;
284
+ }
285
+ /**
286
+ * Adds tick spacing for an axis that has gapBetweenMajorTicks defined.
287
+ *
288
+ * @param {object} axisFormat the current axis format, may be null
289
+ * @param {object} axis the current axis
290
+ * @param {boolean} isDateType indicates if the columns is a date type
291
+ */
292
+
293
+
294
+ static addTickSpacing(axisFormat, axis, isDateType) {
295
+ var {
296
+ gapBetweenMajorTicks
297
+ } = axis;
298
+
299
+ if (gapBetweenMajorTicks > 0) {
300
+ var updatedFormat = axisFormat || {};
301
+ var tickSpacing = gapBetweenMajorTicks;
302
+
303
+ if (isDateType) {
304
+ // Need to convert from nanoseconds to milliseconds
305
+ tickSpacing = gapBetweenMajorTicks / NANOS_PER_MILLI;
424
306
  }
425
307
 
426
- return [];
427
- }
428
- /**
429
- * Create a default series data object. Apply styling to the object afterward.
430
- * @returns {Object} A simple series data object with no styling
431
- */
432
-
433
- }, {
434
- key: "makeSeriesData",
435
- value: function makeSeriesData(type, mode, name) {
436
- var orientation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ChartUtils.ORIENTATION.VERTICAL;
437
- return {
438
- type: type,
439
- mode: mode,
440
- name: name,
441
- orientation: orientation
442
- };
443
- }
444
- /**
445
- * Create a data series (trace) for use with plotly
446
- * @param {dh.plot.Series} series The series to create the series data with
447
- * @param {Map<dh.plot.AxisType, dh.plot.Axis[]>} axisTypeMap The map of axes grouped by type
448
- * @param {boolean|string} seriesVisibility Visibility setting for the series
449
- * @returns {Object} The series data (trace) object for use with plotly.
450
- */
451
-
452
- }, {
453
- key: "makeSeriesDataFromSeries",
454
- value: function makeSeriesDataFromSeries(series, axisTypeMap, seriesVisibility) {
455
- var name = series.name,
456
- plotStyle = series.plotStyle,
457
- lineColor = series.lineColor,
458
- shapeColor = series.shapeColor,
459
- sources = series.sources;
460
- var isBusinessTime = sources.some(function (source) {
461
- return source.axis.businessCalendar;
462
- });
463
- var type = ChartUtils.getChartType(plotStyle, isBusinessTime);
464
- var mode = ChartUtils.getPlotlyChartMode(plotStyle);
465
- var orientation = ChartUtils.getPlotlySeriesOrientation(series);
466
- var seriesData = ChartUtils.makeSeriesData(type, mode, name, orientation);
467
- ChartUtils.addSourcesToSeriesData(seriesData, plotStyle, sources, axisTypeMap);
468
- ChartUtils.addStylingToSeriesData(seriesData, plotStyle, lineColor, shapeColor, seriesVisibility);
469
- return seriesData;
308
+ if (axis.log) {
309
+ tickSpacing = Math.log(tickSpacing);
310
+ } // Note that tickmode defaults to 'auto'
311
+
312
+
313
+ updatedFormat.tickmode = 'linear';
314
+ updatedFormat.dtick = tickSpacing;
315
+ return updatedFormat;
470
316
  }
471
- }, {
472
- key: "addSourcesToSeriesData",
473
- value: function addSourcesToSeriesData(seriesDataParam, plotStyle, sources, axisTypeMap) {
474
- var seriesData = seriesDataParam;
475
-
476
- for (var k = 0; k < sources.length; k += 1) {
477
- var source = sources[k];
478
- var axis = source.axis,
479
- sourceType = source.type;
480
- var dataAttributeName = ChartUtils.getPlotlyProperty(plotStyle, sourceType);
481
- seriesData[dataAttributeName] = [];
482
- var axisProperty = ChartUtils.getAxisPropertyName(axis.type);
483
- var axes = axisTypeMap.get(axis.type);
484
- var axisIndex = axes.indexOf(axis);
485
-
486
- if (axisProperty != null) {
487
- var axisIndexString = axisIndex > 0 ? "".concat(axisIndex + 1) : '';
488
- seriesData["".concat(axisProperty, "axis")] = "".concat(axisProperty).concat(axisIndexString);
317
+
318
+ return axisFormat;
319
+ }
320
+ /**
321
+ * Retrieve the data source for a given axis in a chart
322
+ * @param {dh.plot.Chart} chart The chart to get the source for
323
+ * @param {dh.plot.Axis} axis The axis to find the source for
324
+ * @returns {dh.plot.Source} The first source matching this axis
325
+ */
326
+
327
+
328
+ static getSourceForAxis(chart, axis) {
329
+ for (var i = 0; i < chart.series.length; i += 1) {
330
+ var series = chart.series[i];
331
+
332
+ for (var j = 0; j < series.sources.length; j += 1) {
333
+ var source = series.sources[j];
334
+
335
+ if (source.axis === axis) {
336
+ return source;
489
337
  }
490
338
  }
491
339
  }
492
- }, {
493
- key: "addStylingToSeriesData",
494
- value: function addStylingToSeriesData(seriesDataParam, plotStyle) {
495
- var lineColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
496
- var shapeColor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
497
- var seriesVisibility = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
498
- var seriesData = seriesDataParam; // Add some empty objects so we can fill them in later with details without checking for existence
499
340
 
500
- seriesData.marker = {
501
- line: {}
502
- }; // border line width on markers
341
+ return null;
342
+ }
343
+ /**
344
+ * Get visibility setting for the series object
345
+ * @param {string} name The series name to get the visibility for
346
+ * @param {object} settings Chart settings
347
+ * @returns {boolean|string} True for visible series and 'legendonly' for hidden
348
+ */
503
349
 
504
- seriesData.line = {
505
- width: 1 // default line width for lines, should eventually be able to override
506
350
 
507
- };
351
+ static getSeriesVisibility(name, settings) {
352
+ var _settings$hiddenSerie;
508
353
 
509
- if (plotStyle === dh.plot.SeriesPlotStyle.AREA) {
510
- seriesData.fill = 'tozeroy';
511
- } else if (plotStyle === dh.plot.SeriesPlotStyle.STACKED_AREA) {
512
- seriesData.stackgroup = 'stack';
513
- } else if (plotStyle === dh.plot.SeriesPlotStyle.STEP) {
514
- seriesData.line.shape = 'hv'; // plot.ly horizontal then vertical step styling
515
- } else if (plotStyle === dh.plot.SeriesPlotStyle.HISTOGRAM) {
516
- // The default histfunc in plotly is 'count', but the data passed up from the API provides explicit x/y values and bins
517
- // Since it's converted to bar, just set the widths of each bar
518
- seriesData.width = [];
519
- Object.assign(seriesData.marker.line, {
520
- color: ChartTheme.paper_bgcolor,
521
- width: 1
522
- });
523
- } else if (plotStyle === dh.plot.SeriesPlotStyle.OHLC) {
524
- seriesData.increasing = {
525
- line: {
526
- color: ChartTheme.ohlc_increasing
527
- }
528
- };
529
- seriesData.decreasing = {
530
- line: {
531
- color: ChartTheme.ohlc_decreasing
532
- }
533
- };
534
- } else if (plotStyle === dh.plot.SeriesPlotStyle.PIE) {
535
- seriesData.textinfo = 'label+percent';
536
- seriesData.outsidetextfont = {
537
- color: ChartTheme.title_color
538
- };
354
+ if (settings !== null && settings !== void 0 && (_settings$hiddenSerie = settings.hiddenSeries) !== null && _settings$hiddenSerie !== void 0 && _settings$hiddenSerie.includes(name)) {
355
+ return 'legendonly';
356
+ }
357
+
358
+ return true;
359
+ }
360
+ /**
361
+ * Get hidden labels array from chart settings
362
+ * @param {object} settings Chart settings
363
+ * @returns {string[]} Array of hidden series names
364
+ */
365
+
366
+
367
+ static getHiddenLabels(settings) {
368
+ if (settings !== null && settings !== void 0 && settings.hiddenSeries) {
369
+ return [...settings.hiddenSeries];
370
+ }
371
+
372
+ return [];
373
+ }
374
+ /**
375
+ * Create a default series data object. Apply styling to the object afterward.
376
+ * @returns {Object} A simple series data object with no styling
377
+ */
378
+
379
+
380
+ static makeSeriesData(type, mode, name) {
381
+ var orientation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ChartUtils.ORIENTATION.VERTICAL;
382
+ return {
383
+ type,
384
+ mode,
385
+ name,
386
+ orientation
387
+ };
388
+ }
389
+ /**
390
+ * Create a data series (trace) for use with plotly
391
+ * @param {dh.plot.Series} series The series to create the series data with
392
+ * @param {Map<dh.plot.AxisType, dh.plot.Axis[]>} axisTypeMap The map of axes grouped by type
393
+ * @param {boolean|string} seriesVisibility Visibility setting for the series
394
+ * @returns {Object} The series data (trace) object for use with plotly.
395
+ */
396
+
397
+
398
+ static makeSeriesDataFromSeries(series, axisTypeMap, seriesVisibility) {
399
+ var {
400
+ name,
401
+ plotStyle,
402
+ lineColor,
403
+ shapeColor,
404
+ sources
405
+ } = series;
406
+ var isBusinessTime = sources.some(source => source.axis.businessCalendar);
407
+ var type = ChartUtils.getChartType(plotStyle, isBusinessTime);
408
+ var mode = ChartUtils.getPlotlyChartMode(plotStyle);
409
+ var orientation = ChartUtils.getPlotlySeriesOrientation(series);
410
+ var seriesData = ChartUtils.makeSeriesData(type, mode, name, orientation);
411
+ ChartUtils.addSourcesToSeriesData(seriesData, plotStyle, sources, axisTypeMap);
412
+ ChartUtils.addStylingToSeriesData(seriesData, plotStyle, lineColor, shapeColor, seriesVisibility);
413
+ return seriesData;
414
+ }
415
+
416
+ static addSourcesToSeriesData(seriesDataParam, plotStyle, sources, axisTypeMap) {
417
+ var seriesData = seriesDataParam;
418
+
419
+ for (var k = 0; k < sources.length; k += 1) {
420
+ var source = sources[k];
421
+ var {
422
+ axis,
423
+ type: sourceType
424
+ } = source;
425
+ var dataAttributeName = ChartUtils.getPlotlyProperty(plotStyle, sourceType);
426
+ seriesData[dataAttributeName] = [];
427
+ var axisProperty = ChartUtils.getAxisPropertyName(axis.type);
428
+ var axes = axisTypeMap.get(axis.type);
429
+ var axisIndex = axes.indexOf(axis);
430
+
431
+ if (axisProperty != null) {
432
+ var axisIndexString = axisIndex > 0 ? "".concat(axisIndex + 1) : '';
433
+ seriesData["".concat(axisProperty, "axis")] = "".concat(axisProperty).concat(axisIndexString);
539
434
  }
435
+ }
436
+ }
540
437
 
541
- if (lineColor != null) {
542
- if (plotStyle === dh.plot.SeriesPlotStyle.BAR) {
543
- seriesData.marker.color = lineColor;
544
- } else {
545
- seriesData.line.color = lineColor;
438
+ static addStylingToSeriesData(seriesDataParam, plotStyle) {
439
+ var lineColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
440
+ var shapeColor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
441
+ var seriesVisibility = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
442
+ var seriesData = seriesDataParam; // Add some empty objects so we can fill them in later with details without checking for existence
443
+
444
+ seriesData.marker = {
445
+ line: {}
446
+ }; // border line width on markers
447
+
448
+ seriesData.line = {
449
+ width: 1 // default line width for lines, should eventually be able to override
450
+
451
+ };
452
+
453
+ if (plotStyle === dh.plot.SeriesPlotStyle.AREA) {
454
+ seriesData.fill = 'tozeroy';
455
+ } else if (plotStyle === dh.plot.SeriesPlotStyle.STACKED_AREA) {
456
+ seriesData.stackgroup = 'stack';
457
+ } else if (plotStyle === dh.plot.SeriesPlotStyle.STEP) {
458
+ seriesData.line.shape = 'hv'; // plot.ly horizontal then vertical step styling
459
+ } else if (plotStyle === dh.plot.SeriesPlotStyle.HISTOGRAM) {
460
+ // The default histfunc in plotly is 'count', but the data passed up from the API provides explicit x/y values and bins
461
+ // Since it's converted to bar, just set the widths of each bar
462
+ seriesData.width = [];
463
+ Object.assign(seriesData.marker.line, {
464
+ color: ChartTheme.paper_bgcolor,
465
+ width: 1
466
+ });
467
+ } else if (plotStyle === dh.plot.SeriesPlotStyle.OHLC) {
468
+ seriesData.increasing = {
469
+ line: {
470
+ color: ChartTheme.ohlc_increasing
471
+ }
472
+ };
473
+ seriesData.decreasing = {
474
+ line: {
475
+ color: ChartTheme.ohlc_decreasing
546
476
  }
477
+ };
478
+ } else if (plotStyle === dh.plot.SeriesPlotStyle.PIE) {
479
+ seriesData.textinfo = 'label+percent';
480
+ seriesData.outsidetextfont = {
481
+ color: ChartTheme.title_color
482
+ };
483
+ }
484
+
485
+ if (lineColor != null) {
486
+ if (plotStyle === dh.plot.SeriesPlotStyle.BAR) {
487
+ seriesData.marker.color = lineColor;
488
+ } else {
489
+ seriesData.line.color = lineColor;
547
490
  }
491
+ }
548
492
 
549
- if (shapeColor != null) {
550
- seriesData.marker.color = shapeColor;
551
- } // Skipping pie charts
552
- // Pie slice visibility is configured in chart layout instead of series data
493
+ if (shapeColor != null) {
494
+ seriesData.marker.color = shapeColor;
495
+ } // Skipping pie charts
496
+ // Pie slice visibility is configured in chart layout instead of series data
553
497
 
554
498
 
555
- if (seriesVisibility != null && plotStyle !== dh.plot.SeriesPlotStyle.PIE) {
556
- seriesData.visible = seriesVisibility;
557
- }
499
+ if (seriesVisibility != null && plotStyle !== dh.plot.SeriesPlotStyle.PIE) {
500
+ seriesData.visible = seriesVisibility;
558
501
  }
559
- /**
560
- * Retrieve the axis formats from the provided figure.
561
- * Currently defaults to just the x/y axes.
562
- * @param {dh.plot.Figure} figure The figure to get the axis formats for
563
- * @param {Formatter} formatter The formatter to use when getting the axis format
564
- * @returns {Map<string, object>} A map of axis layout property names to axis formats
565
- */
566
-
567
- }, {
568
- key: "getAxisFormats",
569
- value: function getAxisFormats(figure, formatter) {
570
- var axisFormats = new Map();
571
- var nullFormat = {
572
- tickformat: null,
573
- ticksuffix: null
574
- };
575
- var charts = figure.charts;
576
-
577
- for (var i = 0; i < charts.length; i += 1) {
578
- var chart = charts[i];
579
- var axisTypeMap = ChartUtils.groupArray(chart.axes, 'type');
580
-
581
- for (var j = 0; j < chart.series.length; j += 1) {
582
- var series = chart.series[j];
583
- var sources = series.sources;
584
-
585
- for (var k = 0; k < sources.length; k += 1) {
586
- var source = sources[k];
587
- var axis = source.axis;
588
- var axisType = axis.type;
589
- var typeAxes = axisTypeMap.get(axisType);
590
- var axisIndex = typeAxes.indexOf(axis);
591
- var axisProperty = ChartUtils.getAxisPropertyName(axisType);
592
- var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
593
-
594
- if (axisFormats.has(axisLayoutProperty)) {
595
- log.debug("".concat(axisLayoutProperty, " already added."));
596
- } else {
597
- var _ret = function () {
598
- log.debug("Adding ".concat(axisLayoutProperty, " to axisFormats."));
599
- var axisFormat = ChartUtils.getPlotlyAxisFormat(source, formatter);
600
-
601
- if (axisFormat === null) {
602
- axisFormats.set(axisLayoutProperty, nullFormat);
603
- } else {
604
- axisFormats.set(axisLayoutProperty, axisFormat);
605
- var businessCalendar = axis.businessCalendar;
606
-
607
- if (businessCalendar) {
608
- var _formatter$getColumnT;
609
-
610
- axisFormat.rangebreaks = [];
611
- var businessPeriods = businessCalendar.businessPeriods,
612
- businessDays = businessCalendar.businessDays,
613
- holidays = businessCalendar.holidays,
614
- calendarTimeZone = businessCalendar.timeZone;
615
- var formatterTimeZone = formatter === null || formatter === void 0 ? void 0 : (_formatter$getColumnT = formatter.getColumnTypeFormatter(BUSINESS_COLUMN_TYPE)) === null || _formatter$getColumnT === void 0 ? void 0 : _formatter$getColumnT.dhTimeZone;
616
- var timeZoneDiff = formatterTimeZone ? (calendarTimeZone.standardOffset - formatterTimeZone.standardOffset) / 60 : 0;
617
-
618
- if (holidays.length > 0) {
619
- var _axisFormat$rangebrea;
620
-
621
- (_axisFormat$rangebrea = axisFormat.rangebreaks).push.apply(_axisFormat$rangebrea, _toConsumableArray(ChartUtils.createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone)));
622
- }
623
-
624
- businessPeriods.forEach(function (period) {
625
- return axisFormat.rangebreaks.push({
626
- pattern: 'hour',
627
- bounds: [ChartUtils.periodToDecimal(period.close) + timeZoneDiff, ChartUtils.periodToDecimal(period.open) + timeZoneDiff]
628
- });
629
- }); // If there are seven business days, then there is no weekend
630
-
631
- if (businessDays.length < DAYS.length) {
632
- ChartUtils.createBoundsFromDays(businessDays).forEach(function (weekendBounds) {
633
- return axisFormat.rangebreaks.push({
634
- pattern: 'day of week',
635
- bounds: weekendBounds
636
- });
637
- });
638
- }
502
+ }
503
+ /**
504
+ * Retrieve the axis formats from the provided figure.
505
+ * Currently defaults to just the x/y axes.
506
+ * @param {dh.plot.Figure} figure The figure to get the axis formats for
507
+ * @param {Formatter} formatter The formatter to use when getting the axis format
508
+ * @returns {Map<string, object>} A map of axis layout property names to axis formats
509
+ */
510
+
511
+
512
+ static getAxisFormats(figure, formatter) {
513
+ var axisFormats = new Map();
514
+ var nullFormat = {
515
+ tickformat: null,
516
+ ticksuffix: null
517
+ };
518
+ var {
519
+ charts
520
+ } = figure;
521
+
522
+ for (var i = 0; i < charts.length; i += 1) {
523
+ var chart = charts[i];
524
+ var axisTypeMap = ChartUtils.groupArray(chart.axes, 'type');
525
+
526
+ for (var j = 0; j < chart.series.length; j += 1) {
527
+ var series = chart.series[j];
528
+ var {
529
+ sources
530
+ } = series;
531
+
532
+ for (var k = 0; k < sources.length; k += 1) {
533
+ var source = sources[k];
534
+ var {
535
+ axis
536
+ } = source;
537
+ var {
538
+ type: axisType
539
+ } = axis;
540
+ var typeAxes = axisTypeMap.get(axisType);
541
+ var axisIndex = typeAxes.indexOf(axis);
542
+ var axisProperty = ChartUtils.getAxisPropertyName(axisType);
543
+ var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
544
+
545
+ if (axisFormats.has(axisLayoutProperty)) {
546
+ log.debug("".concat(axisLayoutProperty, " already added."));
547
+ } else {
548
+ var _ret = function () {
549
+ log.debug("Adding ".concat(axisLayoutProperty, " to axisFormats."));
550
+ var axisFormat = ChartUtils.getPlotlyAxisFormat(source, formatter);
551
+
552
+ if (axisFormat === null) {
553
+ axisFormats.set(axisLayoutProperty, nullFormat);
554
+ } else {
555
+ axisFormats.set(axisLayoutProperty, axisFormat);
556
+ var {
557
+ businessCalendar
558
+ } = axis;
559
+
560
+ if (businessCalendar) {
561
+ var _formatter$getColumnT;
562
+
563
+ axisFormat.rangebreaks = [];
564
+ var {
565
+ businessPeriods,
566
+ businessDays,
567
+ holidays,
568
+ timeZone: calendarTimeZone
569
+ } = businessCalendar;
570
+ var formatterTimeZone = formatter === null || formatter === void 0 ? void 0 : (_formatter$getColumnT = formatter.getColumnTypeFormatter(BUSINESS_COLUMN_TYPE)) === null || _formatter$getColumnT === void 0 ? void 0 : _formatter$getColumnT.dhTimeZone;
571
+ var timeZoneDiff = formatterTimeZone ? (calendarTimeZone.standardOffset - formatterTimeZone.standardOffset) / 60 : 0;
572
+
573
+ if (holidays.length > 0) {
574
+ axisFormat.rangebreaks.push(...ChartUtils.createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone));
639
575
  }
640
576
 
641
- if (axisFormats.size === chart.axes.length) {
642
- return {
643
- v: axisFormats
644
- };
577
+ businessPeriods.forEach(period => axisFormat.rangebreaks.push({
578
+ pattern: 'hour',
579
+ bounds: [ChartUtils.periodToDecimal(period.close) + timeZoneDiff, ChartUtils.periodToDecimal(period.open) + timeZoneDiff]
580
+ })); // If there are seven business days, then there is no weekend
581
+
582
+ if (businessDays.length < DAYS.length) {
583
+ ChartUtils.createBoundsFromDays(businessDays).forEach(weekendBounds => axisFormat.rangebreaks.push({
584
+ pattern: 'day of week',
585
+ bounds: weekendBounds
586
+ }));
645
587
  }
646
588
  }
647
- }();
648
589
 
649
- if (_typeof(_ret) === "object") return _ret.v;
650
- }
590
+ if (axisFormats.size === chart.axes.length) {
591
+ return {
592
+ v: axisFormats
593
+ };
594
+ }
595
+ }
596
+ }();
597
+
598
+ if (typeof _ret === "object") return _ret.v;
651
599
  }
652
600
  }
653
601
  }
654
-
655
- return axisFormats;
656
602
  }
657
- }, {
658
- key: "getChartType",
659
- value: function getChartType(plotStyle, isBusinessTime) {
660
- switch (plotStyle) {
661
- case dh.plot.SeriesPlotStyle.HISTOGRAM:
662
- // When reading data from the `Figure`, it already provides bins and values, so rather than using
663
- // plot.ly to calculate the bins and sum values, just convert it to a bar chart
664
- return 'bar';
665
-
666
- default:
667
- return ChartUtils.getPlotlyChartType(plotStyle, isBusinessTime);
668
- }
603
+
604
+ return axisFormats;
605
+ }
606
+
607
+ static getChartType(plotStyle, isBusinessTime) {
608
+ switch (plotStyle) {
609
+ case dh.plot.SeriesPlotStyle.HISTOGRAM:
610
+ // When reading data from the `Figure`, it already provides bins and values, so rather than using
611
+ // plot.ly to calculate the bins and sum values, just convert it to a bar chart
612
+ return 'bar';
613
+
614
+ default:
615
+ return ChartUtils.getPlotlyChartType(plotStyle, isBusinessTime);
669
616
  }
670
- /**
671
- * Return the plotly axis property name
672
- * @param {dh.plot.AxisType} axisType The axis type to get the property name for
673
- */
674
-
675
- }, {
676
- key: "getAxisPropertyName",
677
- value: function getAxisPropertyName(axisType) {
678
- switch (axisType) {
679
- case dh.plot.AxisType.X:
680
- return 'x';
681
-
682
- case dh.plot.AxisType.Y:
683
- return 'y';
684
-
685
- default:
686
- return null;
687
- }
617
+ }
618
+ /**
619
+ * Return the plotly axis property name
620
+ * @param {dh.plot.AxisType} axisType The axis type to get the property name for
621
+ */
622
+
623
+
624
+ static getAxisPropertyName(axisType) {
625
+ switch (axisType) {
626
+ case dh.plot.AxisType.X:
627
+ return 'x';
628
+
629
+ case dh.plot.AxisType.Y:
630
+ return 'y';
631
+
632
+ default:
633
+ return null;
688
634
  }
689
- /**
690
- * Returns the plotly "side" value for the provided axis position
691
- * @param {dh.plot.AxisPosition} axisPosition The Iris AxisPosition of the axis
692
- */
635
+ }
636
+ /**
637
+ * Returns the plotly "side" value for the provided axis position
638
+ * @param {dh.plot.AxisPosition} axisPosition The Iris AxisPosition of the axis
639
+ */
693
640
 
694
- }, {
695
- key: "getAxisSide",
696
- value: function getAxisSide(axisPosition) {
697
- switch (axisPosition) {
698
- case dh.plot.AxisPosition.BOTTOM:
699
- return 'bottom';
700
641
 
701
- case dh.plot.AxisPosition.TOP:
702
- return 'top';
642
+ static getAxisSide(axisPosition) {
643
+ switch (axisPosition) {
644
+ case dh.plot.AxisPosition.BOTTOM:
645
+ return 'bottom';
703
646
 
704
- case dh.plot.AxisPosition.LEFT:
705
- return 'left';
647
+ case dh.plot.AxisPosition.TOP:
648
+ return 'top';
706
649
 
707
- case dh.plot.AxisPosition.RIGHT:
708
- return 'right';
650
+ case dh.plot.AxisPosition.LEFT:
651
+ return 'left';
709
652
 
710
- default:
711
- return null;
712
- }
713
- }
714
- /**
715
- * Retrieve the chart that contains the passed in series from the figure
716
- * @param {dh.plot.Figure} figure The figure to retrieve the chart from
717
- * @param {dh.plot.Series} series The series to get the chart for
718
- */
719
-
720
- }, {
721
- key: "getChartForSeries",
722
- value: function getChartForSeries(figure, series) {
723
- var charts = figure.charts;
724
-
725
- for (var i = 0; i < charts.length; i += 1) {
726
- var chart = charts[i];
727
-
728
- for (var j = 0; j < chart.series.length; j += 1) {
729
- if (series === chart.series[j]) {
730
- return chart;
731
- }
732
- }
733
- }
653
+ case dh.plot.AxisPosition.RIGHT:
654
+ return 'right';
734
655
 
735
- return null;
656
+ default:
657
+ return null;
736
658
  }
737
- /**
738
- * Get an object mapping axis to their ranges
739
- * @param {object} layout The plotly layout object to get the ranges from
740
- * @returns {object} An object mapping the axis name to it's range
741
- */
742
-
743
- }, {
744
- key: "getLayoutRanges",
745
- value: function getLayoutRanges(layout) {
746
- var ranges = {};
747
- var keys = Object.keys(layout).filter(function (key) {
748
- return key.indexOf('axis') >= 0;
749
- });
659
+ }
660
+ /**
661
+ * Retrieve the chart that contains the passed in series from the figure
662
+ * @param {dh.plot.Figure} figure The figure to retrieve the chart from
663
+ * @param {dh.plot.Series} series The series to get the chart for
664
+ */
750
665
 
751
- for (var i = 0; i < keys.length; i += 1) {
752
- var key = keys[i];
753
666
 
754
- if (layout[key] && layout[key].range && !layout[key].autorange) {
755
- // Only want to add the range if it's not autoranged
756
- ranges[key] = _toConsumableArray(layout[key].range);
757
- }
758
- }
667
+ static getChartForSeries(figure, series) {
668
+ var {
669
+ charts
670
+ } = figure;
759
671
 
760
- return ranges;
761
- }
762
- /**
763
- * Updates the axes positions and sizes in the layout object provided.
764
- * If the axis did not exist in the layout previously, it is created and added.
765
- * Any axis that no longer exists in axes is removed.
766
- * With Downsampling enabled, will also update the range on the axis itself as appropriate
767
- * @param {object} layoutParam The layout object to update
768
- * @param {dh.plot.Axis[]} axes The axes to update the layout with
769
- * @param {number} plotWidth The width of the plot to calculate the axis sizes for
770
- * @param {number} plotHeight The height of the plot to calculate the axis sizes for
771
- * @param {func} getRangeParser A function to retrieve the range parser for a given axis
772
- */
773
-
774
- }, {
775
- key: "updateLayoutAxes",
776
- value: function updateLayoutAxes(layoutParam, axes) {
777
- var plotWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
778
- var plotHeight = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
779
- var getRangeParser = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
780
- 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;
781
- 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; // Adjust the bounds based on where the legend is
782
- // For now, always assume the legend is shown on the right
783
-
784
- var bounds = {
785
- left: 0,
786
- bottom: 0,
787
- top: 1,
788
- right: 1
789
- };
790
- var axisPositionMap = ChartUtils.groupArray(axes, 'position');
791
- var rightAxes = axisPositionMap.get(dh.plot.AxisPosition.RIGHT) || [];
672
+ for (var i = 0; i < charts.length; i += 1) {
673
+ var chart = charts[i];
792
674
 
793
- if (rightAxes.length > 0) {
794
- if (plotWidth > 0) {
795
- bounds.right = 1 - Math.max(0, Math.min(ChartUtils.LEGEND_WIDTH_PX / plotWidth, ChartUtils.MAX_LEGEND_SIZE));
796
- } else {
797
- bounds.right = 1 - ChartUtils.DEFAULT_AXIS_SIZE;
675
+ for (var j = 0; j < chart.series.length; j += 1) {
676
+ if (series === chart.series[j]) {
677
+ return chart;
798
678
  }
799
679
  }
680
+ }
681
+
682
+ return null;
683
+ }
684
+ /**
685
+ * Get an object mapping axis to their ranges
686
+ * @param {object} layout The plotly layout object to get the ranges from
687
+ * @returns {object} An object mapping the axis name to it's range
688
+ */
800
689
 
801
- var layout = layoutParam;
802
- var axisTypeMap = ChartUtils.groupArray(axes, 'type');
803
690
 
804
- var axisTypes = _toConsumableArray(axisTypeMap.keys());
691
+ static getLayoutRanges(layout) {
692
+ var ranges = {};
693
+ var keys = Object.keys(layout).filter(key => key.indexOf('axis') >= 0);
805
694
 
806
- for (var j = 0; j < axisTypes.length; j += 1) {
807
- var axisType = axisTypes[j];
808
- var axisProperty = ChartUtils.getAxisPropertyName(axisType);
695
+ for (var i = 0; i < keys.length; i += 1) {
696
+ var key = keys[i];
809
697
 
810
- if (axisProperty != null) {
811
- var typeAxes = axisTypeMap.get(axisType);
812
- var isYAxis = axisType === dh.plot.AxisType.Y;
813
- var plotSize = isYAxis ? plotHeight : plotWidth;
814
- var axisIndex = 0;
698
+ if (layout[key] && layout[key].range && !layout[key].autorange) {
699
+ // Only want to add the range if it's not autoranged
700
+ ranges[key] = [...layout[key].range];
701
+ }
702
+ }
815
703
 
816
- for (axisIndex = 0; axisIndex < typeAxes.length; axisIndex += 1) {
817
- var axis = typeAxes[axisIndex];
704
+ return ranges;
705
+ }
706
+ /**
707
+ * Updates the axes positions and sizes in the layout object provided.
708
+ * If the axis did not exist in the layout previously, it is created and added.
709
+ * Any axis that no longer exists in axes is removed.
710
+ * With Downsampling enabled, will also update the range on the axis itself as appropriate
711
+ * @param {object} layoutParam The layout object to update
712
+ * @param {dh.plot.Axis[]} axes The axes to update the layout with
713
+ * @param {number} plotWidth The width of the plot to calculate the axis sizes for
714
+ * @param {number} plotHeight The height of the plot to calculate the axis sizes for
715
+ * @param {func} getRangeParser A function to retrieve the range parser for a given axis
716
+ */
717
+
718
+
719
+ static updateLayoutAxes(layoutParam, axes) {
720
+ var plotWidth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
721
+ var plotHeight = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
722
+ var getRangeParser = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
723
+ 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;
724
+ 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; // Adjust the bounds based on where the legend is
725
+ // For now, always assume the legend is shown on the right
726
+
727
+ var bounds = {
728
+ left: 0,
729
+ bottom: 0,
730
+ top: 1,
731
+ right: 1
732
+ };
733
+ var axisPositionMap = ChartUtils.groupArray(axes, 'position');
734
+ var rightAxes = axisPositionMap.get(dh.plot.AxisPosition.RIGHT) || [];
735
+
736
+ if (rightAxes.length > 0) {
737
+ if (plotWidth > 0) {
738
+ bounds.right = 1 - Math.max(0, Math.min(ChartUtils.LEGEND_WIDTH_PX / plotWidth, ChartUtils.MAX_LEGEND_SIZE));
739
+ } else {
740
+ bounds.right = 1 - ChartUtils.DEFAULT_AXIS_SIZE;
741
+ }
742
+ }
818
743
 
819
- var _axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
744
+ var layout = layoutParam;
745
+ var axisTypeMap = ChartUtils.groupArray(axes, 'type');
746
+ var axisTypes = [...axisTypeMap.keys()];
820
747
 
821
- if (layout[_axisLayoutProperty] == null) {
822
- layout[_axisLayoutProperty] = ChartUtils.makeLayoutAxis(axisType);
823
- }
748
+ for (var j = 0; j < axisTypes.length; j += 1) {
749
+ var axisType = axisTypes[j];
750
+ var axisProperty = ChartUtils.getAxisPropertyName(axisType);
824
751
 
825
- var layoutAxis = layout[_axisLayoutProperty];
826
- ChartUtils.updateLayoutAxis(layoutAxis, axis, axisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds);
827
- var range = layoutAxis.range,
828
- autorange = layoutAxis.autorange;
752
+ if (axisProperty != null) {
753
+ var typeAxes = axisTypeMap.get(axisType);
754
+ var isYAxis = axisType === dh.plot.AxisType.Y;
755
+ var plotSize = isYAxis ? plotHeight : plotWidth;
756
+ var axisIndex = 0;
829
757
 
830
- if (getRangeParser && range && !autorange) {
831
- var rangeParser = getRangeParser(axis);
758
+ for (axisIndex = 0; axisIndex < typeAxes.length; axisIndex += 1) {
759
+ var axis = typeAxes[axisIndex];
832
760
 
833
- var _rangeParser = rangeParser(range),
834
- _rangeParser2 = _slicedToArray(_rangeParser, 2),
835
- rangeStart = _rangeParser2[0],
836
- rangeEnd = _rangeParser2[1];
761
+ var _axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
837
762
 
838
- log.debug('Setting downsample range', plotSize, rangeStart, rangeEnd);
839
- axis.range(plotSize, rangeStart, rangeEnd);
840
- } else {
841
- axis.range(plotSize);
842
- }
763
+ if (layout[_axisLayoutProperty] == null) {
764
+ layout[_axisLayoutProperty] = ChartUtils.makeLayoutAxis(axisType);
843
765
  }
844
766
 
845
- var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
846
-
847
- while (layout[axisLayoutProperty] != null) {
848
- delete layout[axisLayoutProperty];
849
- axisIndex += 1;
850
- axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
767
+ var layoutAxis = layout[_axisLayoutProperty];
768
+ ChartUtils.updateLayoutAxis(layoutAxis, axis, axisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds);
769
+ var {
770
+ range,
771
+ autorange
772
+ } = layoutAxis;
773
+
774
+ if (getRangeParser && range && !autorange) {
775
+ var rangeParser = getRangeParser(axis);
776
+ var [rangeStart, rangeEnd] = rangeParser(range);
777
+ log.debug('Setting downsample range', plotSize, rangeStart, rangeEnd);
778
+ axis.range(plotSize, rangeStart, rangeEnd);
779
+ } else {
780
+ axis.range(plotSize);
851
781
  }
852
782
  }
783
+
784
+ var axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
785
+
786
+ while (layout[axisLayoutProperty] != null) {
787
+ delete layout[axisLayoutProperty];
788
+ axisIndex += 1;
789
+ axisLayoutProperty = ChartUtils.getAxisLayoutProperty(axisProperty, axisIndex);
790
+ }
853
791
  }
854
792
  }
855
- }, {
856
- key: "getAxisLayoutProperty",
857
- value: function getAxisLayoutProperty(axisProperty, axisIndex) {
858
- var axisIndexString = axisIndex > 0 ? "".concat(axisIndex + 1) : '';
859
- return "".concat(axisProperty, "axis").concat(axisIndexString);
860
- }
861
- /**
862
- * Updates the layout axis object in place
863
- * @param {object} layoutAxisParam The plotly layout axis param
864
- * @param {dh.plot.Axis} axis The Iris Axis to update the plotly layout with
865
- * @param {number} axisIndex The type index for this axis
866
- * @param {Map<dh.plot.AxisPosition, dh.plot.Axis>} axisPositionMap All the axes mapped by position
867
- * @param {number} axisSize The size of each axis in percent
868
- * @param {object} bounds The bounds of the axes domains
869
- */
870
-
871
- }, {
872
- key: "updateLayoutAxis",
873
- value: function updateLayoutAxis(layoutAxisParam, axis, axisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds) {
874
- var isYAxis = axis.type === dh.plot.AxisType.Y;
875
- var axisSize = isYAxis ? yAxisSize : xAxisSize;
876
- var layoutAxis = layoutAxisParam;
877
- layoutAxis.title.text = axis.label;
793
+ }
878
794
 
879
- if (axis.log) {
880
- layoutAxis.type = 'log';
881
- }
795
+ static getAxisLayoutProperty(axisProperty, axisIndex) {
796
+ var axisIndexString = axisIndex > 0 ? "".concat(axisIndex + 1) : '';
797
+ return "".concat(axisProperty, "axis").concat(axisIndexString);
798
+ }
799
+ /**
800
+ * Updates the layout axis object in place
801
+ * @param {object} layoutAxisParam The plotly layout axis param
802
+ * @param {dh.plot.Axis} axis The Iris Axis to update the plotly layout with
803
+ * @param {number} axisIndex The type index for this axis
804
+ * @param {Map<dh.plot.AxisPosition, dh.plot.Axis>} axisPositionMap All the axes mapped by position
805
+ * @param {number} axisSize The size of each axis in percent
806
+ * @param {object} bounds The bounds of the axes domains
807
+ */
808
+
809
+
810
+ static updateLayoutAxis(layoutAxisParam, axis, axisIndex, axisPositionMap, xAxisSize, yAxisSize, bounds) {
811
+ var isYAxis = axis.type === dh.plot.AxisType.Y;
812
+ var axisSize = isYAxis ? yAxisSize : xAxisSize;
813
+ var layoutAxis = layoutAxisParam;
814
+ layoutAxis.title.text = axis.label;
815
+
816
+ if (axis.log) {
817
+ layoutAxis.type = 'log';
818
+ }
882
819
 
883
- layoutAxis.side = ChartUtils.getAxisSide(axis.position);
820
+ layoutAxis.side = ChartUtils.getAxisSide(axis.position);
884
821
 
885
- if (axisIndex > 0) {
886
- layoutAxis.overlaying = ChartUtils.getAxisPropertyName(axis.type);
887
- var positionAxes = axisPositionMap.get(axis.position);
888
- var sideIndex = positionAxes.indexOf(axis);
822
+ if (axisIndex > 0) {
823
+ layoutAxis.overlaying = ChartUtils.getAxisPropertyName(axis.type);
824
+ var positionAxes = axisPositionMap.get(axis.position);
825
+ var sideIndex = positionAxes.indexOf(axis);
889
826
 
890
- if (sideIndex > 0) {
891
- layoutAxis.anchor = 'free';
827
+ if (sideIndex > 0) {
828
+ layoutAxis.anchor = 'free';
892
829
 
893
- if (axis.position === dh.plot.AxisPosition.RIGHT) {
894
- layoutAxis.position = bounds.right + (sideIndex - positionAxes.length + 1) * axisSize;
895
- } else if (axis.position === dh.plot.AxisPosition.TOP) {
896
- layoutAxis.position = bounds.top + (sideIndex - positionAxes.length + 1) * axisSize;
897
- } else if (axis.position === dh.plot.AxisPosition.BOTTOM) {
898
- layoutAxis.position = bounds.bottom + (positionAxes.length - sideIndex + 1) * axisSize;
899
- } else if (axis.position === dh.plot.AxisPosition.LEFT) {
900
- layoutAxis.position = bounds.left + (positionAxes.length - sideIndex + 1) * axisSize;
901
- }
830
+ if (axis.position === dh.plot.AxisPosition.RIGHT) {
831
+ layoutAxis.position = bounds.right + (sideIndex - positionAxes.length + 1) * axisSize;
832
+ } else if (axis.position === dh.plot.AxisPosition.TOP) {
833
+ layoutAxis.position = bounds.top + (sideIndex - positionAxes.length + 1) * axisSize;
834
+ } else if (axis.position === dh.plot.AxisPosition.BOTTOM) {
835
+ layoutAxis.position = bounds.bottom + (positionAxes.length - sideIndex + 1) * axisSize;
836
+ } else if (axis.position === dh.plot.AxisPosition.LEFT) {
837
+ layoutAxis.position = bounds.left + (positionAxes.length - sideIndex + 1) * axisSize;
902
838
  }
903
- } else if (axis.type === dh.plot.AxisType.X) {
904
- var leftAxes = axisPositionMap.get(dh.plot.AxisPosition.LEFT) || [];
905
- var rightAxes = axisPositionMap.get(dh.plot.AxisPosition.RIGHT) || [];
906
- var left = Math.max(bounds.left, bounds.left + (leftAxes.length - 1) * yAxisSize);
907
- var right = Math.min(bounds.right - (rightAxes.length - 1) * yAxisSize, bounds.right);
908
- layoutAxis.domain = [left, right];
909
- } else if (axis.type === dh.plot.AxisType.Y) {
910
- var bottomAxes = axisPositionMap.get(dh.plot.AxisPosition.BOTTOM) || [];
911
- var topAxes = axisPositionMap.get(dh.plot.AxisPosition.TOP) || [];
912
- var bottom = Math.max(bounds.bottom, bounds.bottom + (bottomAxes.length - 1) * xAxisSize);
913
- var top = Math.min(bounds.top - (topAxes.length - 1) * xAxisSize, bounds.top);
914
- layoutAxis.domain = [bottom, top];
915
839
  }
840
+ } else if (axis.type === dh.plot.AxisType.X) {
841
+ var leftAxes = axisPositionMap.get(dh.plot.AxisPosition.LEFT) || [];
842
+ var rightAxes = axisPositionMap.get(dh.plot.AxisPosition.RIGHT) || [];
843
+ var left = Math.max(bounds.left, bounds.left + (leftAxes.length - 1) * yAxisSize);
844
+ var right = Math.min(bounds.right - (rightAxes.length - 1) * yAxisSize, bounds.right);
845
+ layoutAxis.domain = [left, right];
846
+ } else if (axis.type === dh.plot.AxisType.Y) {
847
+ var bottomAxes = axisPositionMap.get(dh.plot.AxisPosition.BOTTOM) || [];
848
+ var topAxes = axisPositionMap.get(dh.plot.AxisPosition.TOP) || [];
849
+ var bottom = Math.max(bounds.bottom, bounds.bottom + (bottomAxes.length - 1) * xAxisSize);
850
+ var top = Math.min(bounds.top - (topAxes.length - 1) * xAxisSize, bounds.top);
851
+ layoutAxis.domain = [bottom, top];
916
852
  }
917
- /**
918
- * Converts an open or close period to a declimal. e.g '09:30" to 9.5
919
- *
920
- * @param {String} period the open or close value of the period
921
- */
922
-
923
- }, {
924
- key: "periodToDecimal",
925
- value: function periodToDecimal(period) {
926
- var values = period.split(':');
927
- return Number(values[0]) + Number(values[1] / 60);
928
- }
929
- /**
930
- * Creates range break bounds for plotly from business days.
931
- * For example a standard business week of ['MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY']
932
- * will result in [[6,1]] meaning close on Saturday and open on Monday.
933
- * If you remove Wednesday from the array, then you get two closures [[6, 1], [3, 4]]
934
- *
935
- * @param {Array} businessDays the days to display on the x-axis
936
- */
937
-
938
- }, {
939
- key: "createBoundsFromDays",
940
- value: function createBoundsFromDays(businessDays) {
941
- var businessDaysInt = businessDays.map(function (day) {
942
- return DAYS.indexOf(day);
943
- });
944
- var nonBusinessDaysInt = DAYS.filter(function (day) {
945
- return !businessDays.includes(day);
946
- }).map(function (day) {
947
- return DAYS.indexOf(day);
948
- }); // These are the days when business reopens (e.g. Monday after a weekend)
949
-
950
- var reopenDays = new Set();
951
- nonBusinessDaysInt.forEach(function (closed) {
952
- for (var i = closed + 1; i < closed + DAYS.length; i += 1) {
953
- var adjustedDay = i % DAYS.length;
954
-
955
- if (businessDaysInt.includes(adjustedDay)) {
956
- reopenDays.add(adjustedDay);
957
- break;
958
- }
959
- }
960
- });
961
- var boundsArray = []; // For each reopen day, find the furthest previous closed day
853
+ }
854
+ /**
855
+ * Converts an open or close period to a declimal. e.g '09:30" to 9.5
856
+ *
857
+ * @param {String} period the open or close value of the period
858
+ */
962
859
 
963
- reopenDays.forEach(function (open) {
964
- for (var i = open - 1; i > open - DAYS.length; i -= 1) {
965
- var adjustedDay = i < 0 ? i + DAYS.length : i;
966
860
 
967
- if (businessDaysInt.includes(adjustedDay)) {
968
- var closedDay = (adjustedDay + 1) % 7;
969
- boundsArray.push([closedDay, open]);
970
- break;
971
- }
972
- }
973
- });
974
- return boundsArray;
975
- }
976
- /**
977
- * Creates an array of range breaks for all holidays.
978
- *
979
- * @param {Array} holidays an array of holidays
980
- * @param {TimeZone} calendarTimeZone the time zone for the business calendar
981
- * @param {TimeZone} formatterTimeZone the time zone for the formatter
982
- */
983
-
984
- }, {
985
- key: "createRangeBreakValuesFromHolidays",
986
- value: function createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone) {
987
- var fullHolidays = [];
988
- var partialHolidays = [];
989
- holidays.forEach(function (holiday) {
990
- if (holiday.businessPeriods.length > 0) {
991
- partialHolidays.push.apply(partialHolidays, _toConsumableArray(ChartUtils.createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone)));
992
- } else {
993
- fullHolidays.push(ChartUtils.createFullHoliday(holiday, calendarTimeZone, formatterTimeZone));
994
- }
995
- });
996
- return [{
997
- values: fullHolidays
998
- }].concat(partialHolidays);
999
- }
1000
- /**
1001
- * Creates the range break value for a full holiday. A full holiday is day that has no business periods.
1002
- *
1003
- * @param {Holiday} holiday the full holiday
1004
- * @param {TimeZone} calendarTimeZone the time zone for the business calendar
1005
- * @param {TimeZone} formatterTimeZone the time zone for the formatter
1006
- */
1007
-
1008
- }, {
1009
- key: "createFullHoliday",
1010
- value: function createFullHoliday(holiday, calendarTimeZone, formatterTimeZone) {
1011
- return ChartUtils.adjustDateForTimeZone("".concat(holiday.date.toString(), " 00:00:00.000000"), calendarTimeZone, formatterTimeZone);
1012
- }
1013
- /**
1014
- * Creates the range break for a partial holiday. A partial holiday is holiday with business periods
1015
- * that are different than the default business periods.
1016
- *
1017
- * @param {Holiday} holiday the partial holiday
1018
- * @param {TimeZone} calendarTimeZone the time zone for the business calendar
1019
- * @param {TimeZone} formatterTimeZone the time zone for the formatter
1020
- */
1021
-
1022
- }, {
1023
- key: "createPartialHoliday",
1024
- value: function createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone) {
1025
- // If a holiday has business periods {open1, close1} and {open2, close2}
1026
- // This will generate range breaks for:
1027
- // closed from 00:00 to open1
1028
- // closed from close1 to open2
1029
- // closed from close2 to 23:59:59.999999
1030
- var dateString = holiday.date.toString();
1031
- var closedPeriods = ['00:00'];
1032
- holiday.businessPeriods.forEach(function (period) {
1033
- closedPeriods.push(period.open);
1034
- closedPeriods.push(period.close);
1035
- }); // To go up to 23:59:59.999999, we calculate the dvalue using 24 - close
1036
-
1037
- closedPeriods.push('24:00');
1038
- var rangeBreaks = [];
1039
-
1040
- for (var i = 0; i < closedPeriods.length; i += 2) {
1041
- var startClose = closedPeriods[i];
1042
- var endClose = closedPeriods[i + 1]; // Skip over any periods where start and close are the same (zero hours)
1043
-
1044
- if (startClose !== endClose) {
1045
- var values = [ChartUtils.adjustDateForTimeZone("".concat(dateString, " ").concat(startClose, ":00.000000"), calendarTimeZone, formatterTimeZone)];
1046
- var dvalue = MILLIS_PER_HOUR * (ChartUtils.periodToDecimal(endClose) - ChartUtils.periodToDecimal(startClose));
1047
- rangeBreaks.push({
1048
- values: values,
1049
- dvalue: dvalue
1050
- });
861
+ static periodToDecimal(period) {
862
+ var values = period.split(':');
863
+ return Number(values[0]) + Number(values[1] / 60);
864
+ }
865
+ /**
866
+ * Creates range break bounds for plotly from business days.
867
+ * For example a standard business week of ['MONDAY','TUESDAY','WEDNESDAY','THURSDAY','FRIDAY']
868
+ * will result in [[6,1]] meaning close on Saturday and open on Monday.
869
+ * If you remove Wednesday from the array, then you get two closures [[6, 1], [3, 4]]
870
+ *
871
+ * @param {Array} businessDays the days to display on the x-axis
872
+ */
873
+
874
+
875
+ static createBoundsFromDays(businessDays) {
876
+ var businessDaysInt = businessDays.map(day => DAYS.indexOf(day));
877
+ var nonBusinessDaysInt = DAYS.filter(day => !businessDays.includes(day)).map(day => DAYS.indexOf(day)); // These are the days when business reopens (e.g. Monday after a weekend)
878
+
879
+ var reopenDays = new Set();
880
+ nonBusinessDaysInt.forEach(closed => {
881
+ for (var i = closed + 1; i < closed + DAYS.length; i += 1) {
882
+ var adjustedDay = i % DAYS.length;
883
+
884
+ if (businessDaysInt.includes(adjustedDay)) {
885
+ reopenDays.add(adjustedDay);
886
+ break;
1051
887
  }
1052
888
  }
889
+ });
890
+ var boundsArray = []; // For each reopen day, find the furthest previous closed day
1053
891
 
1054
- return rangeBreaks;
1055
- }
1056
- /**
1057
- * Adjusts a date string from the calendar time zone to the formatter time zone.
1058
- *
1059
- * @param {string} dateString the date string
1060
- * @param {TimeZone} calendarTimeZone the time zone for the business calendar
1061
- * @param {TimeZone} formatterTimeZone the time zone for the formatter
1062
- */
1063
-
1064
- }, {
1065
- key: "adjustDateForTimeZone",
1066
- value: function adjustDateForTimeZone(dateString, calendarTimeZone, formatterTimeZone) {
1067
- if (formatterTimeZone && formatterTimeZone.standardOffset !== calendarTimeZone.standardOffset) {
1068
- return ChartUtils.unwrapValue(ChartUtils.wrapValue(dateString, BUSINESS_COLUMN_TYPE, calendarTimeZone), formatterTimeZone);
892
+ reopenDays.forEach(open => {
893
+ for (var i = open - 1; i > open - DAYS.length; i -= 1) {
894
+ var adjustedDay = i < 0 ? i + DAYS.length : i;
895
+
896
+ if (businessDaysInt.includes(adjustedDay)) {
897
+ var closedDay = (adjustedDay + 1) % 7;
898
+ boundsArray.push([closedDay, open]);
899
+ break;
900
+ }
1069
901
  }
902
+ });
903
+ return boundsArray;
904
+ }
905
+ /**
906
+ * Creates an array of range breaks for all holidays.
907
+ *
908
+ * @param {Array} holidays an array of holidays
909
+ * @param {TimeZone} calendarTimeZone the time zone for the business calendar
910
+ * @param {TimeZone} formatterTimeZone the time zone for the formatter
911
+ */
912
+
913
+
914
+ static createRangeBreakValuesFromHolidays(holidays, calendarTimeZone, formatterTimeZone) {
915
+ var fullHolidays = [];
916
+ var partialHolidays = [];
917
+ holidays.forEach(holiday => {
918
+ if (holiday.businessPeriods.length > 0) {
919
+ partialHolidays.push(...ChartUtils.createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone));
920
+ } else {
921
+ fullHolidays.push(ChartUtils.createFullHoliday(holiday, calendarTimeZone, formatterTimeZone));
922
+ }
923
+ });
924
+ return [{
925
+ values: fullHolidays
926
+ }, ...partialHolidays];
927
+ }
928
+ /**
929
+ * Creates the range break value for a full holiday. A full holiday is day that has no business periods.
930
+ *
931
+ * @param {Holiday} holiday the full holiday
932
+ * @param {TimeZone} calendarTimeZone the time zone for the business calendar
933
+ * @param {TimeZone} formatterTimeZone the time zone for the formatter
934
+ */
1070
935
 
1071
- return dateString;
936
+
937
+ static createFullHoliday(holiday, calendarTimeZone, formatterTimeZone) {
938
+ return ChartUtils.adjustDateForTimeZone("".concat(holiday.date.toString(), " 00:00:00.000000"), calendarTimeZone, formatterTimeZone);
939
+ }
940
+ /**
941
+ * Creates the range break for a partial holiday. A partial holiday is holiday with business periods
942
+ * that are different than the default business periods.
943
+ *
944
+ * @param {Holiday} holiday the partial holiday
945
+ * @param {TimeZone} calendarTimeZone the time zone for the business calendar
946
+ * @param {TimeZone} formatterTimeZone the time zone for the formatter
947
+ */
948
+
949
+
950
+ static createPartialHoliday(holiday, calendarTimeZone, formatterTimeZone) {
951
+ // If a holiday has business periods {open1, close1} and {open2, close2}
952
+ // This will generate range breaks for:
953
+ // closed from 00:00 to open1
954
+ // closed from close1 to open2
955
+ // closed from close2 to 23:59:59.999999
956
+ var dateString = holiday.date.toString();
957
+ var closedPeriods = ['00:00'];
958
+ holiday.businessPeriods.forEach(period => {
959
+ closedPeriods.push(period.open);
960
+ closedPeriods.push(period.close);
961
+ }); // To go up to 23:59:59.999999, we calculate the dvalue using 24 - close
962
+
963
+ closedPeriods.push('24:00');
964
+ var rangeBreaks = [];
965
+
966
+ for (var i = 0; i < closedPeriods.length; i += 2) {
967
+ var startClose = closedPeriods[i];
968
+ var endClose = closedPeriods[i + 1]; // Skip over any periods where start and close are the same (zero hours)
969
+
970
+ if (startClose !== endClose) {
971
+ var values = [ChartUtils.adjustDateForTimeZone("".concat(dateString, " ").concat(startClose, ":00.000000"), calendarTimeZone, formatterTimeZone)];
972
+ var dvalue = MILLIS_PER_HOUR * (ChartUtils.periodToDecimal(endClose) - ChartUtils.periodToDecimal(startClose));
973
+ rangeBreaks.push({
974
+ values,
975
+ dvalue
976
+ });
977
+ }
1072
978
  }
1073
- /**
1074
- * Groups an array and returns a map
1075
- * @param {object[]} array The object to group
1076
- * @param {string} property The property name to group by
1077
- * @returns {Map<object, object>} A map containing the items grouped by their values for the property
1078
- */
1079
-
1080
- }, {
1081
- key: "groupArray",
1082
- value: function groupArray(array, property) {
1083
- return array.reduce(function (result, item) {
1084
- var key = item[property];
1085
- var group = result.get(key) || [];
1086
- group.push(item);
1087
- result.set(key, group);
1088
- return result;
1089
- }, new Map());
979
+
980
+ return rangeBreaks;
981
+ }
982
+ /**
983
+ * Adjusts a date string from the calendar time zone to the formatter time zone.
984
+ *
985
+ * @param {string} dateString the date string
986
+ * @param {TimeZone} calendarTimeZone the time zone for the business calendar
987
+ * @param {TimeZone} formatterTimeZone the time zone for the formatter
988
+ */
989
+
990
+
991
+ static adjustDateForTimeZone(dateString, calendarTimeZone, formatterTimeZone) {
992
+ if (formatterTimeZone && formatterTimeZone.standardOffset !== calendarTimeZone.standardOffset) {
993
+ return ChartUtils.unwrapValue(ChartUtils.wrapValue(dateString, BUSINESS_COLUMN_TYPE, calendarTimeZone), formatterTimeZone);
1090
994
  }
1091
- /**
1092
- * Update
1093
- */
1094
-
1095
- }, {
1096
- key: "updateRanges",
1097
- value: function updateRanges() {}
1098
- /**
1099
- * Unwraps a value provided from API to a value plotly can understand
1100
- * Eg. Unwraps DateWrapper, LongWrapper objects.
1101
- */
1102
-
1103
- }, {
1104
- key: "unwrapValue",
1105
- value: function unwrapValue(value) {
1106
- var timeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
1107
-
1108
- if (value != null) {
1109
- if (value.asDate) {
1110
- return dh.i18n.DateTimeFormat.format(ChartUtils.DATE_FORMAT, value, timeZone);
1111
- }
1112
995
 
1113
- if (value.asNumber) {
1114
- return value.asNumber();
1115
- }
996
+ return dateString;
997
+ }
998
+ /**
999
+ * Groups an array and returns a map
1000
+ * @param {object[]} array The object to group
1001
+ * @param {string} property The property name to group by
1002
+ * @returns {Map<object, object>} A map containing the items grouped by their values for the property
1003
+ */
1004
+
1005
+
1006
+ static groupArray(array, property) {
1007
+ return array.reduce((result, item) => {
1008
+ var key = item[property];
1009
+ var group = result.get(key) || [];
1010
+ group.push(item);
1011
+ result.set(key, group);
1012
+ return result;
1013
+ }, new Map());
1014
+ }
1015
+ /**
1016
+ * Update
1017
+ */
1018
+
1019
+
1020
+ static updateRanges() {}
1021
+ /**
1022
+ * Unwraps a value provided from API to a value plotly can understand
1023
+ * Eg. Unwraps DateWrapper, LongWrapper objects.
1024
+ */
1025
+
1026
+
1027
+ static unwrapValue(value) {
1028
+ var timeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
1029
+
1030
+ if (value != null) {
1031
+ if (value.asDate) {
1032
+ return dh.i18n.DateTimeFormat.format(ChartUtils.DATE_FORMAT, value, timeZone);
1116
1033
  }
1117
1034
 
1118
- return value;
1119
- }
1120
- /**
1121
- *
1122
- * @param {any} value The value to wrap up
1123
- * @param {string} columnType The type of column this value is from
1124
- * @param {dh.i18n.TimeZone} timeZone The time zone if applicable
1125
- */
1126
-
1127
- }, {
1128
- key: "wrapValue",
1129
- value: function wrapValue(value, columnType) {
1130
- var timeZone = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
1131
-
1132
- if (TableUtils.isDateType(columnType) && typeof value === 'string') {
1133
- // Need to limit the format to the actual length of the string range set in plotly
1134
- // Otherwise parse will fail
1135
- var text = value;
1136
- var format = ChartUtils.DATE_FORMAT.substr(0, value.length);
1137
- var date = dh.i18n.DateTimeFormat.parse(format, text);
1138
-
1139
- if (!timeZone) {
1140
- return date;
1141
- } // IDS-5994 Due to date parsing, time zone, and daylight savings shenanigans, we need
1142
- // to pass the actual offset with the time to have it parse correctly.
1143
- // However, the offset can change based on the date because of Daylight Savings
1144
- // So we end up parsing the date multiple times. And curse daylight savings.
1145
-
1146
-
1147
- var tzFormat = "".concat(format, " Z");
1148
- var estimatedOffset = dh.i18n.DateTimeFormat.format('Z', date, timeZone);
1149
- var estimatedDate = dh.i18n.DateTimeFormat.parse(tzFormat, "".concat(text, " ").concat(estimatedOffset));
1150
- var offset = dh.i18n.DateTimeFormat.format('Z', estimatedDate, timeZone);
1151
- return dh.i18n.DateTimeFormat.parse(tzFormat, "".concat(text, " ").concat(offset));
1035
+ if (value.asNumber) {
1036
+ return value.asNumber();
1152
1037
  }
1038
+ }
1153
1039
 
1154
- return value;
1040
+ return value;
1041
+ }
1042
+ /**
1043
+ *
1044
+ * @param {any} value The value to wrap up
1045
+ * @param {string} columnType The type of column this value is from
1046
+ * @param {dh.i18n.TimeZone} timeZone The time zone if applicable
1047
+ */
1048
+
1049
+
1050
+ static wrapValue(value, columnType) {
1051
+ var timeZone = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
1052
+
1053
+ if (TableUtils.isDateType(columnType) && typeof value === 'string') {
1054
+ // Need to limit the format to the actual length of the string range set in plotly
1055
+ // Otherwise parse will fail
1056
+ var text = value;
1057
+ var format = ChartUtils.DATE_FORMAT.substr(0, value.length);
1058
+ var date = dh.i18n.DateTimeFormat.parse(format, text);
1059
+
1060
+ if (!timeZone) {
1061
+ return date;
1062
+ } // IDS-5994 Due to date parsing, time zone, and daylight savings shenanigans, we need
1063
+ // to pass the actual offset with the time to have it parse correctly.
1064
+ // However, the offset can change based on the date because of Daylight Savings
1065
+ // So we end up parsing the date multiple times. And curse daylight savings.
1066
+
1067
+
1068
+ var tzFormat = "".concat(format, " Z");
1069
+ var estimatedOffset = dh.i18n.DateTimeFormat.format('Z', date, timeZone);
1070
+ var estimatedDate = dh.i18n.DateTimeFormat.parse(tzFormat, "".concat(text, " ").concat(estimatedOffset));
1071
+ var offset = dh.i18n.DateTimeFormat.format('Z', estimatedDate, timeZone);
1072
+ return dh.i18n.DateTimeFormat.parse(tzFormat, "".concat(text, " ").concat(offset));
1155
1073
  }
1156
- }, {
1157
- key: "makeLayoutAxis",
1158
- value: function makeLayoutAxis(type) {
1159
- var axis = {
1160
- automargin: true,
1161
- gridcolor: ChartTheme.gridcolor,
1162
- linecolor: ChartTheme.linecolor,
1163
- rangeslider: {
1164
- visible: false
1165
- },
1166
- showline: true,
1167
- ticklen: 5,
1168
- // act as padding, can't find a tick padding
1169
- tickcolor: ChartTheme.paper_bgcolor,
1170
- // hide ticks as padding
1171
- tickfont: {
1172
- color: ChartTheme.zerolinecolor
1173
- },
1174
- title: {
1175
- font: {
1176
- color: ChartTheme.title_color
1177
- }
1178
- }
1179
- };
1180
1074
 
1181
- if (type === dh.plot.AxisType.X) {
1182
- Object.assign(axis, {
1183
- showgrid: true
1184
- });
1185
- } else if (type === dh.plot.AxisType.Y) {
1186
- Object.assign(axis, {
1187
- zerolinecolor: ChartTheme.zerolinecolor,
1188
- zerolinewidth: 2
1189
- });
1190
- }
1075
+ return value;
1076
+ }
1191
1077
 
1192
- return axis;
1193
- }
1194
- }, {
1195
- key: "makeDefaultLayout",
1196
- value: function makeDefaultLayout() {
1197
- var layout = _objectSpread(_objectSpread({}, ChartTheme), {}, {
1198
- autosize: true,
1199
- colorway: ChartTheme.colorway ? ChartTheme.colorway.split(' ') : [],
1078
+ static makeLayoutAxis(type) {
1079
+ var axis = {
1080
+ automargin: true,
1081
+ gridcolor: ChartTheme.gridcolor,
1082
+ linecolor: ChartTheme.linecolor,
1083
+ rangeslider: {
1084
+ visible: false
1085
+ },
1086
+ showline: true,
1087
+ ticklen: 5,
1088
+ // act as padding, can't find a tick padding
1089
+ tickcolor: ChartTheme.paper_bgcolor,
1090
+ // hide ticks as padding
1091
+ tickfont: {
1092
+ color: ChartTheme.zerolinecolor
1093
+ },
1094
+ title: {
1200
1095
  font: {
1201
- family: "'Fira Sans', sans-serif"
1202
- },
1203
- title: {
1204
- font: {
1205
- color: ChartTheme.title_color
1206
- },
1207
- yanchor: 'top',
1208
- pad: _objectSpread({}, ChartUtils.DEFAULT_TITLE_PADDING),
1209
- y: 1,
1210
- text: 'Untitled'
1211
- },
1212
- legend: {
1213
- font: {
1214
- color: ChartTheme.title_color
1215
- }
1216
- },
1217
- margin: _objectSpread({}, ChartUtils.DEFAULT_MARGIN),
1218
- xaxis: ChartUtils.makeLayoutAxis(dh.plot.AxisType.X),
1219
- yaxis: ChartUtils.makeLayoutAxis(dh.plot.AxisType.Y)
1220
- });
1096
+ color: ChartTheme.title_color
1097
+ }
1098
+ }
1099
+ };
1221
1100
 
1222
- layout.datarevision = 0;
1223
- return layout;
1224
- }
1225
- /**
1226
- * Dehydrate settings so they can be JSONified
1227
- * @param {object} settings Chart builder settings
1228
- */
1229
-
1230
- }, {
1231
- key: "dehydrateSettings",
1232
- value: function dehydrateSettings(settings) {
1233
- return _objectSpread(_objectSpread({}, settings), {}, {
1234
- type: "".concat(settings.type)
1101
+ if (type === dh.plot.AxisType.X) {
1102
+ Object.assign(axis, {
1103
+ showgrid: true
1235
1104
  });
1236
- }
1237
- /**
1238
- * Hydrate settings from a JSONable object
1239
- * @param {object} settings Dehydrated settings
1240
- */
1241
-
1242
- }, {
1243
- key: "hydrateSettings",
1244
- value: function hydrateSettings(settings) {
1245
- return _objectSpread(_objectSpread({}, settings), {}, {
1246
- type: dh.plot.SeriesPlotStyle[settings.type]
1105
+ } else if (type === dh.plot.AxisType.Y) {
1106
+ Object.assign(axis, {
1107
+ zerolinecolor: ChartTheme.zerolinecolor,
1108
+ zerolinewidth: 2
1247
1109
  });
1248
1110
  }
1249
- }, {
1250
- key: "titleFromSettings",
1251
- value: function titleFromSettings(settings) {
1252
- var series = settings.series,
1253
- xAxis = settings.xAxis,
1254
- _settings$title = settings.title,
1255
- title = _settings$title === void 0 ? "".concat(series.join(', '), " by ").concat(xAxis) : _settings$title;
1256
- return title;
1257
- }
1258
- /**
1259
- * Creates the Figure settings from the Chart Builder settings
1260
- * This should be deprecated at some point, and have Chart Builder create the figure settings directly.
1261
- * This logic will still need to exist to translate existing charts, but could be part of a migration script
1262
- * to translate the data.
1263
- * Change when we decide to add more functionality to the Chart Builder.
1264
- * @param {object} settings The chart builder settings
1265
- * @param {string} settings.title The title for this figure
1266
- * @param {string} settings.xAxis The name of the column to use for the x-axis
1267
- * @param {string[]} settings.series The name of the columns to use for the series of this figure
1268
- * @param {dh.plot.SeriesPlotStyle} settings.type The plot style for this figure
1269
- */
1270
-
1271
- }, {
1272
- key: "makeFigureSettings",
1273
- value: function makeFigureSettings(settings, table) {
1274
- var series = settings.series,
1275
- settingsAxis = settings.xAxis,
1276
- type = settings.type;
1277
- var title = ChartUtils.titleFromSettings(settings);
1278
- var xAxis = {
1279
- formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1280
- type: "".concat(dh.plot.AxisType.X),
1281
- position: "".concat(dh.plot.AxisPosition.BOTTOM)
1282
- };
1283
- var yAxis = {
1284
- formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1285
- type: "".concat(dh.plot.AxisType.Y),
1286
- position: "".concat(dh.plot.AxisPosition.LEFT)
1287
- };
1288
- return {
1289
- charts: [{
1290
- chartType: "".concat(dh.plot.ChartType.XY),
1291
- axes: [xAxis, yAxis],
1292
- series: series.map(function (name) {
1293
- return {
1294
- plotStyle: "".concat(type),
1295
- name: name,
1296
- dataSources: [{
1297
- type: "".concat(dh.plot.SourceType.X),
1298
- columnName: settingsAxis,
1299
- axis: xAxis,
1300
- table: table
1301
- }, {
1302
- type: "".concat(dh.plot.SourceType.Y),
1303
- columnName: name,
1304
- axis: yAxis,
1305
- table: table
1306
- }]
1307
- };
1308
- })
1309
- }],
1310
- title: title
1311
- };
1312
- }
1313
- }]);
1314
1111
 
1315
- return ChartUtils;
1316
- }();
1112
+ return axis;
1113
+ }
1114
+
1115
+ static makeDefaultLayout() {
1116
+ var layout = _objectSpread(_objectSpread({}, ChartTheme), {}, {
1117
+ autosize: true,
1118
+ colorway: ChartTheme.colorway ? ChartTheme.colorway.split(' ') : [],
1119
+ font: {
1120
+ family: "'Fira Sans', sans-serif"
1121
+ },
1122
+ title: {
1123
+ font: {
1124
+ color: ChartTheme.title_color
1125
+ },
1126
+ yanchor: 'top',
1127
+ pad: _objectSpread({}, ChartUtils.DEFAULT_TITLE_PADDING),
1128
+ y: 1,
1129
+ text: 'Untitled'
1130
+ },
1131
+ legend: {
1132
+ font: {
1133
+ color: ChartTheme.title_color
1134
+ }
1135
+ },
1136
+ margin: _objectSpread({}, ChartUtils.DEFAULT_MARGIN),
1137
+ xaxis: ChartUtils.makeLayoutAxis(dh.plot.AxisType.X),
1138
+ yaxis: ChartUtils.makeLayoutAxis(dh.plot.AxisType.Y)
1139
+ });
1140
+
1141
+ layout.datarevision = 0;
1142
+ return layout;
1143
+ }
1144
+ /**
1145
+ * Dehydrate settings so they can be JSONified
1146
+ * @param {object} settings Chart builder settings
1147
+ */
1148
+
1149
+
1150
+ static dehydrateSettings(settings) {
1151
+ return _objectSpread(_objectSpread({}, settings), {}, {
1152
+ type: "".concat(settings.type)
1153
+ });
1154
+ }
1155
+ /**
1156
+ * Hydrate settings from a JSONable object
1157
+ * @param {object} settings Dehydrated settings
1158
+ */
1159
+
1160
+
1161
+ static hydrateSettings(settings) {
1162
+ return _objectSpread(_objectSpread({}, settings), {}, {
1163
+ type: dh.plot.SeriesPlotStyle[settings.type]
1164
+ });
1165
+ }
1166
+
1167
+ static titleFromSettings(settings) {
1168
+ var {
1169
+ series,
1170
+ xAxis,
1171
+ title = "".concat(series.join(', '), " by ").concat(xAxis)
1172
+ } = settings;
1173
+ return title;
1174
+ }
1175
+ /**
1176
+ * Creates the Figure settings from the Chart Builder settings
1177
+ * This should be deprecated at some point, and have Chart Builder create the figure settings directly.
1178
+ * This logic will still need to exist to translate existing charts, but could be part of a migration script
1179
+ * to translate the data.
1180
+ * Change when we decide to add more functionality to the Chart Builder.
1181
+ * @param {object} settings The chart builder settings
1182
+ * @param {string} settings.title The title for this figure
1183
+ * @param {string} settings.xAxis The name of the column to use for the x-axis
1184
+ * @param {string[]} settings.series The name of the columns to use for the series of this figure
1185
+ * @param {dh.plot.SeriesPlotStyle} settings.type The plot style for this figure
1186
+ */
1187
+
1188
+
1189
+ static makeFigureSettings(settings, table) {
1190
+ var {
1191
+ series,
1192
+ xAxis: settingsAxis,
1193
+ type
1194
+ } = settings;
1195
+ var title = ChartUtils.titleFromSettings(settings);
1196
+ var xAxis = {
1197
+ formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1198
+ type: "".concat(dh.plot.AxisType.X),
1199
+ position: "".concat(dh.plot.AxisPosition.BOTTOM)
1200
+ };
1201
+ var yAxis = {
1202
+ formatType: "".concat(dh.plot.AxisFormatType.NUMBER),
1203
+ type: "".concat(dh.plot.AxisType.Y),
1204
+ position: "".concat(dh.plot.AxisPosition.LEFT)
1205
+ };
1206
+ return {
1207
+ charts: [{
1208
+ chartType: "".concat(dh.plot.ChartType.XY),
1209
+ axes: [xAxis, yAxis],
1210
+ series: series.map(name => ({
1211
+ plotStyle: "".concat(type),
1212
+ name,
1213
+ dataSources: [{
1214
+ type: "".concat(dh.plot.SourceType.X),
1215
+ columnName: settingsAxis,
1216
+ axis: xAxis,
1217
+ table
1218
+ }, {
1219
+ type: "".concat(dh.plot.SourceType.Y),
1220
+ columnName: name,
1221
+ axis: yAxis,
1222
+ table
1223
+ }]
1224
+ }))
1225
+ }],
1226
+ title
1227
+ };
1228
+ }
1229
+
1230
+ }
1317
1231
 
1318
1232
  _defineProperty(ChartUtils, "DEFAULT_AXIS_SIZE", 0.15);
1319
1233