@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,158 @@
1
+ import { match, P } from "ts-pattern"
2
+ import {
3
+ GRAPHER_CHART_TYPES,
4
+ GRAPHER_MAP_TYPE,
5
+ GrapherChartOrMapType,
6
+ GrapherVariant,
7
+ } from "../../types/index.js"
8
+ import { ChartInterface, ChartState } from "./ChartInterface"
9
+ import { ChartManager } from "./ChartManager"
10
+ import { ComponentClass, Component } from "react"
11
+ import { Bounds } from "../../utils/index.js"
12
+
13
+ import { LineChartState } from "../lineCharts/LineChartState.js"
14
+ import { SlopeChartState } from "../slopeCharts/SlopeChartState"
15
+ import { DiscreteBarChartState } from "../barCharts/DiscreteBarChartState.js"
16
+ import { StackedAreaChartState } from "../stackedCharts/StackedAreaChartState.js"
17
+ import { StackedBarChartState } from "../stackedCharts/StackedBarChartState.js"
18
+ import { StackedDiscreteBarChartState } from "../stackedCharts/StackedDiscreteBarChartState"
19
+ import { ScatterPlotChartState } from "../scatterCharts/ScatterPlotChartState"
20
+ import { MarimekkoChartState } from "../stackedCharts/MarimekkoChartState"
21
+ import { MapChartState } from "../mapCharts/MapChartState"
22
+
23
+ import { LineChart } from "../lineCharts/LineChart"
24
+ import { SlopeChart } from "../slopeCharts/SlopeChart.js"
25
+ import { DiscreteBarChart } from "../barCharts/DiscreteBarChart.js"
26
+ import { StackedAreaChart } from "../stackedCharts/StackedAreaChart"
27
+ import { StackedBarChart } from "../stackedCharts/StackedBarChart"
28
+ import { StackedDiscreteBarChart } from "../stackedCharts/StackedDiscreteBarChart"
29
+ import { ScatterPlotChart } from "../scatterCharts/ScatterPlotChart"
30
+ import { MarimekkoChart } from "../stackedCharts/MarimekkoChart"
31
+ import { MapChart } from "../mapCharts/MapChart"
32
+
33
+ import { LineChartThumbnail } from "../lineCharts/LineChartThumbnail"
34
+ import { SlopeChartThumbnail } from "../slopeCharts/SlopeChartThumbnail"
35
+ import { DiscreteBarChartThumbnail } from "../barCharts/DiscreteBarChartThumbnail.js"
36
+ import { StackedAreaChartThumbnail } from "../stackedCharts/StackedAreaChartThumbnail"
37
+ import { StackedBarChartThumbnail } from "../stackedCharts/StackedBarChartThumbnail"
38
+ import { StackedDiscreteBarChartThumbnail } from "../stackedCharts/StackedDiscreteBarChartThumbnail"
39
+ import { ScatterPlotChartThumbnail } from "../scatterCharts/ScatterPlotChartThumbnail"
40
+ import { MarimekkoChartThumbnail } from "../stackedCharts/MarimekkoChartThumbnail"
41
+ import { MapChartThumbnail } from "../mapCharts/MapChartThumbnail"
42
+
43
+ export interface ChartComponentProps<TState extends ChartState = ChartState> {
44
+ chartState: TState
45
+ bounds?: Bounds
46
+ }
47
+
48
+ interface ChartComponentClass<T extends ChartState = ChartState>
49
+ extends ComponentClass<ChartComponentProps<T>> {
50
+ new (props: ChartComponentProps<T>): Component & ChartInterface
51
+ }
52
+
53
+ type ChartFactoryProps = {
54
+ manager: ChartManager
55
+ chartType: GrapherChartOrMapType
56
+ chartState?: ChartState
57
+ variant?: GrapherVariant
58
+ } & Omit<ChartComponentProps, "chartState">
59
+
60
+ const ChartComponentClassMap = new Map<
61
+ GrapherChartOrMapType,
62
+ ChartComponentClass<any>
63
+ >([
64
+ [GRAPHER_CHART_TYPES.LineChart, LineChart],
65
+ [GRAPHER_CHART_TYPES.SlopeChart, SlopeChart],
66
+ [GRAPHER_CHART_TYPES.DiscreteBar, DiscreteBarChart],
67
+ [GRAPHER_CHART_TYPES.StackedArea, StackedAreaChart],
68
+ [GRAPHER_CHART_TYPES.StackedBar, StackedBarChart],
69
+ [GRAPHER_CHART_TYPES.StackedDiscreteBar, StackedDiscreteBarChart],
70
+ [GRAPHER_CHART_TYPES.ScatterPlot, ScatterPlotChart],
71
+ [GRAPHER_CHART_TYPES.Marimekko, MarimekkoChart],
72
+ [GRAPHER_MAP_TYPE, MapChart],
73
+ ])
74
+
75
+ const ChartThumbnailClassMap = new Map<
76
+ GrapherChartOrMapType,
77
+ ChartComponentClass<any>
78
+ >([
79
+ [GRAPHER_CHART_TYPES.LineChart, LineChartThumbnail],
80
+ [GRAPHER_CHART_TYPES.SlopeChart, SlopeChartThumbnail],
81
+ [GRAPHER_CHART_TYPES.DiscreteBar, DiscreteBarChartThumbnail],
82
+ [GRAPHER_CHART_TYPES.StackedArea, StackedAreaChartThumbnail],
83
+ [GRAPHER_CHART_TYPES.StackedBar, StackedBarChartThumbnail],
84
+ [GRAPHER_CHART_TYPES.StackedDiscreteBar, StackedDiscreteBarChartThumbnail],
85
+ [GRAPHER_CHART_TYPES.ScatterPlot, ScatterPlotChartThumbnail],
86
+ [GRAPHER_CHART_TYPES.Marimekko, MarimekkoChartThumbnail],
87
+ [GRAPHER_MAP_TYPE, MapChartThumbnail],
88
+ ])
89
+
90
+ const ChartStateMap = new Map<
91
+ GrapherChartOrMapType,
92
+ new (args: { manager: ChartManager }) => ChartState
93
+ >([
94
+ [GRAPHER_CHART_TYPES.LineChart, LineChartState],
95
+ [GRAPHER_CHART_TYPES.SlopeChart, SlopeChartState],
96
+ [GRAPHER_CHART_TYPES.DiscreteBar, DiscreteBarChartState],
97
+ [GRAPHER_CHART_TYPES.StackedArea, StackedAreaChartState],
98
+ [GRAPHER_CHART_TYPES.StackedBar, StackedBarChartState],
99
+ [GRAPHER_CHART_TYPES.StackedDiscreteBar, StackedDiscreteBarChartState],
100
+ [GRAPHER_CHART_TYPES.ScatterPlot, ScatterPlotChartState],
101
+ [GRAPHER_CHART_TYPES.Marimekko, MarimekkoChartState],
102
+ [GRAPHER_MAP_TYPE, MapChartState],
103
+ ])
104
+
105
+ export function makeChartState(
106
+ chartType: GrapherChartOrMapType,
107
+ manager: ChartManager
108
+ ): ChartState {
109
+ const StateClass = ChartStateMap.get(chartType) ?? LineChartState
110
+ return new StateClass({ manager })
111
+ }
112
+
113
+ function getChartComponentClass(
114
+ chartType: GrapherChartOrMapType,
115
+ variant = GrapherVariant.Default
116
+ ): ChartComponentClass {
117
+ const { ClassMap, DefaultChartClass } = match(variant)
118
+ .with(
119
+ P.union(GrapherVariant.Default, GrapherVariant.Uncaptioned),
120
+ () => ({
121
+ ClassMap: ChartComponentClassMap,
122
+ DefaultChartClass: LineChart,
123
+ })
124
+ )
125
+ .with(GrapherVariant.Thumbnail, () => ({
126
+ ClassMap: ChartThumbnailClassMap,
127
+ DefaultChartClass: LineChartThumbnail,
128
+ }))
129
+ .exhaustive()
130
+
131
+ const ChartClass = ClassMap.get(chartType) ?? DefaultChartClass
132
+
133
+ return ChartClass as ChartComponentClass
134
+ }
135
+
136
+ export const ChartComponent = ({
137
+ manager,
138
+ chartType,
139
+ chartState,
140
+ variant = GrapherVariant.Default,
141
+ ...componentProps
142
+ }: ChartFactoryProps): React.ReactElement => {
143
+ const validChartState = chartState ?? makeChartState(chartType, manager)
144
+ const ChartClass = getChartComponentClass(chartType, variant)
145
+ return <ChartClass {...componentProps} chartState={validChartState} />
146
+ }
147
+
148
+ export const makeChartInstance = ({
149
+ manager,
150
+ chartType,
151
+ chartState,
152
+ variant = GrapherVariant.Default,
153
+ ...componentProps
154
+ }: ChartFactoryProps): ChartInterface => {
155
+ const validChartState = chartState ?? makeChartState(chartType, manager)
156
+ const ChartClass = getChartComponentClass(chartType, variant)
157
+ return new ChartClass({ ...componentProps, chartState: validChartState })
158
+ }
@@ -0,0 +1,26 @@
1
+ import * as React from "react"
2
+ import {
3
+ ALL_GRAPHER_CHART_TYPES,
4
+ GrapherChartType,
5
+ } from "../../types/index.js"
6
+
7
+ // Just a utility for testing
8
+ export class ChartTypeSwitcher extends React.Component<{
9
+ onChange: (chartType: GrapherChartType) => void
10
+ }> {
11
+ override render(): React.ReactElement {
12
+ return (
13
+ <select
14
+ onChange={(event): void =>
15
+ this.props.onChange(event.target.value as any)
16
+ }
17
+ >
18
+ {ALL_GRAPHER_CHART_TYPES.map((value) => (
19
+ <option key={value} value={value}>
20
+ {value}
21
+ </option>
22
+ ))}
23
+ </select>
24
+ )
25
+ }
26
+ }
@@ -0,0 +1,364 @@
1
+ import * as React from "react"
2
+ import {
3
+ Box,
4
+ excludeUndefined,
5
+ getRegionByName,
6
+ Url,
7
+ } from "../../utils/index.js"
8
+ import {
9
+ SeriesStrategy,
10
+ EntityName,
11
+ SeriesName,
12
+ ColumnSlug,
13
+ GrapherTabName,
14
+ GRAPHER_TAB_NAMES,
15
+ ProjectionColumnInfo,
16
+ CoreValueType,
17
+ PrimitiveType,
18
+ ColumnTypeNames,
19
+ Time,
20
+ } from "../../types/index.js"
21
+ import { LineChartSeries } from "../lineCharts/LineChartConstants"
22
+ import { SelectionArray } from "../selection/SelectionArray"
23
+ import { ChartManager } from "./ChartManager"
24
+ import {
25
+ GRAPHER_SIDE_PANEL_CLASS,
26
+ GRAPHER_TIMELINE_CLASS,
27
+ GRAPHER_SETTINGS_CLASS,
28
+ SVG_STYLE_PROPS,
29
+ BASE_FONT_SIZE,
30
+ Patterns,
31
+ GRAPHER_IMAGE_WIDTH_1X,
32
+ GRAPHER_IMAGE_WIDTH_2X,
33
+ } from "../core/GrapherConstants"
34
+ import { ChartSeries } from "./ChartInterface"
35
+ import {
36
+ ErrorValueTypes,
37
+ isNotErrorValueOrEmptyCell,
38
+ OwidTable,
39
+ } from "../../core-table/index.js"
40
+ import { GRAPHER_BACKGROUND_DEFAULT } from "../color/ColorConstants"
41
+ import { InteractionState } from "../interaction/InteractionState"
42
+
43
+ export const autoDetectYColumnSlugs = (manager: ChartManager): string[] => {
44
+ if (manager.yColumnSlugs && manager.yColumnSlugs.length)
45
+ return manager.yColumnSlugs
46
+ if (manager.yColumnSlug) return [manager.yColumnSlug]
47
+ return manager.table.numericColumnSlugs
48
+ }
49
+
50
+ export const getDefaultFailMessage = (manager: ChartManager): string => {
51
+ if (manager.table.rootTable.isBlank) return `No table loaded yet`
52
+ if (manager.table.rootTable.entityNameColumn.isMissing)
53
+ return `Table is missing an EntityName column`
54
+ if (manager.table.rootTable.timeColumn.isMissing)
55
+ return `Table is missing a Time column`
56
+ const yColumnSlugs = autoDetectYColumnSlugs(manager)
57
+ if (!yColumnSlugs.length) return "Missing Y axis column"
58
+ const selection = makeSelectionArray(manager.selection)
59
+ if (!selection.hasSelection) return `No ${manager.entityType} selected`
60
+ return ""
61
+ }
62
+
63
+ export const getSeriesKey = (
64
+ series: LineChartSeries,
65
+ index: number
66
+ ): string => {
67
+ return `${series.seriesName}-${series.color}-${
68
+ series.isProjection ? "projection" : ""
69
+ }-${index}`
70
+ }
71
+
72
+ export const autoDetectSeriesStrategy = (
73
+ manager: ChartManager,
74
+ handleProjections: boolean = false
75
+ ): SeriesStrategy => {
76
+ if (manager.seriesStrategy) return manager.seriesStrategy
77
+
78
+ let columnThreshold: number = 1
79
+
80
+ if (handleProjections && manager.transformedTable) {
81
+ const yColumnSlugs = autoDetectYColumnSlugs(manager)
82
+ const yColumns = yColumnSlugs.map((slug) =>
83
+ manager.transformedTable!.get(slug)
84
+ )
85
+ const hasNormalAndProjectedSeries =
86
+ yColumns.some((col) => col.isProjection) &&
87
+ yColumns.some((col) => !col.isProjection)
88
+ if (hasNormalAndProjectedSeries) {
89
+ columnThreshold = 2
90
+ }
91
+ }
92
+
93
+ return autoDetectYColumnSlugs(manager).length > columnThreshold
94
+ ? SeriesStrategy.column
95
+ : SeriesStrategy.entity
96
+ }
97
+
98
+ export interface ClipPath {
99
+ id: string
100
+ element: React.ReactElement
101
+ }
102
+
103
+ export const makeClipPath = (props: {
104
+ name?: string
105
+ renderUid: number
106
+ box: Box
107
+ }): {
108
+ id: string
109
+ element: React.ReactElement
110
+ } => {
111
+ const name = props.name ?? "boundsClip"
112
+ const id = `${name}-${props.renderUid}`
113
+ return {
114
+ id: `url(#${id})`,
115
+ element: (
116
+ <defs>
117
+ <clipPath id={id}>
118
+ <rect {...props.box}></rect>
119
+ </clipPath>
120
+ </defs>
121
+ ),
122
+ }
123
+ }
124
+
125
+ export const makeSelectionArray = (
126
+ selection?: SelectionArray | EntityName[]
127
+ ): SelectionArray =>
128
+ selection instanceof SelectionArray
129
+ ? selection
130
+ : new SelectionArray(selection ?? [])
131
+
132
+ export function isElementInteractive(element: HTMLElement): boolean {
133
+ const interactiveTags = ["a", "button", "input"]
134
+ const interactiveClassNames = [
135
+ GRAPHER_TIMELINE_CLASS,
136
+ GRAPHER_SIDE_PANEL_CLASS,
137
+ GRAPHER_SETTINGS_CLASS,
138
+ ].map((className) => `.${className}`)
139
+
140
+ const selector = [...interactiveTags, ...interactiveClassNames].join(", ")
141
+
142
+ // check if the target is an interactive element or contained within one
143
+ return element.closest(selector) !== null
144
+ }
145
+
146
+ export function getShortNameForEntity(entityName: string): string | undefined {
147
+ const region = getRegionByName(entityName)
148
+ return region?.shortName
149
+ }
150
+
151
+ export function isTargetOutsideElement(
152
+ target: EventTarget,
153
+ element: Node
154
+ ): boolean {
155
+ const targetNode = target as Node
156
+ return (
157
+ !element.contains(targetNode) &&
158
+ // check that the target is still mounted to the document (we also get
159
+ // click events on nodes that have since been removed by React)
160
+ document.contains(targetNode)
161
+ )
162
+ }
163
+
164
+ export function getHoverStateForSeries(
165
+ series: ChartSeries,
166
+ props: {
167
+ hoveredSeriesNames: SeriesName[]
168
+ // usually the hover mode is active when there is
169
+ // at least one hovered element. But sometimes the hover
170
+ // mode might be active although there are no hovered elements.
171
+ // For example, when the facet legend is hovered but a particular
172
+ // chart doesn't plot the hovered element.
173
+ isHoverModeActive?: boolean
174
+ }
175
+ ): InteractionState {
176
+ const hoveredSeriesNames = props.hoveredSeriesNames
177
+ const isHoverModeActive =
178
+ props.isHoverModeActive ?? hoveredSeriesNames.length > 0
179
+
180
+ const isActive = hoveredSeriesNames.includes(series.seriesName)
181
+
182
+ return new InteractionState(isActive, isHoverModeActive)
183
+ }
184
+
185
+ /** Useful for sorting series by their interaction state */
186
+ export function byHoverThenFocusState(series: {
187
+ hover: InteractionState
188
+ focus: InteractionState
189
+ }): number {
190
+ // active series rank highest and hover trumps focus
191
+ if (series.hover.active) return 4
192
+ if (series.focus.active) return 3
193
+
194
+ // series in their default state rank in the middle
195
+ if (!series.hover.background && !series.focus.background) return 2
196
+
197
+ // background series rank lowest
198
+ return 1
199
+ }
200
+
201
+ export function makeAxisLabel({
202
+ label,
203
+ displayUnit,
204
+ }: {
205
+ label: string
206
+ displayUnit?: string
207
+ }): {
208
+ mainLabel: string // shown in bold
209
+ unit?: string // shown in normal weight, usually in parens
210
+ } {
211
+ // No unit to display
212
+ if (!displayUnit) return { mainLabel: label }
213
+
214
+ // Extract text in parens at the end of the label,
215
+ // e.g. "Population (millions)" is split into "Population " and "(millions)"
216
+ const [
217
+ _fullMatch,
218
+ untrimmedMainLabelText = undefined,
219
+ labelTextInParens = undefined,
220
+ ] = label.trim().match(/^(.*?)(\([^()]*\))?$/s) ?? []
221
+ const mainLabelText = untrimmedMainLabelText?.trim() ?? ""
222
+
223
+ // Don't show unit twice if it's contained in the label
224
+ const displayLabel =
225
+ labelTextInParens === `(${displayUnit})` ? mainLabelText : label
226
+
227
+ return { mainLabel: displayLabel, unit: displayUnit }
228
+ }
229
+
230
+ /**
231
+ * Given a URL for a CF function grapher thumbnail, generate a srcSet for the image at different widths
232
+ * @param defaultSrc - `https://ourworldindata.org/grapher/thumbnail/life-expectancy.png?tab=chart`
233
+ * @returns srcSet - `https://ourworldindata.org/grapher/thumbnail/life-expectancy.png?tab=chart&imWidth=850 850w, https://ourworldindata.org/grapher/thumbnail/life-expectancy.png?tab=chart&imWidth=1700 1700w`
234
+ */
235
+ export function generateGrapherImageSrcSet(defaultSrc: string): string {
236
+ const url = Url.fromURL(defaultSrc)
237
+ const existingQueryParams = url.queryParams
238
+ const imWidths = [
239
+ GRAPHER_IMAGE_WIDTH_1X.toString(),
240
+ GRAPHER_IMAGE_WIDTH_2X.toString(),
241
+ ]
242
+ const srcSet = imWidths
243
+ .map((imWidth) => {
244
+ return `${url.setQueryParams({ ...existingQueryParams, imWidth }).fullUrl} ${imWidth}w`
245
+ })
246
+ .join(", ")
247
+
248
+ return srcSet
249
+ }
250
+
251
+ export const isChartTab = (tab: GrapherTabName): boolean =>
252
+ tab !== GRAPHER_TAB_NAMES.Table && tab !== GRAPHER_TAB_NAMES.WorldMap
253
+
254
+ export const isMapTab = (tab: GrapherTabName): boolean =>
255
+ tab === GRAPHER_TAB_NAMES.WorldMap
256
+
257
+ export function combineHistoricalAndProjectionColumns(
258
+ table: OwidTable,
259
+ info: ProjectionColumnInfo,
260
+ options?: { shouldAddIsProjectionColumn: boolean }
261
+ ): OwidTable {
262
+ const {
263
+ historicalSlug,
264
+ projectedSlug,
265
+ combinedSlug,
266
+ slugForIsProjectionColumn,
267
+ } = info
268
+
269
+ const transformFn = (
270
+ row: Record<ColumnSlug, { value: CoreValueType; time: Time }>,
271
+ time: Time
272
+ ): { isProjection: boolean; value: PrimitiveType } | undefined => {
273
+ // It's possible to have both a historical and a projected value
274
+ // for a given year. In that case, we prefer the historical value.
275
+
276
+ const historical = row[historicalSlug]
277
+ const projected = row[projectedSlug]
278
+
279
+ const historicalTimeDiff = Math.abs(historical.time - time)
280
+ const projectionTimeDiff = Math.abs(projected.time - time)
281
+
282
+ if (
283
+ isNotErrorValueOrEmptyCell(historical.value) &&
284
+ // If tolerance was applied to the historical column, we need to
285
+ // make sure the interpolated historical value doesn't get picked
286
+ // over the actual projected value
287
+ historicalTimeDiff <= projectionTimeDiff
288
+ )
289
+ return { value: historical.value, isProjection: false }
290
+
291
+ if (isNotErrorValueOrEmptyCell(projected.value)) {
292
+ return { value: projected.value, isProjection: true }
293
+ }
294
+
295
+ return undefined
296
+ }
297
+
298
+ // Combine the historical and projected values into a single column
299
+ table = table.combineColumns(
300
+ [projectedSlug, historicalSlug],
301
+ { ...table.get(projectedSlug).def, slug: combinedSlug },
302
+ (row, time) =>
303
+ transformFn(row, time)?.value ??
304
+ ErrorValueTypes.MissingValuePlaceholder
305
+ )
306
+
307
+ // Add a column indicating whether the value is a projection or not
308
+ if (options?.shouldAddIsProjectionColumn)
309
+ table = table.combineColumns(
310
+ [projectedSlug, historicalSlug],
311
+ {
312
+ slug: slugForIsProjectionColumn,
313
+ type: ColumnTypeNames.Boolean,
314
+ },
315
+ (row, time) =>
316
+ transformFn(row, time)?.isProjection ??
317
+ ErrorValueTypes.MissingValuePlaceholder
318
+ )
319
+
320
+ return table
321
+ }
322
+
323
+ export function NoDataPattern({
324
+ patternId = Patterns.noDataPattern,
325
+ scale = 1,
326
+ }: {
327
+ patternId?: string
328
+ scale?: number
329
+ }): React.ReactElement {
330
+ const patternTransforms = excludeUndefined([
331
+ `rotate(-45 2 2)`,
332
+ scale !== 1 ? `scale(${scale})` : undefined,
333
+ ])
334
+ return (
335
+ <pattern
336
+ id={patternId}
337
+ patternUnits="userSpaceOnUse"
338
+ width="4"
339
+ height="4"
340
+ patternTransform={patternTransforms.join(" ")}
341
+ >
342
+ <path d="M -1,2 l 6,0" stroke="#ccc" strokeWidth={0.7} />
343
+ </pattern>
344
+ )
345
+ }
346
+
347
+ export function getChartSvgProps({
348
+ fontSize,
349
+ backgroundColor,
350
+ }: {
351
+ fontSize?: number
352
+ backgroundColor?: string
353
+ }): React.SVGProps<SVGSVGElement> {
354
+ return {
355
+ xmlns: "http://www.w3.org/2000/svg",
356
+ version: "1.1",
357
+ style: {
358
+ ...SVG_STYLE_PROPS,
359
+ fontSize: fontSize ?? BASE_FONT_SIZE,
360
+ // Needs to be set here or else pngs will have a black background
361
+ backgroundColor: backgroundColor ?? GRAPHER_BACKGROUND_DEFAULT,
362
+ },
363
+ }
364
+ }
@@ -0,0 +1,45 @@
1
+ // todo: remove
2
+
3
+ import { GrapherState } from "../core/GrapherState"
4
+ import { computed, makeObservable } from "mobx"
5
+ import { ChartDimension } from "./ChartDimension"
6
+ import { DimensionProperty } from "../../utils/index.js"
7
+
8
+ export class DimensionSlot {
9
+ private grapherState: GrapherState
10
+ property: DimensionProperty
11
+ constructor(grapher: GrapherState, property: DimensionProperty) {
12
+ makeObservable(this)
13
+ this.grapherState = grapher
14
+ this.property = property
15
+ }
16
+
17
+ @computed get name(): string {
18
+ const names = {
19
+ y: this.grapherState.isDiscreteBar ? "X axis" : "Y axis",
20
+ x: "X axis",
21
+ size: "Size",
22
+ color: "Color",
23
+ filter: "Filter",
24
+ }
25
+
26
+ return (names as any)[this.property] || ""
27
+ }
28
+
29
+ @computed get allowMultiple(): boolean {
30
+ return (
31
+ this.property === DimensionProperty.y &&
32
+ this.grapherState.supportsMultipleYColumns
33
+ )
34
+ }
35
+
36
+ @computed get isOptional(): boolean {
37
+ return this.allowMultiple
38
+ }
39
+
40
+ @computed get dimensions(): ChartDimension[] {
41
+ return this.grapherState.dimensions.filter(
42
+ (d) => d.property === this.property
43
+ )
44
+ }
45
+ }
@@ -0,0 +1,94 @@
1
+ import React from "react"
2
+ import { computed, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import { Bounds } from "../../utils/index.js"
5
+ import { DEFAULT_GRAPHER_BOUNDS } from "../core/GrapherConstants.js"
6
+ import { CaptionedChartManager } from "../captionedChart/CaptionedChart.js"
7
+ import { GRAPHER_BACKGROUND_DEFAULT } from "../color/ColorConstants.js"
8
+ import { getChartSvgProps, NoDataPattern } from "./ChartUtils.js"
9
+
10
+ interface StaticChartWrapperProps {
11
+ manager: CaptionedChartManager
12
+ bounds?: Bounds
13
+ children: React.ReactNode
14
+ }
15
+
16
+ @observer
17
+ export class StaticChartWrapper extends React.Component<StaticChartWrapperProps> {
18
+ constructor(props: StaticChartWrapperProps) {
19
+ super(props)
20
+ makeObservable(this)
21
+ }
22
+
23
+ @computed private get manager(): CaptionedChartManager {
24
+ return this.props.manager
25
+ }
26
+
27
+ @computed protected get bounds(): Bounds {
28
+ return (
29
+ this.props.bounds ??
30
+ this.manager.staticBounds ??
31
+ DEFAULT_GRAPHER_BOUNDS
32
+ )
33
+ }
34
+
35
+ @computed private get fonts(): React.ReactElement {
36
+ let origin = ""
37
+ try {
38
+ if (this.manager.bakedGrapherURL)
39
+ origin = new URL(this.manager.bakedGrapherURL).origin
40
+ } catch {
41
+ // ignore
42
+ }
43
+ const css = `@import url(${origin}/fonts.css)`
44
+ return (
45
+ <defs>
46
+ <style>{css}</style>
47
+ </defs>
48
+ )
49
+ }
50
+
51
+ @computed private get backgroundColor(): string {
52
+ return this.manager.backgroundColor ?? GRAPHER_BACKGROUND_DEFAULT
53
+ }
54
+
55
+ @computed private get noDataPattern(): React.ReactElement {
56
+ return (
57
+ <defs>
58
+ <NoDataPattern />
59
+ </defs>
60
+ )
61
+ }
62
+
63
+ override render(): React.ReactElement {
64
+ const { manager } = this
65
+
66
+ const bounds = this.manager.staticBoundsWithDetails ?? this.bounds
67
+ const width = bounds.width
68
+ const height = bounds.height
69
+
70
+ const includeFontsStyle = !manager.isExportingForWikimedia
71
+ const includeBackgroundRect = !!manager.isExportingForWikimedia
72
+
73
+ return (
74
+ <svg
75
+ {...getChartSvgProps(this.manager)}
76
+ width={width}
77
+ height={height}
78
+ viewBox={`0 0 ${width} ${height}`}
79
+ >
80
+ {includeFontsStyle && this.fonts}
81
+ {this.noDataPattern}
82
+ {includeBackgroundRect && (
83
+ <rect
84
+ className="background-fill"
85
+ fill={this.backgroundColor}
86
+ width={width}
87
+ height={height}
88
+ />
89
+ )}
90
+ {this.props.children}
91
+ </svg>
92
+ )
93
+ }
94
+ }