@kiwibit/chart 20.0.0 → 20.0.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.
@@ -1,488 +0,0 @@
1
- // Angular Imports
2
- import { AfterViewInit, Directive, ElementRef, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
3
- // Kiwi Chart Imports
4
- import { BasePoint, Chart, Point, Shape, ShapeVariant, Trace } from '../models/chart.models';
5
- import { ADD_POINT, RESTORE, SAVE_AS_SVG, ZOOM_IN, ZOOM_OUT } from '../constants/chart.constants';
6
- // Echarts Imports
7
- import * as echarts from 'echarts/core';
8
- import {
9
- ComposeOption,
10
- CustomSeriesOption,
11
- LegendComponentOption,
12
- LineSeriesOption,
13
- ScatterSeriesOption,
14
- ToolboxComponentOption
15
- } from 'echarts/types/dist/shared';
16
- import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, DataZoomComponent, ToolboxComponent, TitleComponentOption, TooltipComponentOption, GridComponentOption, DatasetComponentOption } from 'echarts/components';
17
- import { LineChart, ScatterChart } from 'echarts/charts';
18
- import { CanvasRenderer } from 'echarts/renderers';
19
- echarts.use([
20
- TitleComponent,
21
- TooltipComponent,
22
- GridComponent,
23
- LineChart,
24
- ScatterChart,
25
- CanvasRenderer,
26
- LegendComponent,
27
- DataZoomComponent,
28
- ToolboxComponent,
29
- ]);
30
- export type ECOption = ComposeOption<
31
- | LineSeriesOption
32
- | TitleComponentOption
33
- | TooltipComponentOption
34
- | GridComponentOption
35
- | DatasetComponentOption
36
- | LegendComponentOption
37
- | ToolboxComponentOption
38
- >;
39
-
40
- @Directive({
41
- selector: 'div[kiwi-chart]',
42
- standalone: true
43
- })
44
- export class KiwiChartDirective implements OnChanges, AfterViewInit {
45
-
46
- /**
47
- * The Chart Object rendered by the canvas. For all the available options refer
48
- * to Chart interface in the models folder.
49
- *
50
- * @type {(Chart | null)}
51
- * @memberof KiwiChartDirective
52
- */
53
- @Input({ required: true }) chart: Chart | null = null;
54
-
55
- /**
56
- * Width and Height of the chart area. The dimensions refer to the father component
57
- * into which the kiwi-chart is inserted. For example in an empty page the width/height
58
- * of the chart can take the whole available space in the page.
59
- *
60
- * @type {string}
61
- * @memberof KiwiChartDirective
62
- */
63
- @Input() width: string = '100%';
64
- @Input() height: string = '480px';
65
-
66
- @Output() chartInit = new EventEmitter<echarts.ECharts>();
67
-
68
- /**
69
- * Output event used to emit to the father component the coordinates
70
- * of the point clicked in the chart area. This functionality to be used must
71
- * have the property "clickToAddPoint" in the Chart object set to true.
72
- *
73
- * @type {EventEmitter<BasePoint>}
74
- * @memberof KiwiChartDirective
75
- */
76
- @Output() addPoint: EventEmitter<BasePoint> = new EventEmitter<BasePoint>();
77
-
78
- /**
79
- * When the cursor hovers the chart area it emits to the father component the
80
- * x and y coordinates relative to the chart reference system.
81
- *
82
- * @type {EventEmitter<BasePoint>}
83
- * @memberof KiwiChartDirective
84
- */
85
- @Output() chartHover: EventEmitter<BasePoint> = new EventEmitter<BasePoint>();
86
-
87
- /**
88
- * This property simply activates or not the dark theme of the chart
89
- * defined by the Echarts library. In addition the background color can be custom
90
- * so that the chart can match the background of the application in which it's used.
91
- *
92
- * @type {boolean}
93
- * @memberof KiwiChartDirective
94
- */
95
- @Input() darkTheme: boolean = false;
96
- @Input() darkThemeBackground: string | null = null;
97
-
98
- /**
99
- * The instance of the Chart.
100
- *
101
- * @type {ECharts}
102
- * @memberof KiwiChartDirective
103
- */
104
- echartsInstance: echarts.ECharts | null = null;
105
-
106
- /**
107
- * Default number of decimals that can have
108
- * the values on the x and y axes.
109
- *
110
- * @private
111
- * @type {number}
112
- * @memberof KiwiChartDirective
113
- */
114
- private readonly MAX_DECIMALS: number = 3;
115
-
116
- private legendSelected: { [key: string]: boolean } = {};
117
- private isLegendClicked: boolean = false;
118
-
119
- /**
120
- * Used to perform actions (as point addition based on the cursor position) on the chart.
121
- *
122
- * @type {(zrender.ZRenderType | null)}
123
- * @memberof KiwiChartComponent
124
- */
125
- zr: echarts.zrender.ZRenderType | null = null;
126
-
127
- /**
128
- * If you resize the page, the chart is automatically re-rendered wiht the right proportions.
129
- *
130
- * @memberof EnchartingDirective
131
- */
132
- @HostListener('window:resize', ['$event'])
133
- onResize() {
134
- if (this.echartsInstance) {
135
- this.echartsInstance.resize();
136
- }
137
- }
138
-
139
- constructor(
140
- private el: ElementRef<HTMLDivElement>
141
- ) { }
142
-
143
- ngAfterViewInit(): void {
144
- if (this.chart) {
145
- this.renderChart(this.chart);
146
- }
147
- }
148
-
149
- ngOnChanges(changes: SimpleChanges): void {
150
- let chart: Chart = changes['chart']?.currentValue;
151
- if (this.echartsInstance) {
152
- // Every time we have an external change we
153
- // destroy the chart and re-initialize it
154
- this.echartsInstance.dispose();
155
- this.renderChart(chart);
156
- }
157
- }
158
-
159
- renderChart(chart: Chart): void {
160
- // Update ElementRef styles
161
- this.el.nativeElement.style.width = this.width;
162
- this.el.nativeElement.style.height = this.height;
163
-
164
- this.echartsInstance = echarts.init(
165
- this.el.nativeElement,
166
- this.darkTheme ? 'dark' : 'default',
167
- {
168
- renderer: 'svg'
169
- }
170
- );
171
-
172
- if (chart) {
173
- this.echartsInstance.setOption({
174
- title: {
175
- text: chart.title,
176
- },
177
- grid: {
178
- id: 0,
179
- width: '70%'
180
- },
181
- backgroundColor: this.darkTheme ? this.darkThemeBackground ?? '#303030' : 'transparent', tooltip: {
182
- axisPointer: {
183
- type: 'cross',
184
- crossStyle: {
185
- color: '#bebebe'
186
- }
187
- }
188
- },
189
- toolbox: {
190
- orient: 'horizontal',
191
- left: 'center',
192
- top: '25px',
193
- feature: {
194
- dataZoom: {
195
- brushStyle: {
196
- borderColor: '#000',
197
- borderWidth: 1,
198
- borderType: 'dashed'
199
- },
200
- emphasis: {
201
- iconStyle: {
202
- textPosition: 'top',
203
- textPadding: 5
204
- }
205
- },
206
- icon: {
207
- zoom: ZOOM_IN,
208
- back: ZOOM_OUT
209
- },
210
- },
211
- saveAsImage: {
212
- emphasis: {
213
- iconStyle: {
214
- textPosition: 'top',
215
- textPadding: 5
216
- }
217
- },
218
- icon: SAVE_AS_SVG,
219
- },
220
- restore: {
221
- emphasis: {
222
- iconStyle: {
223
- textPosition: 'top',
224
- textPadding: 5
225
- }
226
- },
227
- icon: RESTORE,
228
- },
229
- myAddPoint: {
230
- show: chart.clickToAddPoint ?? false,
231
- title: chart.addPointCustomName ?? 'Add Point',
232
- icon: ADD_POINT,
233
- onclick: () => {
234
- if (this.echartsInstance) {
235
- const option: ECOption = this.echartsInstance.getOption();
236
- const toolbox = option.toolbox as ToolboxComponentOption[];
237
- if (toolbox) {
238
- const status: boolean = toolbox[0].feature?.['myAddPoint']?.iconStatus;
239
- const offColor: string = 'rgb(102,102,102)';
240
- const highlightColor: string = 'rgb(62,152,197)';
241
- this.echartsInstance.setOption({
242
- toolbox: {
243
- feature: {
244
- myAddPoint: {
245
- iconStatus: !status,
246
- iconStyle: {
247
- borderColor: !status ? highlightColor : offColor
248
- }
249
- }
250
- }
251
- }
252
- });
253
- }
254
- }
255
- },
256
- emphasis: {
257
- iconStyle: {
258
- textPosition: 'top',
259
- textPadding: 5
260
- }
261
- }
262
- }
263
- },
264
- },
265
- dataZoom: [
266
- {
267
- type: 'inside',
268
- xAxisIndex: [0],
269
- throttle: 0,
270
- filterMode: 'none',
271
- disabled: !chart.scrollToZoom
272
- },
273
- {
274
- type: 'inside',
275
- yAxisIndex: [0],
276
- throttle: 0,
277
- filterMode: 'none',
278
- disabled: !chart.scrollToZoom
279
- },
280
- ],
281
- legend: {
282
- inactiveColor: this.darkTheme ? '#8b8b8b' : '#ccc',
283
- data: chart.shapes.map(
284
- (shape: Shape) => ({
285
- name: shape.name,
286
- icon: 'circle',
287
- })
288
- ),
289
- selected: chart.shapes.reduce(
290
- (accumulator, shape: Shape) => ({
291
- ...accumulator,
292
- [shape.name as string]: this.getLegendItemSelection(shape),
293
- }),
294
- {}),
295
- show: chart.showLegend ?? false,
296
- orient: 'vertical',
297
- left: 'right',
298
- padding: [60, 20],
299
- type: 'scroll',
300
- textStyle: {
301
- width: 120,
302
- fontWeight: 'bold',
303
- overflow: 'break'
304
- }
305
- },
306
- xAxis: {
307
- type: chart.xAxisType,
308
- name: chart.xAxisUom ? `${chart.xAxisName} [ ${chart.xAxisUom} ]` : chart.xAxisName,
309
- nameLocation: 'middle',
310
- nameGap: 30,
311
- splitLine: {
312
- show: chart.showGrid ?? true,
313
- lineStyle: {
314
- color: this.darkTheme ? '#595959' : '#ccc'
315
- }
316
- },
317
- min: chart.xMin?.toFixed(chart.maxAxesDecimals ?? this.MAX_DECIMALS),
318
- max: chart.xMax?.toFixed(chart.maxAxesDecimals ?? this.MAX_DECIMALS),
319
- },
320
- yAxis: {
321
- type: chart.yAxisType,
322
- name: chart.yAxisUom ? `${chart.yAxisName} [ ${chart.yAxisUom} ]` : chart.yAxisName,
323
- nameLocation: 'middle',
324
- nameGap: 50,
325
- splitLine: {
326
- show: chart.showGrid ?? true,
327
- lineStyle: {
328
- color: this.darkTheme ? '#595959' : '#ccc'
329
- }
330
- },
331
- min: chart.yMin?.toFixed(chart.maxAxesDecimals ?? this.MAX_DECIMALS),
332
- max: chart.yMax?.toFixed(chart.maxAxesDecimals ?? this.MAX_DECIMALS),
333
- },
334
- series: this.createSeries(chart.shapes),
335
- animation: chart.hasAnimations,
336
- animationDuration: chart.animationDuration ?? 250,
337
- animationEasing: 'cubicOut'
338
- },
339
- true,
340
- true
341
- );
342
- }
343
-
344
- this.setupZrEventHandler(this.echartsInstance);
345
-
346
- this.setupLegendEventHandler(this.echartsInstance);
347
- }
348
-
349
- createSeries(shapes: Shape[]): Array<LineSeriesOption | CustomSeriesOption | ScatterSeriesOption> {
350
- let series: Array<LineSeriesOption | CustomSeriesOption | ScatterSeriesOption> = [];
351
- shapes.forEach(
352
- (shape: Shape) => {
353
- switch (shape.variant) {
354
- case ShapeVariant.TRACE:
355
- series.push(this.createTrace(shape as Trace))
356
- break;
357
- default:
358
- break;
359
- }
360
- }
361
- );
362
- return series;
363
- }
364
-
365
- createTrace(trace: Trace): LineSeriesOption | ScatterSeriesOption {
366
- return {
367
- type: trace.type,
368
- name: trace.name,
369
- data: trace.points.map(
370
- (point: Point) => ({
371
- value: [point.x, point.y],
372
- symbol: point.symbol ?? 'circle',
373
- name: point.name,
374
- symbolSize: point.symbolSize ?? 2,
375
- itemStyle: {
376
- color: point.color
377
- },
378
- emphasis: {
379
- disabled: true
380
- },
381
- label: {
382
- show: true,
383
- position: 'bottom',
384
- align: 'left',
385
- verticalAlign: 'bottom',
386
- formatter: () => `${point.name ?? ''}`,
387
- fontSize: 13,
388
- padding: [0, 0, 0, 10],
389
- width: 100,
390
- overflow: 'truncate',
391
- ellipsis: '...',
392
- fontWeight: 'bold',
393
- color: this.darkTheme ? '#fff' : '#000'
394
- },
395
- tooltip: {
396
- formatter: ({ value }: { value: number[] }) => `
397
- <strong>${this.chart?.xAxisName}:</strong> ${value[0].toFixed(3).replace(/[.,]000$/, "")}
398
- <br>
399
- <strong>${this.chart?.yAxisName}:</strong> ${value[1].toFixed(3).replace(/[.,]000$/, "")}
400
- `
401
- }
402
- })
403
- ),
404
- color: trace.color,
405
- lineStyle: {
406
- width: trace.width,
407
- type: trace.style,
408
- opacity: trace.opacity ?? 1
409
- },
410
- smooth: trace.smooth ?? false
411
- };
412
- }
413
-
414
- getLegendItemSelection(shape: Shape): boolean {
415
- if (this.isLegendClicked) {
416
- return this.legendSelected[shape.name as string] ?? true;
417
- }
418
- else {
419
- return shape.selectedByDefault ?? true
420
- }
421
- }
422
-
423
- /**
424
- * intercept a selection change event on the legend and save the state
425
- * of all selections on the supporting variable legendSelected
426
- *
427
- * @param ec
428
- */
429
- setupLegendEventHandler(ec: echarts.ECharts) {
430
- if (this.echartsInstance != null) {
431
- this.echartsInstance.on('legendselectchanged', (params: any) => {
432
- this.isLegendClicked = true;
433
- this.legendSelected = params.selected;
434
- });
435
- }
436
-
437
- }
438
-
439
- setupZrEventHandler(ec: echarts.ECharts) {
440
- this.zr = ec.getZr();
441
- /**
442
- * Intercepts the click event on the chart (if the clickToAddPoint property is set to true)
443
- * and emits the point coordinates to the father component.
444
- */
445
- this.zr.on('click', params => {
446
- let option: any = ec.getOption();
447
- let active = option?.toolbox?.[0]?.feature?.myAddPoint?.iconStatus;
448
- if (active && this.chart?.clickToAddPoint) {
449
- const pointInPixel = [params.offsetX, params.offsetY];
450
- const pointInGrid = ec.convertFromPixel({gridId: 0}, pointInPixel);
451
- if (ec.containPixel({gridId: 0}, pointInPixel) && pointInGrid) {
452
- let newPoint: { x: number, y: number } = {
453
- x: +pointInGrid[0].toFixed(3),
454
- y: +pointInGrid[1].toFixed(3)
455
- };
456
- this.addPoint.emit(newPoint);
457
- }
458
- }
459
- });
460
- /**
461
- * This is used perform custom actions when the mouse is hovering the chart area
462
- */
463
- this.zr.on('mousemove', params => {
464
- const pointInPixel = [params.offsetX, params.offsetY];
465
- const pointInGrid = ec.convertFromPixel('grid', pointInPixel);
466
- /*
467
- * Logic to emit to the father component the x and y cdinates when the
468
- * cursor is hovering the chart area .
469
- */
470
- if (ec.containPixel('grid', pointInPixel) && pointInGrid) {
471
- let newPoint: { x: number, y: number } = {
472
- x: +pointInGrid[0].toFixed(3),
473
- y: +pointInGrid[1].toFixed(3)
474
- };
475
- this.chartHover.emit(newPoint);
476
- }
477
- /* Logic to change the cursor icon when the "Click to Add Point" feature is active and viceversa. */
478
- const option: any = ec.getOption();
479
- const addPointIsActive = option?.toolbox?.[0]?.feature?.myAddPoint?.iconStatus;
480
- if (addPointIsActive) {
481
- this.zr?.setCursorStyle(
482
- ec.containPixel('grid', pointInPixel) ? 'copy' : 'default'
483
- );
484
- }
485
- });
486
- }
487
-
488
- }
package/src/public-api.ts DELETED
@@ -1,6 +0,0 @@
1
- /*
2
- * Public API Surface of chart
3
- */
4
-
5
- export * from './lib/components/chart.component';
6
- export * from './lib/models/chart.models';
package/src/test.ts DELETED
@@ -1,15 +0,0 @@
1
- // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2
-
3
- import 'zone.js';
4
- import 'zone.js/testing';
5
- import { getTestBed } from '@angular/core/testing';
6
- import {
7
- BrowserDynamicTestingModule,
8
- platformBrowserDynamicTesting
9
- } from '@angular/platform-browser-dynamic/testing';
10
-
11
- // First, initialize the Angular testing environment.
12
- getTestBed().initTestEnvironment(
13
- BrowserDynamicTestingModule,
14
- platformBrowserDynamicTesting(),
15
- );
package/tsconfig.lib.json DELETED
@@ -1,15 +0,0 @@
1
- /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
- {
3
- "extends": "../../../tsconfig.json",
4
- "compilerOptions": {
5
- "outDir": "../../../out-tsc/lib",
6
- "declaration": true,
7
- "declarationMap": true,
8
- "inlineSources": true,
9
- "types": []
10
- },
11
- "exclude": [
12
- "src/test.ts",
13
- "**/*.spec.ts"
14
- ]
15
- }
@@ -1,10 +0,0 @@
1
- /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
- {
3
- "extends": "./tsconfig.lib.json",
4
- "compilerOptions": {
5
- "declarationMap": false
6
- },
7
- "angularCompilerOptions": {
8
- "compilationMode": "partial"
9
- }
10
- }
@@ -1,17 +0,0 @@
1
- /* To learn more about this file see: https://angular.io/config/tsconfig. */
2
- {
3
- "extends": "../../../tsconfig.json",
4
- "compilerOptions": {
5
- "outDir": "../../../out-tsc/spec",
6
- "types": [
7
- "jasmine"
8
- ]
9
- },
10
- "files": [
11
- "src/test.ts"
12
- ],
13
- "include": [
14
- "**/*.spec.ts",
15
- "**/*.d.ts"
16
- ]
17
- }