@dataloop-ai/components 0.18.0 → 0.18.2

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 (277) hide show
  1. package/package.json +6 -3
  2. package/src/App.vue +5 -227
  3. package/src/assets/constants.scss +2 -1
  4. package/src/assets/globals.scss +21 -0
  5. package/src/components/basic/DlAccordion/DlAccordion.vue +26 -4
  6. package/src/components/basic/DlAccordion/components/AccordionHeader.vue +2 -1
  7. package/src/components/basic/DlAvatar/DlAvatar.vue +1 -1
  8. package/src/components/basic/DlButton/DlButton.vue +115 -25
  9. package/src/components/basic/DlButton/utils.ts +45 -2
  10. package/src/components/basic/DlChip/DlChip.vue +3 -7
  11. package/src/components/basic/DlChip/utils.ts +4 -4
  12. package/src/components/basic/DlContainer/DlContainer.vue +70 -0
  13. package/src/components/basic/DlContainer/index.ts +3 -0
  14. package/src/components/basic/DlEmptyState/DlEmptyState.vue +282 -0
  15. package/src/components/basic/DlEmptyState/index.ts +2 -0
  16. package/src/components/basic/DlEmptyState/types.ts +20 -0
  17. package/src/components/basic/DlGrid/DlGrid.vue +163 -0
  18. package/src/components/basic/DlGrid/index.ts +4 -0
  19. package/src/components/basic/DlGrid/types.ts +5 -0
  20. package/src/components/basic/DlKpi/components/KpiInfo.vue +2 -1
  21. package/src/components/basic/DlListItem/DlListItem.vue +96 -66
  22. package/src/components/basic/DlListItem/utils.ts +0 -3
  23. package/src/components/basic/DlPanelContainer/DlPanelContainer.vue +37 -13
  24. package/src/components/basic/DlPopup/DlPopup.vue +58 -11
  25. package/src/components/basic/DlPopup/components/PopupHeader.vue +11 -6
  26. package/src/components/basic/DlProgressChart/DlProgressChart.vue +2 -1
  27. package/src/components/basic/DlWidget/DlWidget.vue +273 -141
  28. package/src/components/basic/DlWidget/index.ts +1 -3
  29. package/src/components/basic/DlWidget/utils.ts +90 -8
  30. package/src/components/basic/index.ts +4 -2
  31. package/src/components/basic/types.ts +2 -0
  32. package/src/components/compound/DlCard/DlCard.vue +796 -0
  33. package/src/components/compound/DlCard/components/DescriptionModal.vue +137 -0
  34. package/src/components/compound/DlCard/types.ts +38 -0
  35. package/src/components/compound/DlCharts/charts/DlBarChart/DlBarChart.vue +39 -4
  36. package/src/components/compound/DlCharts/charts/DlColumnChart/DlColumnChart.vue +128 -36
  37. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/DlConfusionMatrix.vue +167 -87
  38. package/src/components/compound/DlCharts/charts/DlConfusionMatrix/utils.ts +2 -1
  39. package/src/components/compound/DlCharts/charts/DlDoughnutChart/DlDoughnutChart.vue +44 -3
  40. package/src/components/compound/DlCharts/charts/DlDoughnutChart/DlDoughnutChartWidget.vue +1 -2
  41. package/src/components/compound/DlCharts/charts/DlDoughnutChart/components/DlDoughnutChartLegend.vue +9 -18
  42. package/src/components/compound/DlCharts/charts/DlLineChart/DlLineChart.vue +48 -9
  43. package/src/components/compound/DlCharts/charts/DlScatterChart/DlScatterChart.vue +667 -0
  44. package/src/components/compound/DlCharts/charts/DlScatterChart/index.ts +2 -0
  45. package/src/components/compound/DlCharts/charts/index.ts +1 -0
  46. package/src/components/compound/DlCharts/components/DlBrush.vue +3 -2
  47. package/src/components/compound/DlCharts/components/DlChartLabels.vue +2 -1
  48. package/src/components/compound/DlCharts/components/DlChartScrollBar.vue +1 -0
  49. package/src/components/compound/DlCharts/types/props.ts +5 -1
  50. package/src/components/compound/DlCharts/utils.ts +1 -1
  51. package/src/components/compound/DlCodeEditor/DlCodeEditor.vue +173 -0
  52. package/src/components/compound/DlCodeEditor/README.md +11 -0
  53. package/src/components/compound/DlCodeEditor/components/CodeEditor.vue +705 -0
  54. package/src/components/compound/DlCodeEditor/index.ts +3 -0
  55. package/src/components/compound/DlCodeEditor/styles/themes-base16.css +12809 -0
  56. package/src/components/compound/DlCodeEditor/styles/themes.css +3999 -0
  57. package/src/components/compound/DlCodeEditor/types.ts +21 -0
  58. package/src/components/compound/DlDateTime/DlDatePicker/DlDatePicker.vue +9 -1
  59. package/src/components/compound/DlDateTime/DlDatePicker/components/DlCalendar.vue +4 -2
  60. package/src/components/compound/DlDateTime/DlDatePicker/components/DlMonthCalendar.vue +2 -1
  61. package/src/components/compound/DlDateTime/DlDateTimeRange/{DlCardSidebar.vue → CardSidebar.vue} +10 -11
  62. package/src/components/compound/DlDateTime/DlDateTimeRange/DlDateTimeRange.vue +18 -9
  63. package/src/components/compound/DlDateTime/DlTimePicker/DlTimePicker.vue +2 -2
  64. package/src/components/compound/DlDialogBox/DlDialogBox.vue +74 -15
  65. package/src/components/compound/DlDialogBox/components/DlDialogBoxFooter.vue +1 -1
  66. package/src/components/compound/DlDialogBox/components/DlDialogBoxHeader.vue +9 -7
  67. package/src/components/compound/DlDropdownButton/DlDropdownButton.vue +13 -4
  68. package/src/components/compound/DlInput/DlInput.vue +80 -17
  69. package/src/components/compound/DlJsonEditor/DlJsonEditor.vue +42 -219
  70. package/src/components/compound/DlOptionGroup/DlOptionGroup.vue +16 -17
  71. package/src/components/compound/DlOptionGroup/components/MenuItemWrapper.vue +2 -2
  72. package/src/components/compound/DlPagination/DlPagination.vue +1 -1
  73. package/src/components/compound/DlPagination/components/PaginationLegend.vue +0 -2
  74. package/src/components/compound/DlPagination/components/RowsSelector.vue +0 -2
  75. package/src/components/compound/DlRange/DlRange.vue +3 -2
  76. package/src/components/compound/DlSearches/DlSearch/DlSearch.vue +12 -5
  77. package/src/components/compound/DlSearches/DlSmartSearch/DlSmartSearch.vue +413 -97
  78. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchFilters.vue +4 -1
  79. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSmartSearchInput.vue +100 -39
  80. package/src/components/compound/DlSearches/DlSmartSearch/components/DlSuggestionsDropdown.vue +12 -7
  81. package/src/components/compound/DlSearches/DlSmartSearch/components/FiltersQuery.vue +5 -6
  82. package/src/components/compound/DlSearches/DlSmartSearch/types.ts +14 -0
  83. package/src/components/compound/DlSearches/DlSmartSearch/utils/highlightSyntax.ts +10 -6
  84. package/src/components/compound/DlSearches/DlSmartSearch/utils/index.ts +172 -48
  85. package/src/components/compound/DlSelect/DlSelect.vue +264 -130
  86. package/src/components/compound/DlSelect/utils.ts +4 -1
  87. package/src/components/compound/DlSlider/DlSlider.vue +10 -2
  88. package/src/components/compound/DlSlider/components/DlSliderBase.vue +3 -3
  89. package/src/components/compound/DlSlider/components/DlSliderInput.vue +17 -26
  90. package/src/components/compound/DlSlider/sliderStyles.scss +5 -1
  91. package/src/components/compound/DlSlider/useSlider.ts +2 -2
  92. package/src/components/compound/DlSlider/utils.ts +2 -2
  93. package/src/components/compound/DlStepper/DlStepper.vue +46 -4
  94. package/src/components/compound/DlStepper/components/DlStepperContent.vue +6 -2
  95. package/src/components/compound/DlStepper/components/DlStepperFooter.vue +12 -0
  96. package/src/components/compound/DlStepper/components/DlStepperSidebar.vue +24 -11
  97. package/src/components/compound/DlStepper/models/Step.ts +37 -8
  98. package/src/components/compound/DlStepper/models/Stepper.ts +108 -15
  99. package/src/components/compound/DlStepper/models/interfaces.ts +2 -1
  100. package/src/components/compound/DlTable/DlTable.vue +49 -14
  101. package/src/components/compound/DlTable/components/DlTd.vue +9 -9
  102. package/src/components/compound/DlTable/components/DlTh.vue +3 -2
  103. package/src/components/compound/DlTable/hooks/tableColumnSelection.ts +35 -40
  104. package/src/components/compound/DlTable/hooks/tableFilter.ts +33 -21
  105. package/src/components/compound/DlTable/hooks/tablePagination.ts +18 -18
  106. package/src/components/compound/DlTable/hooks/tableRowExpand.ts +2 -1
  107. package/src/components/compound/DlTable/hooks/tableRowSelection.ts +0 -1
  108. package/src/components/compound/DlTable/hooks/tableSort.ts +52 -47
  109. package/src/components/compound/DlTable/styles/dl-table-styles.scss +8 -0
  110. package/src/components/compound/DlTabs/DlTabs.vue +83 -31
  111. package/src/components/compound/DlTabs/components/DlTab.vue +14 -4
  112. package/src/components/compound/DlTabs/components/TabsWrapper.vue +32 -27
  113. package/src/components/compound/DlThumbnailGallery/DlThumbnailGallery.vue +268 -0
  114. package/src/components/compound/DlThumbnailGallery/index.ts +2 -0
  115. package/src/components/compound/DlThumbnailGallery/types.ts +11 -0
  116. package/src/components/compound/DlToast/api/useToast.ts +42 -1
  117. package/src/components/compound/DlToast/components/ToastComponent.vue +24 -32
  118. package/src/components/compound/DlToast/types.ts +52 -0
  119. package/src/components/compound/DlTreeTable/DlTreeTable.vue +1293 -0
  120. package/src/components/compound/DlTreeTable/components/DlTdTree.vue +119 -0
  121. package/src/components/compound/DlTreeTable/components/DlTrTree.vue +52 -0
  122. package/src/components/compound/DlTreeTable/index.ts +3 -0
  123. package/src/components/compound/DlTreeTable/types.ts +1 -0
  124. package/src/components/compound/DlTreeTable/utils/convertToNestedObject.ts +51 -0
  125. package/src/components/compound/DlTreeTable/utils/flatTreeData.ts +19 -0
  126. package/src/components/compound/DlTreeTable/utils/getFromChildren.ts +39 -0
  127. package/src/components/compound/DlTreeTable/utils/trSpacing.ts +13 -0
  128. package/src/components/compound/DlTreeTable/utils/treeTableRowSelection.ts +184 -0
  129. package/src/components/compound/index.ts +14 -1
  130. package/src/components/compound/types.ts +2 -0
  131. package/src/components/essential/DlBadge/DlBadge.vue +3 -3
  132. package/src/components/essential/DlCheckbox/DlCheckbox.vue +10 -7
  133. package/src/components/essential/DlEllipsis/DlEllipsis.vue +141 -0
  134. package/src/components/essential/DlIcon/DlIcon.vue +5 -5
  135. package/src/components/essential/DlLabel/DlLabel.vue +190 -0
  136. package/src/components/essential/DlLabel/index.ts +2 -0
  137. package/src/components/essential/DlList/DlList.vue +3 -3
  138. package/src/components/essential/DlMenu/DlMenu.vue +41 -22
  139. package/src/components/essential/DlMenu/utils.ts +8 -7
  140. package/src/components/essential/DlPageLayout/DlPageLayout.vue +90 -0
  141. package/src/components/essential/DlPageLayout/index.ts +2 -0
  142. package/src/components/essential/DlProgressBar/DlProgressBar.vue +1 -1
  143. package/src/components/essential/DlRadio/DlRadio.vue +10 -5
  144. package/src/components/essential/DlSeparator/DlSeparator.vue +2 -2
  145. package/src/components/essential/DlSpinner/index.ts +1 -13
  146. package/src/components/essential/DlSpinner/styles/spinnerStyles.scss +7 -0
  147. package/src/components/essential/DlSwitch/DlSwitch.vue +6 -3
  148. package/src/components/essential/DlTextArea/DlTextArea.vue +212 -7
  149. package/src/components/essential/DlThemeProvider/DlThemeProvider.vue +6 -0
  150. package/src/components/essential/DlTypography/DlTypography.vue +7 -1
  151. package/src/components/essential/index.ts +3 -2
  152. package/src/components/shared/DlInfoErrorMessage/DlInfoErrorMessage.vue +1 -1
  153. package/src/components/{essential → shared}/DlTooltip/DlTooltip.vue +26 -19
  154. package/src/components/shared/DlVirtualScroll/DlVirtualScroll.vue +106 -43
  155. package/src/components/shared/DlVirtualScroll/useVirtualScroll.ts +28 -4
  156. package/src/components/shared/index.ts +1 -0
  157. package/src/components/types.ts +2 -0
  158. package/src/demos/BarChartDemo.vue +59 -2
  159. package/src/demos/ColumnChartDemo.vue +67 -2
  160. package/src/demos/DlAccordionDemo.vue +92 -43
  161. package/src/demos/DlAlertDemo.vue +14 -0
  162. package/src/demos/DlButtonDemo.vue +41 -4
  163. package/src/demos/DlCardDemo.vue +156 -19
  164. package/src/demos/DlChartDoughnutDemo.vue +49 -2
  165. package/src/demos/DlCheckboxDemo.vue +28 -3
  166. package/src/demos/DlCodeEditor/DlCodeEditorDemo.vue +247 -0
  167. package/src/demos/DlCodeEditor/index.ts +2 -0
  168. package/src/demos/DlConfusionMatrixDemo.vue +93 -37
  169. package/src/demos/DlDemoPage.vue +235 -0
  170. package/src/demos/DlDialogBoxDemo.vue +56 -51
  171. package/src/demos/DlDropdownButtonDemo.vue +35 -27
  172. package/src/demos/DlEmptyStateDemo.vue +81 -0
  173. package/src/demos/DlGridDemo.vue +40 -0
  174. package/src/demos/DlInputDemo.vue +21 -1
  175. package/src/demos/DlJsonEditorDemo.vue +59 -0
  176. package/src/demos/DlLabelDemo.vue +208 -0
  177. package/src/demos/DlLineChartDemo.vue +50 -2
  178. package/src/demos/DlListDemo.vue +12 -9
  179. package/src/demos/DlMenuDemo.vue +147 -20
  180. package/src/demos/DlPageLayoutDemo.vue +146 -0
  181. package/src/demos/DlPanelContainerDemo.vue +113 -2
  182. package/src/demos/DlPopupDemo.vue +82 -1
  183. package/src/demos/DlRadioDemo.vue +16 -1
  184. package/src/demos/DlScatterChartDemo.vue +161 -0
  185. package/src/demos/DlSearchDemo.vue +9 -0
  186. package/src/demos/DlSelectDemo.vue +124 -27
  187. package/src/demos/DlSpinnerDemo.vue +0 -2
  188. package/src/demos/DlStepperDemo/DlStepperDemo.vue +5 -1
  189. package/src/demos/DlStepperDemo/EmptyStateStepper.vue +149 -0
  190. package/src/demos/DlStepperDemo/SimpleStepper.vue +4 -0
  191. package/src/demos/DlStepperDemo/steps/GeneralStep.vue +1 -0
  192. package/src/demos/DlSwitchDemo.vue +12 -0
  193. package/src/demos/DlTableDemo.vue +84 -5
  194. package/src/demos/DlTabsDemo.vue +92 -3
  195. package/src/demos/DlTextAreaDemo.vue +14 -17
  196. package/src/demos/DlThumbnailGalleryDemo.vue +99 -0
  197. package/src/demos/DlToastDemo.vue +3 -9
  198. package/src/demos/DlTooltipDemo.vue +66 -2
  199. package/src/demos/DlTreeTableDemo.vue +694 -0
  200. package/src/demos/DlVirtualScrollDemo.vue +3 -12
  201. package/src/demos/DlWidgetDemo.vue +252 -61
  202. package/src/demos/SmartSearchDemo/DlSmartSearchDemo.vue +151 -32
  203. package/src/demos/index.ts +23 -4
  204. package/src/hooks/use-anchor.ts +15 -17
  205. package/src/hooks/use-arrow-navigation.ts +64 -21
  206. package/src/hooks/use-model-toggle.ts +14 -16
  207. package/src/hooks/use-portal.ts +9 -3
  208. package/src/hooks/use-scroll-target.ts +2 -4
  209. package/src/hooks/use-size-observer.ts +3 -2
  210. package/src/hooks/use-suggestions.ts +239 -49
  211. package/src/hooks/use-transition.ts +10 -4
  212. package/src/index.ts +22 -1
  213. package/src/layouts/DlDatasetBrowser/DemoComponents/DatasetFooter.vue +78 -0
  214. package/src/layouts/DlDatasetBrowser/DemoComponents/DatasetHeader.vue +22 -0
  215. package/src/layouts/DlDatasetBrowser/DemoComponents/DatasetLeftDrawer.vue +96 -0
  216. package/src/layouts/DlDatasetBrowser/DemoComponents/DatasetMainContent.vue +51 -0
  217. package/src/layouts/DlDatasetBrowser/DemoComponents/DatasetRightDrawer.vue +88 -0
  218. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/ActionsMenu.vue +70 -0
  219. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/AutomationMenu.vue +106 -0
  220. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/CardView.vue +101 -0
  221. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/CardViewGallery.vue +141 -0
  222. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/CardViewTable.vue +193 -0
  223. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/EmptyState/LayoutEmptyState.vue +227 -0
  224. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/EmptyState/UploadData.vue +106 -0
  225. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/MainContentImages.vue +540 -0
  226. package/src/layouts/DlDatasetBrowser/DemoComponents/MainContent/MainContentNav.vue +329 -0
  227. package/src/layouts/DlDatasetBrowser/DemoComponents/NavbarKpi.vue +84 -0
  228. package/src/layouts/DlDatasetBrowser/DemoComponents/NavbarSearch.vue +132 -0
  229. package/src/layouts/DlDatasetBrowser/DemoComponents/SearchFilterMenu.vue +19 -0
  230. package/src/layouts/DlDatasetBrowser/DemoComponents/filters/AddFilter.vue +212 -0
  231. package/src/layouts/DlDatasetBrowser/DemoComponents/types/imageMetadata.ts +28 -0
  232. package/src/layouts/DlDatasetBrowser/DlDatasetBrowser.vue +42 -0
  233. package/src/layouts/DlStudioLayout/DlStudioLayout.vue +42 -0
  234. package/src/layouts/DlStudioLayout/components/Demo/LeftMenuContent.vue +23 -0
  235. package/src/layouts/DlStudioLayout/components/Demo/StudioFooter.vue +25 -0
  236. package/src/layouts/DlStudioLayout/components/Demo/StudioHeader.vue +121 -0
  237. package/src/layouts/DlStudioLayout/components/Demo/StudioLeftDrawer.vue +245 -0
  238. package/src/layouts/DlStudioLayout/components/Demo/StudioMainContent.vue +31 -0
  239. package/src/layouts/DlStudioLayout/components/Demo/StudioTabsMenu.vue +117 -0
  240. package/src/layouts/DlStudioLayout/components/Demo/TabMenu/FilterMenu.vue +62 -0
  241. package/src/layouts/DlStudioLayout/components/Demo/TabMenu/TabMenuAnnotations.vue +98 -0
  242. package/src/layouts/DlStudioLayout/components/Demo/TabMenu/TabMenuItem.vue +66 -0
  243. package/src/layouts/DlStudioLayout/components/LayoutNavbar.vue +24 -0
  244. package/src/layouts/DlStudioLayout/components/ListAutocomplete.vue +149 -0
  245. package/src/layouts/DlStudioLayout/components/NavigationDrawer.vue +147 -0
  246. package/src/layouts/DlStudioLayout/index.ts +2 -0
  247. package/src/layouts/DlStudioLayout/types/HorizontalItems.ts +9 -0
  248. package/src/layouts/DlStudioLayout/types/VerticalItems.ts +10 -0
  249. package/src/simple-code-editor.d.ts +1 -0
  250. package/src/utils/click-outside.ts +1 -1
  251. package/src/utils/dom.ts +5 -5
  252. package/src/utils/events.ts +3 -3
  253. package/src/utils/global-nodes.ts +2 -2
  254. package/src/utils/input-sizes.ts +5 -2
  255. package/src/utils/is-ellipsis-active.ts +4 -1
  256. package/src/utils/parse-smart-query.ts +209 -111
  257. package/src/utils/portal.ts +5 -5
  258. package/src/utils/position-engine.ts +7 -7
  259. package/src/utils/render.ts +1 -1
  260. package/src/utils/scroll.ts +2 -2
  261. package/src/utils/selection.ts +3 -3
  262. package/vite.config.ts +9 -1
  263. package/src/components/basic/DlCard/DlCard.vue +0 -241
  264. package/src/components/basic/DlCard/types.ts +0 -20
  265. package/src/components/basic/DlEllipsis/DlEllipsis.vue +0 -114
  266. package/src/components/basic/DlWidget/DlGrid.vue +0 -33
  267. package/src/components/basic/DlWidget/DlGridRow.vue +0 -32
  268. package/src/components/compound/DlSearches/DlSmartSearch/utils/utils.ts +0 -124
  269. package/src/components/compound/DlToast/utils/config.ts +0 -17
  270. package/src/components/essential/DlTextHolder/DlTextHolder.vue +0 -65
  271. package/src/components/essential/DlTextHolder/index.ts +0 -2
  272. package/src/demos/DlTextHolderDemo.vue +0 -42
  273. package/src/utils/swapNodes.ts +0 -30
  274. /package/src/components/{basic → compound}/DlCard/index.ts +0 -0
  275. /package/src/components/compound/DlDateTime/DlDateTimeRange/{DlDateInput.vue → DateInput.vue} +0 -0
  276. /package/src/components/{basic → essential}/DlEllipsis/index.ts +0 -0
  277. /package/src/components/{essential → shared}/DlTooltip/index.ts +0 -0
@@ -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'
@@ -229,6 +229,7 @@ export default defineComponent({
229
229
  const rangeStyles = computed(() => ({
230
230
  '--dl-track-width': 0.25 * parseInt(props.thumbSize) + 'px',
231
231
  '--text-color': getColor(props.textColor, 'dl-color-darker'),
232
+ '--thumb-size': props.thumbSize,
232
233
  '--width': props.width,
233
234
  '--color': getColor(props.color, 'dl-color-secondary'),
234
235
  width: props.width
@@ -238,14 +239,14 @@ export default defineComponent({
238
239
  width: 0.5 * parseInt(props.thumbSize) + 'px',
239
240
  height: props.thumbSize,
240
241
  left: `${100 * ratioMin.value}%`,
241
- zIndex: state.focus.value === 'min' ? 2 : void 0
242
+ zIndex: state.focus.value === 'min' ? 2 : null
242
243
  }))
243
244
 
244
245
  const maxThumbStyle = computed(() => ({
245
246
  width: 0.5 * parseInt(props.thumbSize) + 'px',
246
247
  height: props.thumbSize,
247
248
  left: `${100 * ratioMax.value}%`,
248
- zIndex: state.focus.value === 'max' ? 2 : void 0
249
+ zIndex: state.focus.value === 'max' ? 2 : null
249
250
  }))
250
251
 
251
252
  function updateValue(change = false) {