@graphenedata/cli 0.0.13 → 0.0.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.
- package/dist/cli/cli.js +8591 -1214
- package/dist/docs/base.md +98 -0
- package/dist/docs/cli.md +22 -0
- package/dist/docs/graphene.md +10 -10
- package/dist/ui/component-utilities/echarts.js +2 -3
- package/dist/ui/component-utilities/formatting.js +3 -11
- package/dist/ui/component-utilities/getSeriesConfig.js +2 -1
- package/dist/ui/components/Area.svelte +188 -151
- package/dist/ui/components/AreaChart.svelte +43 -79
- package/dist/ui/components/Bar.svelte +273 -255
- package/dist/ui/components/BarChart.svelte +58 -112
- package/dist/ui/components/BigValue.svelte +13 -7
- package/dist/ui/components/Chart.svelte +280 -317
- package/dist/ui/components/Column.svelte +102 -113
- package/dist/ui/components/DateRange.svelte +37 -27
- package/dist/ui/components/Dropdown.svelte +77 -57
- package/dist/ui/components/DropdownOption.svelte +10 -7
- package/dist/ui/components/ECharts.svelte +23 -16
- package/dist/ui/components/ErrorChart.svelte +85 -21
- package/dist/ui/components/GrapheneQuery.svelte +7 -3
- package/dist/ui/components/InlineDelta.svelte +53 -34
- package/dist/ui/components/Line.svelte +192 -178
- package/dist/ui/components/LineChart.svelte +53 -96
- package/dist/ui/components/PieChart.svelte +26 -15
- package/dist/ui/components/QueryLoad.svelte +15 -10
- package/dist/ui/components/SortIcon.svelte +5 -1
- package/dist/ui/components/Table.svelte +15 -9
- package/dist/ui/components/TableCell.svelte +30 -17
- package/dist/ui/components/TableGroupRow.svelte +26 -19
- package/dist/ui/components/TableGroupToggle.svelte +9 -6
- package/dist/ui/components/TableHeader.svelte +37 -27
- package/dist/ui/components/TableRow.svelte +30 -20
- package/dist/ui/components/TableSubtotalRow.svelte +16 -9
- package/dist/ui/components/TableTotalRow.svelte +18 -11
- package/dist/ui/components/TextInput.svelte +23 -20
- package/dist/ui/components/_Table.svelte +303 -260
- package/dist/ui/internal/LocalApp.svelte +40 -0
- package/dist/ui/internal/NavSidebar.svelte +27 -30
- package/dist/ui/internal/PageError.svelte +23 -0
- package/dist/ui/internal/checkSocket.ts +48 -0
- package/dist/ui/internal/queryEngine.ts +9 -2
- package/dist/ui/internal/telemetry.ts +1 -0
- package/dist/ui/web.js +5 -55
- package/package.json +8 -9
- package/dist/ui/internal/NavSidebarHMR.svelte +0 -8
|
@@ -1,302 +1,317 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import {getContext
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {getContext} from 'svelte'
|
|
3
3
|
import {propKey, configKey} from '../component-utilities/chartContext.js'
|
|
4
|
-
|
|
5
|
-
const config = getContext(configKey)
|
|
6
|
-
|
|
4
|
+
import type {Writable} from 'svelte/store'
|
|
7
5
|
import getSeriesConfig from '../component-utilities/getSeriesConfig.js'
|
|
8
6
|
import getStackedData from '../component-utilities/getStackedData.js'
|
|
9
7
|
import getSortedData from '../component-utilities/getSortedData.js'
|
|
10
8
|
import formatTitle from '../component-utilities/formatTitle.js'
|
|
11
9
|
import getCompletedData from '../component-utilities/getCompletedData.js'
|
|
12
10
|
import getYAxisIndex from '../component-utilities/getYAxisIndex.js'
|
|
13
|
-
|
|
14
|
-
import {
|
|
15
|
-
formatValue,
|
|
16
|
-
getFormatObjectFromString,
|
|
17
|
-
} from '../component-utilities/formatting.js'
|
|
11
|
+
import {formatValue, getFormatObjectFromString} from '../component-utilities/formatting.js'
|
|
18
12
|
import {getThemeStores} from '../component-utilities/themeStores'
|
|
19
13
|
import {parseCommaList} from '../component-utilities/inputUtils.ts'
|
|
20
14
|
|
|
15
|
+
interface Props {
|
|
16
|
+
y?: any, y2?: any, series?: any, options?: any, name?: any, type?: string, stackName?: any
|
|
17
|
+
fillColor?: any, fillOpacity?: any, outlineColor?: any, outlineWidth?: any
|
|
18
|
+
labels?: boolean | string, seriesLabels?: boolean | string, labelSize?: number
|
|
19
|
+
labelPosition?: string, labelColor?: any, labelFmt?: any, yLabelFmt?: any, y2LabelFmt?: any
|
|
20
|
+
y2SeriesType?: string, stackTotalLabel?: boolean | string, showAllLabels?: boolean | string
|
|
21
|
+
seriesOrder?: any, seriesLabelFmt?: any
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const chartProps: Writable<any> = getContext(propKey)
|
|
25
|
+
const config: Writable<any> = getContext(configKey)
|
|
21
26
|
const {resolveColor} = getThemeStores()
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
|
|
28
|
+
let {
|
|
29
|
+
y = undefined, y2 = undefined, series = undefined, options = undefined, name = undefined,
|
|
30
|
+
type = 'stacked', stackName = undefined, fillColor = undefined, fillOpacity = undefined,
|
|
31
|
+
outlineColor = undefined, outlineWidth = undefined, labels = false, seriesLabels = true,
|
|
32
|
+
labelSize = 11, labelPosition = undefined, labelColor = undefined, labelFmt = undefined,
|
|
33
|
+
yLabelFmt = undefined, y2LabelFmt = undefined, y2SeriesType = 'bar', stackTotalLabel = true,
|
|
34
|
+
showAllLabels = false, seriesOrder = undefined, seriesLabelFmt = undefined,
|
|
35
|
+
}: Props = $props()
|
|
36
|
+
|
|
37
|
+
// Use $derived for values that depend on props
|
|
38
|
+
let ySet = $derived(y ? true : false)
|
|
39
|
+
let y2Set = $derived(y2 ? true : false)
|
|
40
|
+
let seriesSet = $derived(series ? true : false)
|
|
41
|
+
|
|
42
|
+
let fillColorStore = $derived(resolveColor(fillColor))
|
|
43
|
+
let outlineColorStore = $derived(resolveColor(outlineColor))
|
|
44
|
+
let labelColorStore = $derived(resolveColor(labelColor))
|
|
45
|
+
let labelsBool = $derived(labels === 'true' || labels === true)
|
|
46
|
+
let seriesLabelsBool = $derived(seriesLabels === 'true' || seriesLabels === true)
|
|
47
|
+
let stackTotalLabelBool = $derived(stackTotalLabel === 'true' || stackTotalLabel === true)
|
|
48
|
+
|
|
49
|
+
// Format objects derived from props
|
|
50
|
+
let labelFormat = $derived(labelFmt ? getFormatObjectFromString(labelFmt) : undefined)
|
|
51
|
+
let yLabelFormat = $derived(yLabelFmt ? getFormatObjectFromString(yLabelFmt) : undefined)
|
|
52
|
+
let y2LabelFormat = $derived(y2LabelFmt ? getFormatObjectFromString(y2LabelFmt) : undefined)
|
|
53
|
+
|
|
54
|
+
let barMaxWidth = 60
|
|
55
|
+
|
|
56
|
+
// Derive values from chartProps store instead of using $effect to assign
|
|
57
|
+
let data = $derived($chartProps.data)
|
|
58
|
+
let x = $derived($chartProps.x)
|
|
59
|
+
let resolvedY = $derived(ySet ? parseCommaList(y) : $chartProps.y)
|
|
60
|
+
let resolvedY2 = $derived(y2Set ? parseCommaList(y2) : $chartProps.y2)
|
|
61
|
+
let yFormat = $derived($chartProps.yFormat)
|
|
62
|
+
let y2Format = $derived($chartProps.y2Format)
|
|
63
|
+
let yCount = $derived($chartProps.yCount)
|
|
64
|
+
let y2Count = $derived($chartProps.y2Count)
|
|
65
|
+
let swapXY = $derived($chartProps.swapXY)
|
|
66
|
+
let baseXType = $derived($chartProps.xType)
|
|
67
|
+
let xMismatch = $derived($chartProps.xMismatch)
|
|
68
|
+
let columnSummary = $derived($chartProps.columnSummary)
|
|
69
|
+
let sort = $derived($chartProps.sort)
|
|
70
|
+
let resolvedSeries = $derived(seriesSet ? series : $chartProps.series)
|
|
71
|
+
let resolvedSeriesOrder = $derived(parseCommaList(seriesOrder))
|
|
72
|
+
|
|
73
|
+
// Value label positions:
|
|
74
|
+
const labelPositions = {
|
|
75
|
+
outside: 'top',
|
|
76
|
+
inside: 'inside',
|
|
63
77
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
78
|
+
|
|
79
|
+
const swapXYLabelPositions = {
|
|
80
|
+
outside: 'right',
|
|
81
|
+
inside: 'inside',
|
|
68
82
|
}
|
|
69
83
|
|
|
70
|
-
|
|
84
|
+
// Compute all the derived state in one $derived.by block to avoid read/write conflicts
|
|
85
|
+
let computedState = $derived.by(() => {
|
|
86
|
+
let isSingleSeries = !resolvedSeries && (!Array.isArray(resolvedY) || resolvedY.length === 1)
|
|
87
|
+
let computedData = data
|
|
88
|
+
let computedXType = baseXType
|
|
89
|
+
let computedName = name
|
|
90
|
+
let computedStackName = stackName
|
|
91
|
+
let computedDefaultLabelPosition = swapXY ? 'right' : 'top'
|
|
92
|
+
let computedStackTotalSeries: any[] = []
|
|
93
|
+
|
|
94
|
+
if (!data || !columnSummary) {
|
|
95
|
+
return {
|
|
96
|
+
data: computedData,
|
|
97
|
+
xType: computedXType,
|
|
98
|
+
name: computedName,
|
|
99
|
+
stackName: computedStackName,
|
|
100
|
+
defaultLabelPosition: computedDefaultLabelPosition,
|
|
101
|
+
stackTotalSeries: computedStackTotalSeries,
|
|
102
|
+
}
|
|
103
|
+
}
|
|
71
104
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
105
|
+
if (isSingleSeries) {
|
|
106
|
+
// Single Series
|
|
107
|
+
let col = Array.isArray(resolvedY) ? resolvedY[0] : resolvedY
|
|
108
|
+
if (col && columnSummary[col]) {
|
|
109
|
+
computedName = computedName ?? formatTitle(col, columnSummary[col].title)
|
|
110
|
+
}
|
|
77
111
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
$: y2 = y2Set ? parseCommaList(y2) : $props.y2
|
|
83
|
-
$: yFormat = $props.yFormat
|
|
84
|
-
$: y2Format = $props.y2Format
|
|
85
|
-
$: yCount = $props.yCount
|
|
86
|
-
$: y2Count = $props.y2Count
|
|
87
|
-
$: swapXY = $props.swapXY
|
|
88
|
-
$: xType = $props.xType
|
|
89
|
-
$: xMismatch = $props.xMismatch
|
|
90
|
-
$: columnSummary = $props.columnSummary
|
|
91
|
-
$: sort = $props.sort
|
|
92
|
-
$: series = seriesSet ? series : $props.series
|
|
93
|
-
$: seriesOrder = parseCommaList(seriesOrder)
|
|
94
|
-
|
|
95
|
-
let stackedData
|
|
96
|
-
let sortOrder
|
|
97
|
-
let defaultLabelPosition
|
|
98
|
-
|
|
99
|
-
$: if (!series && (!Array.isArray(y) || y.length === 1)) {
|
|
100
|
-
// Single Series
|
|
101
|
-
{
|
|
102
|
-
let col = Array.isArray(y) ? y[0] : y
|
|
103
|
-
name = name ?? formatTitle(col, columnSummary[col].title)
|
|
104
|
-
}
|
|
112
|
+
if (swapXY && computedXType !== 'category') {
|
|
113
|
+
computedData = getCompletedData(computedData, x, resolvedY, resolvedSeries, true, computedXType !== 'time')
|
|
114
|
+
computedXType = 'category'
|
|
115
|
+
}
|
|
105
116
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
computedStackName = 'stack1'
|
|
118
|
+
computedDefaultLabelPosition = swapXY ? 'right' : 'top'
|
|
119
|
+
} else {
|
|
120
|
+
// Multi Series
|
|
121
|
+
// Sort by stack total for category axis
|
|
122
|
+
if (sort === true && computedXType === 'category') {
|
|
123
|
+
let stackedData = getStackedData(computedData, x, resolvedY)
|
|
110
124
|
|
|
111
|
-
|
|
125
|
+
if (Array.isArray(resolvedY) && resolvedY.length > 1) {
|
|
126
|
+
stackedData = getSortedData(stackedData, 'stackTotal', false)
|
|
127
|
+
} else {
|
|
128
|
+
let col = Array.isArray(resolvedY) ? resolvedY[0] : resolvedY
|
|
129
|
+
stackedData = getSortedData(stackedData, col, false)
|
|
130
|
+
}
|
|
112
131
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
stackedData = getStackedData(data, x, y)
|
|
132
|
+
let sortOrder = stackedData.map((d: any) => d[x])
|
|
133
|
+
computedData = [...computedData].sort(function (a: any, b: any) {
|
|
134
|
+
return sortOrder.indexOf(a[x]) - sortOrder.indexOf(b[x])
|
|
135
|
+
})
|
|
136
|
+
}
|
|
119
137
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
// Run fill for missing series entries, only if it's a stacked bar
|
|
139
|
+
if (swapXY || ((computedXType === 'value' || computedXType === 'category') && type.includes('stacked'))) {
|
|
140
|
+
computedData = getCompletedData(computedData, x, resolvedY, resolvedSeries, true, computedXType === 'value')
|
|
141
|
+
computedXType = 'category'
|
|
142
|
+
} else if (computedXType === 'time' && type.includes('stacked')) {
|
|
143
|
+
computedData = getCompletedData(computedData, x, resolvedY, resolvedSeries, true, true)
|
|
125
144
|
}
|
|
126
145
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
146
|
+
if (type.includes('stacked')) {
|
|
147
|
+
computedStackName = computedStackName ?? 'stack1'
|
|
148
|
+
computedDefaultLabelPosition = 'inside'
|
|
149
|
+
} else {
|
|
150
|
+
computedStackName = undefined
|
|
151
|
+
computedDefaultLabelPosition = swapXY ? 'right' : 'top'
|
|
152
|
+
}
|
|
131
153
|
}
|
|
132
154
|
|
|
133
|
-
//
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
xType = 'category'
|
|
137
|
-
} else if (xType === 'time' && type.includes('stacked')) {
|
|
138
|
-
data = getCompletedData(data, x, y, series, true, true)
|
|
155
|
+
// Compute stack total series for stacked charts
|
|
156
|
+
if (type === 'stacked' && computedData) {
|
|
157
|
+
computedStackTotalSeries = getStackedData(computedData, x, resolvedY)
|
|
139
158
|
}
|
|
140
159
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
160
|
+
return {
|
|
161
|
+
data: computedData,
|
|
162
|
+
xType: computedXType,
|
|
163
|
+
name: computedName,
|
|
164
|
+
stackName: computedStackName,
|
|
165
|
+
defaultLabelPosition: computedDefaultLabelPosition,
|
|
166
|
+
stackTotalSeries: computedStackTotalSeries,
|
|
148
167
|
}
|
|
149
|
-
}
|
|
168
|
+
})
|
|
150
169
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
170
|
+
// Extract computed values for use in template and other derived values
|
|
171
|
+
let processedData = $derived(computedState.data)
|
|
172
|
+
let xType = $derived(computedState.xType)
|
|
173
|
+
let resolvedName = $derived(computedState.name)
|
|
174
|
+
let resolvedStackName = $derived(computedState.stackName)
|
|
175
|
+
let defaultLabelPosition = $derived(computedState.defaultLabelPosition)
|
|
176
|
+
let stackTotalSeries = $derived(computedState.stackTotalSeries)
|
|
155
177
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
inside: 'inside',
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const swapXYLabelPositions = {
|
|
163
|
-
outside: 'right',
|
|
164
|
-
inside: 'inside',
|
|
165
|
-
}
|
|
178
|
+
let resolvedLabelPosition = $derived(
|
|
179
|
+
(swapXY ? swapXYLabelPositions[labelPosition] : labelPositions[labelPosition]) ?? defaultLabelPosition,
|
|
180
|
+
)
|
|
166
181
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
[yLabelFormat ?? labelFormat ?? yFormat, y2LabelFormat ?? labelFormat ?? y2Format][
|
|
190
|
-
getYAxisIndex(params.componentIndex, yCount, y2Count)
|
|
191
|
-
],
|
|
192
|
-
)
|
|
182
|
+
$effect(() => {
|
|
183
|
+
// Don't run until we have data
|
|
184
|
+
if (!processedData || !columnSummary) return
|
|
185
|
+
|
|
186
|
+
let baseConfig = {
|
|
187
|
+
type: 'bar',
|
|
188
|
+
stack: resolvedStackName,
|
|
189
|
+
label: {
|
|
190
|
+
show: labelsBool && seriesLabelsBool,
|
|
191
|
+
formatter: function (params: any) {
|
|
192
|
+
return params.value[swapXY ? 0 : 1] === 0
|
|
193
|
+
? ''
|
|
194
|
+
: formatValue(
|
|
195
|
+
params.value[swapXY ? 0 : 1],
|
|
196
|
+
[yLabelFormat ?? labelFormat ?? yFormat, y2LabelFormat ?? labelFormat ?? y2Format][
|
|
197
|
+
getYAxisIndex(params.componentIndex, yCount, y2Count)
|
|
198
|
+
],
|
|
199
|
+
)
|
|
200
|
+
},
|
|
201
|
+
position: resolvedLabelPosition,
|
|
202
|
+
fontSize: labelSize,
|
|
203
|
+
color: $labelColorStore,
|
|
193
204
|
},
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
borderColor: $outlineColorStore,
|
|
209
|
-
borderWidth: outlineWidth,
|
|
210
|
-
},
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export let seriesLabelFmt = undefined
|
|
214
|
-
|
|
215
|
-
$: seriesConfig = getSeriesConfig(
|
|
216
|
-
data,
|
|
217
|
-
x,
|
|
218
|
-
y,
|
|
219
|
-
series,
|
|
220
|
-
swapXY,
|
|
221
|
-
baseConfig,
|
|
222
|
-
name,
|
|
223
|
-
xMismatch,
|
|
224
|
-
columnSummary,
|
|
225
|
-
seriesOrder,
|
|
226
|
-
undefined,
|
|
227
|
-
undefined,
|
|
228
|
-
y2,
|
|
229
|
-
seriesLabelFmt,
|
|
230
|
-
)
|
|
205
|
+
labelLayout: {
|
|
206
|
+
hideOverlap: showAllLabels ? false : true,
|
|
207
|
+
},
|
|
208
|
+
emphasis: {
|
|
209
|
+
focus: 'series',
|
|
210
|
+
},
|
|
211
|
+
barMaxWidth: barMaxWidth,
|
|
212
|
+
itemStyle: {
|
|
213
|
+
color: $fillColorStore,
|
|
214
|
+
opacity: fillOpacity,
|
|
215
|
+
borderColor: $outlineColorStore,
|
|
216
|
+
borderWidth: outlineWidth,
|
|
217
|
+
},
|
|
218
|
+
}
|
|
231
219
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
220
|
+
let seriesConfig = getSeriesConfig(
|
|
221
|
+
processedData,
|
|
222
|
+
x,
|
|
223
|
+
resolvedY,
|
|
224
|
+
resolvedSeries,
|
|
225
|
+
swapXY,
|
|
226
|
+
baseConfig,
|
|
227
|
+
resolvedName,
|
|
228
|
+
xMismatch,
|
|
229
|
+
columnSummary,
|
|
230
|
+
resolvedSeriesOrder,
|
|
231
|
+
undefined,
|
|
232
|
+
undefined,
|
|
233
|
+
resolvedY2,
|
|
234
|
+
seriesLabelFmt,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
config.update((d: any) => {
|
|
238
|
+
// Guard against incomplete config state
|
|
239
|
+
if (!d.series) d.series = []
|
|
240
|
+
if (!d.legend) d.legend = {data: []}
|
|
241
|
+
if (!d.legend.data) d.legend.data = []
|
|
242
|
+
|
|
243
|
+
d.series.push(...seriesConfig)
|
|
244
|
+
// Push series into legend:
|
|
245
|
+
d.legend.data.push(...seriesConfig.map((s: any) => s.name.toString()))
|
|
246
|
+
|
|
247
|
+
// Stacked chart total label:
|
|
248
|
+
// series !== x is to avoid an issue where same column is used for both - stackTotalLabel can't handle that
|
|
249
|
+
if (
|
|
250
|
+
labelsBool === true &&
|
|
251
|
+
type === 'stacked' &&
|
|
252
|
+
((Array.isArray(resolvedY) && resolvedY.length > 1) || (resolvedSeries !== undefined)) &&
|
|
253
|
+
stackTotalLabelBool === true &&
|
|
254
|
+
resolvedSeries !== x
|
|
255
|
+
) {
|
|
256
|
+
// push stack total series for total label
|
|
257
|
+
d.series.push({
|
|
258
|
+
type: 'bar',
|
|
259
|
+
stack: resolvedStackName,
|
|
260
|
+
name: 'stackTotal',
|
|
261
|
+
color: 'none',
|
|
262
|
+
data: stackTotalSeries.map((row: any) => {
|
|
263
|
+
let axisValue = xMismatch ? row[x].toString() : row[x]
|
|
264
|
+
if (swapXY) return [0, axisValue]
|
|
265
|
+
return [axisValue, 0]
|
|
266
|
+
}),
|
|
267
|
+
label: {
|
|
268
|
+
show: true,
|
|
269
|
+
position: swapXY ? 'right' : 'top',
|
|
270
|
+
formatter: function (params: any) {
|
|
271
|
+
let sum = 0
|
|
272
|
+
seriesConfig.forEach((s: any) => {
|
|
273
|
+
sum += s.data[params.dataIndex][swapXY ? 0 : 1]
|
|
274
|
+
})
|
|
275
|
+
return sum === 0 ? '' : formatValue(sum, labelFormat ?? yFormat)
|
|
276
|
+
},
|
|
277
|
+
fontWeight: 'bold',
|
|
278
|
+
fontSize: labelSize,
|
|
279
|
+
padding: swapXY ? [0, 0, 0, 5] : undefined,
|
|
266
280
|
},
|
|
267
|
-
|
|
268
|
-
fontSize: labelSize,
|
|
269
|
-
padding: swapXY ? [0, 0, 0, 5] : undefined,
|
|
270
|
-
},
|
|
271
|
-
})
|
|
281
|
+
})
|
|
272
282
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
283
|
+
// disable legend selected mode when stackTotalLabel is displayed:
|
|
284
|
+
d.legend.selectedMode = false
|
|
285
|
+
}
|
|
286
|
+
return d
|
|
287
|
+
})
|
|
277
288
|
})
|
|
278
289
|
|
|
279
|
-
|
|
290
|
+
let chartOverrides = $derived({
|
|
280
291
|
// Evidence definition of axes (yAxis = dependent, xAxis = independent)
|
|
281
292
|
xAxis: {
|
|
282
293
|
boundaryGap: ['1%', '2%'],
|
|
283
294
|
type: xType,
|
|
284
295
|
},
|
|
285
|
-
}
|
|
296
|
+
})
|
|
286
297
|
|
|
287
|
-
|
|
288
|
-
|
|
298
|
+
// Use $effect.pre() instead of beforeUpdate for runes mode
|
|
299
|
+
$effect.pre(() => {
|
|
300
|
+
// This ensures that these overrides always run before we render the chart.
|
|
289
301
|
// otherwise, this block won't re-execute after a change to the data object, and
|
|
290
302
|
// the chart will re-render using the base config from Chart.svelte
|
|
291
303
|
|
|
292
304
|
if (options) {
|
|
293
|
-
config.update((d) => {
|
|
305
|
+
config.update((d: any) => {
|
|
294
306
|
return {...d, ...options}
|
|
295
307
|
})
|
|
296
308
|
}
|
|
297
309
|
|
|
298
310
|
if (chartOverrides) {
|
|
299
|
-
config.update((d) => {
|
|
311
|
+
config.update((d: any) => {
|
|
312
|
+
// Guard against incomplete config state
|
|
313
|
+
if (!d.yAxis || !Array.isArray(d.yAxis)) return d
|
|
314
|
+
|
|
300
315
|
if (type.includes('stacked')) {
|
|
301
316
|
d.tooltip = {...d.tooltip, order: 'seriesDesc'}
|
|
302
317
|
} else {
|
|
@@ -305,22 +320,25 @@
|
|
|
305
320
|
if (type === 'stacked100') {
|
|
306
321
|
if (swapXY) {
|
|
307
322
|
d.xAxis = {...d.xAxis, max: 1}
|
|
308
|
-
} else {
|
|
323
|
+
} else if (d.yAxis[0]) {
|
|
309
324
|
d.yAxis[0] = {...d.yAxis[0], max: 1}
|
|
310
325
|
}
|
|
311
326
|
}
|
|
312
327
|
if (swapXY) {
|
|
313
328
|
d.yAxis = {...d.yAxis, ...chartOverrides.xAxis}
|
|
314
|
-
d.xAxis = {...d.xAxis
|
|
329
|
+
d.xAxis = {...d.xAxis}
|
|
315
330
|
} else {
|
|
316
|
-
d.yAxis[0]
|
|
331
|
+
if (d.yAxis[0]) {
|
|
332
|
+
d.yAxis[0] = {...d.yAxis[0]}
|
|
333
|
+
}
|
|
317
334
|
d.xAxis = {...d.xAxis, ...chartOverrides.xAxis}
|
|
318
|
-
if (y2Count > 0) {
|
|
319
|
-
|
|
320
|
-
if (['line', 'bar', 'scatter'].includes(y2SeriesType)) {
|
|
335
|
+
if (y2Count > 0 && d.yAxis[1]) {
|
|
336
|
+
if (['line', 'bar', 'scatter'].includes(y2SeriesType) && d.series) {
|
|
321
337
|
for (let i = 0; i < y2Count; i++) {
|
|
322
|
-
d.series[yCount + i]
|
|
323
|
-
|
|
338
|
+
if (d.series[yCount + i]) {
|
|
339
|
+
d.series[yCount + i].type = y2SeriesType
|
|
340
|
+
d.series[yCount + i].stack = undefined
|
|
341
|
+
}
|
|
324
342
|
}
|
|
325
343
|
}
|
|
326
344
|
}
|