@buildcanada/charts 0.1.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 (404) hide show
  1. package/LICENSE.md +8 -0
  2. package/README.md +113 -0
  3. package/package.json +137 -0
  4. package/src/components/BodyPortal/BodyPortal.tsx +40 -0
  5. package/src/components/Button/Button.scss +110 -0
  6. package/src/components/Button/Button.tsx +101 -0
  7. package/src/components/Checkbox.scss +93 -0
  8. package/src/components/Checkbox.tsx +47 -0
  9. package/src/components/ExpandableToggle/ExpandableToggle.scss +123 -0
  10. package/src/components/ExpandableToggle/ExpandableToggle.tsx +60 -0
  11. package/src/components/GrapherTabIcon.tsx +156 -0
  12. package/src/components/GrapherTrendArrow.scss +16 -0
  13. package/src/components/GrapherTrendArrow.tsx +30 -0
  14. package/src/components/Halo/Halo.tsx +44 -0
  15. package/src/components/LabeledSwitch/LabeledSwitch.scss +109 -0
  16. package/src/components/LabeledSwitch/LabeledSwitch.tsx +62 -0
  17. package/src/components/MarkdownTextWrap/MarkdownTextWrap.tsx +1173 -0
  18. package/src/components/OverlayHeader.scss +18 -0
  19. package/src/components/OverlayHeader.tsx +29 -0
  20. package/src/components/RadioButton.scss +69 -0
  21. package/src/components/RadioButton.tsx +42 -0
  22. package/src/components/SimpleMarkdownText.tsx +89 -0
  23. package/src/components/TextInput.scss +17 -0
  24. package/src/components/TextInput.tsx +19 -0
  25. package/src/components/TextWrap/TextWrap.tsx +361 -0
  26. package/src/components/TextWrap/TextWrapUtils.ts +32 -0
  27. package/src/components/closeButton/CloseButton.scss +40 -0
  28. package/src/components/closeButton/CloseButton.tsx +27 -0
  29. package/src/components/index.ts +70 -0
  30. package/src/components/loadingIndicator/LoadingIndicator.scss +40 -0
  31. package/src/components/loadingIndicator/LoadingIndicator.tsx +28 -0
  32. package/src/components/markdown/remarkPlainLinks.ts +36 -0
  33. package/src/components/reactUtil.ts +20 -0
  34. package/src/components/stubs/CodeSnippet.tsx +19 -0
  35. package/src/components/stubs/DataCitation.tsx +16 -0
  36. package/src/components/stubs/IndicatorKeyData.tsx +45 -0
  37. package/src/components/stubs/IndicatorProcessing.tsx +15 -0
  38. package/src/components/stubs/IndicatorSources.tsx +15 -0
  39. package/src/components/styles/colors.scss +113 -0
  40. package/src/components/styles/mixins.scss +630 -0
  41. package/src/components/styles/typography.scss +579 -0
  42. package/src/components/styles/util.scss +89 -0
  43. package/src/components/styles/variables.scss +208 -0
  44. package/src/config/ChartsConfig.ts +163 -0
  45. package/src/config/ChartsProvider.tsx +157 -0
  46. package/src/config/index.ts +20 -0
  47. package/src/core-table/CoreTable.ts +1355 -0
  48. package/src/core-table/CoreTableColumns.ts +973 -0
  49. package/src/core-table/CoreTableUtils.ts +793 -0
  50. package/src/core-table/ErrorValues.ts +73 -0
  51. package/src/core-table/OwidTable.ts +1175 -0
  52. package/src/core-table/OwidTableSynthesizers.ts +272 -0
  53. package/src/core-table/OwidTableUtil.ts +76 -0
  54. package/src/core-table/Transforms.ts +484 -0
  55. package/src/core-table/index.ts +82 -0
  56. package/src/explorer/ColumnGrammar.ts +217 -0
  57. package/src/explorer/Explorer.sample.ts +212 -0
  58. package/src/explorer/Explorer.scss +148 -0
  59. package/src/explorer/Explorer.tsx +1283 -0
  60. package/src/explorer/ExplorerConstants.ts +85 -0
  61. package/src/explorer/ExplorerControls.scss +156 -0
  62. package/src/explorer/ExplorerControls.tsx +210 -0
  63. package/src/explorer/ExplorerDecisionMatrix.ts +471 -0
  64. package/src/explorer/ExplorerGrammar.ts +161 -0
  65. package/src/explorer/ExplorerProgram.ts +568 -0
  66. package/src/explorer/ExplorerUtils.ts +59 -0
  67. package/src/explorer/GrapherGrammar.ts +387 -0
  68. package/src/explorer/gridLang/GrammarUtils.ts +121 -0
  69. package/src/explorer/gridLang/GridCell.ts +298 -0
  70. package/src/explorer/gridLang/GridLangConstants.ts +255 -0
  71. package/src/explorer/gridLang/GridProgram.ts +311 -0
  72. package/src/explorer/gridLang/readme.md +17 -0
  73. package/src/explorer/index.ts +69 -0
  74. package/src/explorer/readme.md +19 -0
  75. package/src/explorer/urlMigrations/CO2UrlMigration.ts +46 -0
  76. package/src/explorer/urlMigrations/CovidUrlMigration.ts +37 -0
  77. package/src/explorer/urlMigrations/EnergyUrlMigration.ts +41 -0
  78. package/src/explorer/urlMigrations/ExplorerPageUrlMigrationSpec.ts +12 -0
  79. package/src/explorer/urlMigrations/ExplorerUrlMigrationUtils.ts +45 -0
  80. package/src/explorer/urlMigrations/ExplorerUrlMigrations.ts +33 -0
  81. package/src/explorer/urlMigrations/LegacyCovidUrlMigration.ts +144 -0
  82. package/src/explorer/urlMigrations/readme.md +39 -0
  83. package/src/grapher/axis/Axis.ts +973 -0
  84. package/src/grapher/axis/AxisConfig.ts +179 -0
  85. package/src/grapher/axis/AxisViews.tsx +597 -0
  86. package/src/grapher/barCharts/DiscreteBarChart.tsx +728 -0
  87. package/src/grapher/barCharts/DiscreteBarChartConstants.ts +60 -0
  88. package/src/grapher/barCharts/DiscreteBarChartHelpers.ts +338 -0
  89. package/src/grapher/barCharts/DiscreteBarChartState.ts +354 -0
  90. package/src/grapher/barCharts/DiscreteBarChartThumbnail.tsx +34 -0
  91. package/src/grapher/captionedChart/CaptionedChart.scss +61 -0
  92. package/src/grapher/captionedChart/CaptionedChart.tsx +523 -0
  93. package/src/grapher/captionedChart/Logos.tsx +141 -0
  94. package/src/grapher/captionedChart/LogosSVG.tsx +16 -0
  95. package/src/grapher/captionedChart/StaticChartRasterizer.tsx +178 -0
  96. package/src/grapher/captionedChart/assets/buildcanada-logo-square.svg +15 -0
  97. package/src/grapher/captionedChart/assets/buildcanada-logo.svg +15 -0
  98. package/src/grapher/captionedChart/assets/canadaspends.svg +7 -0
  99. package/src/grapher/captionedChart/readme.md +14 -0
  100. package/src/grapher/chart/Chart.tsx +62 -0
  101. package/src/grapher/chart/ChartAreaContent.tsx +172 -0
  102. package/src/grapher/chart/ChartDimension.ts +121 -0
  103. package/src/grapher/chart/ChartInterface.ts +83 -0
  104. package/src/grapher/chart/ChartManager.ts +113 -0
  105. package/src/grapher/chart/ChartTabs.ts +178 -0
  106. package/src/grapher/chart/ChartTypeMap.tsx +158 -0
  107. package/src/grapher/chart/ChartTypeSwitcher.tsx +26 -0
  108. package/src/grapher/chart/ChartUtils.tsx +364 -0
  109. package/src/grapher/chart/DimensionSlot.ts +45 -0
  110. package/src/grapher/chart/StaticChartWrapper.tsx +94 -0
  111. package/src/grapher/chart/guidedChartUtils.ts +82 -0
  112. package/src/grapher/color/BinningStrategies.ts +484 -0
  113. package/src/grapher/color/BinningStrategyEqualSizeBins.ts +132 -0
  114. package/src/grapher/color/BinningStrategyLogarithmic.ts +121 -0
  115. package/src/grapher/color/CategoricalColorAssigner.ts +97 -0
  116. package/src/grapher/color/ColorBrewerSchemes.ts +80 -0
  117. package/src/grapher/color/ColorConstants.ts +20 -0
  118. package/src/grapher/color/ColorScale.ts +339 -0
  119. package/src/grapher/color/ColorScaleBin.ts +147 -0
  120. package/src/grapher/color/ColorScaleConfig.ts +204 -0
  121. package/src/grapher/color/ColorScheme.ts +137 -0
  122. package/src/grapher/color/ColorSchemes.ts +149 -0
  123. package/src/grapher/color/ColorUtils.ts +86 -0
  124. package/src/grapher/color/CustomSchemes.ts +1772 -0
  125. package/src/grapher/color/readme.md +84 -0
  126. package/src/grapher/comparisonLine/ComparisonLine.tsx +31 -0
  127. package/src/grapher/comparisonLine/ComparisonLineConstants.ts +11 -0
  128. package/src/grapher/comparisonLine/ComparisonLineGenerator.ts +60 -0
  129. package/src/grapher/comparisonLine/ComparisonLineHelpers.ts +10 -0
  130. package/src/grapher/comparisonLine/CustomComparisonLine.tsx +159 -0
  131. package/src/grapher/comparisonLine/VerticalComparisonLine.tsx +208 -0
  132. package/src/grapher/controls/ActionButtons.scss +97 -0
  133. package/src/grapher/controls/ActionButtons.tsx +453 -0
  134. package/src/grapher/controls/CommandPalette.scss +50 -0
  135. package/src/grapher/controls/CommandPalette.tsx +74 -0
  136. package/src/grapher/controls/ContentSwitchers.scss +93 -0
  137. package/src/grapher/controls/ContentSwitchers.tsx +238 -0
  138. package/src/grapher/controls/Controls.scss +158 -0
  139. package/src/grapher/controls/DataTableFilterDropdown.scss +7 -0
  140. package/src/grapher/controls/DataTableFilterDropdown.tsx +168 -0
  141. package/src/grapher/controls/DataTableSearchField.scss +3 -0
  142. package/src/grapher/controls/DataTableSearchField.tsx +76 -0
  143. package/src/grapher/controls/Dropdown.scss +252 -0
  144. package/src/grapher/controls/Dropdown.tsx +235 -0
  145. package/src/grapher/controls/EntitySelectionToggle.tsx +135 -0
  146. package/src/grapher/controls/MapRegionDropdown.scss +3 -0
  147. package/src/grapher/controls/MapRegionDropdown.tsx +104 -0
  148. package/src/grapher/controls/MapResetButton.tsx +115 -0
  149. package/src/grapher/controls/MapZoomDropdown.scss +9 -0
  150. package/src/grapher/controls/MapZoomDropdown.tsx +270 -0
  151. package/src/grapher/controls/MapZoomToSelectionButton.tsx +87 -0
  152. package/src/grapher/controls/SearchField.scss +78 -0
  153. package/src/grapher/controls/SearchField.tsx +63 -0
  154. package/src/grapher/controls/SettingsMenu.scss +191 -0
  155. package/src/grapher/controls/SettingsMenu.tsx +399 -0
  156. package/src/grapher/controls/ShareMenu.scss +58 -0
  157. package/src/grapher/controls/ShareMenu.tsx +304 -0
  158. package/src/grapher/controls/SortIcon.tsx +39 -0
  159. package/src/grapher/controls/VerticalScrollContainer.tsx +263 -0
  160. package/src/grapher/controls/controlsRow/ControlsRow.tsx +168 -0
  161. package/src/grapher/controls/dropdown-icons.scss +4 -0
  162. package/src/grapher/controls/entityPicker/EntityPicker.scss +255 -0
  163. package/src/grapher/controls/entityPicker/EntityPicker.tsx +816 -0
  164. package/src/grapher/controls/entityPicker/EntityPickerConstants.ts +23 -0
  165. package/src/grapher/controls/globalEntitySelector/GlobalEntitySelector.scss +129 -0
  166. package/src/grapher/controls/globalEntitySelector/GlobalEntitySelector.tsx +463 -0
  167. package/src/grapher/controls/globalEntitySelector/GlobalEntitySelectorConstants.ts +3 -0
  168. package/src/grapher/controls/globalEntitySelector/readme.md +17 -0
  169. package/src/grapher/controls/settings/AbsRelToggle.tsx +64 -0
  170. package/src/grapher/controls/settings/AxisScaleToggle.tsx +53 -0
  171. package/src/grapher/controls/settings/FacetStrategySelector.tsx +110 -0
  172. package/src/grapher/controls/settings/FacetYDomainToggle.tsx +51 -0
  173. package/src/grapher/controls/settings/NoDataAreaToggle.tsx +38 -0
  174. package/src/grapher/controls/settings/ZoomToggle.tsx +36 -0
  175. package/src/grapher/core/EntitiesByRegionType.ts +174 -0
  176. package/src/grapher/core/EntityCodes.ts +19 -0
  177. package/src/grapher/core/EntityUrlBuilder.ts +200 -0
  178. package/src/grapher/core/FetchingGrapher.tsx +156 -0
  179. package/src/grapher/core/Grapher.tsx +760 -0
  180. package/src/grapher/core/GrapherAnalytics.ts +229 -0
  181. package/src/grapher/core/GrapherConstants.ts +173 -0
  182. package/src/grapher/core/GrapherState.tsx +3659 -0
  183. package/src/grapher/core/GrapherUrl.ts +184 -0
  184. package/src/grapher/core/GrapherUrlMigrations.ts +29 -0
  185. package/src/grapher/core/GrapherUseHelpers.tsx +147 -0
  186. package/src/grapher/core/LegacyToOwidTable.ts +841 -0
  187. package/src/grapher/core/grapher.entry.ts +5 -0
  188. package/src/grapher/core/grapher.scss +257 -0
  189. package/src/grapher/core/loadGrapherTableHelpers.ts +116 -0
  190. package/src/grapher/core/loadVariable.ts +104 -0
  191. package/src/grapher/core/relatedQuestion.ts +12 -0
  192. package/src/grapher/core/typography.scss +206 -0
  193. package/src/grapher/dataTable/DataTable.sample.ts +206 -0
  194. package/src/grapher/dataTable/DataTable.scss +249 -0
  195. package/src/grapher/dataTable/DataTable.tsx +1332 -0
  196. package/src/grapher/dataTable/DataTableConstants.ts +186 -0
  197. package/src/grapher/entitySelector/EntitySelector.scss +255 -0
  198. package/src/grapher/entitySelector/EntitySelector.tsx +1838 -0
  199. package/src/grapher/facet/FacetChart.tsx +943 -0
  200. package/src/grapher/facet/FacetChartConstants.ts +24 -0
  201. package/src/grapher/facet/FacetChartUtils.ts +51 -0
  202. package/src/grapher/facet/FacetMap.tsx +604 -0
  203. package/src/grapher/facet/FacetMapConstants.ts +23 -0
  204. package/src/grapher/facet/readme.md +13 -0
  205. package/src/grapher/focus/FocusArray.ts +79 -0
  206. package/src/grapher/footer/Footer.scss +63 -0
  207. package/src/grapher/footer/Footer.tsx +809 -0
  208. package/src/grapher/footer/FooterManager.ts +44 -0
  209. package/src/grapher/fullScreen/FullScreen.scss +11 -0
  210. package/src/grapher/fullScreen/FullScreen.tsx +61 -0
  211. package/src/grapher/header/Header.scss +35 -0
  212. package/src/grapher/header/Header.tsx +372 -0
  213. package/src/grapher/header/HeaderManager.ts +28 -0
  214. package/src/grapher/index.ts +157 -0
  215. package/src/grapher/interaction/InteractionState.ts +60 -0
  216. package/src/grapher/legend/HorizontalColorLegends.tsx +923 -0
  217. package/src/grapher/legend/LegendInteractionState.ts +40 -0
  218. package/src/grapher/legend/VerticalColorLegend.tsx +295 -0
  219. package/src/grapher/lineCharts/LineChart.tsx +968 -0
  220. package/src/grapher/lineCharts/LineChartConstants.ts +89 -0
  221. package/src/grapher/lineCharts/LineChartHelpers.ts +184 -0
  222. package/src/grapher/lineCharts/LineChartState.ts +394 -0
  223. package/src/grapher/lineCharts/LineChartThumbnail.tsx +437 -0
  224. package/src/grapher/lineCharts/Lines.tsx +258 -0
  225. package/src/grapher/lineLegend/LineLegend.tsx +723 -0
  226. package/src/grapher/lineLegend/LineLegendConstants.ts +9 -0
  227. package/src/grapher/lineLegend/LineLegendFilterAlgorithms.ts +143 -0
  228. package/src/grapher/lineLegend/LineLegendHelpers.ts +253 -0
  229. package/src/grapher/lineLegend/LineLegendTypes.ts +32 -0
  230. package/src/grapher/mapCharts/CanadaTopology.ts +17922 -0
  231. package/src/grapher/mapCharts/ChoroplethGlobe.tsx +949 -0
  232. package/src/grapher/mapCharts/ChoroplethMap.tsx +662 -0
  233. package/src/grapher/mapCharts/GeoFeatures.ts +184 -0
  234. package/src/grapher/mapCharts/GlobeController.ts +496 -0
  235. package/src/grapher/mapCharts/MapAnnotationPlacements.json +1040 -0
  236. package/src/grapher/mapCharts/MapAnnotationPlacements.ts +31 -0
  237. package/src/grapher/mapCharts/MapAnnotations.ts +723 -0
  238. package/src/grapher/mapCharts/MapChart.sample.ts +59 -0
  239. package/src/grapher/mapCharts/MapChart.scss +5 -0
  240. package/src/grapher/mapCharts/MapChart.tsx +720 -0
  241. package/src/grapher/mapCharts/MapChartConstants.ts +260 -0
  242. package/src/grapher/mapCharts/MapChartState.ts +416 -0
  243. package/src/grapher/mapCharts/MapChartThumbnail.tsx +25 -0
  244. package/src/grapher/mapCharts/MapComponents.tsx +338 -0
  245. package/src/grapher/mapCharts/MapConfig.ts +156 -0
  246. package/src/grapher/mapCharts/MapHelpers.ts +181 -0
  247. package/src/grapher/mapCharts/MapProjections.ts +49 -0
  248. package/src/grapher/mapCharts/MapSparkline.tsx +257 -0
  249. package/src/grapher/mapCharts/MapTooltip.scss +49 -0
  250. package/src/grapher/mapCharts/MapTooltip.tsx +409 -0
  251. package/src/grapher/mapCharts/MapTopology.ts +1766 -0
  252. package/src/grapher/mapCharts/d3-bboxCollide.js +204 -0
  253. package/src/grapher/mapCharts/d3-geo-projection.ts +198 -0
  254. package/src/grapher/modal/DownloadIcons.tsx +39 -0
  255. package/src/grapher/modal/DownloadModal.scss +300 -0
  256. package/src/grapher/modal/DownloadModal.tsx +1226 -0
  257. package/src/grapher/modal/EmbedModal.scss +40 -0
  258. package/src/grapher/modal/EmbedModal.tsx +160 -0
  259. package/src/grapher/modal/EntitySelectorModal.tsx +59 -0
  260. package/src/grapher/modal/Modal.scss +31 -0
  261. package/src/grapher/modal/Modal.tsx +90 -0
  262. package/src/grapher/modal/ModalHeader.scss +12 -0
  263. package/src/grapher/modal/ModalHeader.tsx +16 -0
  264. package/src/grapher/modal/SourcesDescriptions.scss +87 -0
  265. package/src/grapher/modal/SourcesDescriptions.tsx +89 -0
  266. package/src/grapher/modal/SourcesKeyDataTable.scss +49 -0
  267. package/src/grapher/modal/SourcesKeyDataTable.tsx +87 -0
  268. package/src/grapher/modal/SourcesModal.scss +301 -0
  269. package/src/grapher/modal/SourcesModal.tsx +568 -0
  270. package/src/grapher/noDataModal/NoDataModal.tsx +125 -0
  271. package/src/grapher/scatterCharts/ConnectedScatterLegend.tsx +143 -0
  272. package/src/grapher/scatterCharts/MultiColorPolyline.tsx +129 -0
  273. package/src/grapher/scatterCharts/NoDataSection.scss +14 -0
  274. package/src/grapher/scatterCharts/NoDataSection.tsx +56 -0
  275. package/src/grapher/scatterCharts/ScatterPlotChart.tsx +792 -0
  276. package/src/grapher/scatterCharts/ScatterPlotChartConstants.ts +157 -0
  277. package/src/grapher/scatterCharts/ScatterPlotChartState.ts +678 -0
  278. package/src/grapher/scatterCharts/ScatterPlotChartThumbnail.tsx +155 -0
  279. package/src/grapher/scatterCharts/ScatterPlotTooltip.tsx +560 -0
  280. package/src/grapher/scatterCharts/ScatterPoints.tsx +153 -0
  281. package/src/grapher/scatterCharts/ScatterPointsWithLabels.tsx +708 -0
  282. package/src/grapher/scatterCharts/ScatterSizeLegend.tsx +327 -0
  283. package/src/grapher/scatterCharts/ScatterUtils.ts +265 -0
  284. package/src/grapher/scatterCharts/Triangle.tsx +41 -0
  285. package/src/grapher/schema/README.md +33 -0
  286. package/src/grapher/schema/defaultGrapherConfig.ts +100 -0
  287. package/src/grapher/schema/grapher-schema.009.yaml +781 -0
  288. package/src/grapher/schema/migrations/helpers.ts +58 -0
  289. package/src/grapher/schema/migrations/migrate.ts +75 -0
  290. package/src/grapher/schema/migrations/migrations.ts +158 -0
  291. package/src/grapher/selection/MapSelectionArray.ts +99 -0
  292. package/src/grapher/selection/SelectionArray.ts +71 -0
  293. package/src/grapher/selection/readme.md +16 -0
  294. package/src/grapher/sidePanel/SidePanel.scss +10 -0
  295. package/src/grapher/sidePanel/SidePanel.tsx +23 -0
  296. package/src/grapher/slideInDrawer/SlideInDrawer.scss +57 -0
  297. package/src/grapher/slideInDrawer/SlideInDrawer.tsx +125 -0
  298. package/src/grapher/slideshowController/SlideShowController.tsx +43 -0
  299. package/src/grapher/slideshowController/readme.md +7 -0
  300. package/src/grapher/slopeCharts/MarkX.tsx +45 -0
  301. package/src/grapher/slopeCharts/Slope.tsx +102 -0
  302. package/src/grapher/slopeCharts/SlopeChart.tsx +1152 -0
  303. package/src/grapher/slopeCharts/SlopeChartConstants.ts +33 -0
  304. package/src/grapher/slopeCharts/SlopeChartHelpers.ts +73 -0
  305. package/src/grapher/slopeCharts/SlopeChartState.ts +392 -0
  306. package/src/grapher/slopeCharts/SlopeChartThumbnail.tsx +368 -0
  307. package/src/grapher/stackedCharts/AbstractStackedChartState.ts +370 -0
  308. package/src/grapher/stackedCharts/MarimekkoBars.tsx +190 -0
  309. package/src/grapher/stackedCharts/MarimekkoBarsForOneEntity.tsx +168 -0
  310. package/src/grapher/stackedCharts/MarimekkoChart.tsx +1144 -0
  311. package/src/grapher/stackedCharts/MarimekkoChartConstants.ts +112 -0
  312. package/src/grapher/stackedCharts/MarimekkoChartHelpers.ts +21 -0
  313. package/src/grapher/stackedCharts/MarimekkoChartState.ts +465 -0
  314. package/src/grapher/stackedCharts/MarimekkoChartThumbnail.tsx +168 -0
  315. package/src/grapher/stackedCharts/MarimekkoInternalLabels.tsx +124 -0
  316. package/src/grapher/stackedCharts/StackedAreaChart.tsx +678 -0
  317. package/src/grapher/stackedCharts/StackedAreaChartState.ts +34 -0
  318. package/src/grapher/stackedCharts/StackedAreaChartThumbnail.tsx +215 -0
  319. package/src/grapher/stackedCharts/StackedAreas.tsx +223 -0
  320. package/src/grapher/stackedCharts/StackedBarChart.tsx +619 -0
  321. package/src/grapher/stackedCharts/StackedBarChartState.ts +80 -0
  322. package/src/grapher/stackedCharts/StackedBarChartThumbnail.tsx +220 -0
  323. package/src/grapher/stackedCharts/StackedBarSegment.tsx +87 -0
  324. package/src/grapher/stackedCharts/StackedBars.tsx +102 -0
  325. package/src/grapher/stackedCharts/StackedConstants.ts +109 -0
  326. package/src/grapher/stackedCharts/StackedDiscreteBarChart.tsx +270 -0
  327. package/src/grapher/stackedCharts/StackedDiscreteBarChartState.ts +296 -0
  328. package/src/grapher/stackedCharts/StackedDiscreteBarChartThumbnail.tsx +27 -0
  329. package/src/grapher/stackedCharts/StackedDiscreteBars.tsx +648 -0
  330. package/src/grapher/stackedCharts/StackedUtils.ts +142 -0
  331. package/src/grapher/tabs/Tabs.scss +169 -0
  332. package/src/grapher/tabs/Tabs.tsx +54 -0
  333. package/src/grapher/tabs/TabsWithDropdown.scss +62 -0
  334. package/src/grapher/tabs/TabsWithDropdown.tsx +114 -0
  335. package/src/grapher/testData/OwidTestData.sample.ts +273 -0
  336. package/src/grapher/testData/OwidTestData.ts +64 -0
  337. package/src/grapher/timeline/TimelineComponent.scss +139 -0
  338. package/src/grapher/timeline/TimelineComponent.tsx +658 -0
  339. package/src/grapher/timeline/TimelineController.ts +368 -0
  340. package/src/grapher/timeline/readme.md +7 -0
  341. package/src/grapher/tooltip/Tooltip.scss +510 -0
  342. package/src/grapher/tooltip/Tooltip.tsx +294 -0
  343. package/src/grapher/tooltip/TooltipContents.tsx +383 -0
  344. package/src/grapher/tooltip/TooltipProps.ts +123 -0
  345. package/src/grapher/tooltip/TooltipState.ts +81 -0
  346. package/src/grapher/verticalLabels/VerticalLabels.tsx +31 -0
  347. package/src/grapher/verticalLabels/VerticalLabelsState.ts +154 -0
  348. package/src/index.ts +226 -0
  349. package/src/styles/charts.scss +15 -0
  350. package/src/types/NominalType.ts +30 -0
  351. package/src/types/OwidOrigin.ts +18 -0
  352. package/src/types/OwidSource.ts +9 -0
  353. package/src/types/OwidVariable.ts +133 -0
  354. package/src/types/OwidVariableDisplayConfigInterface.ts +49 -0
  355. package/src/types/analyticsTypes.ts +54 -0
  356. package/src/types/dbTypes/Tags.ts +11 -0
  357. package/src/types/domainTypes/Archive.ts +139 -0
  358. package/src/types/domainTypes/Author.ts +28 -0
  359. package/src/types/domainTypes/ContentGraph.ts +76 -0
  360. package/src/types/domainTypes/CoreTableTypes.ts +305 -0
  361. package/src/types/domainTypes/DeployStatus.ts +23 -0
  362. package/src/types/domainTypes/Layout.ts +34 -0
  363. package/src/types/domainTypes/Posts.ts +34 -0
  364. package/src/types/domainTypes/Search.ts +299 -0
  365. package/src/types/domainTypes/Site.ts +8 -0
  366. package/src/types/domainTypes/StaticViz.ts +64 -0
  367. package/src/types/domainTypes/Toc.ts +11 -0
  368. package/src/types/domainTypes/Tombstone.ts +19 -0
  369. package/src/types/domainTypes/Various.ts +79 -0
  370. package/src/types/gdocTypes/Gdoc.ts +280 -0
  371. package/src/types/grapherTypes/BinningStrategyTypes.ts +46 -0
  372. package/src/types/grapherTypes/GrapherConstants.ts +53 -0
  373. package/src/types/grapherTypes/GrapherTypes.ts +743 -0
  374. package/src/types/index.ts +316 -0
  375. package/src/types/wordpressTypes/WordpressTypes.ts +9 -0
  376. package/src/utils/Bounds.ts +439 -0
  377. package/src/utils/BrowserUtils.ts +12 -0
  378. package/src/utils/FuzzySearch.ts +74 -0
  379. package/src/utils/MultiDimDataPageConfig.ts +31 -0
  380. package/src/utils/OwidVariable.ts +82 -0
  381. package/src/utils/PointVector.ts +97 -0
  382. package/src/utils/PromiseCache.ts +36 -0
  383. package/src/utils/PromiseSwitcher.ts +52 -0
  384. package/src/utils/TimeBounds.ts +130 -0
  385. package/src/utils/Tippy.tsx +57 -0
  386. package/src/utils/Util.ts +2369 -0
  387. package/src/utils/archival/archivalDate.ts +48 -0
  388. package/src/utils/dayjs.ts +32 -0
  389. package/src/utils/formatValue.ts +242 -0
  390. package/src/utils/grapherConfigUtils.ts +81 -0
  391. package/src/utils/image.ts +225 -0
  392. package/src/utils/index.ts +318 -0
  393. package/src/utils/isPresent.ts +5 -0
  394. package/src/utils/metadataHelpers.ts +329 -0
  395. package/src/utils/persistable/Persistable.ts +82 -0
  396. package/src/utils/persistable/readme.md +50 -0
  397. package/src/utils/regions.json +5635 -0
  398. package/src/utils/regions.ts +463 -0
  399. package/src/utils/serializers.ts +16 -0
  400. package/src/utils/string.ts +42 -0
  401. package/src/utils/urls/Url.ts +195 -0
  402. package/src/utils/urls/UrlMigration.ts +10 -0
  403. package/src/utils/urls/UrlUtils.ts +54 -0
  404. package/src/utils/urls/readme.md +90 -0
@@ -0,0 +1,270 @@
1
+ import * as _ from "lodash-es"
2
+ import React from "react"
3
+ import * as R from "remeda"
4
+ import {
5
+ Bounds,
6
+ Time,
7
+ HorizontalAlign,
8
+ EntityName,
9
+ getRelativeMouse,
10
+ exposeInstanceOnWindow,
11
+ } from "../../utils/index.js"
12
+ import { action, computed, makeObservable, observable } from "mobx"
13
+ import { observer } from "mobx-react"
14
+ import { SeriesName } from "../../types/index.js"
15
+ import {
16
+ BASE_FONT_SIZE,
17
+ DEFAULT_GRAPHER_BOUNDS,
18
+ } from "../core/GrapherConstants"
19
+ import { NoDataModal } from "../noDataModal/NoDataModal"
20
+ import { ChartInterface } from "../chart/ChartInterface"
21
+ import { ChartManager } from "../chart/ChartManager"
22
+ import { TooltipState } from "../tooltip/Tooltip"
23
+ import {
24
+ LEGEND_STYLE_FOR_STACKED_CHARTS,
25
+ StackedSeries,
26
+ } from "./StackedConstants"
27
+ import {
28
+ HorizontalCategoricalColorLegend,
29
+ HorizontalColorLegendManager,
30
+ } from "../legend/HorizontalColorLegends"
31
+ import { CategoricalBin, ColorScaleBin } from "../color/ColorScaleBin"
32
+ import { LegendInteractionState } from "../legend/LegendInteractionState"
33
+ import { StackedDiscreteBarChartState } from "./StackedDiscreteBarChartState"
34
+ import { ChartComponentProps } from "../chart/ChartTypeMap.js"
35
+ import { StackedDiscreteBars } from "./StackedDiscreteBars"
36
+
37
+ export interface StackedDiscreteBarChartManager extends ChartManager {
38
+ endTime?: Time
39
+ hideTotalValueLabel?: boolean
40
+ }
41
+
42
+ type StackedDiscreteBarChartProps =
43
+ ChartComponentProps<StackedDiscreteBarChartState>
44
+
45
+ @observer
46
+ export class StackedDiscreteBarChart
47
+ extends React.Component<StackedDiscreteBarChartProps>
48
+ implements ChartInterface, HorizontalColorLegendManager
49
+ {
50
+ base = React.createRef<SVGGElement>()
51
+
52
+ constructor(props: StackedDiscreteBarChartProps) {
53
+ super(props)
54
+
55
+ makeObservable(this, {
56
+ focusSeriesName: observable,
57
+ tooltipState: observable,
58
+ })
59
+ }
60
+
61
+ focusSeriesName: SeriesName | undefined = undefined
62
+
63
+ @computed get chartState(): StackedDiscreteBarChartState {
64
+ return this.props.chartState
65
+ }
66
+
67
+ @computed private get manager(): StackedDiscreteBarChartManager {
68
+ return this.chartState.manager
69
+ }
70
+
71
+ @computed private get bounds(): Bounds {
72
+ // bottom padding avoids axis labels to be cut off at some resolutions
73
+ return (this.props.bounds ?? DEFAULT_GRAPHER_BOUNDS)
74
+ .padRight(10)
75
+ .padBottom(2)
76
+ }
77
+
78
+ @computed private get baseFontSize(): number {
79
+ return this.manager.fontSize ?? BASE_FONT_SIZE
80
+ }
81
+
82
+ @computed get isStatic(): boolean {
83
+ return this.manager.isStatic ?? false
84
+ }
85
+
86
+ @computed private get showLegend(): boolean {
87
+ return (
88
+ !!this.manager.showLegend &&
89
+ !this.manager.isDisplayedAlongsideComplementaryTable
90
+ )
91
+ }
92
+
93
+ @computed private get boundsWithoutLegend(): Bounds {
94
+ return this.bounds.padTop(
95
+ this.showLegend && this.legend.height > 0
96
+ ? this.legend.height + this.legendPaddingTop
97
+ : 0
98
+ )
99
+ }
100
+
101
+ // legend props
102
+
103
+ @computed private get legendPaddingTop(): number {
104
+ return 0.5 * this.baseFontSize
105
+ }
106
+
107
+ @computed get legendX(): number {
108
+ return this.bounds.x
109
+ }
110
+
111
+ @computed get categoryLegendY(): number {
112
+ return this.bounds.top
113
+ }
114
+
115
+ @computed get legendWidth(): number {
116
+ return this.bounds.width
117
+ }
118
+
119
+ @computed get legendAlign(): HorizontalAlign {
120
+ return HorizontalAlign.left
121
+ }
122
+
123
+ @computed get fontSize(): number {
124
+ return this.baseFontSize
125
+ }
126
+
127
+ @computed private get legendBins(): CategoricalBin[] {
128
+ return this.series.map((series, index) => {
129
+ return new CategoricalBin({
130
+ index,
131
+ value: series.seriesName,
132
+ label: series.seriesName,
133
+ color: series.color,
134
+ })
135
+ })
136
+ }
137
+
138
+ @computed get categoricalLegendData(): CategoricalBin[] {
139
+ return this.showLegend ? this.legendBins : []
140
+ }
141
+
142
+ getLegendBinState(bin: ColorScaleBin): LegendInteractionState {
143
+ const { focusSeriesName } = this
144
+
145
+ // If nothing is focused, all items are active
146
+ if (!focusSeriesName) {
147
+ return LegendInteractionState.Default
148
+ }
149
+
150
+ // Check if this bin contains the focused series
151
+ const isFocused = bin.contains(focusSeriesName)
152
+ return isFocused
153
+ ? LegendInteractionState.Focused
154
+ : LegendInteractionState.Muted
155
+ }
156
+
157
+ legendStyleConfig = LEGEND_STYLE_FOR_STACKED_CHARTS
158
+
159
+ @computed get externalLegend(): HorizontalColorLegendManager | undefined {
160
+ if (!this.showLegend) {
161
+ return {
162
+ categoricalLegendData: this.legendBins,
163
+ legendStyleConfig: this.legendStyleConfig,
164
+ }
165
+ }
166
+ return undefined
167
+ }
168
+
169
+ @action.bound onLegendMouseOver(bin: ColorScaleBin): void {
170
+ this.focusSeriesName = R.first(
171
+ this.series
172
+ .map((s) => s.seriesName)
173
+ .filter((name) => bin.contains(name))
174
+ )
175
+ }
176
+
177
+ @action.bound onLegendMouseLeave(): void {
178
+ this.focusSeriesName = undefined
179
+ }
180
+
181
+ @computed private get legend(): HorizontalCategoricalColorLegend {
182
+ return new HorizontalCategoricalColorLegend({ manager: this })
183
+ }
184
+
185
+ tooltipState = new TooltipState<{
186
+ entityName: string
187
+ seriesName?: string
188
+ }>()
189
+
190
+ @action.bound private onMouseMove(ev: React.MouseEvent): void {
191
+ const ref = this.manager.base?.current
192
+ if (ref) {
193
+ this.tooltipState.position = getRelativeMouse(ref, ev)
194
+ }
195
+ }
196
+
197
+ override render(): React.ReactElement {
198
+ if (this.chartState.errorInfo.reason)
199
+ return (
200
+ <NoDataModal
201
+ manager={this.manager}
202
+ bounds={this.bounds}
203
+ message={this.chartState.errorInfo.reason}
204
+ />
205
+ )
206
+
207
+ return this.manager.isStatic
208
+ ? this.renderStatic()
209
+ : this.renderInteractive()
210
+ }
211
+
212
+ private renderLegend(): React.ReactElement | undefined {
213
+ if (!this.showLegend) return
214
+ return <HorizontalCategoricalColorLegend manager={this} />
215
+ }
216
+
217
+ private renderStatic(): React.ReactElement {
218
+ return (
219
+ <>
220
+ {this.renderLegend()}
221
+ <StackedDiscreteBars
222
+ chartState={this.chartState}
223
+ bounds={this.boundsWithoutLegend}
224
+ tooltipState={this.tooltipState}
225
+ focusSeriesName={this.focusSeriesName}
226
+ />
227
+ </>
228
+ )
229
+ }
230
+
231
+ private renderInteractive(): React.ReactElement {
232
+ const { bounds } = this
233
+
234
+ // needs to be referenced here, otherwise it's not updated in the renderRow function
235
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
236
+ this.focusSeriesName
237
+
238
+ return (
239
+ <g
240
+ ref={this.base}
241
+ className="StackedDiscreteBarChart"
242
+ onMouseMove={this.onMouseMove}
243
+ >
244
+ <rect
245
+ x={bounds.left}
246
+ y={bounds.top}
247
+ width={bounds.width}
248
+ height={bounds.height}
249
+ opacity={0}
250
+ fill="rgba(255,255,255,0)"
251
+ />
252
+ {this.renderLegend()}
253
+ <StackedDiscreteBars
254
+ chartState={this.chartState}
255
+ bounds={this.boundsWithoutLegend}
256
+ tooltipState={this.tooltipState}
257
+ focusSeriesName={this.focusSeriesName}
258
+ />
259
+ </g>
260
+ )
261
+ }
262
+
263
+ @computed private get series(): readonly StackedSeries<EntityName>[] {
264
+ return this.chartState.series
265
+ }
266
+
267
+ override componentDidMount(): void {
268
+ exposeInstanceOnWindow(this)
269
+ }
270
+ }
@@ -0,0 +1,296 @@
1
+ import * as _ from "lodash-es"
2
+ import { computed, makeObservable } from "mobx"
3
+ import { ChartState } from "../chart/ChartInterface"
4
+ import { StackedDiscreteBarChartManager } from "./StackedDiscreteBarChart"
5
+ import { CoreColumn, OwidTable } from "../../core-table/index.js"
6
+ import {
7
+ ChartErrorInfo,
8
+ ColorSchemeName,
9
+ EntityName,
10
+ FacetStrategy,
11
+ MissingDataStrategy,
12
+ SortBy,
13
+ SortConfig,
14
+ SortOrder,
15
+ } from "../../types/index.js"
16
+ import {
17
+ autoDetectYColumnSlugs,
18
+ getDefaultFailMessage,
19
+ getShortNameForEntity,
20
+ makeSelectionArray,
21
+ } from "../chart/ChartUtils"
22
+ import { SelectionArray } from "../selection/SelectionArray"
23
+ import { Item, StackedSeries } from "./StackedConstants"
24
+ import {
25
+ stackSeriesInBothDirections,
26
+ withMissingValuesAsZeroes,
27
+ } from "./StackedUtils"
28
+ import { CategoricalColorAssigner } from "../color/CategoricalColorAssigner"
29
+ import { ColorScheme } from "../color/ColorScheme"
30
+ import { ColorSchemes } from "../color/ColorSchemes"
31
+ import { excludeUndefined } from "../../utils/index.js"
32
+ import { FocusArray } from "../focus/FocusArray"
33
+
34
+ export class StackedDiscreteBarChartState implements ChartState {
35
+ manager: StackedDiscreteBarChartManager
36
+
37
+ constructor({ manager }: { manager: StackedDiscreteBarChartManager }) {
38
+ this.manager = manager
39
+ makeObservable(this)
40
+ }
41
+
42
+ @computed get inputTable(): OwidTable {
43
+ return this.manager.table
44
+ }
45
+
46
+ @computed get transformedTable(): OwidTable {
47
+ return (
48
+ this.manager.transformedTable ??
49
+ this.transformTable(this.inputTable)
50
+ )
51
+ }
52
+
53
+ transformTable(table: OwidTable): OwidTable {
54
+ if (!this.yColumnSlugs.length) return table
55
+
56
+ table = table.filterByEntityNames(
57
+ this.selectionArray.selectedEntityNames
58
+ )
59
+
60
+ // TODO: remove this filter once we don't have mixed type columns in datasets
61
+ table = table.replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
62
+
63
+ table = table.dropRowsWithErrorValuesForAllColumns(this.yColumnSlugs)
64
+
65
+ this.yColumnSlugs.forEach((slug) => {
66
+ table = table.interpolateColumnWithTolerance(slug)
67
+ })
68
+
69
+ table = this.applyMissingDataStrategy(table)
70
+
71
+ if (this.manager.isRelativeMode) {
72
+ table = table
73
+ .replaceNegativeCellsWithErrorValues(this.yColumnSlugs)
74
+ .toPercentageFromEachColumnForEachEntityAndTime(
75
+ this.yColumnSlugs
76
+ )
77
+
78
+ // Apply missing data strategy _again_ because we might've introduced new error values just now
79
+ table = this.applyMissingDataStrategy(table)
80
+ }
81
+
82
+ return table
83
+ }
84
+
85
+ transformTableForSelection(table: OwidTable): OwidTable {
86
+ table = table
87
+ .replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
88
+ .replaceNegativeCellsWithErrorValues(this.yColumnSlugs)
89
+ .dropRowsWithErrorValuesForAllColumns(this.yColumnSlugs)
90
+
91
+ table = this.applyMissingDataStrategy(table)
92
+
93
+ return table
94
+ }
95
+
96
+ private applyMissingDataStrategy(table: OwidTable): OwidTable {
97
+ // We want to remove all rows with missing data for at least one column if:
98
+ // - MissingDataStrategy is explicitly set to hide, or
99
+ // - We are in relative mode and MissingDataStrategy is not explicitly set to show:
100
+ // If we are showing relative mode, we want to drop all rows that are missing data for
101
+ // any column, because otherwise the displayed data will be misleading in that it may
102
+ // suggest patterns that are not actually present.
103
+ // see https://github.com/owid/owid-grapher/issues/2860
104
+
105
+ const shouldRemoveRows =
106
+ this.missingDataStrategy === MissingDataStrategy.hide ||
107
+ (this.manager.isRelativeMode &&
108
+ this.missingDataStrategy !== MissingDataStrategy.show)
109
+ if (shouldRemoveRows) {
110
+ // If MissingDataStrategy is explicitly set to hide, drop rows (= times) where one of
111
+ // the y columns has no data
112
+ return table.dropRowsWithErrorValuesForAnyColumn(this.yColumnSlugs)
113
+ }
114
+
115
+ // Otherwise, don't apply any special treatment
116
+ return table
117
+ }
118
+
119
+ @computed get selectionArray(): SelectionArray {
120
+ return makeSelectionArray(this.manager.selection)
121
+ }
122
+
123
+ @computed get focusArray(): FocusArray {
124
+ return this.manager.focusArray ?? new FocusArray()
125
+ }
126
+
127
+ @computed get isFocusModeActive(): boolean {
128
+ return this.focusArray.hasFocusedSeries
129
+ }
130
+
131
+ @computed get missingDataStrategy(): MissingDataStrategy {
132
+ return this.manager.missingDataStrategy || MissingDataStrategy.auto
133
+ }
134
+
135
+ @computed get yColumnSlugs(): string[] {
136
+ return this.manager.yColumnSlugs ?? autoDetectYColumnSlugs(this.manager)
137
+ }
138
+
139
+ @computed get yColumns(): CoreColumn[] {
140
+ return this.transformedTable.getColumns(this.yColumnSlugs)
141
+ }
142
+
143
+ @computed get formatColumn(): CoreColumn {
144
+ return this.yColumns[0]
145
+ }
146
+
147
+ @computed get sortColumnSlug(): string | undefined {
148
+ return this.sortConfig.sortColumnSlug
149
+ }
150
+
151
+ @computed get sortColumn(): CoreColumn | undefined {
152
+ return this.sortColumnSlug
153
+ ? this.transformedTable.getColumns([this.sortColumnSlug])[0]
154
+ : undefined
155
+ }
156
+
157
+ @computed get sortConfig(): SortConfig {
158
+ return this.manager.sortConfig ?? {}
159
+ }
160
+
161
+ @computed get colorScheme(): ColorScheme {
162
+ return (
163
+ (this.manager.baseColorScheme
164
+ ? ColorSchemes.get(this.manager.baseColorScheme)
165
+ : null) ?? ColorSchemes.get(ColorSchemeName["owid-distinct"])
166
+ )
167
+ }
168
+
169
+ @computed get categoricalColorAssigner(): CategoricalColorAssigner {
170
+ const seriesCount = this.yColumns.length
171
+ return new CategoricalColorAssigner({
172
+ colorScheme: this.colorScheme,
173
+ invertColorScheme: this.manager.invertColorScheme,
174
+ colorMap: this.inputTable.columnDisplayNameToColorMap,
175
+ autoColorMapCache: this.manager.seriesColorMap,
176
+ numColorsInUse: seriesCount,
177
+ })
178
+ }
179
+
180
+ @computed get unstackedSeries(): StackedSeries<EntityName>[] {
181
+ return (
182
+ this.yColumns
183
+ .map((col) => {
184
+ return {
185
+ seriesName: col.displayName,
186
+ columnSlug: col.slug,
187
+ color: this.categoricalColorAssigner.assign(
188
+ col.displayName
189
+ ),
190
+ points: col.owidRows.map((row) => ({
191
+ time: row.originalTime,
192
+ position: row.entityName,
193
+ value: row.value,
194
+ valueOffset: 0,
195
+ })),
196
+ }
197
+ })
198
+ // Do not plot columns without data
199
+ .filter((series) => series.points.length > 0)
200
+ )
201
+ }
202
+
203
+ @computed get series(): readonly StackedSeries<EntityName>[] {
204
+ return stackSeriesInBothDirections(
205
+ withMissingValuesAsZeroes(this.unstackedSeries)
206
+ )
207
+ }
208
+
209
+ @computed get items(): readonly Item[] {
210
+ const entityNames = this.selectionArray.selectedEntityNames
211
+ const items = entityNames
212
+ .map((entityName) => {
213
+ let totalValue = 0
214
+ const bars = excludeUndefined(
215
+ this.series.map((series) => {
216
+ const point = series.points.find(
217
+ (point) => point.position === entityName
218
+ )
219
+ if (!point) return undefined
220
+ totalValue += point.value
221
+ return {
222
+ point,
223
+ columnSlug: series.columnSlug!,
224
+ color: series.color,
225
+ seriesName: series.seriesName,
226
+ }
227
+ })
228
+ )
229
+
230
+ return {
231
+ entityName,
232
+ shortEntityName: getShortNameForEntity(entityName),
233
+ bars,
234
+ totalValue,
235
+ focus: this.focusArray.state(entityName),
236
+ }
237
+ })
238
+ .filter((item) => item.bars.length)
239
+
240
+ return items
241
+ }
242
+
243
+ @computed get sortedItems(): readonly Item[] {
244
+ let sortByFunc: (item: Item) => number | string | undefined
245
+ switch (this.sortConfig.sortBy) {
246
+ case SortBy.custom:
247
+ sortByFunc = (): undefined => undefined
248
+ break
249
+ case SortBy.entityName:
250
+ sortByFunc = (item: Item): string => item.entityName
251
+ break
252
+ case SortBy.column: {
253
+ const owidRowsByEntityName =
254
+ this.sortColumn?.owidRowsByEntityName
255
+ sortByFunc = (item: Item): number => {
256
+ const rows = owidRowsByEntityName?.get(item.entityName)
257
+ return rows?.[0]?.value ?? 0
258
+ }
259
+ break
260
+ }
261
+ default:
262
+ case SortBy.total:
263
+ sortByFunc = (item: Item): number => item.totalValue
264
+ }
265
+ const sortedItems = _.sortBy(this.items, sortByFunc)
266
+ const sortOrder = this.sortConfig.sortOrder ?? SortOrder.desc
267
+ if (sortOrder === SortOrder.desc) return sortedItems.toReversed()
268
+ else return sortedItems
269
+ }
270
+
271
+ @computed get availableFacetStrategies(): FacetStrategy[] {
272
+ const strategies = [FacetStrategy.none]
273
+
274
+ if (this.yColumns.length > 1) strategies.push(FacetStrategy.metric)
275
+
276
+ return strategies
277
+ }
278
+
279
+ @computed get errorInfo(): ChartErrorInfo {
280
+ const column = this.yColumns[0]
281
+
282
+ if (!column) return { reason: "No column to chart" }
283
+
284
+ const message = getDefaultFailMessage(this.manager)
285
+ if (message) return { reason: message }
286
+
287
+ const { entityTypePlural = "entities" } = this.manager
288
+
289
+ // TODO is it better to use .series for this check?
290
+ return this.yColumns.every((col) => col.isEmpty)
291
+ ? {
292
+ reason: `No data for the selected ${entityTypePlural}`,
293
+ }
294
+ : { reason: "" }
295
+ }
296
+ }
@@ -0,0 +1,27 @@
1
+ import React from "react"
2
+ import { computed, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import { ChartInterface } from "../chart/ChartInterface"
5
+ import { StackedDiscreteBarChartState } from "./StackedDiscreteBarChartState"
6
+ import { ChartComponentProps } from "../chart/ChartTypeMap.js"
7
+ import { StackedDiscreteBars } from "./StackedDiscreteBars"
8
+
9
+ @observer
10
+ export class StackedDiscreteBarChartThumbnail
11
+ extends React.Component<ChartComponentProps<StackedDiscreteBarChartState>>
12
+ implements ChartInterface
13
+ {
14
+ constructor(props: ChartComponentProps<StackedDiscreteBarChartState>) {
15
+ super(props)
16
+ // Ensure that the component is observable
17
+ makeObservable(this)
18
+ }
19
+
20
+ @computed get chartState(): StackedDiscreteBarChartState {
21
+ return this.props.chartState
22
+ }
23
+
24
+ override render(): React.ReactElement {
25
+ return <StackedDiscreteBars {...this.props} />
26
+ }
27
+ }