@operato/scene-chartjs 8.0.0-beta.1 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/src/chartjs.ts DELETED
@@ -1,139 +0,0 @@
1
- import './ox-chart'
2
-
3
- import cloneDeep from 'lodash/cloneDeep'
4
-
5
- import { Component, ComponentNature, error, HTMLOverlayElement, Properties } from '@hatiolab/things-scene'
6
-
7
- import { OxChart } from './ox-chart'
8
-
9
- const NATURE: ComponentNature = {
10
- mutable: false,
11
- resizable: true,
12
- rotatable: true,
13
- properties: [
14
- {
15
- type: 'chartjs',
16
- label: '',
17
- name: 'chart'
18
- }
19
- ],
20
- 'value-property': 'data',
21
- help: 'scene/component/chartjs'
22
- }
23
-
24
- export default class ChartJS extends HTMLOverlayElement {
25
- private _isChartChanged = false
26
- private _isDataChanged = false
27
-
28
- get nature() {
29
- return NATURE
30
- }
31
-
32
- get hasTextProperty() {
33
- return false
34
- }
35
-
36
- get tagName() {
37
- return 'ox-chart'
38
- }
39
-
40
- dispose(): void {
41
- ;(this.element as OxChart)?.dispose()
42
-
43
- super.dispose()
44
- }
45
-
46
- isShadowable() {
47
- return false
48
- }
49
-
50
- createElement() {
51
- super.createElement()
52
-
53
- var { width, height } = this.bounds
54
- var element = this.element as OxChart
55
- var data = this.data
56
-
57
- element.width = width
58
- element.height = height
59
-
60
- this._setChartConfig(element)
61
- element.data = data
62
- }
63
-
64
- /* component.property => element.property */
65
- setElementProperties(element: OxChart) {
66
- this.setState('lineWidth', 0) // border 표현이 자연스럽게 바뀌면 지울것.
67
-
68
- var { chart: chartConfig } = this.state
69
- var { width, height } = this.bounds
70
- var data = this.data
71
-
72
- try {
73
- element.width = width
74
- element.height = height
75
-
76
- if (chartConfig && this._isChartChanged) {
77
- this._setChartConfig(element)
78
- this._isChartChanged = false
79
- }
80
-
81
- if (this._isDataChanged) {
82
- element.data = data
83
- this._isDataChanged = false
84
- }
85
- } catch (e) {
86
- error(e)
87
- }
88
- }
89
-
90
- _setChartConfig(element: OxChart) {
91
- var { chart: chartConfig, fontSize = 12, fontFamily, fontColor, shadow } = this.state
92
- var { left = 0, top = 0, blurSize = 0, color = 'transparent' } = shadow || {}
93
-
94
- const fontOption = {
95
- defaultFontSize: fontSize,
96
- defaultFontFamily: fontFamily,
97
- defaultFontColor: fontColor
98
- }
99
-
100
- const shadowOption = {
101
- shadowOffsetX: left,
102
- shadowOffsetY: top,
103
- shadowBlur: blurSize,
104
- shadowColor: color
105
- }
106
-
107
- var cloneChartConf = cloneDeep(chartConfig)
108
-
109
- cloneChartConf.options = {
110
- ...cloneChartConf.options,
111
- ...fontOption,
112
- tooltips: false
113
- }
114
-
115
- cloneChartConf.data.datasets = cloneChartConf.data.datasets.map((dataset: any) => {
116
- return {
117
- ...dataset,
118
- ...shadowOption
119
- }
120
- })
121
-
122
- element.options = cloneChartConf
123
- }
124
-
125
- onchange(after: Properties, before: Properties) {
126
- this._isChartChanged = false
127
-
128
- if ('chart' in after || 'fontSize' in after || 'fontFamily' in after || 'fontColor' in after || 'shadow' in after)
129
- this._isChartChanged = true
130
-
131
- super.onchange(after, before)
132
- }
133
-
134
- onchangeData(data: any) {
135
- this._isDataChanged = true
136
- }
137
- }
138
-
139
- Component.register('chartjs', ChartJS)
@@ -1,404 +0,0 @@
1
- import { TinyColor } from '@ctrl/tinycolor'
2
- import { format as formatText } from '@operato/utils/format.js'
3
-
4
- export function convertConfigure(chart: SceneChart.ChartConfig) {
5
- if (!chart) return
6
-
7
- var data = chart.data || {}
8
- var datasets = data.datasets || []
9
- var options = chart.options || {}
10
- var scales = options.scales || {}
11
- var xAxes: Array<SceneChart.ChartXAxe>
12
- var yAxes: Array<SceneChart.ChartYAxe>
13
- var scale
14
- var legend = options.legend || {}
15
- var tooltips = options.tooltip === false ? undefined : (options.tooltips = options.tooltips || {})
16
- var multiAxis = options.multiAxis
17
- var stacked = false
18
- var yStacked = [false, false]
19
- var fontSize = Number(options.defaultFontSize)
20
- var fontFamily = options.defaultFontFamily
21
- var fontColor = options.defaultFontColor
22
- var theme = options.theme
23
-
24
- // backward compatible
25
- _configureBackwardsCompatible(chart.type, options)
26
-
27
- // setup series configure
28
- for (let i in datasets) {
29
- let series = datasets[i]
30
-
31
- if (options.stacked && !series.stack) {
32
- series.stack = 'A'
33
- }
34
-
35
- /*
36
- * TODO from chartjs 2.9, categoryPercentage, barPercentage properties move to dataset.
37
- * so need to move related properties - categorySpacing, barSpacing should be moved to series.
38
- */
39
- if (chart.type == 'bar') {
40
- let categorySpacing = (scales.xAxes && scales.xAxes[0].categorySpacing) || 0
41
- let barSpacing = (scales.xAxes && scales.xAxes[0].barSpacing) || 0
42
-
43
- series.categoryPercentage = 1 - categorySpacing || 1
44
- series.barPercentage = 1 - barSpacing || 0.8
45
- } else if (chart.type == 'horizontalBar') {
46
- let categorySpacing = (scales.yAxes && scales.yAxes[0].categorySpacing) || 0
47
- let barSpacing = (scales.yAxes && scales.yAxes[0].barSpacing) || 0
48
-
49
- series.categoryPercentage = 1 - categorySpacing || 1
50
- series.barPercentage = 1 - barSpacing || 0.8
51
- }
52
-
53
- _setSeriesConfigures(series, chart)
54
-
55
- if (!multiAxis) {
56
- if (series.yAxisID == 'right') series.yAxisID = 'left'
57
- }
58
- }
59
-
60
- delete options.stacked
61
-
62
- var leftSeries = datasets.filter(d => d.yAxisID == 'left')
63
- var rightSeries = datasets.filter(d => d.yAxisID == 'right')
64
-
65
- leftSeries.forEach(s => {
66
- var filtered = leftSeries.filter(ss => s.stack == ss.stack)
67
- if (filtered.length > 1) {
68
- yStacked[0] = true
69
- return
70
- }
71
- })
72
-
73
- rightSeries.forEach(s => {
74
- var filtered = rightSeries.filter(ss => s.stack == ss.stack)
75
- if (filtered.length > 1) {
76
- yStacked[1] = true
77
- return
78
- }
79
- })
80
-
81
- stacked = yStacked[0] || yStacked[1]
82
-
83
- // setup options
84
- // 1. setup scales
85
- switch (chart.type) {
86
- case 'line':
87
- case 'bar':
88
- case 'horizontalBar':
89
- xAxes = scales.xAxes || []
90
- yAxes = scales.yAxes || []
91
-
92
- if (chart.type == 'horizontalBar') {
93
- xAxes = scales.yAxes || []
94
- yAxes = scales.xAxes || []
95
- }
96
-
97
- // 1-1. setup xAxes
98
- for (let i in xAxes) {
99
- let axis = xAxes[i]
100
- _setStacked(axis, stacked)
101
- _setScalesFont(axis, {
102
- fontSize,
103
- fontFamily
104
- })
105
- _setScalesAutoMinMax(axis)
106
- _setScalesTickRotation(axis)
107
- _setAxisTitle(axis)
108
- _setScalesTheme(axis, theme, fontColor)
109
- _appendTickCallback(axis.ticks)
110
-
111
- axis.gridLines!.display = options.xGridLine
112
- }
113
-
114
- // 1-2. setup yAxes
115
- for (let i in yAxes) {
116
- let axis = yAxes[i]
117
-
118
- //@ts-ignore
119
- if (i == 1) {
120
- _setMultiAxis(axis, multiAxis)
121
- }
122
- _setStacked(axis, yStacked[i])
123
- _setScalesFont(axis, {
124
- fontSize,
125
- fontFamily
126
- })
127
- _setScalesAutoMinMax(axis)
128
- _setAxisTitle(axis)
129
- _setScalesTheme(axis, theme, fontColor)
130
- _appendTickCallback(axis.ticks)
131
-
132
- //@ts-ignore
133
- if (i == 0) axis.gridLines.display = options.yGridLine
134
-
135
- //@ts-ignore
136
- if (i == 1) axis.gridLines.display = options.y2ndGridLine
137
- }
138
-
139
- break
140
- case 'pie':
141
- case 'doughnut':
142
- break
143
- default:
144
- scale = options.scale || {}
145
- _setScalesFont(scale, {
146
- fontSize,
147
- fontFamily
148
- })
149
- break
150
- }
151
-
152
- // 2. setup legend
153
- _setLegendFont(legend, {
154
- fontSize,
155
- fontFamily
156
- })
157
- legend.labels && (legend.labels.boxWidth = 15)
158
- _setLegendTheme(legend, theme, fontColor)
159
-
160
- // 3. setup tooltips
161
- options.tooltip &&
162
- _setTooltipFont(tooltips!, {
163
- fontSize,
164
- fontFamily
165
- })
166
- options.tooltip && _setTooltipCallback(tooltips!)
167
- }
168
-
169
- function _configureBackwardsCompatible(type: string, options: SceneChart.ChartOptions) {
170
- switch (type) {
171
- case 'horizontalBar':
172
- if (!options.scales) options.scales = {}
173
- break
174
- case 'radar':
175
- case 'polarArea':
176
- if (options.defaultFontColor) {
177
- options.scale!.ticks!.fontColor = options.defaultFontColor
178
- if (options.scale.pointLabels) {
179
- options.scale.pointLabels.fontColor = options.defaultFontColor
180
- } else {
181
- options.scale.pointLabels = { fontColor: options.defaultFontColor }
182
- }
183
- }
184
- options.scale!.ticks!.backdropColor = options.fillStyle ? options.fillStyle : '#00ff0000'
185
- break
186
- case 'line':
187
- case 'bar':
188
- if (!options.scales) options.scales = {}
189
- if (!options.scales.yAxes) options.scales.yAxes = []
190
-
191
- if (options.scales.yAxes.length === 1) {
192
- let yAxes = options.scales.yAxes
193
- yAxes.push({
194
- position: 'right',
195
- id: 'right',
196
- display: options.multiAxis || false,
197
- gridLines: {
198
- display: (yAxes[0] && yAxes[0].gridLines && yAxes[0].gridLines.display) || false
199
- },
200
- ticks: {
201
- beginAtZero: false,
202
- callback: function (value: any, index: number, values: any[]) {
203
- var returnValue = value
204
- if (typeof returnValue == 'number') {
205
- returnValue = returnValue.toLocaleString()
206
- }
207
-
208
- return returnValue
209
- }
210
- }
211
- })
212
- }
213
- break
214
- case 'pie':
215
- case 'doughnut':
216
- break
217
- default:
218
- if (!options.scale) options.scale = {}
219
-
220
- break
221
- }
222
- }
223
-
224
- function _setStacked(axis: SceneChart.ChartXAxe, stacked: boolean) {
225
- axis.stacked = stacked
226
- }
227
-
228
- function _setMultiAxis(axis: SceneChart.ChartXAxe, multiAxis: boolean) {
229
- axis.display = multiAxis
230
- }
231
-
232
- function _setAxisTitle(axis: SceneChart.ChartXAxe) {
233
- if (!axis.scaleLabel) axis.scaleLabel = {}
234
- axis.scaleLabel.labelString = axis.axisTitle
235
- axis.scaleLabel.display = axis.axisTitle ? true : false
236
- }
237
-
238
- function _setScalesFont(
239
- axis: SceneChart.ChartXAxe | SceneChart.RadialLinearScale,
240
- { fontSize, fontFamily }: { fontSize: number; fontFamily: string }
241
- ) {
242
- axis.ticks = axis.ticks ? axis.ticks : {}
243
- axis.ticks.fontSize = fontSize
244
-
245
- if (fontFamily) {
246
- axis.ticks.fontFamily = fontFamily
247
- }
248
-
249
- ;(axis as SceneChart.RadialLinearScale).pointLabels = {
250
- fontSize,
251
- fontFamily
252
- }
253
- }
254
-
255
- function _setScalesAutoMinMax(axis: SceneChart.ChartXAxe) {
256
- axis.ticks = axis.ticks ? axis.ticks : {}
257
-
258
- let autoMin = axis.ticks.autoMin
259
- let autoMax = axis.ticks.autoMax
260
-
261
- if (autoMin === true) {
262
- delete axis.ticks.min
263
- }
264
- if (autoMax === true) {
265
- delete axis.ticks.max
266
- }
267
- }
268
-
269
- function _setScalesTickRotation(axis: SceneChart.ChartXAxe) {
270
- axis.ticks = axis.ticks ? axis.ticks : {}
271
- // axis.ticks.maxRotation = 0
272
- }
273
-
274
- function _setScalesTheme(axis: SceneChart.ChartXAxe, theme: SceneChart.Theme, fontColor: string) {
275
- var baseColor = _getBaseColorFromTheme(theme)
276
-
277
- axis.gridLines = axis.gridLines ? axis.gridLines : {}
278
- if (axis.gridLines) {
279
- axis.gridLines.zeroLineColor = baseColor.clone().setAlpha(0.5).toString()
280
- axis.gridLines.color = baseColor.clone().setAlpha(0.1).toString()
281
- }
282
-
283
- axis.ticks = axis.ticks ? axis.ticks : {}
284
- axis.ticks.fontColor = fontColor ? fontColor : baseColor.clone().setAlpha(0.5).toString()
285
- }
286
-
287
- function _setLegendFont(
288
- legend: SceneChart.ChartLegendOptions,
289
- { fontFamily, fontSize }: { fontFamily: string; fontSize: number }
290
- ) {
291
- legend.labels = legend.labels ? legend.labels : {}
292
- legend.labels.fontSize = fontSize
293
- if (fontFamily) legend.labels.fontFamily = fontFamily
294
- }
295
-
296
- function _setLegendTheme(legend: SceneChart.ChartLegendOptions, theme: SceneChart.Theme, fontColor: string) {
297
- var baseColor = _getBaseColorFromTheme(theme)
298
-
299
- legend.labels = legend.labels ? legend.labels : {}
300
- legend.labels.fontColor = fontColor ? fontColor : baseColor.clone().setAlpha(0.5).toString()
301
- }
302
-
303
- function _getBaseColorFromTheme(theme: SceneChart.Theme) {
304
- let darkColor = '#000'
305
- let lightColor = '#fff'
306
-
307
- var baseColor
308
-
309
- switch (theme) {
310
- case 'light':
311
- baseColor = lightColor
312
- break
313
- case 'dark':
314
- default:
315
- baseColor = darkColor
316
- break
317
- }
318
-
319
- baseColor = new TinyColor(baseColor)
320
-
321
- return baseColor
322
- }
323
-
324
- function _setSeriesConfigures(series: SceneChart.ChartDataSets, chart: SceneChart.ChartConfig) {
325
- var type = series.type || chart.type
326
- var stackGroup = `${type} ${series.yAxisID} ${series.stack || series.dataKey}`
327
- var color = series.color ? series.color : series.backgroundColor
328
-
329
- var dataLabelAnchor = series.dataLabelAnchor || 'center'
330
- var dataLabelOffset = series.dataLabelOffset || 0
331
- var dataLabelRotation = series.dataLabelRotation || 0
332
-
333
- switch (type) {
334
- case 'bar':
335
- case 'horizontalBar':
336
- series.borderColor = series.backgroundColor = color
337
- break
338
-
339
- case 'line':
340
- case 'radar':
341
- color = series.color ? series.color : series.borderColor
342
- series.pointBackgroundColor = series.pointBorderColor = series.borderColor = series.backgroundColor = color
343
- series.pointBorderWidth = (series.borderWidth as number) * 0.5
344
- series.pointHoverRadius = series.pointRadius
345
- if (series.fill == undefined) series.fill = false
346
- break
347
-
348
- default:
349
- series.borderColor = series.backgroundColor = color
350
- break
351
- }
352
-
353
- series.stack = stackGroup
354
-
355
- series.dataLabelAnchor = dataLabelAnchor
356
- series.dataLabelOffset = dataLabelOffset
357
- series.dataLabelRotation = dataLabelRotation
358
- }
359
-
360
- function _appendTickCallback(ticks: SceneChart.TickOptions | undefined) {
361
- if (!ticks) {
362
- return
363
- }
364
-
365
- ticks.callback = function (value, index, values) {
366
- var returnValue
367
- if (!Number.isNaN(Number(value))) {
368
- returnValue = Number(value).toLocaleString()
369
- } else {
370
- returnValue = value
371
- }
372
-
373
- if (returnValue) return returnValue
374
- }
375
- }
376
-
377
- function _setTooltipFont(
378
- tooltips: SceneChart.ChartTooltipOptions,
379
- { fontSize, fontFamily }: { fontSize: number; fontFamily: string }
380
- ) {
381
- tooltips.titleFontSize = tooltips.bodyFontSize = tooltips.footerFontSize = fontSize
382
- if (fontFamily) tooltips.titleFontFamily = tooltips.bodyFontFamily = tooltips.footerFontFamily = fontFamily
383
- }
384
-
385
- function _setTooltipCallback(tooltips: SceneChart.ChartTooltipOptions) {
386
- tooltips.callbacks = tooltips.callbacks || {}
387
-
388
- tooltips.intersect = false
389
- tooltips.mode = 'index'
390
-
391
- tooltips.callbacks.label = function (tooltipItem: SceneChart.ChartTooltipItem, data: SceneChart.ChartData) {
392
- var value: any = data.datasets?.[tooltipItem.datasetIndex || 0].data?.[tooltipItem.index || 0]
393
- var datasetLabel = data.datasets?.[tooltipItem.datasetIndex || 0].label
394
- var label = datasetLabel || data.labels?.[tooltipItem.index || 0]
395
-
396
- var format = data.datasets?.[tooltipItem.datasetIndex || 0].valueFormat || ''
397
- var prefix = data.datasets?.[tooltipItem.datasetIndex || 0].valuePrefix || ''
398
- var suffix = data.datasets?.[tooltipItem.datasetIndex || 0].valueSuffix || ''
399
-
400
- var stringValue = format ? formatText(format, Number(value)) : Number(value).toLocaleString()
401
-
402
- return `${label}: ${prefix + stringValue + suffix}`
403
- }
404
- }
@@ -1,8 +0,0 @@
1
- import '@operato/chart/ox-property-editor-chart.js'
2
-
3
- export default [
4
- {
5
- type: 'chartjs',
6
- element: 'ox-property-editor-chart'
7
- }
8
- ]
package/src/index.ts DELETED
@@ -1,4 +0,0 @@
1
- import 'core-js/stable'
2
- import 'regenerator-runtime/runtime'
3
- import './chartjs'
4
- export default './chartjs'