@operato/chart 8.0.0-beta.0 → 8.0.0-beta.1

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.
Files changed (39) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/package.json +6 -6
  3. package/.editorconfig +0 -29
  4. package/.storybook/main.js +0 -3
  5. package/.storybook/preview.js +0 -52
  6. package/.storybook/server.mjs +0 -8
  7. package/src/chartjs/config-converter.ts +0 -341
  8. package/src/chartjs/ox-chart-js.ts +0 -207
  9. package/src/editors/configurer.ts +0 -336
  10. package/src/editors/index.ts +0 -8
  11. package/src/editors/input-chart-abstract.ts +0 -202
  12. package/src/editors/input-chart-styles.ts +0 -206
  13. package/src/editors/ox-input-chart-hbar.ts +0 -157
  14. package/src/editors/ox-input-chart-mixed.ts +0 -241
  15. package/src/editors/ox-input-chart-pie.ts +0 -69
  16. package/src/editors/ox-input-chart-radar.ts +0 -56
  17. package/src/editors/ox-input-chart-timeseries.ts +0 -279
  18. package/src/editors/ox-property-editor-chart.ts +0 -72
  19. package/src/editors/templates/annotations.ts +0 -295
  20. package/src/editors/templates/display-value.ts +0 -111
  21. package/src/editors/templates/series.ts +0 -316
  22. package/src/global.d.ts +0 -1
  23. package/src/index.ts +0 -0
  24. package/src/progress/ox-progress-circle.ts +0 -133
  25. package/src/scichart/ox-scichart.ts +0 -151
  26. package/src/scichart/scichart-builder.ts +0 -508
  27. package/src/types.d.ts +0 -124
  28. package/stories/common.ts +0 -87
  29. package/stories/ox-input-chart-bar.stories.ts +0 -188
  30. package/stories/ox-input-chart-doughnut.stories.ts +0 -130
  31. package/stories/ox-input-chart-hbar.stories.ts +0 -188
  32. package/stories/ox-input-chart-line.stories.ts +0 -198
  33. package/stories/ox-input-chart-pie.stories.ts +0 -130
  34. package/stories/ox-input-chart-polar-area.stories.ts +0 -130
  35. package/stories/ox-input-chart-radar.stories.ts +0 -141
  36. package/stories/ox-input-chart-timeseries.stories.ts +0 -268
  37. package/tsconfig.json +0 -25
  38. package/web-dev-server.config.mjs +0 -27
  39. package/web-test-runner.config.mjs +0 -41
package/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [8.0.0-beta.1](https://github.com/hatiolab/operato/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2025-01-08)
7
+
8
+
9
+ ### :bug: Bug Fix
10
+
11
+ * missing .npmignore ([be05985](https://github.com/hatiolab/operato/commit/be05985abfae4af53501f718dd52932099f7fbcb))
12
+
13
+
14
+
6
15
  ## [8.0.0-beta.0](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.56...v8.0.0-beta.0) (2025-01-07)
7
16
 
8
17
  **Note:** Version bump only for package @operato/chart
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@operato/chart",
3
3
  "description": "Webcomponents for chart following open-wc recommendations",
4
4
  "author": "heartyoh@hatiolab.com",
5
- "version": "8.0.0-beta.0",
5
+ "version": "8.0.0-beta.1",
6
6
  "main": "dist/src/index.js",
7
7
  "module": "dist/src/index.js",
8
8
  "types": "src/types.d.ts",
@@ -72,10 +72,10 @@
72
72
  "dependencies": {
73
73
  "@ctrl/tinycolor": "^4.1.0",
74
74
  "@material/web": "^2.0.0",
75
- "@operato/input": "^8.0.0-beta.0",
76
- "@operato/property-editor": "^8.0.0-beta.0",
77
- "@operato/styles": "^8.0.0-beta.0",
78
- "@operato/utils": "^8.0.0-beta.0",
75
+ "@operato/input": "^8.0.0-beta.1",
76
+ "@operato/property-editor": "^8.0.0-beta.1",
77
+ "@operato/styles": "^8.0.0-beta.1",
78
+ "@operato/utils": "^8.0.0-beta.1",
79
79
  "d3": "^7.8.5",
80
80
  "lit": "^3.1.2",
81
81
  "lodash-es": "^4.17.21",
@@ -119,5 +119,5 @@
119
119
  "prettier --write"
120
120
  ]
121
121
  },
122
- "gitHead": "c4e9cc245659d050a9ffd66542083a6daad4bcb9"
122
+ "gitHead": "d5b28a2e9deb632c0dc80132f6a7196dd6fe4220"
123
123
  }
package/.editorconfig DELETED
@@ -1,29 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # editorconfig.org
4
-
5
- root = true
6
-
7
-
8
- [*]
9
-
10
- # Change these settings to your own preference
11
- indent_style = space
12
- indent_size = 2
13
-
14
- # We recommend you to keep these unchanged
15
- end_of_line = lf
16
- charset = utf-8
17
- trim_trailing_whitespace = true
18
- insert_final_newline = true
19
-
20
- [*.md]
21
- trim_trailing_whitespace = false
22
-
23
- [*.json]
24
- indent_size = 2
25
-
26
- [*.{html,js,md}]
27
- block_comment_start = /**
28
- block_comment = *
29
- block_comment_end = */
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- stories: ['../dist/stories/**/*.stories.{js,md,mdx}']
3
- }
@@ -1,52 +0,0 @@
1
- import { i18next } from '@operato/i18n'
2
-
3
- export const globalTypes = {
4
- locale: {
5
- name: 'Locale',
6
- description: 'Internationalization locale',
7
- toolbar: {
8
- icon: 'globe',
9
- items: [
10
- { value: 'en', right: '🇺🇸', title: 'English' },
11
- { value: 'ko', right: '🇰🇷', title: '한국어' },
12
- { value: 'zh', right: '🇨🇳', title: '中文' },
13
- { value: 'ja', right: '🇯🇵', title: '日本語' },
14
- { value: 'ms', right: '🇲🇾', title: 'Bahasa Melayu' }
15
- ],
16
- showName: true
17
- }
18
- },
19
- theme: {
20
- name: 'Theme',
21
- description: 'Global theme for components',
22
- toolbar: {
23
- icon: 'paintbrush',
24
- items: [
25
- { value: 'light', title: 'Light' },
26
- { value: 'dark', title: 'Dark' }
27
- ],
28
- showName: true
29
- }
30
- }
31
- }
32
-
33
- export const decorators = [
34
- (Story, context) => {
35
- const { locale, theme } = context.globals
36
-
37
- if (locale) {
38
- i18next.changeLanguage(locale)
39
- }
40
-
41
- // Set the theme class for the document
42
- if (theme === 'dark') {
43
- document.documentElement.classList.add('dark')
44
- document.documentElement.classList.remove('light')
45
- } else {
46
- document.documentElement.classList.add('light')
47
- document.documentElement.classList.remove('dark')
48
- }
49
-
50
- return Story()
51
- }
52
- ]
@@ -1,8 +0,0 @@
1
- import { storybookPlugin } from '@web/dev-server-storybook'
2
- import baseConfig from '../web-dev-server.config.mjs'
3
-
4
- export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
5
- ...baseConfig,
6
- open: '/',
7
- plugins: [storybookPlugin({ type: 'web-components' }), ...baseConfig.plugins]
8
- })
@@ -1,341 +0,0 @@
1
- import { TinyColor } from '@ctrl/tinycolor'
2
- import { format as formatText } from '@operato/utils/format.js'
3
-
4
- function getBaseColorFromTheme(theme?: 'light' | 'dark' | 'auto') {
5
- return new TinyColor(theme == 'dark' ? '#fff' : '#000')
6
- }
7
-
8
- function getThemeFromBrowser() {
9
- return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
10
- }
11
-
12
- export function convertConfigure(
13
- config: OperatoChart.ChartConfig,
14
- { fontSize, fontFamily, fontColor }: { fontSize?: number; fontFamily?: string; fontColor?: string }
15
- ) {
16
- if (!config) {
17
- return
18
- }
19
-
20
- const { type: chartType, options, data: fromData } = config
21
- var {
22
- theme,
23
- animation,
24
- tooltip,
25
- stacked,
26
- legend,
27
- scales: fromScales,
28
- xGridLine,
29
- yGridLine,
30
- y2ndGridLine,
31
- multiAxis
32
- } = options || {}
33
- const { datasets = [] } = fromData || {}
34
-
35
- if (theme === 'auto') {
36
- theme = getThemeFromBrowser()
37
- }
38
-
39
- const { xAxes = [], yAxes = [] } = fromScales || {}
40
- const toScales = {} as any
41
-
42
- chartType != 'pie' &&
43
- xAxes.forEach((xAxis, index) => {
44
- const { axisTitle, barSpacing, categorySpacing, barPercentage, ticks } = xAxis
45
- const id = xAxes.length > 1 ? `x${index + 1}` : 'x'
46
-
47
- toScales[id] = setupScale(
48
- {
49
- axis: 'x',
50
- id,
51
- position: 'bottom',
52
- display: true,
53
- title: {
54
- display: !!axisTitle,
55
- text: axisTitle
56
- },
57
- grid: {
58
- display: xGridLine
59
- },
60
- beginAtZero: false,
61
- ticks
62
- },
63
- { fontSize, fontFamily, fontColor, theme }
64
- )
65
- })
66
-
67
- chartType != 'pie' &&
68
- yAxes.forEach((yAxis, index) => {
69
- const { axisTitle, barSpacing, categorySpacing, barPercentage, ticks } = yAxis
70
- const id = yAxes.length > 1 ? `right` : 'left'
71
-
72
- toScales[id] = setupScale(
73
- {
74
- axis: 'y',
75
- id,
76
- position: id,
77
- display: true,
78
- title: {
79
- display: !!axisTitle,
80
- text: axisTitle
81
- },
82
- grid: {
83
- display: index == 0 ? yGridLine : y2ndGridLine
84
- },
85
- ticks,
86
- stacked: stacked ? true : false
87
- },
88
- { fontSize, fontFamily, fontColor, theme }
89
- )
90
- })
91
-
92
- // setup series configure
93
- // for (let i in datasets) {
94
- // let series = datasets[i]
95
- //
96
- // /*
97
- // * TODO from chartjs 2.9, categoryPercentage, barPercentage properties move to dataset.
98
- // * so need to move related properties - categorySpacing, barSpacing should be moved to series.
99
- // */
100
- // if (chartType == 'bar') {
101
- // let categorySpacing = (xAxes && xAxes[0].categorySpacing) || 0
102
- // let barSpacing = (xAxes && xAxes[0].barSpacing) || 0
103
-
104
- // series.categoryPercentage = 1 - categorySpacing || 1
105
- // series.barPercentage = 1 - barSpacing || 0.8
106
- // } else if (chartType == 'horizontalBar') {
107
- // let categorySpacing = (yAxes && yAxes[0].categorySpacing) || 0
108
- // let barSpacing = (yAxes && yAxes[0].barSpacing) || 0
109
-
110
- // series.categoryPercentage = 1 - categorySpacing || 1
111
- // series.barPercentage = 1 - barSpacing || 0.8
112
- // }
113
- // }
114
-
115
- const converted = {
116
- type: chartType == 'horizontalBar' ? 'bar' : chartType,
117
- options: {
118
- animation,
119
- stacked,
120
- maintainAspectRatio: false,
121
- // parsing: false /* recommendations for performance */,
122
- // normalized: true /* recommendations for performance */,
123
- plugins: {
124
- legend: setupLegend(legend || {}, { fontSize, fontFamily, fontColor, theme }),
125
- tooltip: setupTooltip(
126
- {
127
- enabled: tooltip,
128
- mode: 'interpolate',
129
- intersect: false
130
- },
131
- { fontSize, fontFamily }
132
- ),
133
- title: {
134
- /* new option candidate - subtitle */
135
- display: false,
136
- text: 'Custom Chart Title'
137
- },
138
- subtitle: {
139
- /* new option candidate - subtitle */
140
- display: false,
141
- text: 'Custom Chart Subtitle'
142
- },
143
- crosshair: {
144
- line: {
145
- color: '#F66', // crosshair line color
146
- width: 1 // crosshair line width
147
- },
148
- sync: {
149
- enabled: true, // enable trace line syncing with other charts
150
- group: 1, // chart group
151
- suppressTooltips: false // suppress tooltips when showing a synced tracer
152
- },
153
- zoom: {
154
- enabled: true, // enable zooming
155
- zoomboxBackgroundColor: 'rgba(66,133,244,0.2)', // background color of zoom box
156
- zoomboxBorderColor: '#48F', // border color of zoom box
157
- zoomButtonText: 'Reset Zoom', // reset zoom button text
158
- zoomButtonClass: 'reset-zoom' // reset zoom button class
159
- },
160
- callbacks: {
161
- beforeZoom: () =>
162
- function (start: number, end: number) {
163
- // called before zoom, return false to prevent zoom
164
- return true
165
- },
166
- afterZoom: () =>
167
- function (start: number, end: number) {
168
- // called after zoom
169
- }
170
- }
171
- }
172
- },
173
- scales: toScales,
174
- indexAxis: chartType == 'horizontalBar' ? 'y' : chartType != 'pie' ? 'x' : ''
175
- },
176
- data: {
177
- datasets: datasets.map((dataset, index) => {
178
- return setupSeries(chartType!, {
179
- ...dataset,
180
- stack:
181
- chartType == 'pie' || chartType == 'doughnut'
182
- ? undefined
183
- : stacked && !dataset.stack
184
- ? '__all__'
185
- : `__${index}__`,
186
- type: dataset.type == 'horizontalBar' ? 'bar' : dataset.type
187
- })
188
- })
189
- }
190
- }
191
-
192
- console.error('converted', config, converted)
193
- return converted
194
- }
195
-
196
- function setupLegend(
197
- legend: any,
198
- {
199
- fontSize,
200
- fontFamily,
201
- fontColor,
202
- theme
203
- }: { fontSize?: number; fontFamily?: string; fontColor?: string; theme?: 'light' | 'dark' | 'auto' }
204
- ) {
205
- legend.labels = legend.labels ? legend.labels : {}
206
-
207
- if (fontSize) {
208
- legend.labels.fontSize = fontSize
209
- }
210
-
211
- if (fontFamily) {
212
- legend.labels.fontFamily = fontFamily
213
- }
214
-
215
- var baseColor = getBaseColorFromTheme(theme)
216
-
217
- legend.labels = legend.labels ? legend.labels : {}
218
- legend.labels.fontColor = fontColor ? fontColor : baseColor.clone().setAlpha(0.5).toString()
219
- // legend.labels.usePointStyle = true
220
-
221
- return legend
222
- }
223
-
224
- function setupTooltip(
225
- tooltip: any,
226
- {
227
- fontSize,
228
- fontFamily,
229
- fontColor,
230
- theme
231
- }: { fontSize?: number; fontFamily?: string; fontColor?: string; theme?: 'light' | 'dark' }
232
- ) {
233
- if (fontSize) {
234
- tooltip.titleFontSize = tooltip.bodyFontSize = tooltip.footerFontSize = fontSize
235
- }
236
-
237
- if (fontFamily) {
238
- tooltip.titleFontFamily = tooltip.bodyFontFamily = tooltip.footerFontFamily = fontFamily
239
- }
240
-
241
- tooltip.mode = 'index'
242
- tooltip.intersect = false
243
- tooltip.callbacks = {
244
- ...tooltip.callbacks,
245
- label: function ({ dataset, label }: { dataset: any; label: any }) {
246
- var prefix = dataset.valuePrefix || ''
247
- var suffix = dataset.valueSuffix || ''
248
- var format = dataset.valueFormat || ''
249
-
250
- var stringValue = format ? formatText(format, Number(label)) : Number(label).toLocaleString()
251
-
252
- return `${prefix + stringValue + suffix}`
253
- }
254
- }
255
-
256
- return tooltip
257
- }
258
-
259
- function setupScale(
260
- axis: any,
261
- {
262
- fontSize,
263
- fontFamily,
264
- fontColor,
265
- theme
266
- }: { fontSize?: number; fontFamily?: string; fontColor?: string; theme?: 'light' | 'dark' | 'auto' }
267
- ) {
268
- axis.ticks = axis.ticks ? axis.ticks : {}
269
-
270
- if (fontSize) {
271
- axis.ticks.fontSize = fontSize
272
- }
273
-
274
- if (fontFamily) {
275
- axis.ticks.fontFamily = fontFamily
276
- }
277
-
278
- axis.pointLabels = {
279
- fontSize,
280
- fontFamily
281
- }
282
-
283
- /* TODO move min, max, autoMin, autoMax from ticks to axis */
284
- const { min, max, autoMin, autoMax } = axis.ticks
285
-
286
- axis.min = min
287
- axis.max = max
288
-
289
- if (autoMin) {
290
- delete axis.min
291
- }
292
- if (autoMax) {
293
- delete axis.max
294
- }
295
-
296
- var baseColor = getBaseColorFromTheme(theme)
297
-
298
- axis.grid = axis.grid ? axis.grid : {}
299
- if (axis.grid) {
300
- axis.grid.tickColor = baseColor.clone().setAlpha(0.5).toString()
301
- axis.grid.color = baseColor.clone().setAlpha(0.1).toString()
302
- }
303
-
304
- axis.ticks = axis.ticks ? axis.ticks : {}
305
- axis.ticks.color = baseColor.clone().setAlpha(0.5).toString()
306
- axis.ticks.textStrokeColor = fontColor ? fontColor : baseColor.clone().setAlpha(0.5).toString()
307
-
308
- return axis
309
- }
310
-
311
- function setupSeries(chartType: string, series: OperatoChart.Dataset) {
312
- var type = series.type || chartType
313
-
314
- // series.parsing = {
315
- // yAxisKey: series.dataKey
316
- // } /* 이 형식의 data는 잘 안되었음. */
317
-
318
- var color = series.color ? series.color : series.backgroundColor
319
-
320
- switch (type) {
321
- case 'bar':
322
- case 'horizontalBar':
323
- series.borderColor = series.backgroundColor = color
324
- break
325
-
326
- case 'line':
327
- case 'radar':
328
- color = series.color ? series.color : series.borderColor
329
- series.pointBackgroundColor = series.pointBorderColor = series.borderColor = series.backgroundColor = color
330
- series.pointBorderWidth = (series.borderWidth as number) * 0.5
331
- series.pointHoverRadius = series.pointRadius
332
- if (series.fill == undefined) series.fill = false
333
- break
334
-
335
- default:
336
- series.borderColor = series.backgroundColor = color
337
- break
338
- }
339
-
340
- return series
341
- }
@@ -1,207 +0,0 @@
1
- import ChartDataLabels from 'chartjs-plugin-datalabels'
2
-
3
- import { LitElement, html, css } from 'lit'
4
- import { property, query, state, customElement } from 'lit/decorators.js'
5
- import { Chart, ChartConfiguration } from 'chart.js/auto'
6
- import { format as formatText } from '@operato/utils/format.js'
7
- import { convertConfigure } from './config-converter'
8
-
9
- Chart.register(ChartDataLabels)
10
-
11
- @customElement('ox-chart-js')
12
- export class OxChartJs extends LitElement {
13
- @property({ type: Object }) config: OperatoChart.ChartConfig | null = null
14
- @property({ type: Array }) data: { [key: string]: any }[] = []
15
- @property({ type: Number }) width!: number
16
- @property({ type: Number }) height!: number
17
-
18
- private chart: Chart | null = null
19
- private chartjsConfig: ChartConfiguration | null = null
20
-
21
- @query('canvas') canvas!: HTMLCanvasElement
22
-
23
- static styles = css`
24
- :host {
25
- display: block;
26
-
27
- background-color: var(--ox-chart-background-color, var(--md-sys-color-surface));
28
- color: var(--ox-chart-color, var(--md-sys-color-on-surface));
29
- }
30
-
31
- canvas {
32
- width: 100%;
33
- height: 100%;
34
- }
35
- `
36
-
37
- disconnectedCallback(): void {
38
- super.disconnectedCallback()
39
- if (this.chart) {
40
- this.chart.destroy()
41
- }
42
- }
43
-
44
- updated(changedProperties: Map<string | number | symbol, unknown>) {
45
- var needUpdateData = false
46
-
47
- if (changedProperties.has('width') || changedProperties.has('height')) {
48
- this.updateChartSize()
49
- }
50
-
51
- if (changedProperties.has('config') && this.config) {
52
- this.chartjsConfig = convertConfigure(this.config, {}) as any
53
-
54
- this.attachPluginOptions(this.chartjsConfig!.options as any)
55
-
56
- this.chart && this.chart.destroy()
57
- this.chart = new Chart(this.canvas, this.chartjsConfig!)
58
-
59
- needUpdateData = true
60
- }
61
-
62
- if (changedProperties.has('data')) {
63
- needUpdateData = true
64
- }
65
-
66
- if (needUpdateData) {
67
- this.updateData()
68
- }
69
- }
70
-
71
- updateData() {
72
- if (!this.chart) {
73
- return
74
- }
75
-
76
- var data = this.data
77
-
78
- if (this.data[0]?.hasOwnProperty('__field1')) {
79
- /* DEPRECATED 이 케이스는 앞으로 지원하지 않는 것이 좋다. 하위 호환성 때문에 제공함. 사용빈도 낮음. */
80
- data = toObjectArrayValue(this.data) as { [key: string]: any }[]
81
- }
82
-
83
- const labelDataKey = this.config!.data.labelDataKey || ''
84
-
85
- labelDataKey && (this.chart!.config.data!.labels = data.map((data: any) => data[labelDataKey]))
86
-
87
- const datasets = this.chart!.config.data.datasets
88
- for (let key in datasets) {
89
- const dataset = datasets[Number(key)]
90
- const dataKey = (dataset as any).dataKey
91
- dataKey && (dataset.data = data.map(d => d[dataKey]) as any)
92
- }
93
-
94
- this.chart.update()
95
- }
96
-
97
- updateChartSize() {
98
- const width = Math.floor(this.width)
99
- const height = Math.floor(this.height)
100
-
101
- this.canvas.style.width = `${width}px`
102
- this.canvas.style.height = `${height}px`
103
-
104
- const _ = () => {
105
- if (this.canvas.offsetWidth == 0 || this.canvas.offsetHeight == 0) {
106
- requestAnimationFrame(_)
107
- } else {
108
- /*
109
- 주의 : chart.resize() 내에서 pixel ratio를 감안해서, canvas 의 width, height를 설정하기때문에,
110
- 별도 처리가 필요하지 않다.
111
- */
112
- this.chart!.resize()
113
- }
114
- }
115
-
116
- requestAnimationFrame(_)
117
- }
118
-
119
- render() {
120
- return html`<canvas></canvas>`
121
- }
122
-
123
- attachPluginOptions(options: OperatoChart.ChartOptions) {
124
- if (!options.plugins) {
125
- options.plugins = {}
126
- }
127
-
128
- this.attachDatalabelPluginOptions(options.plugins)
129
- }
130
-
131
- attachDatalabelPluginOptions(pluginOptions: any) {
132
- pluginOptions.datalabels = {
133
- ...pluginOptions.datalabels,
134
- display: function (context: any) {
135
- return !!context.dataset.displayValue
136
- },
137
- anchor: function (context: any) {
138
- return context.dataset.dataLabelAnchor || 'center'
139
- },
140
- offset: function (context: any) {
141
- return context.dataset.dataLabelOffset || 0
142
- },
143
- align: function (context: any) {
144
- return context.dataset.dataLabelAnchor || 'center'
145
- },
146
- rotation: function (context: any) {
147
- return context.dataset.dataLabelRotation || 0
148
- },
149
- color: function (context: any) {
150
- return context.dataset?.defaultFontColor || '#000'
151
- },
152
- font: function (context: any) {
153
- return {
154
- size: context.dataset?.defaultFontSize,
155
- family: context.chart.options?.defaultFontFamily
156
- }
157
- },
158
- clamp: true,
159
- formatter: function (value: string, context: any) {
160
- var prefix = context.dataset.valuePrefix || ''
161
- var suffix = context.dataset.valueSuffix || ''
162
- var format = context.dataset.valueFormat || ''
163
-
164
- if (value === undefined) {
165
- return value
166
- }
167
-
168
- var stringValue = format ? formatText(format, Number(value)) : Number(value).toLocaleString()
169
- return prefix + stringValue + suffix
170
- }
171
- }
172
- }
173
- }
174
-
175
- function toObjectArrayValue(array: any[]): any[] | null {
176
- if (!array || array.length === 0) {
177
- return null
178
- }
179
-
180
- let indexKeyMap: any = {}
181
- let value = []
182
-
183
- for (let key in array[0]) {
184
- indexKeyMap[key] = array[0][key]
185
- }
186
-
187
- for (var i = 1; i < array.length; i++) {
188
- let object: any = {}
189
- let thisObject = array[i]
190
-
191
- for (let key in indexKeyMap) {
192
- let k = indexKeyMap[key]
193
- let v = thisObject[key]
194
- object[k] = v
195
- }
196
-
197
- value.push(object)
198
- }
199
-
200
- return value
201
- }
202
-
203
- declare global {
204
- interface HTMLElementTagNameMap {
205
- 'ox-chart-js': OxChartJs
206
- }
207
- }