@record-evolution/widget-linechart 1.7.1 → 1.7.2
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.
- package/dist/widget-linechart.js +499 -410
- package/dist/widget-linechart.js.map +1 -1
- package/package.json +1 -1
- package/src/default-data.json +11 -11
- package/src/definition-schema.d.ts +15 -5
- package/src/definition-schema.json +42 -4
- package/src/widget-linechart.ts +151 -15
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
{
|
|
2
|
-
"title": "
|
|
3
|
-
"description": "A versatile chart widget for visualizing data as line charts, bar charts, or scatter plots. Use this widget for time-series data, trend analysis, comparisons, and general data visualization. Supports multiple data series with different chart types in the same view, automatic pivot-based series generation, zoom controls, and flexible styling options. The ECharts-based rendering provides smooth animations and interactive tooltips. Ideal for monitoring dashboards, historical data analysis, and any scenario requiring visual data representation over continuous or categorical dimensions.",
|
|
2
|
+
"title": "Chart Configuration",
|
|
3
|
+
"description": "A versatile chart widget for visualizing data as line charts, bar charts, or scatter plots. Despite the package name, this is also THE bar chart widget: set dataseries[].type to 'bar' for vertical bars and axis.orientation to 'horizontal' for horizontal ones. Use this widget for time-series data, trend analysis, comparisons, frequency distributions, and general data visualization. Supports multiple data series with different chart types in the same view, automatic pivot-based series generation, zoom controls, and flexible styling options. The ECharts-based rendering provides smooth animations and interactive tooltips. Ideal for monitoring dashboards, historical data analysis, and any scenario requiring visual data representation over continuous or categorical dimensions.",
|
|
4
|
+
"aiSelection": {
|
|
5
|
+
"dataShape": "One or more series of (x, y) pairs. x is a timestamp, a number, or a category label and defines the position along the x-value dimension; y is the measured quantity. All series in a chart share one x dimension. An optional third column bound to data[].pivot splits a single series into one line or bar per distinct value of that column, and an optional data[].r sizes the marker for a bubble chart. Needs at least two columns of data; a single scalar has no shape to plot.",
|
|
6
|
+
"useWhen": [
|
|
7
|
+
"A quantity is measured repeatedly over time and the trend, shape or direction of change is the point (axis.timeseries: true, dataseries[].type: 'line').",
|
|
8
|
+
"A quantity is compared across a handful of discrete categories — counts, totals, frequency distributions, per-machine or per-site comparisons (dataseries[].type: 'bar', axis.timeseries: false). This is the correct widget for any bar chart; there is no separate bar chart widget.",
|
|
9
|
+
"Categories are being ranked, or their names are long enough to be unreadable side by side under a vertical axis (dataseries[].type: 'bar', axis.orientation: 'horizontal').",
|
|
10
|
+
"Two numeric variables are being correlated as a cloud of individual points (dataseries[].type: 'scatter'), optionally with data[].r encoding a third variable as marker size.",
|
|
11
|
+
"Several quantities with different units or wildly different ranges belong on one chart (assign the second group dataseries[].yAxis: 'right').",
|
|
12
|
+
"The same measurement is broken down by an entity — one line per machine, per site, per program (bind the breakdown column to data[].pivot)."
|
|
13
|
+
],
|
|
14
|
+
"notFor": [
|
|
15
|
+
"Parts of a whole, shares, or percentages that add up to 100% — use widget-doughnut.",
|
|
16
|
+
"A single current number, reading or KPI with no second dimension to plot — use widget-value, or widget-gauge when it should be read against a min/max range.",
|
|
17
|
+
"Records the user needs to read row by row, or data with more columns than an x and a y — use widget-table.",
|
|
18
|
+
"Intensity or density across two categorical dimensions at once, i.e. a matrix or calendar grid — use widget-heatmap.",
|
|
19
|
+
"How long an entity stayed in each discrete state over time (state timelines, machine mode history, up/down periods drawn as spans). A bar chart of state durations is the wrong shape — use widget-statehistory.",
|
|
20
|
+
"Anything positioned by geographic coordinates — use widget-mapbox.",
|
|
21
|
+
"A single binary or few-valued status shown as an indicator rather than plotted — use widget-signal, or widget-switch when the user must also be able to toggle it.",
|
|
22
|
+
"Free text, headings or explanatory prose — use widget-label, widget-textbox or widget-markdown."
|
|
23
|
+
]
|
|
24
|
+
},
|
|
4
25
|
"type": "object",
|
|
5
26
|
"properties": {
|
|
6
27
|
"title": {
|
|
@@ -73,9 +94,18 @@
|
|
|
73
94
|
"dataDrivenDisabled": true,
|
|
74
95
|
"order": 4
|
|
75
96
|
},
|
|
97
|
+
"orientation": {
|
|
98
|
+
"title": "Bar Direction",
|
|
99
|
+
"description": "The direction in which bars grow and the chart is read. 'vertical' (the default) places the x-values (categories or timestamps) along the horizontal axis at the bottom and the measured y-values along the vertical axis, so bars grow upwards. 'horizontal' swaps the two axes: the x-values run down the left-hand vertical axis, first data point at the top, and the y-values grow to the right, producing a horizontal bar chart. Choose 'horizontal' for ranked or frequency charts, and whenever category names are long enough to be unreadable when squeezed under a vertical axis. This setting affects only the drawing direction, not the meaning of the other options: 'X-Axis Label' always names the x-value dimension and 'Y-Axis Label' always names the measured values, whichever side of the chart they end up on. Applies to all series in the chart, including line and scatter series.",
|
|
100
|
+
"type": "string",
|
|
101
|
+
"enum": ["vertical", "horizontal"],
|
|
102
|
+
"default": "vertical",
|
|
103
|
+
"dataDrivenDisabled": true,
|
|
104
|
+
"order": 4.5
|
|
105
|
+
},
|
|
76
106
|
"columnLayout": {
|
|
77
|
-
"title": "
|
|
78
|
-
"description": "
|
|
107
|
+
"title": "Stack Multiple Charts Vertically",
|
|
108
|
+
"description": "Controls how SEPARATE charts are arranged relative to each other when the series are grouped into more than one chart via 'Chart Name' (dataseries[].advanced.chartName). Enabled = the charts are stacked one above the other, Disabled = the charts sit side by side. This is a page-layout option and has no effect on a single chart; to change the direction bars grow in, use 'Bar Direction' (axis.orientation) instead.",
|
|
79
109
|
"type": "boolean",
|
|
80
110
|
"dataDrivenDisabled": true,
|
|
81
111
|
"order": 5
|
|
@@ -218,6 +248,14 @@
|
|
|
218
248
|
"none"
|
|
219
249
|
],
|
|
220
250
|
"order": 5
|
|
251
|
+
},
|
|
252
|
+
"showValueLabels": {
|
|
253
|
+
"title": "Show Value Labels",
|
|
254
|
+
"description": "When enabled, each data point's y-value is printed as text directly on the chart: above the top of every bar in a vertical bar chart, just past the end of the bar in a horizontal one, and above the marker for line and scatter series. Enable this whenever the reader is meant to read exact numbers off the chart rather than estimate them against the axis — the usual expectation for bar charts of counts, totals or frequencies, and the setting to use when someone asks for the values to be shown on or above the bars. Numbers are rounded to two decimal places; non-numeric values are printed unchanged. Leave it disabled for charts with many data points, where the labels would overlap each other.",
|
|
255
|
+
"type": "boolean",
|
|
256
|
+
"default": false,
|
|
257
|
+
"dataDrivenDisabled": true,
|
|
258
|
+
"order": 6
|
|
221
259
|
}
|
|
222
260
|
}
|
|
223
261
|
},
|
package/src/widget-linechart.ts
CHANGED
|
@@ -30,7 +30,7 @@ echarts.use([
|
|
|
30
30
|
LegacyGridContainLabel
|
|
31
31
|
])
|
|
32
32
|
|
|
33
|
-
import {
|
|
33
|
+
import { ChartConfiguration } from './definition-schema'
|
|
34
34
|
import { EChartsOption, SeriesOption } from 'echarts'
|
|
35
35
|
import { TitleOption } from 'echarts/types/dist/shared'
|
|
36
36
|
|
|
@@ -43,12 +43,19 @@ type SeriesOptionX = SeriesOption & {
|
|
|
43
43
|
minDate?: number
|
|
44
44
|
maxDate?: number
|
|
45
45
|
drawOrder: number
|
|
46
|
+
xAxisIndex?: number
|
|
46
47
|
yAxisIndex?: number
|
|
48
|
+
// Which value axis (0 = primary, 1 = secondary) this series belongs to,
|
|
49
|
+
// independent of orientation. In a vertical chart the value axes are the
|
|
50
|
+
// y axes (left/right), in a horizontal one they are the x axes (bottom/top),
|
|
51
|
+
// so xAxisIndex/yAxisIndex alone cannot be read without knowing the
|
|
52
|
+
// orientation — this field can.
|
|
53
|
+
valueAxisIndex?: number
|
|
47
54
|
}
|
|
48
55
|
@customElement('widget-linechart-versionplaceholder')
|
|
49
56
|
export class WidgetLinechart extends LitElement {
|
|
50
57
|
@property({ type: Object })
|
|
51
|
-
inputData?:
|
|
58
|
+
inputData?: ChartConfiguration
|
|
52
59
|
|
|
53
60
|
@property({ type: Object })
|
|
54
61
|
theme?: Theme
|
|
@@ -270,9 +277,49 @@ export class WidgetLinechart extends LitElement {
|
|
|
270
277
|
echarts.registerTheme(theme.theme_name, filteredTheme)
|
|
271
278
|
}
|
|
272
279
|
|
|
280
|
+
/** True when bars grow to the right instead of upwards (axis.orientation). */
|
|
281
|
+
isHorizontal(): boolean {
|
|
282
|
+
return this.inputData?.axis?.orientation === 'horizontal'
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Index of the measured y-value inside a data point's `value` tuple.
|
|
287
|
+
*
|
|
288
|
+
* A point is stored as `[x, y, r]` for a vertical chart. A horizontal chart
|
|
289
|
+
* swaps the first two entries to `[y, x, r]`, because ECharts always maps
|
|
290
|
+
* tuple index 0 to the x axis and index 1 to the y axis — and in a
|
|
291
|
+
* horizontal chart the measured value is what belongs on the x axis.
|
|
292
|
+
*/
|
|
293
|
+
private valueIndex(): number {
|
|
294
|
+
return this.isHorizontal() ? 0 : 1
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Index of the x-value (category/timestamp) inside a data point's `value` tuple. */
|
|
298
|
+
private categoryIndex(): number {
|
|
299
|
+
return this.isHorizontal() ? 1 : 0
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Formatter for the on-chart value labels (styling.showValueLabels).
|
|
304
|
+
* Rounds to two decimals to match the numeric axis labels, and leaves
|
|
305
|
+
* categorical y-values untouched.
|
|
306
|
+
*/
|
|
307
|
+
private valueLabelFormatter(valueIdx: number) {
|
|
308
|
+
return (params: any) => {
|
|
309
|
+
const raw = Array.isArray(params?.value) ? params.value[valueIdx] : params?.value
|
|
310
|
+
if (raw === undefined || raw === null || raw === '') return ''
|
|
311
|
+
const num = Number(raw)
|
|
312
|
+
return isNaN(num) ? String(raw) : String(Math.round(num * 100) / 100)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
273
316
|
transformData() {
|
|
274
317
|
if (!this?.inputData?.dataseries?.length) return
|
|
275
318
|
|
|
319
|
+
const horizontal = this.isHorizontal()
|
|
320
|
+
const valueIdx = this.valueIndex()
|
|
321
|
+
const categoryIdx = this.categoryIndex()
|
|
322
|
+
|
|
276
323
|
// reset all existing chart dataseries
|
|
277
324
|
this.canvasList.forEach((chartM) => {
|
|
278
325
|
chartM.series = []
|
|
@@ -309,22 +356,29 @@ export class WidgetLinechart extends LitElement {
|
|
|
309
356
|
: derivedBgColors[i]
|
|
310
357
|
: undefined
|
|
311
358
|
const data = distincts.length === 1 ? ds.data : ds.data?.filter((d) => d.pivot === piv)
|
|
359
|
+
// The value tuple is [x, y, r] for a vertical chart and [y, x, r]
|
|
360
|
+
// for a horizontal one — ECharts always reads index 0 as the x
|
|
361
|
+
// axis, and in a horizontal chart the measured value lives there.
|
|
362
|
+
const toTuple = (x: any, y: any, r: any) => (horizontal ? [y, x, r] : [x, y, r])
|
|
312
363
|
let data2 = this.inputData?.axis?.timeseries
|
|
313
|
-
? (data?.map((d) => ({
|
|
314
|
-
|
|
315
|
-
|
|
364
|
+
? (data?.map((d) => ({
|
|
365
|
+
name: d.x,
|
|
366
|
+
value: toTuple(new Date(d.x ?? '').getTime(), d.y, d.r)
|
|
367
|
+
})) ?? [])
|
|
368
|
+
: (data?.map((d) => ({ name: d.x, value: toTuple(d.x, d.y, d.r) })) ?? [])
|
|
316
369
|
|
|
317
370
|
let minDate: number = 0,
|
|
318
371
|
maxDate: number = 0,
|
|
319
372
|
extraData: (string | number | undefined)[][] = []
|
|
320
373
|
if (this.xAxisType() === 'time' && data2) {
|
|
321
|
-
const dates = data2.map((d: any) => d.value[
|
|
374
|
+
const dates = data2.map((d: any) => d.value[categoryIdx] as number)
|
|
322
375
|
minDate = Math.min(...dates)
|
|
323
376
|
maxDate = Math.max(...dates)
|
|
324
377
|
// extraData = (pds?.data as any[][])?.filter((d: any) => d[0] < minDate) ?? []
|
|
325
378
|
// data2.unshift(...extraData) // add old data to the beginning of the new data
|
|
326
379
|
// data2 = [...extraData, ...data2] // leave old data in for smooth shifting animation and delete after draw
|
|
327
380
|
}
|
|
381
|
+
const valueAxisIndex = ds.yAxis === 'right' ? 1 : 0
|
|
328
382
|
const pds: SeriesOptionX = {
|
|
329
383
|
id: name,
|
|
330
384
|
name: name,
|
|
@@ -346,9 +400,21 @@ export class WidgetLinechart extends LitElement {
|
|
|
346
400
|
symbol: ds.styling?.pointStyle ?? 'circle',
|
|
347
401
|
symbolSize: (d: any[]) => d[2] ?? 0,
|
|
348
402
|
showSymbol: ds.styling?.pointStyle === 'none' ? false : true,
|
|
403
|
+
label: {
|
|
404
|
+
show: ds.styling?.showValueLabels ?? false,
|
|
405
|
+
// Bars grow upwards when vertical and rightwards when
|
|
406
|
+
// horizontal, so the label sits past the growing end.
|
|
407
|
+
position: horizontal ? 'right' : 'top',
|
|
408
|
+
fontSize: 12,
|
|
409
|
+
formatter: this.valueLabelFormatter(valueIdx)
|
|
410
|
+
},
|
|
349
411
|
data: data2 ?? [],
|
|
350
412
|
drawOrder: ds.advanced?.drawOrder ?? 0,
|
|
351
|
-
|
|
413
|
+
valueAxisIndex: valueAxisIndex,
|
|
414
|
+
// The secondary value axis is the right y axis when vertical
|
|
415
|
+
// and the top x axis when horizontal.
|
|
416
|
+
xAxisIndex: horizontal ? valueAxisIndex : 0,
|
|
417
|
+
yAxisIndex: horizontal ? 0 : valueAxisIndex
|
|
352
418
|
}
|
|
353
419
|
let chartName = ds.advanced?.chartName ?? ''
|
|
354
420
|
chartName = chartName.replace('#split#', prefix)
|
|
@@ -485,6 +551,7 @@ export class WidgetLinechart extends LitElement {
|
|
|
485
551
|
const modifier = 1
|
|
486
552
|
// Sort chartContainer children by drawOrder and label
|
|
487
553
|
if (!this.chartContainer) return
|
|
554
|
+
const horizontal = this.isHorizontal()
|
|
488
555
|
for (const canvas of this.canvasList.values()) {
|
|
489
556
|
if (canvas.element) this.chartContainer.appendChild(canvas.element)
|
|
490
557
|
}
|
|
@@ -513,9 +580,14 @@ export class WidgetLinechart extends LitElement {
|
|
|
513
580
|
yAxisScalingRight: this.inputData?.axis?.yAxisScalingRight,
|
|
514
581
|
xAxisType: this.xAxisType(),
|
|
515
582
|
yAxisType: this.yAxisType(),
|
|
583
|
+
// Flipping the orientation swaps which option key holds the
|
|
584
|
+
// single category axis and which holds the value-axis array,
|
|
585
|
+
// so it must force a notMerge rebuild rather than a merge.
|
|
586
|
+
orientation: this.inputData?.axis?.orientation ?? 'vertical',
|
|
516
587
|
seriesCount: chart.series.length,
|
|
517
588
|
seriesNames: chart.series.map((s) => s.name).join(','),
|
|
518
|
-
seriesAxes: chart.series.map((s) => s.
|
|
589
|
+
seriesAxes: chart.series.map((s) => s.valueAxisIndex ?? 0).join(','),
|
|
590
|
+
seriesLabels: chart.series.map((s) => ((s as any).label?.show ? 1 : 0)).join(',')
|
|
519
591
|
})
|
|
520
592
|
const configChanged = chart.lastConfig !== currentConfig
|
|
521
593
|
chart.lastConfig = currentConfig
|
|
@@ -553,8 +625,9 @@ export class WidgetLinechart extends LitElement {
|
|
|
553
625
|
}
|
|
554
626
|
}
|
|
555
627
|
|
|
556
|
-
|
|
557
|
-
option.
|
|
628
|
+
const showZoom = this.inputData?.axis?.xAxisZoom ?? false
|
|
629
|
+
option.dataZoom[0].show = showZoom
|
|
630
|
+
option.toolbox.show = showZoom
|
|
558
631
|
|
|
559
632
|
// Y axes: index 0 = left (primary), index 1 = right (secondary).
|
|
560
633
|
// The template holds an array, but getOption() (merge path) also returns
|
|
@@ -563,9 +636,10 @@ export class WidgetLinechart extends LitElement {
|
|
|
563
636
|
while (yAxes.length < 2) yAxes.push({})
|
|
564
637
|
option.yAxis = yAxes
|
|
565
638
|
|
|
566
|
-
const
|
|
639
|
+
const hasValueLabels = chart.series.some((s) => !!(s as any).label?.show)
|
|
640
|
+
const rightAxisUsed = chart.series.some((s) => (s.valueAxisIndex ?? 0) === 1)
|
|
567
641
|
const leftAxisUsed =
|
|
568
|
-
chart.series.length === 0 || chart.series.some((s) => (s.
|
|
642
|
+
chart.series.length === 0 || chart.series.some((s) => (s.valueAxisIndex ?? 0) === 0)
|
|
569
643
|
const showLeftAxis = showYAxis && leftAxisUsed
|
|
570
644
|
const showRightAxis = showYAxis && rightAxisUsed
|
|
571
645
|
|
|
@@ -606,6 +680,42 @@ export class WidgetLinechart extends LitElement {
|
|
|
606
680
|
})
|
|
607
681
|
if (numericAxisLabel) yAxes[1].axisLabel = numericAxisLabel
|
|
608
682
|
|
|
683
|
+
// Orientation swap. Everything above builds one category axis (the
|
|
684
|
+
// x-values) and a two-entry array of value axes (the y-values). A
|
|
685
|
+
// vertical chart puts them where they were built; a horizontal one
|
|
686
|
+
// moves the category axis onto `yAxis` and the value axes onto
|
|
687
|
+
// `xAxis`. The axis *labels* keep their meaning either way:
|
|
688
|
+
// 'X-Axis Label' names the x-value dimension wherever it is drawn.
|
|
689
|
+
if (horizontal) {
|
|
690
|
+
const catAxis: any = Array.isArray(option.xAxis) ? option.xAxis[0] : option.xAxis
|
|
691
|
+
option.yAxis = {
|
|
692
|
+
...catAxis,
|
|
693
|
+
position: 'left',
|
|
694
|
+
// Read top-to-bottom, so the first data point is the top
|
|
695
|
+
// bar — the convention for ranked horizontal bar charts.
|
|
696
|
+
inverse: true,
|
|
697
|
+
// 'start' is the top of an inverted axis, which keeps the
|
|
698
|
+
// axis name clear of the value axis running along the bottom.
|
|
699
|
+
// When a secondary value axis is in use it is drawn along
|
|
700
|
+
// the top, so the name has to clear its tick labels too.
|
|
701
|
+
nameLocation: 'start',
|
|
702
|
+
nameGap: showRightAxis ? 30 : 10,
|
|
703
|
+
nameTextStyle: { align: 'left' }
|
|
704
|
+
}
|
|
705
|
+
option.xAxis = yAxes.map((axis: any, index: number) => ({
|
|
706
|
+
...axis,
|
|
707
|
+
position: index === 0 ? 'bottom' : 'top',
|
|
708
|
+
nameLocation: 'middle',
|
|
709
|
+
nameGap: 27,
|
|
710
|
+
nameTextStyle: { align: 'center' }
|
|
711
|
+
}))
|
|
712
|
+
// Zooming still applies to the x-value dimension, which now
|
|
713
|
+
// lives on the y axis.
|
|
714
|
+
option.dataZoom = [
|
|
715
|
+
{ ...(option.dataZoom?.[0] ?? {}), xAxisIndex: undefined, yAxisIndex: [0] }
|
|
716
|
+
]
|
|
717
|
+
}
|
|
718
|
+
|
|
609
719
|
option.series = chart.series
|
|
610
720
|
option.legend.show = showLegend
|
|
611
721
|
|
|
@@ -616,6 +726,13 @@ export class WidgetLinechart extends LitElement {
|
|
|
616
726
|
const topPadding =
|
|
617
727
|
(showTitle || hasYAxisLabel || hasYAxisLabelRight ? 30 : 0) +
|
|
618
728
|
(showLegend && hasYAxisLabelRight ? 25 : 0)
|
|
729
|
+
// An ECharts slider dataZoom is ~30px thick and sits outside the
|
|
730
|
+
// grid's own bookkeeping, so nothing reserves room for it. Left
|
|
731
|
+
// unaccounted it is drawn straight over the plot, clipping the foot
|
|
732
|
+
// of every bar and washing out the axis labels underneath.
|
|
733
|
+
const ZOOM_THICKNESS = 40
|
|
734
|
+
const zoomPadBottom = showZoom && !horizontal ? ZOOM_THICKNESS : 0
|
|
735
|
+
const zoomPadRight = showZoom && horizontal ? ZOOM_THICKNESS : 0
|
|
619
736
|
option.grid = {
|
|
620
737
|
...option.grid,
|
|
621
738
|
show: showBox,
|
|
@@ -623,12 +740,31 @@ export class WidgetLinechart extends LitElement {
|
|
|
623
740
|
borderWidth: showBox ? 1 : 0,
|
|
624
741
|
borderColor: this.themeTitleColor ?? '#ccc',
|
|
625
742
|
top: topPadding,
|
|
626
|
-
bottom
|
|
627
|
-
left
|
|
628
|
-
|
|
743
|
+
// The category axis sits at the bottom when vertical and on the
|
|
744
|
+
// left when horizontal; the value axis is the other way round.
|
|
745
|
+
// The zoom slider is not accounted for by `containLabel`, so its
|
|
746
|
+
// thickness has to be reserved here as well — see ZOOM_THICKNESS.
|
|
747
|
+
bottom: ((horizontal ? showLeftAxis : showXAxis) ? 20 : 0) + zoomPadBottom,
|
|
748
|
+
left: (horizontal ? showXAxis : showLeftAxis) ? 20 : 0,
|
|
749
|
+
// A horizontal chart grows towards the right edge, so the last
|
|
750
|
+
// axis tick and any value label printed past the end of a bar
|
|
751
|
+
// need room that `containLabel` does not reserve for them.
|
|
752
|
+
right: (horizontal ? (hasValueLabels ? 45 : 15) : 0) + zoomPadRight,
|
|
629
753
|
containLabel: showXAxis || showYAxis
|
|
630
754
|
}
|
|
631
755
|
|
|
756
|
+
// Anchor the slider to the edge whose dimension it zooms: the bottom
|
|
757
|
+
// for a vertical chart, the right-hand side for a horizontal one
|
|
758
|
+
// (where it controls the y axis and ECharts draws it upright).
|
|
759
|
+
if (showZoom) {
|
|
760
|
+
Object.assign(
|
|
761
|
+
option.dataZoom[0],
|
|
762
|
+
horizontal
|
|
763
|
+
? { right: 0, top: topPadding, bottom: 20, left: undefined }
|
|
764
|
+
: { bottom: 0, left: undefined, right: undefined, top: undefined }
|
|
765
|
+
)
|
|
766
|
+
}
|
|
767
|
+
|
|
632
768
|
// Calculate animation duration based on update frequency
|
|
633
769
|
const animationDuration = this.updateThresholdMs //this.calculateAnimationDuration(chart, label)
|
|
634
770
|
option.animation = true
|