@icij/murmur-next 4.0.0

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 (296) hide show
  1. package/.github/workflows/deploy-github-pages.yaml +50 -0
  2. package/.storybook/app.scss +14 -0
  3. package/.storybook/doc_variables.scss +20 -0
  4. package/.storybook/main.ts +35 -0
  5. package/.storybook/preview-head.html +2 -0
  6. package/.storybook/preview.ts +32 -0
  7. package/README.md +71 -0
  8. package/deploy.js +15 -0
  9. package/docs/components/ApiTable.vue +171 -0
  10. package/docs/components/App.vue +146 -0
  11. package/docs/components/CollapsibleBlock.vue +122 -0
  12. package/docs/components/DocsHeader.vue +68 -0
  13. package/docs/components/DocsMenu.vue +201 -0
  14. package/docs/components/DocsMenuSection.vue +109 -0
  15. package/docs/components/EditLink.vue +49 -0
  16. package/docs/components/OutboundLink.vue +13 -0
  17. package/docs/components/PalettePresenter.vue +96 -0
  18. package/docs/components/RepositoryLink.vue +28 -0
  19. package/docs/components/SampleCard.vue +119 -0
  20. package/docs/main.js +42 -0
  21. package/docs/pages/components/accordion/doc.md +96 -0
  22. package/docs/pages/components/active-text-truncate/doc.md +44 -0
  23. package/docs/pages/components/advanced-link-form/doc.md +105 -0
  24. package/docs/pages/components/brand/doc.md +30 -0
  25. package/docs/pages/components/brand-expansion/doc.md +70 -0
  26. package/docs/pages/components/confirm-button/doc.md +91 -0
  27. package/docs/pages/components/content-placeholder/doc.md +16 -0
  28. package/docs/pages/components/custom-pagination/doc.md +61 -0
  29. package/docs/pages/components/digits-input/doc.md +28 -0
  30. package/docs/pages/components/donate-form/doc.md +20 -0
  31. package/docs/pages/components/embed-form/doc.md +22 -0
  32. package/docs/pages/components/embeddable-footer/doc.md +60 -0
  33. package/docs/pages/components/follow-us-popover/doc.md +5 -0
  34. package/docs/pages/components/generic-footer/doc.md +21 -0
  35. package/docs/pages/components/generic-header/doc.md +24 -0
  36. package/docs/pages/components/haptic-copy/doc.md +27 -0
  37. package/docs/pages/components/imddb-header/doc.md +23 -0
  38. package/docs/pages/components/ordinal-legend/doc.md +44 -0
  39. package/docs/pages/components/range-picker/doc.md +86 -0
  40. package/docs/pages/components/responsive-iframe/doc.md +13 -0
  41. package/docs/pages/components/scale-legend/doc.md +65 -0
  42. package/docs/pages/components/secret-input/doc.md +12 -0
  43. package/docs/pages/components/selectable-dropdown/doc.md +156 -0
  44. package/docs/pages/components/sharing-options/doc.md +13 -0
  45. package/docs/pages/components/sharing-options-link/doc.md +36 -0
  46. package/docs/pages/components/sign-up-form/doc.md +13 -0
  47. package/docs/pages/components/slide-up-down/doc.md +28 -0
  48. package/docs/pages/components/textured-deck/doc.md +78 -0
  49. package/docs/pages/components/tiny-pagination/doc.md +92 -0
  50. package/docs/pages/datavisualisation/bars/doc.md +110 -0
  51. package/docs/pages/datavisualisation/columns/doc.md +165 -0
  52. package/docs/pages/datavisualisation/lines/doc.md +139 -0
  53. package/docs/pages/datavisualisation/stacked-bar/doc.md +160 -0
  54. package/docs/pages/datavisualisation/stacked-column/doc.md +191 -0
  55. package/docs/pages/getting-started/about-icij/doc.md +13 -0
  56. package/docs/pages/getting-started/custom-bootstrap/doc.md +36 -0
  57. package/docs/pages/getting-started/installation-guide/doc.md +59 -0
  58. package/docs/pages/getting-started/internationalization/doc.md +74 -0
  59. package/docs/pages/maps/choropleth-map/doc.md +420 -0
  60. package/docs/pages/maps/choropleth-map-annotation/doc.md +373 -0
  61. package/docs/pages/maps/symbol-map/doc.md +203 -0
  62. package/docs/pages/structure/breakpoints/doc.md +3 -0
  63. package/docs/pages/structure/grid/doc.md +3 -0
  64. package/docs/pages/utilities/assets/doc.md +138 -0
  65. package/docs/pages/utilities/config/doc.md +52 -0
  66. package/docs/pages/utilities/iframes/doc.md +3 -0
  67. package/docs/pages/visual/colors/doc.md +31 -0
  68. package/docs/pages/visual/iconography/doc.md +56 -0
  69. package/docs/pages/visual/states/doc.md +77 -0
  70. package/docs/pages/visual/themes/doc.md +3 -0
  71. package/docs/pages/visual/typography/doc.md +71 -0
  72. package/docs/routes.js +25 -0
  73. package/docs/store/index.js +21 -0
  74. package/docs/styles/app.scss +36 -0
  75. package/docs/styles/variables.scss +20 -0
  76. package/lib/assets/images/icij-full-white.svg +6 -0
  77. package/lib/assets/images/icij-full.svg +6 -0
  78. package/lib/assets/images/icij.png +0 -0
  79. package/lib/assets/images/icij.svg +46 -0
  80. package/lib/assets/images/icij@2x.png +0 -0
  81. package/lib/assets/images/murmur-dark.png +0 -0
  82. package/lib/assets/images/murmur-dark.svg +79 -0
  83. package/lib/assets/images/murmur-white.png +0 -0
  84. package/lib/assets/images/murmur-white.svg +68 -0
  85. package/lib/components/AccordionStep.vue +128 -0
  86. package/lib/components/AccordionWrapper.vue +138 -0
  87. package/lib/components/ActiveTextTruncate.vue +258 -0
  88. package/lib/components/AdvancedLinkForm.vue +273 -0
  89. package/lib/components/Brand.vue +150 -0
  90. package/lib/components/BrandExpansion.vue +237 -0
  91. package/lib/components/ConfirmButton.vue +204 -0
  92. package/lib/components/ContentPlaceholder.vue +100 -0
  93. package/lib/components/CustomPagination.vue +225 -0
  94. package/lib/components/DigitsInput.vue +180 -0
  95. package/lib/components/DonateForm.vue +367 -0
  96. package/lib/components/EmbedForm.vue +173 -0
  97. package/lib/components/EmbeddableFooter.vue +201 -0
  98. package/lib/components/Fa.js +3 -0
  99. package/lib/components/FollowUsPopover.vue +117 -0
  100. package/lib/components/GenericFooter.vue +218 -0
  101. package/lib/components/GenericHeader.vue +259 -0
  102. package/lib/components/HapticCopy.vue +256 -0
  103. package/lib/components/ImddbHeader.vue +336 -0
  104. package/lib/components/OrdinalLegend.vue +164 -0
  105. package/lib/components/RangePicker.vue +430 -0
  106. package/lib/components/ResponsiveIframe.vue +48 -0
  107. package/lib/components/ScaleLegend.vue +230 -0
  108. package/lib/components/SecretInput.vue +132 -0
  109. package/lib/components/SelectableDropdown.vue +368 -0
  110. package/lib/components/SharingOptions.vue +230 -0
  111. package/lib/components/SharingOptionsLink.vue +259 -0
  112. package/lib/components/SignUpForm.vue +181 -0
  113. package/lib/components/SlideUpDown.vue +131 -0
  114. package/lib/components/TexturedDeck.vue +101 -0
  115. package/lib/components/TinyPagination.vue +268 -0
  116. package/lib/components/index.js +31 -0
  117. package/lib/composables/chart.ts +182 -0
  118. package/lib/composables/resizeObserver.ts +37 -0
  119. package/lib/composables/sendEmail.ts +50 -0
  120. package/lib/config.default.ts +33 -0
  121. package/lib/config.ts +70 -0
  122. package/lib/d3-geo-projection.d.ts +1 -0
  123. package/lib/datavisualisations/BarChart.vue +275 -0
  124. package/lib/datavisualisations/ColumnChart.vue +527 -0
  125. package/lib/datavisualisations/LineChart.vue +274 -0
  126. package/lib/datavisualisations/StackedBarChart.vue +614 -0
  127. package/lib/datavisualisations/StackedColumnChart.vue +640 -0
  128. package/lib/datavisualisations/index.js +5 -0
  129. package/lib/enums.ts +25 -0
  130. package/lib/i18n.ts +16 -0
  131. package/lib/keys.ts +2 -0
  132. package/lib/locales/en.json +140 -0
  133. package/lib/locales/fr.json +117 -0
  134. package/lib/locales/locales/en.json +140 -0
  135. package/lib/locales/locales/fr.json +117 -0
  136. package/lib/main.ts +87 -0
  137. package/lib/maps/ChoroplethMap.vue +825 -0
  138. package/lib/maps/ChoroplethMapAnnotation.vue +336 -0
  139. package/lib/maps/SymbolMap.vue +628 -0
  140. package/lib/maps/index.js +3 -0
  141. package/lib/querystring-es3.d.ts +1 -0
  142. package/lib/shims-bootstrap-vue.d.ts +5 -0
  143. package/lib/shims-tsx.d.ts +11 -0
  144. package/lib/shims-vue.d.ts +14 -0
  145. package/lib/styles/functions.scss +20 -0
  146. package/lib/styles/lib.scss +19 -0
  147. package/lib/styles/mixins.scss +37 -0
  148. package/lib/styles/utilities.scss +18 -0
  149. package/lib/styles/variables.scss +94 -0
  150. package/lib/styles/variables_dark.scss +1 -0
  151. package/lib/types.ts +46 -0
  152. package/lib/utils/animation.ts +24 -0
  153. package/lib/utils/assets.ts +46 -0
  154. package/lib/utils/clipboard.ts +41 -0
  155. package/lib/utils/iframe-resizer.ts +49 -0
  156. package/lib/utils/placeholder.ts +66 -0
  157. package/lib/utils/placeholderTypes.ts +21 -0
  158. package/lib/utils/strings.ts +8 -0
  159. package/loaders/highlight-loader.js +13 -0
  160. package/loaders/markdown-loader.js +91 -0
  161. package/loaders/metadata-loader.js +18 -0
  162. package/loaders/sass-extract-loader.js +14 -0
  163. package/loaders/vue-docgen-loader.js +14 -0
  164. package/package.json +96 -0
  165. package/plugins/MdPluginTypes.ts +10 -0
  166. package/plugins/docs.ts +50 -0
  167. package/plugins/front-matter.ts +36 -0
  168. package/plugins/highlight.ts +27 -0
  169. package/plugins/markdown-it/api-table.ts +25 -0
  170. package/plugins/markdown-it/sample-card.ts +31 -0
  171. package/plugins/plugin-delete.ts +47 -0
  172. package/plugins/plugin-docgen.ts +23 -0
  173. package/plugins/sass-vars.ts +25 -0
  174. package/plugins/vue-docgen.ts +29 -0
  175. package/public/android-chrome-192x192.png +0 -0
  176. package/public/android-chrome-512x512.png +0 -0
  177. package/public/apple-touch-icon.png +0 -0
  178. package/public/assets/img/arrow-bottom.svg +3 -0
  179. package/public/assets/img/texture-brick-black.jpg +0 -0
  180. package/public/assets/img/texture-brick.jpg +0 -0
  181. package/public/assets/img/texture-carbon-black.jpg +0 -0
  182. package/public/assets/img/texture-carbon.jpg +0 -0
  183. package/public/assets/img/texture-crack-black.jpg +0 -0
  184. package/public/assets/img/texture-crack.jpg +0 -0
  185. package/public/assets/img/texture-rock-black.jpg +0 -0
  186. package/public/assets/img/texture-rock.jpg +0 -0
  187. package/public/assets/img/texture-sand-black.jpg +0 -0
  188. package/public/assets/img/texture-sand.jpg +0 -0
  189. package/public/assets/img/texture-silk-black.jpg +0 -0
  190. package/public/assets/img/texture-silk.jpg +0 -0
  191. package/public/assets/topojson/france-departments.json +1 -0
  192. package/public/assets/topojson/paris-arrondissements.json +1 -0
  193. package/public/assets/topojson/world-countries-sans-antarctica.json +1 -0
  194. package/public/favicon-16x16.png +0 -0
  195. package/public/favicon-32x32.png +0 -0
  196. package/public/favicon.ico +0 -0
  197. package/public/site.webmanifest +1 -0
  198. package/stories/assets/code-brackets.svg +1 -0
  199. package/stories/assets/colors.svg +1 -0
  200. package/stories/assets/comments.svg +1 -0
  201. package/stories/assets/direction.svg +1 -0
  202. package/stories/assets/flow.svg +1 -0
  203. package/stories/assets/plugin.svg +1 -0
  204. package/stories/assets/repo.svg +1 -0
  205. package/stories/assets/stackalt.svg +1 -0
  206. package/stories/getting-started/about-icij.mdx +14 -0
  207. package/stories/getting-started/custom-bootstrap.mdx +23 -0
  208. package/stories/getting-started/installation-guide.mdx +62 -0
  209. package/stories/getting-started/internationalization.mdx +63 -0
  210. package/stories/murmur/components/AccordionStep.stories.ts +33 -0
  211. package/stories/murmur/components/AccordionWrapper.stories.ts +69 -0
  212. package/stories/murmur/components/ActiveTextTruncate.stories.ts +32 -0
  213. package/stories/murmur/components/AdvancedLinkForm.stories.ts +77 -0
  214. package/stories/murmur/components/Brand.stories.ts +30 -0
  215. package/stories/murmur/components/BrandExpansion.stories.ts +41 -0
  216. package/stories/murmur/components/ConfirmButton.stories.ts +40 -0
  217. package/stories/murmur/components/ContentPlaceholder.stories.ts +41 -0
  218. package/stories/murmur/components/CustomPagination.stories.ts +42 -0
  219. package/stories/murmur/components/DigitsInput.stories.ts +29 -0
  220. package/stories/murmur/components/DonateForm.stories.ts +29 -0
  221. package/stories/murmur/components/EmbedForm.stories.ts +35 -0
  222. package/stories/murmur/components/EmbeddableFooter.stories.ts +59 -0
  223. package/stories/murmur/components/FollowUsPopover.stories.ts +24 -0
  224. package/stories/murmur/components/GenericFooter.stories.ts +27 -0
  225. package/stories/murmur/components/GenericHeader.stories.ts +27 -0
  226. package/stories/murmur/components/HapticCopy.stories.ts +40 -0
  227. package/stories/murmur/components/ImddbHeader.stories.ts +27 -0
  228. package/stories/murmur/components/OrdinalLegend.stories.ts +49 -0
  229. package/stories/murmur/components/RangePicker.stories.ts +98 -0
  230. package/stories/murmur/components/ResponsiveIframe.stories.ts +24 -0
  231. package/stories/murmur/components/ScaleLegend.stories.ts +65 -0
  232. package/stories/murmur/components/SecretInput.stories.ts +60 -0
  233. package/stories/murmur/components/SelectableDropdown.stories.ts +143 -0
  234. package/stories/murmur/components/SharingOptions.stories.ts +32 -0
  235. package/stories/murmur/components/SharingOptionsLink.stories.ts +53 -0
  236. package/stories/murmur/components/SignUpForm.stories.ts +51 -0
  237. package/stories/murmur/components/SlideUpDown.stories.ts +32 -0
  238. package/stories/murmur/components/TexturedDeck.stories.ts +83 -0
  239. package/stories/murmur/components/TinyPagination.stories.ts +65 -0
  240. package/stories/murmur/datavisualisations/BarChart.stories.ts +54 -0
  241. package/stories/murmur/datavisualisations/ColumnChart.stories.ts +88 -0
  242. package/stories/murmur/datavisualisations/LineChart.stories.ts +139 -0
  243. package/stories/murmur/datavisualisations/StackedBarChart.stories.ts +199 -0
  244. package/stories/murmur/datavisualisations/StackedColumnChart.stories.ts +136 -0
  245. package/stories/murmur/decorators.ts +108 -0
  246. package/stories/murmur/maps/ChoroplethMap.stories.ts +440 -0
  247. package/stories/murmur/maps/ChoroplethMapAnnotation.stories.ts +26 -0
  248. package/stories/murmur/maps/SymbolMap.stories.ts +24 -0
  249. package/stories/murmur/utils.ts +7 -0
  250. package/tests/unit/components/AccordionStep.spec.ts +157 -0
  251. package/tests/unit/components/AccordionWrapper.spec.ts +57 -0
  252. package/tests/unit/components/ActiveTextTruncate.spec.js +30 -0
  253. package/tests/unit/components/AdvancedLinkForm.spec.js +124 -0
  254. package/tests/unit/components/Brand.spec.js +50 -0
  255. package/tests/unit/components/ContentPlaceholder.spec.js +29 -0
  256. package/tests/unit/components/CustomPagination.spec.js +72 -0
  257. package/tests/unit/components/DigitsInput.spec.ts +157 -0
  258. package/tests/unit/components/DonateForm.spec.js +149 -0
  259. package/tests/unit/components/EmbedForm.spec.js +108 -0
  260. package/tests/unit/components/EmbeddableFooter.spec.js +11 -0
  261. package/tests/unit/components/Fa.spec.js +18 -0
  262. package/tests/unit/components/FollowUsPopover.spec.js +29 -0
  263. package/tests/unit/components/GenericFooter.spec.js +29 -0
  264. package/tests/unit/components/GenericHeader.spec.js +104 -0
  265. package/tests/unit/components/HapticCopy.spec.js +123 -0
  266. package/tests/unit/components/ImddbHeader.spec.js +96 -0
  267. package/tests/unit/components/OrdinalLegend.spec.js +120 -0
  268. package/tests/unit/components/RangePicker.spec.ts +87 -0
  269. package/tests/unit/components/ResponsiveIframe.spec.js +20 -0
  270. package/tests/unit/components/ScaleLegend.spec.js +139 -0
  271. package/tests/unit/components/SecretInput.spec.js +81 -0
  272. package/tests/unit/components/SelectableDropdown.spec.js +160 -0
  273. package/tests/unit/components/SharingOptions.spec.js +125 -0
  274. package/tests/unit/components/SharingOptionsLink.spec.js +184 -0
  275. package/tests/unit/components/SignUpForm.spec.js +145 -0
  276. package/tests/unit/components/SlideUpDown.spec.js +59 -0
  277. package/tests/unit/components/TinyPagination.spec.js +46 -0
  278. package/tests/unit/config.spec.js +136 -0
  279. package/tests/unit/datavisualisations/BarChart.spec.js +63 -0
  280. package/tests/unit/datavisualisations/ColumnChart.spec.js +344 -0
  281. package/tests/unit/datavisualisations/LineChart.spec.js +155 -0
  282. package/tests/unit/datavisualisations/StackedBarChart.spec.js +294 -0
  283. package/tests/unit/datavisualisations/StackedColumnChart.spec.js +443 -0
  284. package/tests/unit/i18n.spec.ts +19 -0
  285. package/tests/unit/main.spec.js +82 -0
  286. package/tests/unit/maps/ChoroplethMap.spec.js +214 -0
  287. package/tests/unit/maps/ChoroplethMapAnnotation.spec.ts +186 -0
  288. package/tests/unit/maps/SymbolMap.spec.js +92 -0
  289. package/tests/unit/require.spec.js +22 -0
  290. package/tests/unit/setup.js +13 -0
  291. package/tests/unit/utils/assets.spec.js +61 -0
  292. package/tests/unit/utils/clipboard.spec.js +18 -0
  293. package/tests/unit/utils/iframe-resizer.spec.js +71 -0
  294. package/tsconfig.json +35 -0
  295. package/vite.config.ts +79 -0
  296. package/vitest.config.ts +19 -0
@@ -0,0 +1,527 @@
1
+ <script lang="ts">
2
+ import {ComponentPublicInstance, computed, defineComponent, PropType, ref, watchEffect,onMounted} from 'vue'
3
+ import {identity, iteratee, sortBy} from 'lodash'
4
+ import * as d3 from 'd3'
5
+ import {chartProps, getChartProps, useChart} from "@/composables/chart";
6
+
7
+ type ColumnBar = {
8
+ datum: { [timeSerie: string]: any },
9
+ width: number,
10
+ height: number,
11
+ x: number,
12
+ y: number,
13
+ }
14
+ //import chart from '../mixins/chart'
15
+
16
+ export default defineComponent({
17
+ name: 'ColumnChart',
18
+ //mixins: [chart],
19
+ props: {
20
+ /**
21
+ * Color of each column (uses the CSS variable --column-color by default)
22
+ */
23
+ columnColor: {
24
+ type: String as PropType<string>,
25
+ default: null
26
+ },
27
+ /**
28
+ * Color of each highlighted column (uses the CSS variable --column-color by default)
29
+ */
30
+ columnHighlightColor: {
31
+ type: String as PropType<string>,
32
+ default: null
33
+ },
34
+ /**
35
+ * Enforce the height of the chart (regardless of the width or the social mode)
36
+ */
37
+ fixedHeight: {
38
+ type: Number as PropType<number>,
39
+ default: null
40
+ },
41
+ /**
42
+ * Enforce a width for each column's label
43
+ */
44
+ fixedLabelWidth: {
45
+ type: Number as PropType<number>,
46
+ default: null
47
+ },
48
+ /**
49
+ * Name of the series (to get the value from in the data collection objects)
50
+ */
51
+ seriesName: {
52
+ type: String as PropType<string>,
53
+ default: 'value'
54
+ },
55
+ /**
56
+ * Hide x axis ticks when no enough space
57
+ */
58
+ xAxisTickCollapse: {
59
+ type: Boolean as PropType<boolean> as PropType<boolean>,
60
+ default: false
61
+ },
62
+ /**
63
+ * Function to apply to format x axis ticks
64
+ */
65
+ xAxisTickFormat: {
66
+ type: [Function, String] as PropType<Function | string >,
67
+ default: ()=>identity
68
+ },
69
+ /**
70
+ * Definition of x axis ticks
71
+ */
72
+ xAxisTicks: {
73
+ type: Array as PropType<string[] | null>,
74
+ default: null
75
+ },
76
+ /**
77
+ * Function to apply to format y axis ticks
78
+ */
79
+ yAxisTickFormat: {
80
+ type: [Function, String] as PropType<Function | string >,
81
+ default: ()=>identity
82
+ },
83
+ /**
84
+ * Definition of y axis ticks
85
+ */
86
+ yAxisTicks: {
87
+ type: [Number, Object] as PropType<number | object>,
88
+ default: 5
89
+ },
90
+ /**
91
+ * Sort columns by one or several keys.
92
+ */
93
+ sortBy: {
94
+ type: [Array, String] as PropType<string | string[]>,
95
+ default: null
96
+ },
97
+ /**
98
+ * Key to use for timeseries
99
+ */
100
+ timeseriesKey: {
101
+ type: String as PropType<string>,
102
+ default: 'date'
103
+ },
104
+ /**
105
+ * Set max value instead of extracting it from the data.
106
+ */
107
+ maxValue: {
108
+ type: Number as PropType<number>,
109
+ default: null
110
+ },
111
+ /**
112
+ * Hide bar tooltips
113
+ */
114
+ noTooltips: {
115
+ type: Boolean as PropType<boolean>
116
+ },
117
+ /**
118
+ * Hide x axis
119
+ */
120
+ noXAxis: {
121
+ type: Boolean as PropType<boolean>
122
+ },
123
+ /**
124
+ * Hide y axis
125
+ */
126
+ noYAxis: {
127
+ type: Boolean as PropType<boolean>
128
+ },
129
+ /**
130
+ * Bar padding as a portion of each bar width
131
+ */
132
+ barPadding: {
133
+ type: Number as PropType<number>,
134
+ default: 0.35
135
+ },
136
+ /**
137
+ * Bar margin in pixel
138
+ */
139
+ barMargin: {
140
+ type: Number as PropType<number>,
141
+ default: 0
142
+ },
143
+ /**
144
+ * A list of highlighted key
145
+ */
146
+ highlights: {
147
+ type: Array as PropType<string[]>,
148
+ default: () => []
149
+ },
150
+ /**
151
+ * Show a "placeholder" behind every bar
152
+ */
153
+ stripped: {
154
+ type: Boolean as PropType<boolean>
155
+ },
156
+ /**
157
+ * Show a "placeholder" behind every bar on hover
158
+ */
159
+ hover: {
160
+ type: Boolean as PropType<boolean>
161
+ },
162
+ ...chartProps()
163
+ },
164
+ setup(props, {emit}) {
165
+ const width = ref(0)
166
+ const height = ref(0)
167
+ const shownTooltip = ref(-1)
168
+ const el = ref<ComponentPublicInstance<HTMLElement> | null>(null)
169
+ const isLoaded = ref(false)
170
+ const {
171
+ loadedData,
172
+ elementsMaxBBox,
173
+ d3Formatter,
174
+ baseHeightRatio,
175
+ dataHasHighlights
176
+ } = useChart(el, getChartProps(props), {emit}, isLoaded, setSizes)
177
+
178
+ const sortedData = computed((): any[] => {
179
+ if (!loadedData.value) {
180
+ return []
181
+ }
182
+ return !props.sortBy ? loadedData.value : sortBy(sortedData.value, props.sortBy)
183
+ })
184
+
185
+ const labelWidth = computed((): number => {
186
+ if (props.fixedLabelWidth) {
187
+ return props.fixedLabelWidth
188
+ }
189
+ const selector = '.column-chart__axis--y .tick text'
190
+ const defaultWidth = 100
191
+ return elementsMaxBBox({selector, defaultWidth}).width
192
+ })
193
+
194
+ const labelHeight = computed((): number => {
195
+ if (props.noYAxis) {
196
+ return 0
197
+ }
198
+ const selector = '.column-chart__axis--y .tick text'
199
+ const defaultHeight = 10
200
+ return elementsMaxBBox({selector, defaultHeight}).height
201
+ })
202
+
203
+ const bucketHeight = computed((): number => {
204
+
205
+ if (props.noXAxis) {
206
+ return 0
207
+ }
208
+ const selector = '.column-chart__axis--x .tick text'
209
+ const defaultHeight = 10
210
+ return elementsMaxBBox({selector, defaultHeight}).height
211
+ })
212
+
213
+ const bucketWidth = computed((): number => {
214
+ const selector = '.column-chart__axis--x .tick text'
215
+ const defaultWidth = 100
216
+ return elementsMaxBBox({selector, defaultWidth}).width
217
+ })
218
+
219
+ const margin = computed((): { left: number; right: number; top: number; bottom: number } => {
220
+ return {
221
+ left: props.noYAxis ? 0 : labelWidth.value + 10,
222
+ right: 0,
223
+ top: labelHeight.value / 2,
224
+ bottom: props.noXAxis ? 0 : bucketHeight.value + 10
225
+ }
226
+ })
227
+
228
+ const padded = computed((): { width: number; height: number } => {
229
+ const widthP = width.value - margin.value.left - margin.value.right
230
+ const heightP = height.value - margin.value.top - margin.value.bottom
231
+ return {width: widthP, height: heightP}
232
+ })
233
+
234
+ const scaleX = computed((): d3.ScaleBand<string> => {
235
+ return d3
236
+ .scaleBand()
237
+ .domain(sortedData.value.map(iteratee(props.timeseriesKey)))
238
+ .range([0, padded.value.width])
239
+ .padding(props.barPadding)
240
+ })
241
+
242
+ const scaleY = computed((): d3.ScaleLinear<number, number> => {
243
+ const maxValue = props.maxValue ?? d3.max(sortedData.value, iteratee(props.seriesName))
244
+ return d3.scaleLinear().domain([0, maxValue]).range([padded.value.height, 0])
245
+ })
246
+
247
+ const bars = computed((): ColumnBar[] => {
248
+ return sortedData.value.map((datum: any) => {
249
+ return {
250
+ datum,
251
+ width: Math.max(1, Math.abs(scaleX.value.bandwidth()) - props.barMargin),
252
+ height: Math.abs(padded.value.height - scaleY.value(datum[props.seriesName])),
253
+ x: (scaleX.value(datum[props.timeseriesKey]) ?? 0) + props.barMargin / 2,
254
+ y: scaleY.value(datum[props.seriesName]) ?? 0
255
+ }
256
+ })
257
+ })
258
+
259
+ const xAxisHiddenTicks = computed((): number => {
260
+ if (!props.xAxisTickCollapse) {
261
+ return 0
262
+ }
263
+
264
+ const hiddenTicks = d3.range(1, sortedData.value.length).find((mod) => {
265
+ const bucketWidthT = bucketWidth.value * 1.5
266
+ return width.value / (bucketWidthT / mod) >= sortedData.value.length
267
+ })
268
+
269
+ return hiddenTicks ?? sortedData.value.length
270
+ })
271
+
272
+ const xAxisTickValues = computed((): string[] => {
273
+ // Either use the explicit `xAxisTicks` prop or use the data
274
+ const ticks = props.xAxisTicks ?? sortedData.value.map(iteratee(props.timeseriesKey))
275
+ // Then filter out ticks according to `this.xAxisHiddenTicks`
276
+ return ticks.map((tick, i) => {
277
+ return (i + 1) % xAxisHiddenTicks.value ? null : tick
278
+ })
279
+ })
280
+
281
+ const xAxis = computed((): d3.Axis<string> => {
282
+ return d3
283
+ .axisBottom(scaleX.value)
284
+ .tickFormat((d) => d3Formatter(d, props.xAxisTickFormat))
285
+ .tickValues(xAxisTickValues.value)
286
+ })
287
+
288
+ const yAxis = computed((): d3.Axis<d3.NumberValue> => {
289
+ return d3
290
+ .axisLeft(scaleY.value)
291
+ .tickFormat((d) =>d3Formatter(d, props.yAxisTickFormat))
292
+ .ticks(props.yAxisTicks)
293
+ }
294
+ )
295
+
296
+ function formatXDatum(d: any) {
297
+ return d3Formatter(d,props.xAxisTickFormat)
298
+ }
299
+
300
+ function formatYDatum(d: any) {
301
+ return d3Formatter(d,props.yAxisTickFormat)
302
+ }
303
+
304
+ function setSizes() {
305
+ width.value = (el.value as HTMLElement)?.offsetWidth ?? 0
306
+ height.value = props.fixedHeight !== null ? props.fixedHeight : width.value * baseHeightRatio.value
307
+ }
308
+
309
+ function select({datum}: { datum: any }) {
310
+ /**
311
+ * Fired when a column is selected
312
+ * @event click
313
+ * @param Mixed New step value.
314
+ */
315
+ emit("select", datum)
316
+ }
317
+
318
+ function update() {
319
+ if (!el.value) {
320
+ return
321
+ }
322
+ d3.select(el.value)
323
+ .select('.column-chart__axis--x')
324
+ .call(xAxis.value as any)
325
+ .select('.domain')
326
+ .remove()
327
+
328
+ d3.select(el.value)
329
+ .select('.column-chart__axis--y')
330
+ .call(yAxis.value as any)
331
+ .selectAll('.tick line')
332
+ .attr('x2', padded.value.width)
333
+ }
334
+
335
+ function barTooltipStyle(bar: { x: number, y: number, width: number }) {
336
+ const top = `${bar.y + margin.value.top}px`
337
+ const left = `${bar.x + bar.width / 2 + margin.value.left}px`
338
+ return {top, left}
339
+ }
340
+
341
+ function highlighted(datum: any): boolean {
342
+ return datum.highlight || props.highlights.includes(datum[props.timeseriesKey])
343
+ }
344
+
345
+
346
+ watchEffect(async () => {
347
+ update()
348
+
349
+ })
350
+
351
+ return {
352
+ el,
353
+ dataHasHighlights,
354
+ width,
355
+ height,
356
+ margin,
357
+ padded,
358
+ shownTooltip,
359
+ bars,
360
+ select,
361
+ highlighted,
362
+ barTooltipStyle,
363
+ formatYDatum,
364
+ formatXDatum
365
+ }
366
+ }
367
+ })
368
+ </script>
369
+
370
+ <template>
371
+ <div
372
+ ref="el"
373
+ :class="{
374
+ 'column-chart--has-highlights': dataHasHighlights,
375
+ 'column-chart--hover': hover,
376
+ 'column-chart--stripped': stripped,
377
+ 'column-chart--social-mode': socialMode
378
+ }"
379
+ :style="{ '--column-color': columnColor, '--column-highlight-color': columnHighlightColor }"
380
+ class="column-chart"
381
+ >
382
+ <svg
383
+ :height="height" :width="width">
384
+ <g :style="{ transform: `translate(${margin.left}px, ${margin.top}px)` }">
385
+ <g
386
+ v-if="!noXAxis"
387
+ :style="{ transform: `translate(0, ${padded.height}px)` }"
388
+ class="column-chart__axis column-chart__axis--x"
389
+ />
390
+ <g v-if="!noYAxis" class="column-chart__axis column-chart__axis--y"/>
391
+ </g>
392
+ <g :style="{ transform: `translate(${margin.left}px, ${margin.top}px)` }" class="column-chart__columns">
393
+ <g
394
+ v-for="(bar, index) in bars"
395
+ :key="index"
396
+ :class="{ 'column-chart__columns__item--highlight': highlighted(bar.datum) }"
397
+ :style="{ transform: `translate(${bar.x}px, 0px)` }"
398
+ class="column-chart__columns__item"
399
+ @click="select(bar)"
400
+ @mouseleave="shownTooltip = -1"
401
+ @mouseover="shownTooltip = index"
402
+ >
403
+ <rect :height="padded.height" :width="bar.width" class="column-chart__columns__item__placeholder"/>
404
+ <rect :height="bar.height" :width="bar.width" :y="bar.y" class="column-chart__columns__item__bar"/>
405
+ </g>
406
+ </g>
407
+ </svg>
408
+ <div v-if="!noTooltips" class="column-chart__tooltips">
409
+ <div v-for="(bar, index) in bars" :key="index">
410
+ <div :style="barTooltipStyle(bar)" class="column-chart__tooltips__item">
411
+ <transition name="fade">
412
+ <div v-if="shownTooltip === index" class="column-chart__tooltips__item__wrapper">
413
+ <slot name="tooltip" v-bind="bar">
414
+ <h6 class="column-chart__tooltips__item__wrapper__heading mb-0">
415
+ {{ formatXDatum(bar.datum[timeseriesKey]) }}
416
+ </h6>
417
+ <div class="column-chart__tooltips__item__wrapper__value">
418
+ {{ formatYDatum(bar.datum[seriesName]) }}
419
+ </div>
420
+ </slot>
421
+ </div>
422
+ </transition>
423
+ </div>
424
+ </div>
425
+ </div>
426
+ </div>
427
+ </template>
428
+
429
+
430
+ <style lang="scss">
431
+ @import '../styles/lib';
432
+
433
+ .column-chart {
434
+ --highlight-opacity: 0.7;
435
+ --placeholder-opacity: 0.1;
436
+
437
+ position: relative;
438
+
439
+ &--has-highlights &__columns__item:not(&__columns__item--highlight):not(:hover) {
440
+ opacity: var(--highlight-opacity);
441
+ filter: grayscale(30%);
442
+ }
443
+
444
+ text {
445
+ font-family: $font-family-base;
446
+ font-size: $font-size-sm;
447
+ fill: currentColor;
448
+ }
449
+
450
+ &__columns__item {
451
+ fill: var(--column-color, var(--dark, $dark));
452
+
453
+ &--highlight {
454
+ fill: var(--column-highlight-color, var(--primary, $primary));
455
+ }
456
+
457
+ &__placeholder {
458
+ opacity: 0;
459
+
460
+ .column-chart--stripped &,
461
+ .column-chart--hover .column-chart__columns__item:hover & {
462
+ opacity: var(--placeholder-opacity);
463
+ }
464
+ }
465
+ }
466
+
467
+ &__axis {
468
+ .domain {
469
+ display: none;
470
+ }
471
+
472
+ .tick line {
473
+ stroke: $border-color;
474
+ }
475
+
476
+ &--x .tick line {
477
+ display: none;
478
+ }
479
+ }
480
+
481
+ &__tooltips {
482
+ pointer-events: none;
483
+ position: absolute;
484
+ top: 0;
485
+ left: 0;
486
+
487
+ &__item {
488
+ display: inline-flex;
489
+ text-align: center;
490
+ flex-direction: row;
491
+ align-items: flex-end;
492
+ justify-content: flex-start;
493
+ position: absolute;
494
+ transform: translate(-50%, -100%);
495
+ margin-top: -0.5 * $tooltip-arrow-width;
496
+
497
+ &__wrapper {
498
+ max-width: $tooltip-max-width;
499
+ background: rgba($tooltip-bg, $tooltip-opacity);
500
+ border-radius: $tooltip-border-radius;
501
+ color: $tooltip-color;
502
+ margin: 0;
503
+ padding: $tooltip-padding-y $tooltip-padding-x;
504
+ &.fade-enter-active,
505
+ &.fade-leave-active {
506
+ transition: $transition-fade;
507
+ }
508
+
509
+ &.fade-enter-from,
510
+ &.fade-leave-to {
511
+ opacity: 0;
512
+ }
513
+
514
+ &:after {
515
+ content: '';
516
+ border: ($tooltip-arrow-width * 0.5) solid transparent;
517
+ border-top-color: rgba($tooltip-bg, $tooltip-opacity);
518
+ transform: translateX(-50%);
519
+ position: absolute;
520
+ left: 50%;
521
+ top: 100%;
522
+ }
523
+ }
524
+ }
525
+ }
526
+ }
527
+ </style>