@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,568 @@
1
+ import * as _ from "lodash-es"
2
+ /* eslint-disable no-sparse-arrays */
3
+ import {
4
+ CoreMatrix,
5
+ ColumnTypeNames,
6
+ CoreTableInputOption,
7
+ OwidColumnDef,
8
+ TableSlug,
9
+ SubNavId,
10
+ FacetAxisDomain,
11
+ GrapherInterface,
12
+ AxisMinMaxValueStr,
13
+ GrapherChartType,
14
+ } from "../types/index.js"
15
+ import {
16
+ CoreTable,
17
+ OwidTable,
18
+ isNotErrorValue,
19
+ } from "../core-table/index.js"
20
+ import {
21
+ GitCommit,
22
+ PromiseCache,
23
+ SerializedGridProgram,
24
+ trimObject,
25
+ fetchWithRetry,
26
+ } from "../utils/index.js"
27
+ import {
28
+ CellDef,
29
+ Grammar,
30
+ GridBoolean,
31
+ GRID_CELL_DELIMITER,
32
+ GRID_NODE_DELIMITER,
33
+ RootKeywordCellDef,
34
+ } from "./gridLang/GridLangConstants.js"
35
+ import { GridProgram } from "./gridLang/GridProgram.js"
36
+ import { ColumnGrammar } from "./ColumnGrammar.js"
37
+ import {
38
+ DefaultNewExplorerSlug,
39
+ ExplorerChartCreationMode,
40
+ ExplorerChoiceParams,
41
+ EXPLORERS_ROUTE_FOLDER,
42
+ } from "./ExplorerConstants.js"
43
+ import { DecisionMatrix } from "./ExplorerDecisionMatrix.js"
44
+ import { ExplorerGrammar } from "./ExplorerGrammar.js"
45
+ import { GrapherGrammar } from "./GrapherGrammar.js"
46
+ import { latestGrapherConfigSchema } from "../grapher/index.js"
47
+
48
+ export const EXPLORER_FILE_SUFFIX = ".explorer.tsv"
49
+
50
+ export interface TableDef {
51
+ url?: string
52
+ columnDefinitions?: OwidColumnDef[]
53
+ inlineData?: string[][]
54
+ slug?: TableSlug
55
+ }
56
+
57
+ export interface ExplorerGrapherInterface extends GrapherInterface {
58
+ grapherId?: number
59
+ tableSlug?: string
60
+ yVariableIds?: string
61
+ xVariableId?: string
62
+ colorVariableId?: string
63
+ sizeVariableId?: string
64
+ yScaleToggle?: boolean
65
+ yAxisMin?: number | AxisMinMaxValueStr.auto
66
+ facetYDomain?: FacetAxisDomain
67
+ relatedQuestionText?: string
68
+ relatedQuestionUrl?: string
69
+ mapTargetTime?: number
70
+ type?: GrapherChartType | "LineChart SlopeChart" | "None"
71
+ }
72
+
73
+ const ExplorerRootDef: CellDef = {
74
+ ...RootKeywordCellDef,
75
+ grammar: ExplorerGrammar,
76
+ }
77
+
78
+ export class ExplorerProgram extends GridProgram {
79
+ constructor(slug: string, tsv: string, lastCommit?: GitCommit) {
80
+ super(slug, tsv, lastCommit, ExplorerRootDef)
81
+ }
82
+
83
+ private _decisionMatrix?: DecisionMatrix
84
+ get decisionMatrix() {
85
+ if (!this._decisionMatrix) {
86
+ this._decisionMatrix = new DecisionMatrix(
87
+ this.decisionMatrixCode ?? "",
88
+ this.lastCommit?.hash
89
+ )
90
+ }
91
+ return this._decisionMatrix
92
+ }
93
+
94
+ static fromJson(json: SerializedGridProgram) {
95
+ return new ExplorerProgram(json.slug, json.program, json.lastCommit)
96
+ }
97
+
98
+ get clone() {
99
+ return ExplorerProgram.fromJson(this.toJson())
100
+ }
101
+
102
+ get isNewFile() {
103
+ return this.slug === DefaultNewExplorerSlug
104
+ }
105
+
106
+ get filename() {
107
+ return this.slug + EXPLORER_FILE_SUFFIX
108
+ }
109
+
110
+ initDecisionMatrix(choiceParams: ExplorerChoiceParams) {
111
+ this.decisionMatrix.setValuesFromChoiceParams(choiceParams)
112
+ return this
113
+ }
114
+
115
+ get fullPath() {
116
+ return makeFullPath(this.slug)
117
+ }
118
+
119
+ get currentlySelectedGrapherRow() {
120
+ const row = this.getKeywordIndex(ExplorerGrammar.graphers.keyword)
121
+ return row === -1
122
+ ? undefined
123
+ : row + this.decisionMatrix.selectedRowIndex + 2
124
+ }
125
+
126
+ static fromMatrix(slug: string, matrix: CoreMatrix) {
127
+ const str = matrix
128
+ .map((row) =>
129
+ row.map((cell) => cell && `${cell}`.replace(/\n/g, "\\n"))
130
+ )
131
+ .map((row) => row.join(GRID_CELL_DELIMITER))
132
+ .join(GRID_NODE_DELIMITER)
133
+ return new ExplorerProgram(slug, str)
134
+ }
135
+
136
+ get explorerTitle() {
137
+ return this.getLineValue(ExplorerGrammar.explorerTitle.keyword)
138
+ }
139
+
140
+ get title() {
141
+ return this.getLineValue(ExplorerGrammar.title.keyword)
142
+ }
143
+
144
+ get subNavId(): SubNavId | undefined {
145
+ return this.getLineValue(ExplorerGrammar.subNavId.keyword) as SubNavId
146
+ }
147
+
148
+ get googleSheet() {
149
+ return this.getLineValue(ExplorerGrammar.googleSheet.keyword)
150
+ }
151
+
152
+ get hideAlertBanner() {
153
+ return (
154
+ this.getLineValue(ExplorerGrammar.hideAlertBanner.keyword) ===
155
+ GridBoolean.true
156
+ )
157
+ }
158
+
159
+ get subNavCurrentId() {
160
+ return this.getLineValue(ExplorerGrammar.subNavCurrentId.keyword)
161
+ }
162
+
163
+ get thumbnail() {
164
+ return this.getLineValue(ExplorerGrammar.thumbnail.keyword)
165
+ }
166
+
167
+ get explorerSubtitle() {
168
+ return this.getLineValue(ExplorerGrammar.explorerSubtitle.keyword)
169
+ }
170
+
171
+ get entityType() {
172
+ return this.getLineValue(ExplorerGrammar.entityType.keyword)
173
+ }
174
+
175
+ get selection() {
176
+ return this.getLine(ExplorerGrammar.selection.keyword)?.slice(1)
177
+ }
178
+
179
+ get pickerColumnSlugs() {
180
+ const slugs = this.getLineValue(
181
+ ExplorerGrammar.pickerColumnSlugs.keyword
182
+ )
183
+ return slugs ? slugs.split(" ") : undefined
184
+ }
185
+
186
+ get hideControls() {
187
+ return this.getLineValue(ExplorerGrammar.hideControls.keyword)
188
+ }
189
+
190
+ get downloadDataLink() {
191
+ return this.getLineValue(ExplorerGrammar.downloadDataLink.keyword)
192
+ }
193
+
194
+ get isPublished() {
195
+ return (
196
+ this.getLineValue(ExplorerGrammar.isPublished.keyword) ===
197
+ GridBoolean.true
198
+ )
199
+ }
200
+
201
+ setPublished(value: boolean) {
202
+ return this.clone.setLineValue(
203
+ ExplorerGrammar.isPublished.keyword,
204
+ value ? GridBoolean.true : GridBoolean.false
205
+ )
206
+ }
207
+
208
+ get wpBlockId() {
209
+ const blockIdString = this.getLineValue(
210
+ ExplorerGrammar.wpBlockId.keyword
211
+ )
212
+ return blockIdString ? parseInt(blockIdString, 10) : undefined
213
+ }
214
+
215
+ get decisionMatrixCode() {
216
+ const keywordIndex = this.getKeywordIndex(
217
+ ExplorerGrammar.graphers.keyword
218
+ )
219
+ if (keywordIndex === -1) return undefined
220
+ return this.getBlock(keywordIndex)
221
+ ?.map((row) => row.join(this.cellDelimiter))
222
+ .join("\n")
223
+ }
224
+
225
+ get grapherCount() {
226
+ return this.decisionMatrix.numRows || 1
227
+ }
228
+
229
+ get tableCount() {
230
+ return this.getRowNumbersStartingWith(ExplorerGrammar.table.keyword)
231
+ .length
232
+ }
233
+
234
+ get tableSlugs(): (TableSlug | undefined)[] {
235
+ return this.lines
236
+ .filter((line) => line[0] === ExplorerGrammar.table.keyword)
237
+ .map((line) => line[2])
238
+ }
239
+
240
+ // for backward compatibility, we currently support explorers
241
+ // that use Grapher IDs as well as CSV data files to create charts,
242
+ // but we plan to drop support for mixed-content explorers in the future
243
+ getChartCreationModeForExplorerGrapherConfig(
244
+ explorerGrapherConfig: ExplorerGrapherInterface
245
+ ): ExplorerChartCreationMode {
246
+ const { decisionMatrix } = this
247
+ const { grapherId } = explorerGrapherConfig
248
+ const yVariableIdsColumn = decisionMatrix.table.get(
249
+ GrapherGrammar.yVariableIds.keyword
250
+ )
251
+ // referring to a variable in a single row triggers
252
+ // ExplorerChartCreationMode.FromVariableIds for all rows
253
+ if (yVariableIdsColumn.numValues)
254
+ return ExplorerChartCreationMode.FromVariableIds
255
+ if (grapherId && isNotErrorValue(grapherId))
256
+ return ExplorerChartCreationMode.FromGrapherId
257
+ return ExplorerChartCreationMode.FromExplorerTableColumnSlugs
258
+ }
259
+
260
+ get chartCreationMode(): ExplorerChartCreationMode {
261
+ return this.getChartCreationModeForExplorerGrapherConfig(
262
+ this.explorerGrapherConfig
263
+ )
264
+ }
265
+
266
+ get whyIsExplorerProgramInvalid(): string {
267
+ const {
268
+ chartCreationMode,
269
+ decisionMatrix: { table },
270
+ } = this
271
+ const { FromVariableIds, FromGrapherId, FromExplorerTableColumnSlugs } =
272
+ ExplorerChartCreationMode
273
+
274
+ const grapherIdColumn = table.get(GrapherGrammar.grapherId.keyword)
275
+ const tableSlugColumn = table.get(GrapherGrammar.tableSlug.keyword)
276
+ const hasGrapherId = grapherIdColumn.numValues > 0
277
+ const hasCsvData = tableSlugColumn.numValues > 0 || this.tableCount > 0
278
+
279
+ if (chartCreationMode === FromVariableIds && hasGrapherId)
280
+ return "Using variables IDs and Grapher IDs to create charts is not supported."
281
+
282
+ if (chartCreationMode === FromVariableIds && hasCsvData)
283
+ return "Using variable IDs and CSV data files to create charts is not supported."
284
+
285
+ if (
286
+ (chartCreationMode === FromGrapherId && hasCsvData) ||
287
+ (chartCreationMode === FromExplorerTableColumnSlugs && hasGrapherId)
288
+ )
289
+ return "Using Grapher IDs and CSV data files to create charts is deprecated."
290
+
291
+ return ""
292
+ }
293
+
294
+ get columnDefsByTableSlug(): Map<TableSlug | undefined, OwidColumnDef[]> {
295
+ const columnDefs = new Map<TableSlug | undefined, OwidColumnDef[]>()
296
+ const colDefsRows = this.getAllRowsMatchingWords(
297
+ ExplorerGrammar.columns.keyword
298
+ )
299
+
300
+ const matrix = this.lines
301
+ for (const row of colDefsRows) {
302
+ const tableSlugs = matrix[row].slice(1)
303
+ const columnDefinitions = parseColumnDefs(this.getBlock(row) ?? [])
304
+ if (tableSlugs.length === 0)
305
+ columnDefs.set(undefined, columnDefinitions)
306
+ else
307
+ tableSlugs.forEach((tableSlug) => {
308
+ columnDefs.set(tableSlug, columnDefinitions)
309
+ })
310
+ }
311
+ return columnDefs
312
+ }
313
+
314
+ get columnDefsWithoutTableSlug(): OwidColumnDef[] {
315
+ return this.columnDefsByTableSlug.get(undefined) ?? []
316
+ }
317
+
318
+ async autofillMissingColumnDefinitionsForTableCommand(tableSlug?: string) {
319
+ const clone = this.clone
320
+ const remoteTable = await clone.constructTable(tableSlug)
321
+ const existingTableDef = this.getTableDef(tableSlug)
322
+ const table =
323
+ remoteTable ||
324
+ (existingTableDef
325
+ ? new CoreTable(
326
+ existingTableDef.inlineData,
327
+ existingTableDef.columnDefinitions
328
+ )
329
+ : undefined)
330
+ const newCols = table.autodetectedColumnDefs
331
+ const missing = newCols
332
+ .appendColumns([
333
+ {
334
+ slug: ColumnGrammar.notes.keyword,
335
+ values: newCols.indices.map(() => `Unreviewed`),
336
+ },
337
+ ])
338
+ .select([
339
+ ColumnGrammar.slug.keyword,
340
+ ,
341
+ ColumnGrammar.name.keyword,
342
+ ,
343
+ ColumnGrammar.type.keyword,
344
+ ColumnGrammar.notes.keyword,
345
+ ] as string[])
346
+
347
+ const colDefsRow = this.getRowMatchingWords(
348
+ ExplorerGrammar.columns.keyword,
349
+ tableSlug
350
+ )
351
+
352
+ if (colDefsRow !== -1)
353
+ clone.updateBlock(
354
+ colDefsRow,
355
+ new CoreTable(clone.getBlock(colDefsRow))
356
+ .concat([missing])
357
+ .toMatrix()
358
+ )
359
+ else
360
+ clone.appendBlock(
361
+ `${ExplorerGrammar.columns.keyword}${
362
+ tableSlug ? this.cellDelimiter + tableSlug : ""
363
+ }`,
364
+ missing.toMatrix()
365
+ )
366
+ return clone
367
+ }
368
+
369
+ constructExplorerGrapherConfig(grapherRow: any): ExplorerGrapherInterface {
370
+ const rootObject = trimAndParseObject(this.tuplesObject, GrapherGrammar)
371
+ let config = { ...rootObject }
372
+
373
+ if (grapherRow && Object.keys(grapherRow).length) {
374
+ config = {
375
+ ...config,
376
+ ...trimAndParseObject(grapherRow, GrapherGrammar),
377
+ }
378
+ }
379
+
380
+ // remove all keys that are not part of the GrapherGrammar
381
+ Object.keys(config).forEach((key) => {
382
+ if (!GrapherGrammar[key]) delete config[key]
383
+ })
384
+
385
+ return config
386
+ }
387
+
388
+ constructGrapherConfig(
389
+ explorerGrapherConfig: ExplorerGrapherInterface
390
+ ): GrapherInterface {
391
+ const partialConfigs: GrapherInterface[] = []
392
+ const fields = Object.entries(explorerGrapherConfig)
393
+
394
+ for (const [field, value] of fields) {
395
+ const cellDef = GrapherGrammar[field]
396
+ partialConfigs.push(cellDef.toGrapherObject(value))
397
+ }
398
+
399
+ const mergedConfig = _.merge({}, ...partialConfigs)
400
+
401
+ // assume config is valid against the latest schema
402
+ mergedConfig.$schema = latestGrapherConfigSchema
403
+
404
+ // TODO: can be removed once relatedQuestions is refactored
405
+ const { relatedQuestionUrl, relatedQuestionText } =
406
+ explorerGrapherConfig
407
+ if (relatedQuestionUrl && relatedQuestionText) {
408
+ mergedConfig.relatedQuestions = [
409
+ { url: relatedQuestionUrl, text: relatedQuestionText },
410
+ ]
411
+ }
412
+
413
+ return mergedConfig
414
+ }
415
+
416
+ /**
417
+ * Grapher config for the currently selected row including global settings.
418
+ * Includes all columns that are part of the GrapherGrammar.
419
+ */
420
+ get explorerGrapherConfig(): ExplorerGrapherInterface {
421
+ const selectedGrapherRow = this.decisionMatrix.selectedRow
422
+ return this.constructExplorerGrapherConfig(selectedGrapherRow)
423
+ }
424
+
425
+ /**
426
+ * Grapher config for the currently selected row, with explorer-specific
427
+ * fields translated to valid GrapherInterface fields.
428
+ *
429
+ * For example, `yAxisMin` is translated to `{yAxis: {min: ... }}`
430
+ */
431
+ get grapherConfig(): GrapherInterface {
432
+ return this.constructGrapherConfig(this.explorerGrapherConfig)
433
+ }
434
+
435
+ /**
436
+ * A static method so that all explorers on the page share requests,
437
+ * and no duplicate requests are sent.
438
+ */
439
+ private static tableDataLoader = new PromiseCache(
440
+ async (url: string): Promise<CoreTableInputOption> => {
441
+ const response = await fetchWithRetry(url)
442
+ if (!response.ok) throw new Error(response.statusText)
443
+ const tableInput: CoreTableInputOption = url.endsWith(".json")
444
+ ? await response.json()
445
+ : await response.text()
446
+ return tableInput
447
+ }
448
+ )
449
+
450
+ async constructTable(tableSlug?: TableSlug): Promise<OwidTable> {
451
+ const tableDef = this.getTableDef(tableSlug)
452
+ if (!tableDef) {
453
+ throw new Error(`Table definitions not found for '${tableSlug}'`)
454
+ }
455
+
456
+ if (tableDef.inlineData) {
457
+ return new OwidTable(
458
+ tableDef.inlineData,
459
+ tableDef.columnDefinitions,
460
+ {
461
+ tableDescription: `Loaded '${tableSlug}' from inline data`,
462
+ tableSlug: tableSlug,
463
+ }
464
+ ).dropEmptyRows()
465
+ } else if (tableDef.url) {
466
+ const input = await ExplorerProgram.tableDataLoader.get(
467
+ tableDef.url
468
+ )
469
+ return new OwidTable(input, tableDef.columnDefinitions, {
470
+ tableDescription: `Loaded from ${tableDef.url}`,
471
+ })
472
+ }
473
+
474
+ throw new Error(`No data for table '${tableSlug}'`)
475
+ }
476
+
477
+ getTableDef(tableSlug?: TableSlug): TableDef | undefined {
478
+ const tableDefRow = this.getRowMatchingWords(
479
+ ExplorerGrammar.table.keyword,
480
+ undefined,
481
+ tableSlug
482
+ )
483
+ if (tableDefRow === -1) return undefined
484
+
485
+ const inlineData = this.getBlock(tableDefRow)
486
+ let url = inlineData ? undefined : this.lines[tableDefRow][1]
487
+
488
+ if (url && !url.includes("://")) {
489
+ const owidDatasetSlug = encodeURIComponent(url)
490
+ url = `https://raw.githubusercontent.com/owid/owid-datasets/master/datasets/${owidDatasetSlug}/${owidDatasetSlug}.csv`
491
+ }
492
+
493
+ const columnDefinitions: OwidColumnDef[] | undefined =
494
+ this.columnDefsByTableSlug.get(tableSlug)
495
+
496
+ return {
497
+ url,
498
+ columnDefinitions,
499
+ inlineData,
500
+ slug: tableSlug,
501
+ }
502
+ }
503
+ }
504
+
505
+ export const makeFullPath = (slug: string) =>
506
+ `${EXPLORERS_ROUTE_FOLDER}/${slug}${EXPLORER_FILE_SUFFIX}`
507
+
508
+ export const trimAndParseObject = (config: any, grammar: Grammar) => {
509
+ // Trim empty properties. Prevents things like clearing "type" which crashes Grapher. The call to grapher.reset will automatically clear things like title, subtitle, if not set.
510
+ const trimmedRow = trimObject(config, true) as any
511
+
512
+ // parse types
513
+ Object.keys(trimmedRow).forEach((key) => {
514
+ const def = grammar[key]
515
+ if (def && def.parse) trimmedRow[key] = def.parse(trimmedRow[key])
516
+ // If there no definition but it is a boolean, parse it (todo: always have a def)
517
+ else if (!def) {
518
+ const value = trimmedRow[key]
519
+ if (value === GridBoolean.true) trimmedRow[key] = true
520
+ else if (value === GridBoolean.false) trimmedRow[key] = false
521
+ }
522
+ })
523
+ return trimmedRow
524
+ }
525
+
526
+ const parseColumnDefs = (block: string[][]): OwidColumnDef[] => {
527
+ /**
528
+ * A column def line can have:
529
+ * - a column named `variableId`, which contains a variable id
530
+ * - a column named `slug`, which is the referenced column in its data file
531
+ *
532
+ * We want to filter out any rows that contain neither of those, and we also
533
+ * want to rename `variableId` to `owidVariableId`.
534
+ */
535
+ const columnsTable = new CoreTable(block)
536
+ .appendColumnsIfNew([
537
+ { slug: "slug", type: ColumnTypeNames.String, name: "slug" },
538
+ {
539
+ slug: "variableId",
540
+ type: ColumnTypeNames.Integer,
541
+ name: "variableId",
542
+ },
543
+ ])
544
+ .renameColumn("variableId", "owidVariableId")
545
+ // Filter out rows that neither have a slug nor an owidVariableId
546
+ .rowFilter(
547
+ (row) => !!(row.slug || typeof row.owidVariableId === "number"),
548
+ "Keep only column defs with a slug or variable id"
549
+ )
550
+ return columnsTable.rows.map((row) => {
551
+ // ignore slug if a variable id is given
552
+ const hasValidVariableId =
553
+ row.owidVariableId && isNotErrorValue(row.owidVariableId)
554
+ if (hasValidVariableId && row.slug) delete row.slug
555
+
556
+ for (const field in row) {
557
+ const cellDef = ColumnGrammar[field]
558
+ if (cellDef?.display) {
559
+ // move field into 'display' object
560
+ row.display = row.display || {}
561
+ row.display[field] = row[field]
562
+ delete row[field]
563
+ }
564
+ }
565
+
566
+ return trimAndParseObject(row, ColumnGrammar)
567
+ })
568
+ }
@@ -0,0 +1,59 @@
1
+ import * as _ from "lodash-es"
2
+ import { SelectionArray } from "../grapher/index.js"
3
+ import { Bounds, deserializeJSONFromHTML } from "../utils/index.js"
4
+ import {
5
+ EMBEDDED_EXPLORER_DELIMITER,
6
+ EMBEDDED_EXPLORER_GRAPHER_CONFIGS,
7
+ EMBEDDED_EXPLORER_PARTIAL_GRAPHER_CONFIGS,
8
+ EXPLORER_CONSTANTS_DELIMITER,
9
+ } from "./ExplorerConstants.js"
10
+ import { ExplorerProps } from "./Explorer.js"
11
+
12
+ export async function buildExplorerProps(
13
+ html: string,
14
+ queryStr: string,
15
+ selection: SelectionArray,
16
+ bounds?: Bounds
17
+ ) {
18
+ const explorerConstants = deserializeJSONFromHTML(
19
+ html,
20
+ EXPLORER_CONSTANTS_DELIMITER
21
+ )
22
+ let grapherConfigs = deserializeJSONFromHTML(
23
+ html,
24
+ EMBEDDED_EXPLORER_GRAPHER_CONFIGS
25
+ )
26
+ let partialGrapherConfigs = deserializeJSONFromHTML(
27
+ html,
28
+ EMBEDDED_EXPLORER_PARTIAL_GRAPHER_CONFIGS
29
+ )
30
+ if (_.isArray(grapherConfigs)) {
31
+ grapherConfigs = grapherConfigs.map((grapherConfig) => ({
32
+ ...grapherConfig,
33
+ adminBaseUrl: explorerConstants.adminBaseUrl,
34
+ bakedGrapherURL: explorerConstants.bakedGrapherUrl,
35
+ }))
36
+ }
37
+ if (_.isArray(partialGrapherConfigs)) {
38
+ partialGrapherConfigs = partialGrapherConfigs.map((grapherConfig) => ({
39
+ ...grapherConfig,
40
+ adminBaseUrl: explorerConstants.adminBaseUrl,
41
+ bakedGrapherURL: explorerConstants.bakedGrapherUrl,
42
+ }))
43
+ }
44
+ const props: ExplorerProps = {
45
+ ...deserializeJSONFromHTML(html, EMBEDDED_EXPLORER_DELIMITER),
46
+ isEmbeddedInAnOwidPage: true,
47
+ adminBaseUrl: explorerConstants.adminBaseUrl,
48
+ bakedBaseUrl: explorerConstants.bakedBaseUrl,
49
+ bakedGrapherUrl: explorerConstants.bakedGrapherUrl,
50
+ dataApiUrl: explorerConstants.dataApiUrl,
51
+ grapherConfigs,
52
+ partialGrapherConfigs,
53
+ queryStr,
54
+ selection: new SelectionArray(selection.selectedEntityNames),
55
+ bounds: bounds,
56
+ staticBounds: bounds,
57
+ }
58
+ return props
59
+ }