@dataloop-ai/components 0.16.45 → 0.16.47

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 (145) hide show
  1. package/.eslintrc.js +2 -2
  2. package/package.json +10 -9
  3. package/src/App.vue +120 -58
  4. package/src/assets/globals.scss +2 -0
  5. package/src/components/basic/DlAlert/DlAlert.vue +1 -1
  6. package/src/components/basic/DlButton/DlButton.vue +13 -13
  7. package/src/components/basic/DlCard/DlCard.vue +234 -0
  8. package/src/components/basic/DlCard/index.ts +3 -0
  9. package/src/components/basic/DlCard/types.ts +20 -0
  10. package/src/components/basic/DlChip/DlChip.vue +1 -0
  11. package/src/components/basic/DlEllipsis/DlEllipsis.vue +90 -0
  12. package/src/components/basic/DlEllipsis/index.ts +2 -0
  13. package/src/components/basic/DlListItem/DlListItem.vue +11 -5
  14. package/src/components/basic/index.ts +2 -0
  15. package/src/components/compound/DlCharts/charts/DlBarChart/DlBarChart.vue +8 -1
  16. package/src/components/compound/DlCharts/charts/DlColumnChart/DlColumnChart.vue +22 -6
  17. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/DlConfusionMatrix.vue +542 -0
  18. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/index.ts +2 -0
  19. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/utils.ts +96 -0
  20. package/src/components/compound/DlCharts/charts/DlDoughnutChart/DlDoughnutChart.vue +2 -2
  21. package/src/components/compound/DlCharts/charts/DlLineChart/DlLineChart.vue +22 -6
  22. package/src/components/compound/DlCharts/charts/index.ts +1 -0
  23. package/src/components/compound/DlCharts/components/DlBrush.vue +8 -1
  24. package/src/components/compound/DlCharts/components/DlChartScrollBar.vue +34 -21
  25. package/src/components/compound/DlCharts/types/DlConfusionMatrix.types.ts +19 -0
  26. package/src/components/compound/DlCharts/types/index.ts +2 -1
  27. package/src/components/compound/DlCharts/types/props.ts +14 -0
  28. package/src/components/compound/DlDialogBox/DlDialogBox.vue +1 -1
  29. package/src/components/compound/DlDialogBox/components/DlDialogBoxFooter.vue +1 -0
  30. package/src/components/compound/DlDropdownButton/DlDropdownButton.vue +58 -12
  31. package/src/components/compound/DlInput/DlInput.vue +45 -23
  32. package/src/components/compound/DlJsonEditor/DlJsonEditor.vue +13 -29
  33. package/src/components/compound/DlPagination/DlPagination.vue +14 -4
  34. package/src/components/compound/DlPagination/components/PageNavigation.vue +24 -25
  35. package/src/components/compound/DlPagination/components/PaginationLegend.vue +2 -1
  36. package/src/components/compound/DlPagination/components/QuickNavigation.vue +1 -0
  37. package/src/components/compound/DlSearches/DlSmartSearch/DlSmartSearch.vue +86 -49
  38. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchInput.vue +86 -69
  39. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSuggestionsDropdown.vue +43 -4
  40. package/src/components/compound/DlSearches/DlSmartSearch/utils/highlightSyntax.ts +1 -55
  41. package/src/components/compound/DlSearches/DlSmartSearch/utils/index.ts +42 -10
  42. package/src/components/compound/DlSearches/DlSmartSearch/utils/utils.ts +107 -0
  43. package/src/components/compound/DlSelect/DlSelect.vue +41 -8
  44. package/src/components/compound/DlTable/DlTable.vue +13 -10
  45. package/src/components/compound/DlTable/styles/dl-table-styles.scss +16 -4
  46. package/src/components/compound/DlToggleButton/DlToggleButton.vue +109 -0
  47. package/src/components/compound/DlToggleButton/config.ts +27 -0
  48. package/src/components/compound/DlToggleButton/index.ts +3 -0
  49. package/src/components/compound/DlToggleButton/types.ts +4 -0
  50. package/src/components/compound/index.ts +1 -0
  51. package/src/components/compound/types.ts +1 -0
  52. package/src/components/essential/DlColorPicker/DlColorPicker.vue +4 -1
  53. package/src/components/essential/DlColorPicker/components/DlColors.vue +2 -6
  54. package/src/components/essential/DlIcon/DlIcon.vue +5 -1
  55. package/src/components/essential/DlMenu/DlMenu.vue +30 -2
  56. package/src/components/essential/DlSeparator/DlSeparator.vue +66 -0
  57. package/src/components/essential/DlSeparator/index.ts +2 -0
  58. package/src/components/essential/DlSpinner/DlSpinner.vue +53 -217
  59. package/src/components/essential/DlSpinner/components/DlSpinnerCircle.vue +156 -0
  60. package/src/components/essential/DlSpinner/components/DlSpinnerClock.vue +191 -0
  61. package/src/components/essential/DlSpinner/components/DlSpinnerDots.vue +225 -0
  62. package/src/components/essential/DlSpinner/components/DlSpinnerGrid.vue +278 -0
  63. package/src/components/essential/DlSpinner/components/DlSpinnerLogo.vue +264 -0
  64. package/src/components/essential/DlSpinner/index.ts +14 -1
  65. package/src/components/essential/DlSpinner/types.ts +7 -0
  66. package/src/components/essential/index.ts +1 -0
  67. package/src/components/essential/types.ts +1 -0
  68. package/src/components/shared/DlItemSection/DlItemSection.vue +21 -15
  69. package/src/components/shared/DlVirtualScroll/DlVirtualScroll.vue +36 -21
  70. package/src/components/shared/DlVirtualScroll/useVirtualScroll.ts +8 -10
  71. package/src/{demo → demos}/DlButtonDemo.vue +15 -0
  72. package/src/demos/DlCardDemo.vue +47 -0
  73. package/src/{demo → demos}/DlColorPickerDemo.vue +16 -1
  74. package/src/demos/DlConfusionMatrixDemo.vue +53 -0
  75. package/src/{demo → demos}/DlDialogBoxDemo.vue +4 -1
  76. package/src/demos/DlDropdownButtonDemo.vue +386 -0
  77. package/src/demos/DlEllipsisDemo.vue +30 -0
  78. package/src/{demo → demos}/DlLineChartDemo.vue +8 -8
  79. package/src/{demo → demos}/DlMenuDemo.vue +61 -2
  80. package/src/{demo → demos}/DlSearchDemo.vue +3 -2
  81. package/src/demos/DlSeparatorDemo.vue +44 -0
  82. package/src/demos/DlSpinnerDemo.vue +59 -0
  83. package/src/{demo → demos}/DlTableDemo.vue +117 -29
  84. package/src/demos/DlToggleButtonDemo.vue +55 -0
  85. package/src/{demo → demos}/DlTooltipDemo.vue +43 -2
  86. package/src/{demo → demos}/DlWidgetDemo.vue +34 -19
  87. package/src/{demo → demos}/SmartSearchDemo/DlSmartSearchDemo.vue +2 -50
  88. package/src/{demo → demos}/index.ts +14 -56
  89. package/src/hooks/use-arrow-navigation.ts +58 -0
  90. package/src/hooks/use-suggestions.ts +97 -74
  91. package/src/utils/colors.ts +1 -1
  92. package/src/utils/draggable-table.ts +2 -2
  93. package/src/utils/index.ts +1 -0
  94. package/src/utils/parse-smart-query.ts +87 -0
  95. package/src/components/compound/DlCharts/types.ts +0 -1
  96. package/src/demo/DlDropdownButtonDemo.vue +0 -260
  97. package/src/demo/DlSpinnerDemo.vue +0 -20
  98. /package/src/{demo → demos}/BarChartDemo.vue +0 -0
  99. /package/src/{demo → demos}/ColumnChartDemo.vue +0 -0
  100. /package/src/{demo → demos}/DlAccordionDemo.vue +0 -0
  101. /package/src/{demo → demos}/DlAlertDemo.vue +0 -0
  102. /package/src/{demo → demos}/DlAvatarDemo.vue +0 -0
  103. /package/src/{demo → demos}/DlBadgeDemo.vue +0 -0
  104. /package/src/{demo → demos}/DlChartDoughnutDemo.vue +0 -0
  105. /package/src/{demo → demos}/DlCheckboxDemo.vue +0 -0
  106. /package/src/{demo → demos}/DlChipDemo.vue +0 -0
  107. /package/src/{demo → demos}/DlCounterDemo.vue +0 -0
  108. /package/src/{demo → demos}/DlDateTimeRangeDemo.vue +0 -0
  109. /package/src/{demo → demos}/DlIconDemo.vue +0 -0
  110. /package/src/{demo → demos}/DlInputDemo.vue +0 -0
  111. /package/src/{demo → demos}/DlKpiDemo.vue +0 -0
  112. /package/src/{demo → demos}/DlLinkDemo.vue +0 -0
  113. /package/src/{demo → demos}/DlListDemo.vue +0 -0
  114. /package/src/{demo → demos}/DlOptionGroupDemo.vue +0 -0
  115. /package/src/{demo → demos}/DlPaginationDemo.vue +0 -0
  116. /package/src/{demo → demos}/DlPanelContainerDemo.vue +0 -0
  117. /package/src/{demo → demos}/DlPopupDemo.vue +0 -0
  118. /package/src/{demo → demos}/DlProgressBarDemo.vue +0 -0
  119. /package/src/{demo → demos}/DlProgressChartDemo.vue +0 -0
  120. /package/src/{demo → demos}/DlRadioDemo.vue +0 -0
  121. /package/src/{demo → demos}/DlRangeDemo.vue +0 -0
  122. /package/src/{demo → demos}/DlSelectDemo.vue +0 -0
  123. /package/src/{demo → demos}/DlSkeletonDemo.vue +0 -0
  124. /package/src/{demo → demos}/DlSliderDemo.vue +0 -0
  125. /package/src/{demo → demos}/DlStepperDemo/CenteredStepperInDialogBox.vue +0 -0
  126. /package/src/{demo → demos}/DlStepperDemo/DlStepperDemo.vue +0 -0
  127. /package/src/{demo → demos}/DlStepperDemo/SimpleStepper.vue +0 -0
  128. /package/src/{demo → demos}/DlStepperDemo/StepperInDialogBox.vue +0 -0
  129. /package/src/{demo → demos}/DlStepperDemo/index.ts +0 -0
  130. /package/src/{demo → demos}/DlStepperDemo/steps/AssignmentsStep.vue +0 -0
  131. /package/src/{demo → demos}/DlStepperDemo/steps/DataStep.vue +0 -0
  132. /package/src/{demo → demos}/DlStepperDemo/steps/GeneralStep.vue +0 -0
  133. /package/src/{demo → demos}/DlStepperDemo/steps/InstructionStep.vue +0 -0
  134. /package/src/{demo → demos}/DlStepperDemo/steps/QualityStep.vue +0 -0
  135. /package/src/{demo → demos}/DlSwitchDemo.vue +0 -0
  136. /package/src/{demo → demos}/DlTabsDemo.vue +0 -0
  137. /package/src/{demo → demos}/DlTdDemo.vue +0 -0
  138. /package/src/{demo → demos}/DlTextAreaDemo.vue +0 -0
  139. /package/src/{demo → demos}/DlTextHolderDemo.vue +0 -0
  140. /package/src/{demo → demos}/DlThDemo.vue +0 -0
  141. /package/src/{demo → demos}/DlToastDemo.vue +0 -0
  142. /package/src/{demo → demos}/DlTrDemo.vue +0 -0
  143. /package/src/{demo → demos}/DlTrendDemo.vue +0 -0
  144. /package/src/{demo → demos}/DlTypographyDemo.vue +0 -0
  145. /package/src/{demo → demos}/SmartSearchDemo/schema.ts +0 -0
@@ -0,0 +1,542 @@
1
+ <template>
2
+ <div
3
+ :style="`max-width: ${maxWidth}`"
4
+ class="confusion-matrix-container"
5
+ >
6
+ <div
7
+ v-if="isValidMatrix"
8
+ ref="wrapper"
9
+ :style="matrixStyles"
10
+ class="wrapper"
11
+ >
12
+ <span
13
+ ref="labelY"
14
+ class="label-tag y"
15
+ >
16
+ {{ leftLabel }}
17
+ </span>
18
+ <div
19
+ ref="yAxisOuter"
20
+ class="y-axis-outer"
21
+ >
22
+ <div
23
+ ref="yAxis"
24
+ class="y-axis"
25
+ >
26
+ <div
27
+ v-for="(label, index) in labels"
28
+ :key="index"
29
+ class="y-axis__element"
30
+ >
31
+ <img
32
+ v-if="labelImages[0]"
33
+ class="legend-avatar"
34
+ :src="labelImages[index]"
35
+ >
36
+ <span v-else>
37
+ {{ label }}
38
+ </span>
39
+ <dl-tooltip :offset="[0, 0]">
40
+ {{ labelStrings[index] }}
41
+ </dl-tooltip>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <div
46
+ ref="verticalWrapper"
47
+ class="vertical_wrapper"
48
+ >
49
+ <div
50
+ ref="matrixWrapper"
51
+ class="matrix-wrapper"
52
+ @scroll="handleMatrixScroll"
53
+ >
54
+ <div
55
+ ref="matrix"
56
+ class="matrix"
57
+ >
58
+ <div
59
+ v-for="cell in flattenedMatrix"
60
+ :key="`${cell.x}-${cell.y}`"
61
+ class="matrix__cell"
62
+ :style="`background-color: ${getCellBackground(
63
+ cell.value
64
+ )}; color: var(--dl-color-text${
65
+ cell.value < 0.5 ? '-darker' : ''
66
+ }-buttons)`"
67
+ @mouseenter="handleShowTooltip(cell, $event)"
68
+ @mouseleave="handleHideTooltip"
69
+ @mousedown="openLink(cell)"
70
+ >
71
+ {{
72
+ cell.value > 0
73
+ ? normalized
74
+ ? cell.value
75
+ : cell.unnormalizedValue
76
+ : null
77
+ }}
78
+ </div>
79
+ </div>
80
+ </div>
81
+ <div class="x-axis">
82
+ <span
83
+ v-for="(label, index) in visibleLabels"
84
+ :key="index"
85
+ class="x-axis__element"
86
+ :style="`${
87
+ !labelImages[0] ? 'transform: rotate(70deg);' : ''
88
+ }`"
89
+ >
90
+ <span class="x-axis__element--text">
91
+ <img
92
+ v-if="labelImages[0]"
93
+ class="legend-avatar"
94
+ :src="labelImages[index]"
95
+ >
96
+ <span v-else>
97
+ {{ label }}
98
+ </span>
99
+ <dl-tooltip> {{ labelStrings[index] }}</dl-tooltip>
100
+ </span>
101
+ </span>
102
+ </div>
103
+ <dl-brush
104
+ track-size="18px"
105
+ thumb-size="20px"
106
+ :max="matrix.length"
107
+ :max-range="2"
108
+ :selection-color="getCellBackground(0.1)"
109
+ :color="getCellBackground()"
110
+ :step="1"
111
+ drag-range
112
+ @update:model-value="handleBrushUpdate"
113
+ />
114
+ <span class="label-tag x"> {{ bottomLabel }} </span>
115
+ </div>
116
+ <div
117
+ ref="colorSpectrum"
118
+ class="color-spectrum"
119
+ >
120
+ <div class="color-spectrum__gradient" />
121
+ <div class="color-spectrum__gradation">
122
+ <div
123
+ v-for="value in gradationValues"
124
+ :key="value"
125
+ class="color-spectrum__gradation--element"
126
+ >
127
+ <span class="color-spectrum__gradation--element-line">-</span>
128
+ {{ value !== gradationValues[0] ? value : null }}
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ <div
134
+ v-else
135
+ class="invalid"
136
+ >
137
+ The given props cannot create a valid matrix.
138
+ </div>
139
+ <div
140
+ v-if="tooltipVisible"
141
+ :style="tooltipStyles"
142
+ class="tooltip"
143
+ >
144
+ <span class="tooltip__x">{{ tooltipState.xLabel }}</span>
145
+ <span class="tooltip__y">{{ tooltipState.yLabel }}</span>
146
+ <span>
147
+ <span
148
+ v-if="tooltipState.value"
149
+ class="tooltip__color"
150
+ :style="`background-color: ${getCellBackground(
151
+ tooltipState.value
152
+ )}`"
153
+ />
154
+ {{ normalized ? 'Normalized' : 'Unnormalized' }}
155
+ {{ tooltipState.value }}
156
+ </span>
157
+ </div>
158
+ </div>
159
+ </template>
160
+
161
+ <script lang="ts">
162
+ import { defineComponent, PropType, ref } from 'vue-demi'
163
+ import DlBrush from '../../components/DlBrush.vue'
164
+ import DlTooltip from '../../../../essential/DlTooltip/DlTooltip.vue'
165
+ import {
166
+ DlConfusionMatrixCell,
167
+ DlConfusionMatrixLabel,
168
+ DlConfusionMatrixBrushState
169
+ } from '../../types'
170
+ import { hexToRgbA } from '../../../../../utils/colors'
171
+ import { colorNames } from '../../../../../utils/css-color-names'
172
+ import { useThemeVariables } from '../../../../../hooks/use-theme'
173
+ import {
174
+ getGradationValues,
175
+ validateMatrix,
176
+ setZoom,
177
+ getCellWidth,
178
+ flattenConfusionMatrix
179
+ } from './utils'
180
+ import { debounce, isObject } from 'lodash'
181
+ export default defineComponent({
182
+ components: {
183
+ DlBrush,
184
+ DlTooltip
185
+ },
186
+ props: {
187
+ labels: {
188
+ required: true,
189
+ type: Array as PropType<string[] | DlConfusionMatrixLabel[]>,
190
+ default: (): string[] | DlConfusionMatrixLabel[] => []
191
+ },
192
+ matrix: {
193
+ required: true,
194
+ type: Array as PropType<number[][] | DlConfusionMatrixCell[][]>,
195
+ default: (): number[][] | DlConfusionMatrixCell[][] => []
196
+ },
197
+ normalized: {
198
+ type: Boolean,
199
+ default: true
200
+ },
201
+ color: {
202
+ type: String,
203
+ default: '--dl-color-secondary'
204
+ },
205
+ bottomLabel: {
206
+ type: String,
207
+ default: 'Predicted Label'
208
+ },
209
+ leftLabel: {
210
+ type: String,
211
+ default: 'True Label'
212
+ },
213
+ maxWidth: {
214
+ type: String,
215
+ default: '800px'
216
+ }
217
+ },
218
+ setup(props) {
219
+ const { variables } = useThemeVariables()
220
+
221
+ const tooltipState = ref<{
222
+ x: string
223
+ y: string
224
+ visible?: boolean
225
+ } | null>(null)
226
+ const currentBrushState = ref<{ min: number; max: number }>({
227
+ min: 0,
228
+ max: props.matrix.length
229
+ })
230
+ const cellWidth = ref<number | null>(null)
231
+
232
+ const getCellBackground = (value: number = 1): string => {
233
+ const object: { [key: string]: any } = {
234
+ ...variables,
235
+ ...colorNames
236
+ }
237
+ const hex = object[props.color]
238
+ return hexToRgbA(hex, value)
239
+ }
240
+ return {
241
+ variables,
242
+ getCellBackground,
243
+ cellWidth,
244
+ tooltipState,
245
+ currentBrushState
246
+ }
247
+ },
248
+ computed: {
249
+ tooltipVisible(): boolean {
250
+ return this.tooltipState?.visible
251
+ },
252
+ visibleLabels(): DlConfusionMatrixLabel[] {
253
+ if (isObject(this.labels[0])) {
254
+ const arr = this.labels as DlConfusionMatrixLabel[]
255
+ return arr.slice(
256
+ this.currentBrushState.min,
257
+ this.currentBrushState.max
258
+ )
259
+ }
260
+ return []
261
+ },
262
+ labelStrings(): string[] | DlConfusionMatrixLabel[] {
263
+ if (isObject(this.labels[0])) {
264
+ const arr = this.labels as DlConfusionMatrixLabel[]
265
+ return arr.map((label: DlConfusionMatrixLabel) => label.title)
266
+ }
267
+ return this.labels
268
+ },
269
+ labelImages(): string[] {
270
+ return this.visibleLabels.map((label: any) => label.image)
271
+ },
272
+ isValidMatrix(): boolean {
273
+ return validateMatrix(this.matrix, this.labels)
274
+ },
275
+ flattenedMatrix(): DlConfusionMatrixCell[] {
276
+ return flattenConfusionMatrix(this.matrix, this.labelStrings)
277
+ },
278
+ matrixStyles(): object {
279
+ return {
280
+ '--matrix-rows': this.matrix.length,
281
+ '--cell-dimensions': `${this.cellWidth}px`,
282
+ '--general-color': this.getCellBackground()
283
+ }
284
+ },
285
+ tooltipStyles(): object {
286
+ return {
287
+ left: `${this.tooltipState?.x + 10}px`,
288
+ top: `${this.tooltipState?.y + 15}px`
289
+ }
290
+ },
291
+ gradationValues(): number[] {
292
+ return this.normalized
293
+ ? [1, 0.8, 0.6, 0.4, 0.2, 0]
294
+ : getGradationValues(this.matrix)
295
+ }
296
+ },
297
+ mounted() {
298
+ if (!this.isValidMatrix) return
299
+ this.resizeMatrix()
300
+ const resizeObserver = new ResizeObserver(this.resizeMatrix)
301
+ resizeObserver.observe(this.$refs.wrapper as Element)
302
+ window.onresize = this.resizeMatrix
303
+ },
304
+ methods: {
305
+ resizeMatrix() {
306
+ const colorSpectrum = this.$refs.colorSpectrum as HTMLElement
307
+ const verticalWrapper = this.$refs.verticalWrapper as HTMLElement
308
+ const labelY = this.$refs.labelY as HTMLElement
309
+ const yAxisOuter = this.$refs.yAxisOuter as HTMLElement
310
+ const width = verticalWrapper?.offsetWidth
311
+
312
+ labelY.style.marginTop = `-${this.leftLabel.length * 16}px`
313
+ this.cellWidth = width / this.matrix.length
314
+ colorSpectrum.style.height = `${width}px`
315
+ yAxisOuter.style.height = `${width}px`
316
+ },
317
+ handleBrushUpdate(brush: DlConfusionMatrixBrushState) {
318
+ if (
319
+ brush.min === this.currentBrushState.min &&
320
+ brush.max === this.currentBrushState.max
321
+ )
322
+ return
323
+ this.updateBrush(this, brush)
324
+ },
325
+ updateBrush: debounce(
326
+ (ctx: any, brush: DlConfusionMatrixBrushState) => {
327
+ setZoom(
328
+ ctx.matrix.length / (brush.max - brush.min),
329
+ ctx.$refs.matrix
330
+ )
331
+ const scroll = brush.min * getCellWidth() + 2
332
+ const container = ctx.$refs.matrixWrapper
333
+ container.scroll(scroll, scroll)
334
+ ctx.currentBrushState = brush
335
+ ctx.resizeYAxis()
336
+ },
337
+ 30
338
+ ),
339
+ resizeYAxis() {
340
+ const yAxis = this.$refs.yAxis as HTMLElement
341
+ yAxis.style.height = `${getCellWidth() * this.matrix.length}px`
342
+ },
343
+ handleMatrixScroll(e: MouseEvent) {
344
+ const target = e.target as HTMLElement
345
+ ;(this.$refs.yAxisOuter as HTMLElement).scroll(0, target.scrollTop)
346
+ },
347
+ handleShowTooltip(cell: DlConfusionMatrixCell, e: MouseEvent) {
348
+ this.showTooltip(this, cell, e)
349
+ },
350
+ handleHideTooltip() {
351
+ this.hideTooltip(this)
352
+ },
353
+ showTooltip: debounce(
354
+ (ctx: any, cell: DlConfusionMatrixCell, e: MouseEvent) => {
355
+ ctx.tooltipState = {
356
+ value: ctx.normalized ? cell.value : cell.unnormalizedValue,
357
+ xLabel: cell.xLabel,
358
+ yLabel: cell.yLabel,
359
+ x: e.pageX,
360
+ y: e.pageY,
361
+ visible: true
362
+ }
363
+ },
364
+ 200
365
+ ),
366
+ hideTooltip: debounce((ctx: any) => {
367
+ if (ctx?.tooltipState) ctx.tooltipState.visible = false
368
+ }, 200),
369
+ openLink(cell: DlConfusionMatrixCell) {
370
+ if (!cell.link) return
371
+ window.open(cell.link, '_blank')
372
+ }
373
+ }
374
+ })
375
+ </script>
376
+
377
+ <style lang="scss">
378
+ .confusion-matrix-container {
379
+ margin: auto;
380
+ }
381
+ .wrapper {
382
+ display: flex;
383
+ width: 100%;
384
+ height: 100%;
385
+ user-select: none;
386
+ }
387
+ .vertical_wrapper {
388
+ width: 80%;
389
+ display: flex;
390
+ flex-direction: column;
391
+ align-items: center;
392
+ }
393
+
394
+ .label-tag {
395
+ font-size: 0.8em;
396
+ color: var(--dl-color-medium);
397
+ }
398
+ .label-tag.y {
399
+ writing-mode: vertical-rl;
400
+ transform: rotate(180deg);
401
+ text-align: center;
402
+ margin-right: 10px;
403
+ }
404
+ .label-tag.x {
405
+ margin-top: 15px;
406
+ }
407
+ .x-axis {
408
+ width: 100%;
409
+ display: flex;
410
+ justify-content: space-between;
411
+ margin-top: 10px;
412
+ min-height: 100px;
413
+ max-height: 100px;
414
+ &__element {
415
+ width: var(--cell-dimensions);
416
+ line-height: 100px;
417
+ overflow: hidden;
418
+ text-overflow: ellipsis;
419
+ }
420
+ }
421
+ .y-axis {
422
+ margin-right: 10px;
423
+ display: flex;
424
+ flex-direction: column;
425
+ justify-content: space-between;
426
+ &__element {
427
+ text-align: center;
428
+ line-height: var(--cell-dimensions);
429
+ overflow: hidden;
430
+ text-overflow: ellipsis;
431
+ }
432
+ }
433
+ .y-axis-outer {
434
+ overflow: hidden;
435
+ width: 200px;
436
+ }
437
+ .y-axis,
438
+ .x-axis {
439
+ color: var(--dl-color-darker);
440
+ font-size: 0.7em;
441
+ }
442
+
443
+ .matrix-wrapper {
444
+ display: flex;
445
+ overflow-y: scroll;
446
+ overflow-x: hidden;
447
+ }
448
+ .matrix-wrapper::-webkit-scrollbar {
449
+ width: 14px;
450
+ }
451
+ .matrix-wrapper::-webkit-scrollbar-thumb {
452
+ border: 4px solid rgba(0, 0, 0, 0);
453
+ background-clip: padding-box;
454
+ border-radius: 9999px;
455
+ background-color: var(--dl-color-separator);
456
+ }
457
+
458
+ .matrix {
459
+ display: grid;
460
+ grid-template-rows: repeat(var(--matrix-rows), 1fr);
461
+ grid-template-columns: repeat(var(--matrix-rows), 1fr);
462
+
463
+ &__cell {
464
+ font-size: 80%;
465
+ cursor: pointer;
466
+ border: 1px solid var(--dl-color-separator);
467
+ box-sizing: border-box;
468
+ width: var(--cell-dimensions);
469
+ height: var(--cell-dimensions);
470
+ display: flex;
471
+ align-items: center;
472
+ justify-content: center;
473
+ }
474
+ }
475
+
476
+ .color-spectrum {
477
+ color: var(--dl-color-darker);
478
+ display: flex;
479
+ margin: 0px 15px;
480
+ &__gradient {
481
+ width: 40%;
482
+ background-image: linear-gradient(
483
+ var(--general-color),
484
+ var(--dl-color-text-buttons)
485
+ );
486
+ }
487
+ &__gradation {
488
+ width: 60%;
489
+ font-size: 0.8em;
490
+ display: flex;
491
+ flex-direction: column;
492
+ justify-content: space-between;
493
+ &--element {
494
+ width: 100%;
495
+ display: flex;
496
+ &-line {
497
+ color: var(--dl-color-separator);
498
+ margin-right: 5px;
499
+ }
500
+ }
501
+ }
502
+ }
503
+
504
+ .tooltip {
505
+ position: absolute;
506
+ border: 1px solid var(--dl-color-separator);
507
+ padding: 8px;
508
+ font-size: 0.8em;
509
+ display: flex;
510
+ flex-direction: column;
511
+ background-color: var(--dl-color-shadow);
512
+ border-radius: 3px;
513
+ animation: fadeIn 0.4s;
514
+
515
+ &__color {
516
+ display: inline-block;
517
+ width: 12px;
518
+ height: 12px;
519
+ }
520
+ }
521
+
522
+ @keyframes fadeIn {
523
+ 0% {
524
+ opacity: 0;
525
+ }
526
+ 100% {
527
+ opacity: 1;
528
+ }
529
+ }
530
+
531
+ .invalid {
532
+ display: flex;
533
+ justify-content: center;
534
+ align-items: center;
535
+ }
536
+
537
+ .legend-avatar {
538
+ border-radius: 50%;
539
+ width: 30px;
540
+ height: 30px;
541
+ }
542
+ </style>
@@ -0,0 +1,2 @@
1
+ import DlConfusionMatrix from './DlConfusionMatrix.vue'
2
+ export { DlConfusionMatrix }
@@ -0,0 +1,96 @@
1
+ import { isObject } from 'lodash'
2
+ import { DlConfusionMatrixCell, DlConfusionMatrixLabel } from '../../types'
3
+
4
+ export function getCellWidth() {
5
+ return document.querySelector('.matrix__cell').getBoundingClientRect().width
6
+ }
7
+
8
+ export function setZoom(zoom: number, el: HTMLElement) {
9
+ const transformOrigin = [0, 0]
10
+ const p = ['webkit', 'moz', 'ms', 'o']
11
+ const s = 'scale(' + zoom + ')'
12
+ const oString =
13
+ transformOrigin[0] * 100 + '% ' + transformOrigin[1] * 100 + '%'
14
+
15
+ for (let i = 0; i < p.length; i++) {
16
+ el.style[(p[i] + 'Transform') as any] = s
17
+ el.style[(p[i] + 'TransformOrigin') as any] = oString
18
+ }
19
+
20
+ el.style['transform'] = s
21
+ el.style['transformOrigin'] = oString
22
+ }
23
+
24
+ export function validateMatrix(
25
+ matrix: number[][] | DlConfusionMatrixCell[][],
26
+ labels: string[] | DlConfusionMatrixLabel[]
27
+ ) {
28
+ let validation = true
29
+ if (matrix.length !== labels.length) return false
30
+ for (let i = 0; i < matrix.length; i++) {
31
+ if (matrix[i].length !== matrix.length) validation = false
32
+ }
33
+ return validation
34
+ }
35
+
36
+ export function normalizeMatrix(flatMatrix: DlConfusionMatrixCell[]) {
37
+ const values = flatMatrix.map((cell) => cell.value)
38
+ const largest = Math.max(...values)
39
+ for (const cell of flatMatrix) {
40
+ cell.unnormalizedValue = cell.value
41
+ cell.value = Number((cell.value / largest).toFixed(1))
42
+ }
43
+ return flatMatrix
44
+ }
45
+
46
+ export function getGradationValues(
47
+ matrix: number[][] | DlConfusionMatrixCell[][],
48
+ step = 5
49
+ ) {
50
+ let max = Number.MIN_VALUE
51
+ let min = Number.MAX_VALUE
52
+
53
+ for (const row of matrix) {
54
+ for (const cell of row) {
55
+ const cellValue = isObject(cell)
56
+ ? (cell as DlConfusionMatrixCell).value
57
+ : cell
58
+ if (cellValue > max) max = cellValue
59
+ if (cellValue < min) min = cellValue
60
+ }
61
+ }
62
+
63
+ const range = (max - min) / step
64
+ const gradationValues = []
65
+ let amount = 0
66
+ for (let i = 0; i < step; i++) {
67
+ gradationValues.push(Number((amount + range).toFixed(1)))
68
+ amount += range
69
+ }
70
+ return gradationValues.reverse()
71
+ }
72
+
73
+ export function flattenConfusionMatrix(
74
+ matrix: number[][] | DlConfusionMatrixCell[][],
75
+ labelStrings: string[] | DlConfusionMatrixLabel[]
76
+ ) {
77
+ const toNormalize: DlConfusionMatrixCell[] = []
78
+
79
+ for (const [rowIndex, row] of matrix.entries()) {
80
+ for (const [cellIndex, cell] of row.entries()) {
81
+ const value = isObject(cell)
82
+ ? (cell as DlConfusionMatrixCell).value
83
+ : cell
84
+ toNormalize.push({
85
+ value,
86
+ unnormalizedValue: value,
87
+ xLabel: labelStrings[rowIndex],
88
+ yLabel: labelStrings[cellIndex],
89
+ x: rowIndex,
90
+ y: cellIndex,
91
+ link: isObject ? (cell as DlConfusionMatrixCell).link : ''
92
+ })
93
+ }
94
+ }
95
+ return normalizeMatrix(toNormalize)
96
+ }
@@ -214,8 +214,8 @@ export default defineComponent({
214
214
  ? {
215
215
  'justify-content': 'end',
216
216
  width: getPixelsFromPercents(
217
- doughnutChartWidgetWidth.value,
218
- sizePercents,
217
+ doughnutChartWidgetHeight.value,
218
+ sizePercents / 1.8,
219
219
  'px'
220
220
  ),
221
221
  height: getPixelsFromPercents(