@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,648 @@
1
+ import * as _ from "lodash-es"
2
+ import React from "react"
3
+ import {
4
+ Bounds,
5
+ excludeUndefined,
6
+ numberMagnitude,
7
+ Time,
8
+ HorizontalAlign,
9
+ EntityName,
10
+ makeIdForHumanConsumption,
11
+ dyFromAlign,
12
+ exposeInstanceOnWindow,
13
+ bind,
14
+ } from "../../utils/index.js"
15
+ import { action, computed, makeObservable } from "mobx"
16
+ import { observer } from "mobx-react"
17
+ import { ScaleType, SeriesName, VerticalAlign } from "../../types/index.js"
18
+ import {
19
+ BASE_FONT_SIZE,
20
+ DEFAULT_GRAPHER_BOUNDS,
21
+ GRAPHER_FONT_SCALE_12,
22
+ GRAPHER_OPACITY_MUTE,
23
+ } from "../core/GrapherConstants"
24
+ import {
25
+ HorizontalAxisComponent,
26
+ HorizontalAxisGridLines,
27
+ HorizontalAxisZeroLine,
28
+ } from "../axis/AxisViews"
29
+ import { AxisConfig } from "../axis/AxisConfig"
30
+ import { ChartInterface } from "../chart/ChartInterface"
31
+ import { OwidTable, CoreColumn } from "../../core-table/index.js"
32
+ import { ChartManager } from "../chart/ChartManager"
33
+ import { TooltipFooterIcon } from "../tooltip/TooltipProps.js"
34
+ import {
35
+ Tooltip,
36
+ TooltipState,
37
+ TooltipTable,
38
+ makeTooltipRoundingNotice,
39
+ makeTooltipToleranceNotice,
40
+ toTooltipTableColumns,
41
+ } from "../tooltip/Tooltip"
42
+ import {
43
+ Bar,
44
+ BAR_OPACITY,
45
+ PlacedItem,
46
+ SizedItem,
47
+ StackedPoint,
48
+ StackedSeries,
49
+ } from "./StackedConstants"
50
+ import { isDarkColor } from "../color/ColorUtils"
51
+ import { HorizontalAxis } from "../axis/Axis"
52
+ import { HashMap, NodeGroup } from "react-move"
53
+ import { easeQuadOut } from "d3-ease"
54
+ import { StackedDiscreteBarChartState } from "./StackedDiscreteBarChartState"
55
+ import { enrichSeriesWithLabels } from "../barCharts/DiscreteBarChartHelpers.js"
56
+
57
+ const BAR_SPACING_FACTOR = 0.35
58
+
59
+ const labelToBarPadding = 5
60
+
61
+ export interface StackedDiscreteBarChartManager extends ChartManager {
62
+ endTime?: Time
63
+ hideTotalValueLabel?: boolean
64
+ }
65
+
66
+ interface StackedBarChartContext {
67
+ yAxis: HorizontalAxis
68
+ targetTime?: number
69
+ timeColumn: CoreColumn
70
+ formatColumn: CoreColumn
71
+ formatValueForLabel: (value: number) => string
72
+ focusSeriesName?: string
73
+ hoverSeriesName?: string
74
+ hoverEntityName?: string
75
+ barHeight: number
76
+ x0: number
77
+ baseFontSize: number
78
+ }
79
+
80
+ interface StackedDiscreteBarsProps {
81
+ chartState: StackedDiscreteBarChartState
82
+ bounds?: Bounds
83
+ tooltipState?: TooltipState<{
84
+ entityName: string
85
+ seriesName?: string
86
+ }>
87
+ focusSeriesName?: SeriesName
88
+ }
89
+
90
+ @observer
91
+ export class StackedDiscreteBars
92
+ extends React.Component<StackedDiscreteBarsProps>
93
+ implements ChartInterface
94
+ {
95
+ base = React.createRef<SVGGElement>()
96
+
97
+ constructor(props: StackedDiscreteBarsProps) {
98
+ super(props)
99
+
100
+ makeObservable(this)
101
+ }
102
+
103
+ @computed get chartState(): StackedDiscreteBarChartState {
104
+ return this.props.chartState
105
+ }
106
+
107
+ @computed private get manager(): StackedDiscreteBarChartManager {
108
+ return this.chartState.manager
109
+ }
110
+
111
+ @computed private get bounds(): Bounds {
112
+ return this.props.bounds ?? DEFAULT_GRAPHER_BOUNDS
113
+ }
114
+
115
+ @computed private get focusSeriesName(): SeriesName | undefined {
116
+ return this.props.focusSeriesName
117
+ }
118
+
119
+ @computed private get tooltipState(): TooltipState<{
120
+ entityName: string
121
+ seriesName?: string
122
+ }> {
123
+ return (
124
+ this.props.tooltipState ??
125
+ new TooltipState<{
126
+ entityName: string
127
+ seriesName?: string
128
+ }>()
129
+ )
130
+ }
131
+
132
+ @computed private get baseFontSize(): number {
133
+ return this.manager.fontSize ?? BASE_FONT_SIZE
134
+ }
135
+
136
+ @computed get isStatic(): boolean {
137
+ return this.manager.isStatic ?? false
138
+ }
139
+
140
+ @computed private get barCount(): number {
141
+ return this.chartState.items.length
142
+ }
143
+
144
+ @computed private get labelFontSize(): number {
145
+ const availableHeight = this.bounds.height / this.barCount
146
+ return Math.min(
147
+ GRAPHER_FONT_SCALE_12 * this.fontSize,
148
+ 1.1 * availableHeight
149
+ )
150
+ }
151
+
152
+ @computed private get labelStyle(): {
153
+ fontSize: number
154
+ fontWeight: number
155
+ lineHeight: number
156
+ } {
157
+ return {
158
+ fontSize: this.labelFontSize,
159
+ fontWeight: 700,
160
+ lineHeight: 1,
161
+ }
162
+ }
163
+
164
+ @computed private get totalValueLabelStyle(): {
165
+ fill: string
166
+ fontSize: number
167
+ } {
168
+ return {
169
+ fill: "#555",
170
+ fontSize: this.labelFontSize,
171
+ }
172
+ }
173
+
174
+ // Account for the width of the legend
175
+ @computed private get labelWidth(): number {
176
+ return _.max(this.sizedItems.map((d) => d.label.width)) ?? 0
177
+ }
178
+
179
+ @computed private get showTotalValueLabel(): boolean {
180
+ return !this.manager.isRelativeMode && !this.manager.hideTotalValueLabel
181
+ }
182
+
183
+ @computed private get showHorizontalAxis(): boolean {
184
+ return !this.showTotalValueLabel
185
+ }
186
+
187
+ // The amount of space we need to allocate for total value labels on the right
188
+ @computed private get totalValueLabelWidth(): number {
189
+ if (!this.showTotalValueLabel) return 0
190
+
191
+ const labels = this.sizedItems.map((d) =>
192
+ this.formatValueForLabel(d.totalValue)
193
+ )
194
+ const longestLabel = _.maxBy(labels, (l) => l.length)
195
+ return Bounds.forText(longestLabel, this.totalValueLabelStyle).width
196
+ }
197
+
198
+ @computed private get x0(): number {
199
+ return 0
200
+ }
201
+
202
+ @computed private get allPoints(): StackedPoint<EntityName>[] {
203
+ return this.series.flatMap((series) => series.points)
204
+ }
205
+
206
+ // Now we can work out the main x axis scale
207
+ @computed private get xDomainDefault(): [number, number] {
208
+ const maxValues = this.allPoints.map(
209
+ (point) => point.value + point.valueOffset
210
+ )
211
+ return [this.x0, Math.max(this.x0, _.max(maxValues) as number)]
212
+ }
213
+
214
+ @computed private get xRange(): [number, number] {
215
+ return [
216
+ this.bounds.left + this.labelWidth,
217
+ this.bounds.right - this.totalValueLabelWidth,
218
+ ]
219
+ }
220
+
221
+ @computed private get yAxisConfig(): AxisConfig {
222
+ return new AxisConfig(this.manager.yAxisConfig, this)
223
+ }
224
+
225
+ @computed get yAxis(): HorizontalAxis {
226
+ // NB: We use the user's YAxis options here to make the XAxis
227
+ const axis = this.yAxisConfig.toHorizontalAxis()
228
+ axis.updateDomainPreservingUserSettings(this.xDomainDefault)
229
+
230
+ axis.scaleType = ScaleType.linear
231
+ axis.formatColumn = this.yColumns[0] // todo: does this work for columns as series?
232
+ axis.range = this.xRange
233
+ axis.label = ""
234
+ return axis
235
+ }
236
+
237
+ @computed private get innerBounds(): Bounds {
238
+ return this.bounds
239
+ .padLeft(this.labelWidth)
240
+ .padBottom(this.showHorizontalAxis ? this.yAxis.height : 0)
241
+ .padRight(this.totalValueLabelWidth)
242
+ }
243
+
244
+ @computed private get sizedItems(): readonly SizedItem[] {
245
+ return enrichSeriesWithLabels({
246
+ series: this.chartState.sortedItems,
247
+ availableHeightPerSeries: this.bounds.height / this.barCount,
248
+ minLabelWidth: 0.3 * this.bounds.width,
249
+ maxLabelWidth: 0.66 * this.bounds.width,
250
+ fontSettings: this.labelStyle,
251
+ })
252
+ }
253
+
254
+ @computed private get placedItems(): PlacedItem[] {
255
+ const { innerBounds, barHeight, barSpacing } = this
256
+
257
+ const topYOffset = innerBounds.top + barHeight / 2 + barSpacing / 2
258
+
259
+ return this.sizedItems.map((d, i) => ({
260
+ yPosition: topYOffset + (barHeight + barSpacing) * i,
261
+ ...d,
262
+ }))
263
+ }
264
+
265
+ /** The total height of the series, i.e. the height of the bar + the white space around it */
266
+ @computed private get seriesHeight(): number {
267
+ return this.innerBounds.height / this.barCount
268
+ }
269
+
270
+ @computed private get barSpacing(): number {
271
+ return this.seriesHeight * BAR_SPACING_FACTOR
272
+ }
273
+
274
+ @computed private get barHeight(): number {
275
+ const totalWhiteSpace = this.barCount * this.barSpacing
276
+ return (this.innerBounds.height - totalWhiteSpace) / this.barCount
277
+ }
278
+
279
+ @computed get fontSize(): number {
280
+ return this.baseFontSize
281
+ }
282
+
283
+ @computed private get formatColumn(): CoreColumn {
284
+ return this.yColumns[0]
285
+ }
286
+
287
+ @bind private formatValueForLabel(value: number): string {
288
+ // Compute how many decimal places we should show.
289
+ // Basically, this makes us show 2 significant digits, or no decimal places if the number
290
+ // is big enough already.
291
+ const magnitude = numberMagnitude(value)
292
+ return this.formatColumn.formatValueShort(value, {
293
+ numDecimalPlaces: Math.max(0, -magnitude + 2),
294
+ })
295
+ }
296
+
297
+ @action.bound private onEntityMouseEnter(
298
+ entityName: string,
299
+ seriesName?: string
300
+ ): void {
301
+ this.tooltipState.target = { entityName, seriesName }
302
+ }
303
+
304
+ @action.bound private onEntityMouseLeave(): void {
305
+ this.tooltipState.target = null
306
+ }
307
+
308
+ override render(): React.ReactElement {
309
+ return this.manager.isStatic
310
+ ? this.renderStatic()
311
+ : this.renderInteractive()
312
+ }
313
+
314
+ @computed private get inputTable(): OwidTable {
315
+ return this.chartState.inputTable
316
+ }
317
+
318
+ @computed private get chartContext(): StackedBarChartContext {
319
+ return {
320
+ yAxis: this.yAxis,
321
+ targetTime: this.manager.endTime,
322
+ timeColumn: this.inputTable.timeColumn,
323
+ formatColumn: this.formatColumn,
324
+ formatValueForLabel: this.formatValueForLabel,
325
+ barHeight: this.barHeight,
326
+ focusSeriesName: this.focusSeriesName,
327
+ hoverSeriesName: this.tooltipState.target?.seriesName,
328
+ hoverEntityName: this.tooltipState.target?.entityName,
329
+ x0: this.x0,
330
+ baseFontSize: this.baseFontSize,
331
+ }
332
+ }
333
+
334
+ renderRow({
335
+ data,
336
+ state,
337
+ }: {
338
+ data: PlacedItem
339
+ state: { translateY: number }
340
+ }): React.ReactElement {
341
+ const { yAxis } = this
342
+ const { entityName, label, bars, totalValue } = data
343
+
344
+ const totalLabel = this.formatValueForLabel(totalValue)
345
+ const showLabelInsideBar = bars.length > 1
346
+
347
+ const opacity = data.focus.background ? GRAPHER_OPACITY_MUTE : 1
348
+
349
+ // We can't just take the last bar here because if the last bar has a negative value,
350
+ // its position on the chart (valueOffset + value) might actually be leftmost rather than rightmost.
351
+ // So we find the maximum position across all bars to determine where to place the total value label.
352
+ const lastValue =
353
+ _.max(bars.map((bar) => bar.point.valueOffset + bar.point.value)) ??
354
+ 0
355
+
356
+ return (
357
+ <g
358
+ key={entityName}
359
+ id={makeIdForHumanConsumption(entityName)}
360
+ className="bar"
361
+ transform={`translate(0, ${state.translateY ?? 0})`}
362
+ opacity={opacity}
363
+ >
364
+ {bars.map((bar) => (
365
+ <StackedDiscreteBars.Bar
366
+ key={bar.seriesName}
367
+ entity={entityName}
368
+ bar={bar}
369
+ chartContext={this.chartContext}
370
+ showLabelInsideBar={showLabelInsideBar}
371
+ onMouseEnter={this.onEntityMouseEnter}
372
+ onMouseLeave={this.onEntityMouseLeave}
373
+ />
374
+ ))}
375
+ {label.renderSVG(
376
+ yAxis.place(this.x0) - labelToBarPadding,
377
+ -label.height / 2,
378
+ {
379
+ textProps: {
380
+ textAnchor: "end",
381
+ fill: "#555",
382
+ onMouseEnter: (): void =>
383
+ this.onEntityMouseEnter(label.text),
384
+ onMouseLeave: this.onEntityMouseLeave,
385
+ },
386
+ }
387
+ )}
388
+ {this.showTotalValueLabel && (
389
+ <text
390
+ transform={`translate(${
391
+ yAxis.place(lastValue) + labelToBarPadding
392
+ }, 0)`}
393
+ dy={dyFromAlign(VerticalAlign.middle)}
394
+ {...this.totalValueLabelStyle}
395
+ >
396
+ {totalLabel}
397
+ </text>
398
+ )}
399
+ </g>
400
+ )
401
+ }
402
+
403
+ renderAxis(): React.ReactElement {
404
+ const { bounds, yAxis, innerBounds } = this
405
+
406
+ return (
407
+ <>
408
+ {this.showHorizontalAxis && (
409
+ <>
410
+ <HorizontalAxisComponent
411
+ bounds={bounds}
412
+ axis={yAxis}
413
+ preferredAxisPosition={innerBounds.bottom}
414
+ />
415
+ <HorizontalAxisGridLines
416
+ horizontalAxis={yAxis}
417
+ bounds={innerBounds}
418
+ />
419
+ </>
420
+ )}
421
+ <HorizontalAxisZeroLine
422
+ horizontalAxis={yAxis}
423
+ bounds={innerBounds}
424
+ strokeWidth={0.5}
425
+ // moves the zero line a little to the left to avoid
426
+ // overlap with the bars
427
+ align={HorizontalAlign.right}
428
+ />
429
+ </>
430
+ )
431
+ }
432
+
433
+ renderStatic(): React.ReactElement {
434
+ return (
435
+ <>
436
+ {this.renderAxis()}
437
+ <g id={makeIdForHumanConsumption("bars")}>
438
+ {this.placedItems.map((item) =>
439
+ this.renderRow({
440
+ data: item,
441
+ state: { translateY: item.yPosition },
442
+ })
443
+ )}
444
+ </g>
445
+ </>
446
+ )
447
+ }
448
+
449
+ renderInteractive(): React.ReactElement {
450
+ const handlePositionUpdate = (d: PlacedItem): HashMap => ({
451
+ translateY: [d.yPosition],
452
+ timing: { duration: 350, ease: easeQuadOut },
453
+ })
454
+
455
+ // needs to be referenced here, otherwise it's not updated in the renderRow function
456
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
457
+ this.focusSeriesName
458
+
459
+ return (
460
+ <>
461
+ {this.renderAxis()}
462
+ <NodeGroup
463
+ data={this.placedItems}
464
+ keyAccessor={(d: PlacedItem): string => d.entityName}
465
+ start={handlePositionUpdate}
466
+ update={handlePositionUpdate}
467
+ >
468
+ {(nodes): React.ReactElement => (
469
+ <g>{nodes.map((node) => this.renderRow(node))}</g>
470
+ )}
471
+ </NodeGroup>
472
+ {this.tooltip}
473
+ </>
474
+ )
475
+ }
476
+
477
+ private static Bar(props: {
478
+ bar: Bar
479
+ entity: string
480
+ chartContext: StackedBarChartContext
481
+ showLabelInsideBar: boolean
482
+ onMouseEnter: (entityName: string, seriesName?: string) => void
483
+ onMouseLeave: () => void
484
+ }): React.ReactElement {
485
+ const { entity, bar, chartContext } = props
486
+ const { yAxis, formatValueForLabel, focusSeriesName, barHeight } =
487
+ chartContext
488
+
489
+ const isFaint =
490
+ focusSeriesName !== undefined && focusSeriesName !== bar.seriesName
491
+ const isHover =
492
+ chartContext.hoverSeriesName === bar.seriesName &&
493
+ chartContext.hoverEntityName === entity
494
+ let barX = yAxis.place(chartContext.x0 + bar.point.valueOffset)
495
+ const barWidth = Math.abs(
496
+ yAxis.place(bar.point.value) - yAxis.place(chartContext.x0)
497
+ )
498
+
499
+ // Place bars that represent negative values on the left
500
+ if (bar.point.value < 0) barX -= barWidth
501
+
502
+ const barLabel = formatValueForLabel(bar.point.value)
503
+ const labelFontSize = GRAPHER_FONT_SCALE_12 * chartContext.baseFontSize
504
+ const labelBounds = Bounds.forText(barLabel, {
505
+ fontSize: labelFontSize,
506
+ })
507
+ // Check that we have enough space to show the bar label
508
+ const showLabelInsideBar =
509
+ props.showLabelInsideBar &&
510
+ labelBounds.width < 0.85 * barWidth &&
511
+ labelBounds.height < 0.85 * barHeight
512
+ const labelColor = isDarkColor(bar.color) ? "#fff" : "#000"
513
+
514
+ const opacity = isHover
515
+ ? BAR_OPACITY.FOCUS
516
+ : isFaint
517
+ ? BAR_OPACITY.MUTE
518
+ : BAR_OPACITY.DEFAULT
519
+
520
+ return (
521
+ <g
522
+ id={makeIdForHumanConsumption(bar.seriesName)}
523
+ onMouseEnter={(): void =>
524
+ props?.onMouseEnter(entity, bar.seriesName)
525
+ }
526
+ onMouseLeave={props?.onMouseLeave}
527
+ >
528
+ <rect
529
+ id={makeIdForHumanConsumption("bar")}
530
+ x={0}
531
+ y={0}
532
+ transform={`translate(${barX}, ${-barHeight / 2})`}
533
+ width={barWidth}
534
+ height={barHeight}
535
+ fill={bar.color}
536
+ opacity={opacity}
537
+ style={{ transition: "height 200ms ease" }}
538
+ />
539
+ {showLabelInsideBar && (
540
+ <text
541
+ x={barX + barWidth / 2}
542
+ y={0}
543
+ width={barWidth}
544
+ height={barHeight}
545
+ fill={labelColor}
546
+ opacity={isFaint ? 0 : 1}
547
+ fontSize={labelFontSize}
548
+ textAnchor="middle"
549
+ dy={dyFromAlign(VerticalAlign.middle)}
550
+ >
551
+ {barLabel}
552
+ </text>
553
+ )}
554
+ </g>
555
+ )
556
+ }
557
+
558
+ @computed private get tooltip(): React.ReactElement | undefined {
559
+ const {
560
+ tooltipState: { target, position, fading },
561
+ formatColumn: { displayUnit },
562
+ manager: { endTime: targetTime },
563
+ inputTable: { timeColumn },
564
+ } = this,
565
+ item = this.placedItems.find(
566
+ ({ entityName }) => entityName === target?.entityName
567
+ ),
568
+ hasNotice = item?.bars.some(
569
+ ({ point }) => !point.fake && point.time !== targetTime
570
+ ),
571
+ targetNotice = hasNotice
572
+ ? timeColumn.formatValue(targetTime)
573
+ : undefined
574
+
575
+ const toleranceNotice = targetNotice
576
+ ? {
577
+ icon: TooltipFooterIcon.Notice,
578
+ text: makeTooltipToleranceNotice(targetNotice),
579
+ }
580
+ : undefined
581
+ const roundingNotice = this.formatColumn.roundsToSignificantFigures
582
+ ? {
583
+ icon: TooltipFooterIcon.None,
584
+ text: makeTooltipRoundingNotice([
585
+ this.formatColumn.numSignificantFigures,
586
+ ]),
587
+ }
588
+ : undefined
589
+ const footer = excludeUndefined([toleranceNotice, roundingNotice])
590
+
591
+ return (
592
+ target &&
593
+ item && (
594
+ <Tooltip
595
+ id="stackedDiscreteBarTooltip"
596
+ tooltipManager={this.manager}
597
+ x={position.x}
598
+ y={position.y}
599
+ style={{ maxWidth: "400px" }}
600
+ offsetX={20}
601
+ offsetY={-16}
602
+ title={target.entityName}
603
+ subtitle={displayUnit}
604
+ subtitleFormat="unit"
605
+ footer={footer}
606
+ dissolve={fading}
607
+ dismiss={() => (this.tooltipState.target = null)}
608
+ >
609
+ <TooltipTable
610
+ columns={toTooltipTableColumns(this.formatColumn)}
611
+ totals={[item.totalValue]}
612
+ rows={item.bars.map((bar) => {
613
+ const {
614
+ seriesName: name,
615
+ color,
616
+ point: { value, time, fake: blurred },
617
+ } = bar
618
+
619
+ return {
620
+ name,
621
+ swatch: { color },
622
+ blurred,
623
+ focused: name === target.seriesName,
624
+ values: [!blurred ? value : undefined],
625
+ originalTime:
626
+ !blurred && time !== targetTime
627
+ ? timeColumn.formatValue(time)
628
+ : undefined,
629
+ }
630
+ })}
631
+ ></TooltipTable>
632
+ </Tooltip>
633
+ )
634
+ )
635
+ }
636
+
637
+ @computed private get yColumns(): CoreColumn[] {
638
+ return this.chartState.yColumns
639
+ }
640
+
641
+ @computed private get series(): readonly StackedSeries<EntityName>[] {
642
+ return this.chartState.series
643
+ }
644
+
645
+ override componentDidMount(): void {
646
+ exposeInstanceOnWindow(this)
647
+ }
648
+ }