@dataloop-ai/components 0.17.95 → 0.17.97

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dataloop-ai/components",
3
- "version": "0.17.95",
3
+ "version": "0.17.97",
4
4
  "exports": {
5
5
  ".": "./index.ts",
6
6
  "./models": "./models.ts",
@@ -0,0 +1,667 @@
1
+ <template>
2
+ <div
3
+ :style="cssVars"
4
+ :class="chartWrapperClasses"
5
+ >
6
+ <DLScatter
7
+ :id="id"
8
+ ref="scatterChart"
9
+ :class="chartClasses"
10
+ :style="(chartStyles, `max-height: ${wrapperHeight}`)"
11
+ :data="chartData"
12
+ :options="chartOptions"
13
+ @mouseout="onChartLeave"
14
+ />
15
+ <slot
16
+ v-if="displayLabels"
17
+ v-bind="{ ...labelStyles, labels: xLabels, chartWidth }"
18
+ name="axe-x-labels"
19
+ >
20
+ <dl-chart-labels
21
+ :font-size="labelStyles.fontSize"
22
+ :title="labelStyles.title"
23
+ :title-size="labelStyles.titleSize"
24
+ :title-color="labelStyles.titleColor"
25
+ :label-color="labelStyles.labelColor"
26
+ :width="chartWidth"
27
+ :labels="xLabels"
28
+ />
29
+ </slot>
30
+ <slot
31
+ v-if="displayBrush"
32
+ v-bind="{
33
+ chartWidth,
34
+ modelValue: brush.value,
35
+ handleBrushUpdate,
36
+ brushClasses,
37
+ ...brushProperties
38
+ }"
39
+ name="brush"
40
+ >
41
+ <dl-brush
42
+ :model-value="brush.value"
43
+ :width="chartWidth"
44
+ :min="brushProperties.min"
45
+ :max="brushProperties.max"
46
+ :class="brushClasses"
47
+ :thumb-size="brushProperties.thumbSize"
48
+ :track-size="brushProperties.trackSize"
49
+ :step="brushProperties.step"
50
+ :drag-range="brushProperties.dragRange"
51
+ @update:model-value="handleBrushUpdate"
52
+ />
53
+ </slot>
54
+ <slot
55
+ v-if="displayLegend"
56
+ v-bind="{
57
+ data: legendDatasets,
58
+ chartWidth,
59
+ onHide: hideData,
60
+ onHoverLegend,
61
+ onLeaveLegend,
62
+ ...legendProperties
63
+ }"
64
+ name="legend"
65
+ >
66
+ <dl-chart-legend
67
+ :datasets="legendDatasets"
68
+ :width="chartWidth"
69
+ :class="legendClasses"
70
+ :align-items="legendProperties.alignItems"
71
+ @hide="hideData"
72
+ @on-hover="onHoverLegend"
73
+ @on-leave="onLeaveLegend"
74
+ />
75
+ </slot>
76
+ </div>
77
+ </template>
78
+
79
+ <script lang="ts">
80
+ import { Scatter as DLScatter } from '../../types/typedCharts'
81
+ import {
82
+ CommonProps,
83
+ ColumnChartProps,
84
+ defaultLineChartProps
85
+ } from '../../types/props'
86
+ import { defineComponent, reactive, watch, ref, computed } from 'vue-demi'
87
+ import DlBrush from '../../components/DlBrush.vue'
88
+ import DlChartLegend from '../../components/DlChartLegend.vue'
89
+ import DlChartLabels from '../../components/DlChartLabels.vue'
90
+ import { updateKeys } from '../../../../../utils/update-key'
91
+ import { hexToRgbA } from '../../../../../utils'
92
+ import {
93
+ Chart as ChartJS,
94
+ Title,
95
+ Tooltip,
96
+ Legend,
97
+ BarElement,
98
+ CategoryScale,
99
+ LinearScale,
100
+ PointElement,
101
+ LineElement,
102
+ BarControllerDatasetOptions,
103
+ TimeScale
104
+ } from 'chart.js'
105
+ import type {
106
+ Chart,
107
+ ChartMeta,
108
+ ChartDataset,
109
+ ActiveElement,
110
+ ChartData,
111
+ DatasetController,
112
+ ScatterControllerDatasetOptions
113
+ } from 'chart.js'
114
+ import { orderBy, merge, isEqual, unionBy, cloneDeep } from 'lodash'
115
+ import { useThemeVariables } from '../../../../../hooks/use-theme'
116
+
117
+ ChartJS.register(
118
+ Title,
119
+ Tooltip,
120
+ Legend,
121
+ BarElement,
122
+ CategoryScale,
123
+ LinearScale,
124
+ PointElement,
125
+ LineElement,
126
+ TimeScale
127
+ )
128
+
129
+ export default defineComponent({
130
+ name: 'DlScatterChart',
131
+ components: {
132
+ DlBrush,
133
+ DlChartLegend,
134
+ DLScatter,
135
+ DlChartLabels
136
+ },
137
+ props: {
138
+ id: {
139
+ type: String,
140
+ default: null
141
+ },
142
+ ...CommonProps,
143
+ ...ColumnChartProps
144
+ },
145
+ setup(props, { slots }) {
146
+ const { variables } = useThemeVariables()
147
+
148
+ const chartWidth = ref('100%')
149
+
150
+ const chartHoverDataset: { value: null | ChartMeta } = {
151
+ value: null
152
+ }
153
+
154
+ const onResize = (
155
+ chart: Chart,
156
+ size: { height: number; width: number }
157
+ ) => {
158
+ if (chart?.scales?.x?.width) {
159
+ chartWidth.value = `${
160
+ parseInt(chart.scales.x.width as unknown as string) -
161
+ parseInt(brushProperties.value.thumbSize) / 4
162
+ }px`
163
+ }
164
+ }
165
+
166
+ const chart = computed(() => {
167
+ return scatterChart.value?.chart?.value || {}
168
+ })
169
+
170
+ const replaceColor = (key: keyof typeof variables) =>
171
+ variables[key] || key
172
+
173
+ const scatterChart = ref(null)
174
+
175
+ const brush = reactive({
176
+ value: {
177
+ min: 0,
178
+ max:
179
+ props.data.datasets.length > 0
180
+ ? orderBy(props.data.datasets, (o) => o.data.length)[0]
181
+ .data.length - 1
182
+ : 1
183
+ }
184
+ })
185
+
186
+ const getChartBackup = () => {
187
+ if (!chart.value) {
188
+ return {
189
+ data: {},
190
+ options: {}
191
+ }
192
+ }
193
+ const datasets: DatasetController<'scatter'> = updateKeys(
194
+ props.data.datasets,
195
+ [
196
+ 'backgroundColor',
197
+ 'pointBackgroundColor',
198
+ 'pointBorderColor',
199
+ 'borderColor',
200
+ 'hoverBorderColor',
201
+ 'hoverBackgroundColor',
202
+ 'pointHoverBackgroundColor',
203
+ 'pointHoverBorderColor'
204
+ ],
205
+ replaceColor
206
+ ).map((item: ScatterControllerDatasetOptions) => {
207
+ return {
208
+ ...item,
209
+ hoverBackgroundColor:
210
+ item.hoverBackgroundColor ||
211
+ hexToRgbA(item.backgroundColor as string, 0.2),
212
+ hoverBorderColor:
213
+ item.hoverBorderColor ||
214
+ hexToRgbA(item.backgroundColor as string, 0.2)
215
+ }
216
+ })
217
+
218
+ const chartProps = cloneDeep({
219
+ options: props.options,
220
+ data: {
221
+ ...props.data,
222
+ datasets
223
+ }
224
+ })
225
+
226
+ return chartProps
227
+ }
228
+
229
+ const chartWrapperClasses = computed(() => {
230
+ const classes = 'dl-scatter-chart-wrapper'
231
+
232
+ if (props.rootClass) {
233
+ classes.concat(' ', props.rootClass)
234
+ }
235
+
236
+ return classes
237
+ })
238
+
239
+ const chartClasses = computed(() => {
240
+ const classes = 'dl-scatter-chart'
241
+
242
+ if (props.chartClass) {
243
+ classes.concat(' ', props.chartClass)
244
+ }
245
+
246
+ return classes
247
+ })
248
+
249
+ const brushClasses = computed(() => {
250
+ const classes = 'dl-brush'
251
+
252
+ if (props.brushClass) {
253
+ classes.concat(' ', props.brushClass)
254
+ }
255
+
256
+ return classes
257
+ })
258
+
259
+ const legendClasses = computed(() => {
260
+ const classes = 'dl-legend'
261
+
262
+ if (props.legendClass) {
263
+ classes.concat(' ', props.legendClass)
264
+ }
265
+
266
+ return classes
267
+ })
268
+
269
+ const brushProperties = computed(() => {
270
+ return merge(defaultLineChartProps.brushProps, props.brushProps)
271
+ })
272
+
273
+ const legendProperties = computed(() => {
274
+ return merge(defaultLineChartProps.legendProps, props.legendProps)
275
+ })
276
+
277
+ const cssVars = computed(() => {
278
+ return {
279
+ '--dl-brush-thumb-size':
280
+ parseInt(brushProperties.value.thumbSize) / 4 + 'px'
281
+ }
282
+ })
283
+
284
+ const replaceDataColors = (data: ChartData) =>
285
+ updateKeys(
286
+ data,
287
+ [
288
+ 'backgroundColor',
289
+ 'pointBackgroundColor',
290
+ 'pointBorderColor',
291
+ 'borderColor',
292
+ 'hoverBorderColor',
293
+ 'hoverBackgroundColor',
294
+ 'pointHoverBackgroundColor',
295
+ 'pointHoverBorderColor'
296
+ ],
297
+ replaceColor
298
+ )
299
+
300
+ const chartData = ref(replaceDataColors(props.data))
301
+
302
+ const legendDatasets = ref(
303
+ unionBy(
304
+ props.legendProps?.datasets || [],
305
+ props.data?.datasets || [],
306
+ 'label'
307
+ )
308
+ )
309
+
310
+ const onChartLeave = () => {
311
+ if (chartHoverDataset.value) {
312
+ const filteredItems = chart.value.data.datasets
313
+ .map((d: ChartDataset, i: number) => ({
314
+ ...d,
315
+ index: i
316
+ }))
317
+ .filter(
318
+ (dataset: ChartDataset) =>
319
+ dataset.label !== chartHoverDataset.value.label
320
+ )
321
+
322
+ const backup = getChartBackup()
323
+
324
+ for (const dataset of filteredItems) {
325
+ chart.value.data.datasets[dataset.index].backgroundColor = (
326
+ backup.data as ChartData<'scatter'>
327
+ ).datasets[dataset.index].backgroundColor
328
+ chart.value.data.datasets[dataset.index].borderColor = (
329
+ backup.data as ChartData<'scatter'>
330
+ ).datasets[dataset.index].borderColor
331
+ }
332
+ chartHoverDataset.value = null
333
+
334
+ chart.value.update()
335
+ }
336
+ }
337
+
338
+ const onHover = (
339
+ event: Event,
340
+ items: ActiveElement[],
341
+ chartJS: Chart
342
+ ) => {
343
+ if (event.type !== 'mousemove') {
344
+ return
345
+ }
346
+ if (
347
+ items.length === 0 ||
348
+ chartJS.getElementsAtEventForMode(
349
+ event,
350
+ 'nearest',
351
+ {
352
+ intersect: true
353
+ },
354
+ true
355
+ ).length === 0
356
+ ) {
357
+ if (chartHoverDataset.value) {
358
+ const filteredItems = chartJS.data.datasets
359
+ .map((d: ChartDataset, i: number) => ({
360
+ ...d,
361
+ index: i
362
+ }))
363
+ .filter(
364
+ (dataset: ChartDataset) =>
365
+ dataset.label !== chartHoverDataset.value.label
366
+ )
367
+ const backup = getChartBackup()
368
+ for (const dataset of filteredItems) {
369
+ chartJS.data.datasets[dataset.index].backgroundColor = (
370
+ backup.data as ChartData<'scatter'>
371
+ ).datasets[dataset.index].backgroundColor
372
+
373
+ chartJS.data.datasets[dataset.index].borderColor = (
374
+ backup.data as ChartData<'scatter'>
375
+ ).datasets[dataset.index].borderColor
376
+ }
377
+
378
+ chartHoverDataset.value = null
379
+
380
+ chartJS.update()
381
+ }
382
+ return
383
+ } else {
384
+ const item = items[0]
385
+ const datasetItem = chartJS.getDatasetMeta(item.datasetIndex)
386
+ if (!chartHoverDataset.value) {
387
+ const filteredDatasets = chartJS.data.datasets
388
+ .map((d: ChartDataset, i: number) => ({
389
+ ...d,
390
+ index: i
391
+ }))
392
+ .filter(
393
+ (ds: ChartDataset) => ds.label !== datasetItem.label
394
+ )
395
+ for (const dataset of filteredDatasets) {
396
+ chartJS.data.datasets[dataset.index].backgroundColor =
397
+ hexToRgbA(dataset.backgroundColor as string, 0.2)
398
+
399
+ chart.value.data.datasets[dataset.index].borderColor =
400
+ dataset?.hoverBorderColor ||
401
+ hexToRgbA(dataset.backgroundColor as string, 0.2)
402
+ }
403
+
404
+ chartHoverDataset.value = datasetItem
405
+
406
+ chartJS.update()
407
+
408
+ return
409
+ }
410
+ if (!isEqual(chartHoverDataset.value, datasetItem)) {
411
+ const filteredItems = chartJS.data.datasets
412
+ .map((d: ChartDataset, i: number) => ({
413
+ ...d,
414
+ index: i
415
+ }))
416
+ .filter(
417
+ (dataset: ChartDataset) =>
418
+ dataset.label !== chartHoverDataset.value.label
419
+ )
420
+
421
+ const backup = getChartBackup()
422
+ for (const dataset of filteredItems) {
423
+ chartJS.data.datasets[dataset.index].backgroundColor = (
424
+ backup.data as ChartData<'scatter'>
425
+ ).datasets[dataset.index].backgroundColor
426
+
427
+ chartJS.data.datasets[dataset.index].borderColor = (
428
+ backup.data as ChartData<'scatter'>
429
+ ).datasets[dataset.index].borderColor
430
+ }
431
+ chartHoverDataset.value = datasetItem
432
+ const allFilteredItems = chartJS.data.datasets
433
+ .map((d: ChartDataset, i: number) => ({
434
+ ...d,
435
+ index: i
436
+ }))
437
+ .filter(
438
+ (dataset: ChartDataset) =>
439
+ dataset.label !== datasetItem.label
440
+ )
441
+ for (const dataset of allFilteredItems) {
442
+ chartJS.data.datasets[dataset.index].backgroundColor =
443
+ hexToRgbA(dataset.backgroundColor as string, 0.2)
444
+ }
445
+ chartJS.update()
446
+ }
447
+ }
448
+ }
449
+
450
+ const chartOptions = reactive(
451
+ updateKeys(
452
+ merge(
453
+ { onResize, onHover },
454
+ defaultLineChartProps.options,
455
+ props.options
456
+ ),
457
+ ['color'],
458
+ replaceColor
459
+ )
460
+ )
461
+
462
+ watch(
463
+ () => chart.value?.scales?.x?.width,
464
+ (val: string) => {
465
+ if (val) {
466
+ chartWidth.value = `${
467
+ parseInt(val as unknown as string) -
468
+ parseInt(brushProperties.value.thumbSize) / 4
469
+ }px`
470
+ }
471
+ },
472
+ { deep: true }
473
+ )
474
+
475
+ const handleBrushUpdate = (value: { min: number; max: number }) => {
476
+ brush.value.min = value.min
477
+ brush.value.max = value.max
478
+
479
+ chart.value.options.scales.x.min = value.min
480
+ chart.value.options.scales.x.max = value.max
481
+
482
+ xLabels.value = chart.value.data.labels.slice(
483
+ value.min,
484
+ value.max + brushProperties.value.step
485
+ )
486
+
487
+ chart.value.update()
488
+ }
489
+
490
+ const xLabels = ref(props.data.labels)
491
+
492
+ const onHoverLegend = (
493
+ item: BarControllerDatasetOptions,
494
+ index: number
495
+ ) => {
496
+ const filteredItems = chart.value.data.datasets
497
+ .map((d: ChartDataset, i: number) => ({
498
+ ...d,
499
+ index: i
500
+ }))
501
+ .filter(
502
+ (dataset: ChartDataset & { index: number }) =>
503
+ dataset.index! !== index
504
+ )
505
+
506
+ for (const dataset of filteredItems) {
507
+ chart.value.data.datasets[dataset.index].backgroundColor =
508
+ dataset?.hoverBackgroundColor ||
509
+ hexToRgbA(dataset.backgroundColor, 0.2)
510
+
511
+ chart.value.data.datasets[dataset.index].borderColor =
512
+ dataset?.hoverBorderColor ||
513
+ hexToRgbA(dataset.backgroundColor, 0.2)
514
+ }
515
+
516
+ chart.value.update()
517
+ }
518
+
519
+ const onLeaveLegend = (
520
+ item: BarControllerDatasetOptions,
521
+ index: number
522
+ ) => {
523
+ const filteredItems = chart.value.data.datasets
524
+ .map((d: ChartDataset, i: number) => ({
525
+ ...d,
526
+ index: i
527
+ }))
528
+ .filter(
529
+ (dataset: ChartDataset & { index: number }) =>
530
+ dataset.index !== index
531
+ )
532
+
533
+ const backup = getChartBackup()
534
+
535
+ for (const dataset of filteredItems) {
536
+ chart.value.data.datasets[dataset.index].backgroundColor = (
537
+ backup.data as ChartData<'scatter'>
538
+ ).datasets[dataset.index].backgroundColor
539
+
540
+ chart.value.data.datasets[dataset.index].borderColor = (
541
+ backup.data as ChartData<'scatter'>
542
+ ).datasets[dataset.index].borderColor
543
+ }
544
+ chart.value.update()
545
+ }
546
+
547
+ const labelStyles = computed(() => {
548
+ const options = merge(
549
+ {},
550
+ defaultLineChartProps.options,
551
+ props.options
552
+ )
553
+
554
+ return {
555
+ title: options.scales.x.title.text,
556
+ titleSize: `${options.scales.x.title.font.size}px`,
557
+ titleColor: options.scales.x.title.color.replace('--', ''),
558
+ labelColor: options.scales.x.ticks.color.replace('--', ''),
559
+ fontSize: `${options.scales.x.ticks.font.size}px`
560
+ }
561
+ })
562
+
563
+ const hideData = (item: BarControllerDatasetOptions, index: number) => {
564
+ onLeaveLegend(item, index)
565
+
566
+ chart.value.data.datasets[index].hidden = !!item.hidden
567
+
568
+ legendDatasets.value.splice(index, 1, {
569
+ ...legendDatasets.value[index],
570
+ hidden: !!item.hidden
571
+ })
572
+
573
+ chart.value.update()
574
+ }
575
+
576
+ watch(variables, () => {
577
+ merge(chart.value.data, getChartBackup().data)
578
+
579
+ merge(
580
+ chart.value.options,
581
+ updateKeys(
582
+ merge(
583
+ { onResize, onHover },
584
+ defaultLineChartProps.options,
585
+ props.options
586
+ ),
587
+ ['color'],
588
+ replaceColor
589
+ )
590
+ )
591
+
592
+ chart.value.options.scales.x.min = brush.value.min
593
+ chart.value.options.scales.x.max = brush.value.max
594
+
595
+ chart.value.update()
596
+ })
597
+
598
+ watch(
599
+ [props.data, props.options],
600
+ ([newData = {}, newOptions = {}]) => {
601
+ chartData.value = replaceDataColors(newData as ChartData)
602
+
603
+ xLabels.value = (newData as ChartData)?.labels
604
+
605
+ chartOptions.value = updateKeys(
606
+ merge(
607
+ { onResize, onHover },
608
+ defaultLineChartProps.options,
609
+ newOptions
610
+ ),
611
+ ['color'],
612
+ replaceColor
613
+ )
614
+ },
615
+ { deep: true }
616
+ )
617
+
618
+ return {
619
+ variables,
620
+ chartData,
621
+ chartOptions,
622
+ brush,
623
+ xLabels,
624
+ scatterChart,
625
+ handleBrushUpdate,
626
+ chartWrapperClasses,
627
+ chartClasses,
628
+ brushClasses,
629
+ legendClasses,
630
+ brushProperties,
631
+ legendDatasets,
632
+ legendProperties,
633
+ hideData,
634
+ chartWidth,
635
+ onHoverLegend,
636
+ onLeaveLegend,
637
+ onChartLeave,
638
+ chart,
639
+ labelStyles,
640
+ cssVars
641
+ }
642
+ }
643
+ })
644
+ </script>
645
+
646
+ <style scoped lang="scss">
647
+ .dl-scatter-chart-wrapper {
648
+ display: flex;
649
+ flex-direction: column;
650
+ align-self: stretch;
651
+ }
652
+
653
+ .dl-brush {
654
+ margin-top: 10px;
655
+ }
656
+
657
+ .dl-legend {
658
+ margin-top: 16px;
659
+ margin-bottom: 16px;
660
+ }
661
+
662
+ .dl-brush,
663
+ .dl-legend {
664
+ align-self: flex-end;
665
+ margin-right: var(--dl-brush-thumb-size);
666
+ }
667
+ </style>
@@ -0,0 +1,2 @@
1
+ import DlScatterChart from './DlScatterChart.vue'
2
+ export { DlScatterChart }
@@ -2,4 +2,5 @@ export * from './DlBarChart'
2
2
  export * from './DlColumnChart'
3
3
  export * from './DlDoughnutChart'
4
4
  export * from './DlLineChart'
5
+ export * from './DlScatterChart'
5
6
  export * from './DlConfusionMatrix'
@@ -0,0 +1,161 @@
1
+ <template>
2
+ <div
3
+ style="
4
+ display: flex;
5
+ width: 1000px;
6
+ flex-wrap: wrap;
7
+ flex-direction: row;
8
+ gap: 0;
9
+ "
10
+ >
11
+ <dl-scatter-chart
12
+ id="example-one"
13
+ :brush-props="brushProps"
14
+ :legend-props="legendProps"
15
+ :data="data"
16
+ :options="options"
17
+ style="width: 100%"
18
+ />
19
+ </div>
20
+ </template>
21
+
22
+ <script lang="ts">
23
+ import { defineComponent } from 'vue-demi'
24
+ import { DlScatterChart } from '../components'
25
+ import { orderBy } from 'lodash'
26
+
27
+ const data = {
28
+ labels: [
29
+ {
30
+ title: '0.1'
31
+ },
32
+ {
33
+ title: '0.2'
34
+ },
35
+ {
36
+ title: '0.3'
37
+ },
38
+ {
39
+ title: '0.4'
40
+ },
41
+ {
42
+ title: '0.5'
43
+ },
44
+ {
45
+ title: '0.6'
46
+ },
47
+ {
48
+ title: '0.7'
49
+ },
50
+ {
51
+ title: '0.8'
52
+ },
53
+ {
54
+ title: '0.9'
55
+ },
56
+ {
57
+ title: '1'
58
+ }
59
+ ],
60
+ datasets: [
61
+ {
62
+ label: 'Scatter Dataset',
63
+ data: [
64
+ { x: 0.1, y: 0.1 },
65
+ { x: 0.2, y: 0.1 },
66
+ { x: 0.3, y: 0.2 },
67
+ { x: 0.4, y: 0.3 },
68
+ { x: 0.5, y: 0.35 },
69
+ { x: 0.6, y: 0.39 },
70
+ { x: 0.7, y: 0.4 },
71
+ { x: 0.8, y: 0.8 },
72
+ { x: 0.9, y: 0.8 }
73
+ ],
74
+ backgroundColor: 'rgb(255, 99, 132)',
75
+ borderColor: 'rgba(255, 99, 132, 1)',
76
+ pointRadius: 5,
77
+ showLine: true
78
+ },
79
+ {
80
+ label: 'Dataset 2',
81
+ data: [
82
+ { x: 0.2, y: 0.1 },
83
+ { x: 0.2, y: 0.2 },
84
+ { x: 0.4, y: 0.2 },
85
+ { x: 0.4, y: 0.3 },
86
+ { x: 0.6, y: 0.65 },
87
+ { x: 0.6, y: 0.85 },
88
+ { x: 0.8, y: 0.6 },
89
+ { x: 0.8, y: 0.7 },
90
+ { x: 0.9, y: 0.8 }
91
+ ],
92
+ backgroundColor: 'rgba(45, 162, 50, 1)',
93
+ borderColor: 'rgba(45, 162, 50, 1)',
94
+ pointRadius: 5,
95
+ showLine: true
96
+ }
97
+ ]
98
+ }
99
+
100
+ const brushProps = {
101
+ min: 0,
102
+ max: orderBy(data.datasets, (o) => o.data.length)[0].data.length - 1
103
+ }
104
+
105
+ const options = {
106
+ scales: {
107
+ x: {
108
+ type: 'linear',
109
+ position: 'bottom',
110
+ axis: 'Recall',
111
+ scaleLabel: {
112
+ display: true,
113
+ labelString: 'Recall'
114
+ }
115
+ },
116
+ y: {
117
+ type: 'linear',
118
+ position: 'left',
119
+ axis: 'Precision',
120
+ scaleLabel: {
121
+ display: true,
122
+ labelString: 'Precision'
123
+ }
124
+ }
125
+ }
126
+ }
127
+
128
+ const legendProps = {
129
+ alignItems: 'center'
130
+ }
131
+
132
+ export default defineComponent({
133
+ name: 'DlScatterChartDemo',
134
+ components: {
135
+ DlScatterChart
136
+ },
137
+ data() {
138
+ return {
139
+ resolution: 'hour',
140
+ options,
141
+ data,
142
+ brushProps,
143
+ legendProps,
144
+ noPointsData: {
145
+ ...data,
146
+ datasets: [
147
+ { ...data.datasets[0], pointRadius: 0, borderWidth: 1 }
148
+ ]
149
+ },
150
+ tensionLineData: {
151
+ ...data,
152
+ datasets: [{ ...data.datasets[1], pointRadius: 0 }]
153
+ },
154
+ tensionOptions: { ...options, tension: 0.5 }
155
+ }
156
+ },
157
+ methods: {}
158
+ })
159
+ </script>
160
+
161
+ <style scoped lang="scss"></style>
@@ -46,6 +46,7 @@ import DlSwitchDemo from './DlSwitchDemo.vue'
46
46
  import DlToastDemo from './DlToastDemo.vue'
47
47
  import DlChartDoughnutDemo from './DlChartDoughnutDemo.vue'
48
48
  import DlLineChartDemo from './DlLineChartDemo.vue'
49
+ import DlScatterChartDemo from './DlScatterChartDemo.vue'
49
50
  import DlSpinner from './DlSpinnerDemo.vue'
50
51
  import DlConfusionMatrix from './DlConfusionMatrixDemo.vue'
51
52
  import DlToggleButtonDemo from './DlToggleButtonDemo.vue'
@@ -107,6 +108,7 @@ export default {
107
108
  DlChartDoughnutDemo,
108
109
  DlBarChartDemo,
109
110
  DlLineChartDemo,
111
+ DlScatterChartDemo,
110
112
  DlSpinner,
111
113
  DlConfusionMatrix,
112
114
  DlToggleButtonDemo,