@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,23 @@
1
+ import { ColumnSlug } from "../../../utils/index.js"
2
+ import { GrapherAnalytics } from "../../core/GrapherAnalytics"
3
+ import { OwidTable } from "../../../core-table/index.js"
4
+ import { CoreColumnDef, EntityName, SortOrder } from "../../../types/index.js"
5
+ import { MapConfig } from "../../mapCharts/MapConfig"
6
+
7
+ export interface EntityPickerManager {
8
+ entityPickerMetric?: ColumnSlug
9
+ entityPickerSort?: SortOrder
10
+ setEntityPicker?: (options: {
11
+ metric: string | undefined
12
+ sort?: SortOrder
13
+ }) => void
14
+ requiredColumnSlugs?: ColumnSlug[] // If this param is provided, and an entity does not have a value for 1+, it will show as unavailable.
15
+ entityPickerColumnDefs?: CoreColumnDef[]
16
+ entityPickerTable?: OwidTable
17
+ entityPickerTableIsLoading?: boolean
18
+ grapherTable?: OwidTable
19
+ entityType?: string
20
+ analytics?: GrapherAnalytics
21
+ availableEntityNames?: EntityName[]
22
+ mapConfig?: MapConfig
23
+ }
@@ -0,0 +1,129 @@
1
+ .global-entity-control-container {
2
+ position: sticky;
3
+ top: 5px;
4
+ z-index: $zindex-global-entity-select;
5
+
6
+ @include xxlg-down {
7
+ margin-left: 128px; // space for ToC "Contents" button
8
+ }
9
+ }
10
+
11
+ .global-entity-control {
12
+ margin-top: 1rem;
13
+ padding: 0.65em;
14
+ border-radius: 8px;
15
+ background-color: #fff;
16
+ box-shadow:
17
+ 0 15px 40px rgba(0, 0, 0, 0.1),
18
+ 0 8px 15px rgba(0, 0, 0, 0.08),
19
+ 0 1px 3px 1px rgba(0, 0, 0, 0.08);
20
+
21
+ display: flex;
22
+ align-items: center;
23
+
24
+ &.is-narrow {
25
+ // must be 1rem to avoid auto-zoom
26
+ font-size: 1rem;
27
+ padding: 0.5em;
28
+ }
29
+
30
+ .select-dropdown-container {
31
+ width: 15%;
32
+ min-width: 16em;
33
+ max-width: 19em;
34
+ margin-right: 0.75em;
35
+ }
36
+
37
+ .selected-items-container {
38
+ flex: 1;
39
+ overflow-y: auto;
40
+ overflow-x: visible;
41
+ }
42
+
43
+ .selected-items {
44
+ display: flex;
45
+ align-content: center;
46
+ }
47
+
48
+ .selected-item {
49
+ display: flex;
50
+ align-items: stretch;
51
+ border-radius: 100px;
52
+ padding: 0;
53
+ margin-right: 0.375em;
54
+ user-select: none;
55
+ white-space: nowrap;
56
+ // enough to avoid clipping box-shadow
57
+ margin-left: 2px;
58
+ margin-top: 2px;
59
+ margin-bottom: 2px;
60
+
61
+ background-color: #3360a9;
62
+ color: #fff;
63
+
64
+ .label {
65
+ font-weight: 700;
66
+ padding: 0.2em 0.8em;
67
+ }
68
+
69
+ &.removable .label {
70
+ padding-right: 0.3em;
71
+ }
72
+
73
+ .remove-icon {
74
+ flex: 0;
75
+ font-size: 15px;
76
+ display: flex;
77
+ align-items: center;
78
+ padding-right: 0.85em;
79
+ padding-left: 0.3em;
80
+ cursor: pointer;
81
+ opacity: 0.5;
82
+
83
+ &:hover {
84
+ opacity: 1;
85
+ }
86
+ }
87
+ }
88
+
89
+ .empty {
90
+ text-align: center;
91
+ color: $blue-40;
92
+ }
93
+
94
+ .narrow-summary {
95
+ flex: 1;
96
+ min-width: 0;
97
+ }
98
+
99
+ .narrow-summary-selected-items {
100
+ overflow: hidden;
101
+ white-space: nowrap;
102
+ text-overflow: ellipsis;
103
+ color: rgba(0, 0, 0, 0.5);
104
+ padding-left: 0.25em;
105
+ }
106
+
107
+ .narrow-summary-selected-item {
108
+ font-weight: 700;
109
+ color: #3360a9;
110
+ }
111
+
112
+ .narrow-actions {
113
+ flex: 0;
114
+ display: flex;
115
+ align-items: center;
116
+ margin-left: 0.5em;
117
+ min-height: 2.25em; // roughly enough space for <select> not to cause a height change
118
+ }
119
+
120
+ .button {
121
+ border-radius: 100px;
122
+ background-color: #3360a9;
123
+ color: white;
124
+ font-weight: 700;
125
+ padding: 0.5em 0.8em;
126
+ border: none;
127
+ white-space: nowrap;
128
+ }
129
+ }
@@ -0,0 +1,463 @@
1
+ import * as _ from "lodash-es"
2
+ import * as React from "react"
3
+ import ReactDOM from "react-dom/client"
4
+ import {
5
+ action,
6
+ observable,
7
+ IReactionDisposer,
8
+ reaction,
9
+ computed,
10
+ makeObservable,
11
+ } from "mobx"
12
+ import { observer } from "mobx-react"
13
+ import Select, {
14
+ components,
15
+ CSSObjectWithLabel,
16
+ GroupBase,
17
+ OptionProps,
18
+ Props,
19
+ } from "react-select"
20
+ import classnames from "classnames"
21
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
22
+ import { faTimes } from "@fortawesome/free-solid-svg-icons"
23
+ import {
24
+ countries,
25
+ getUserCountryInformation,
26
+ getWindowUrl,
27
+ setWindowUrl,
28
+ lazy,
29
+ RegionType,
30
+ } from "../../../utils/index.js"
31
+ import { GrapherAnalytics } from "../../core/GrapherAnalytics"
32
+ import { WORLD_ENTITY_NAME } from "../../core/GrapherConstants"
33
+ import { GLOBAL_ENTITY_SELECTOR_ELEMENT } from "./GlobalEntitySelectorConstants"
34
+ import { SelectionArray } from "../../selection/SelectionArray"
35
+ import { EntityName } from "../../../types/index.js"
36
+ import { setSelectedEntityNamesParam } from "../../core/EntityUrlBuilder"
37
+
38
+ enum GlobalEntitySelectionModes {
39
+ none = "none",
40
+ // Possibly might need the `add` state in the future to
41
+ // add country from geolocation without clearing others.
42
+ // One thing to figure out is what its behaviour should
43
+ // be for single-entity charts.
44
+
45
+ // add = "add",
46
+ override = "override",
47
+ }
48
+
49
+ interface DropdownEntity {
50
+ label: string
51
+ value: string
52
+ }
53
+
54
+ const getAllEntitiesSortedWithWorld = lazy(() =>
55
+ _.sortBy(countries, (c) => c.name)
56
+ // Add 'World'
57
+ .concat([
58
+ {
59
+ name: WORLD_ENTITY_NAME,
60
+ code: "OWID_WRL",
61
+ slug: "world",
62
+ regionType: RegionType.Other,
63
+ },
64
+ ])
65
+ )
66
+
67
+ const Option = (
68
+ props: OptionProps<DropdownEntity, true, any>
69
+ ): React.ReactElement => {
70
+ return (
71
+ <div>
72
+ <components.Option {...props}>
73
+ <input type="checkbox" checked={props.isSelected} readOnly />{" "}
74
+ <label>{props.label}</label>
75
+ </components.Option>
76
+ </div>
77
+ )
78
+ }
79
+
80
+ const SelectOptions: Props<DropdownEntity, true, any> = {
81
+ components: {
82
+ IndicatorSeparator: null,
83
+ Option,
84
+ },
85
+ menuPlacement: "bottom",
86
+ isClearable: false,
87
+ isMulti: true,
88
+ backspaceRemovesValue: false,
89
+ blurInputOnSelect: false,
90
+ closeMenuOnSelect: false,
91
+ controlShouldRenderValue: false,
92
+ hideSelectedOptions: false,
93
+ placeholder: "Add a country to all charts...",
94
+ styles: {
95
+ placeholder: (base: CSSObjectWithLabel): CSSObjectWithLabel => ({
96
+ ...base,
97
+ whiteSpace: "nowrap",
98
+ }),
99
+ valueContainer: (base: CSSObjectWithLabel): CSSObjectWithLabel => ({
100
+ ...base,
101
+ paddingTop: 0,
102
+ paddingBottom: 0,
103
+ }),
104
+ control: (base: CSSObjectWithLabel): CSSObjectWithLabel => ({
105
+ ...base,
106
+ minHeight: "initial",
107
+ }),
108
+ dropdownIndicator: (base: CSSObjectWithLabel): CSSObjectWithLabel => ({
109
+ ...base,
110
+ padding: "0 5px",
111
+ }),
112
+ },
113
+ }
114
+
115
+ function SelectedItems(props: {
116
+ selectedEntityNames: EntityName[]
117
+ emptyLabel: string
118
+ canRemove?: boolean
119
+ onRemove?: (item: EntityName) => void
120
+ }): React.ReactElement {
121
+ const canRemove = (props.canRemove ?? true) && props.onRemove !== undefined
122
+ const onRemove = props.onRemove || _.noop
123
+ const isEmpty = props.selectedEntityNames.length === 0
124
+ return (
125
+ <div className="selected-items-container">
126
+ {isEmpty ? (
127
+ <div className="empty">{props.emptyLabel}</div>
128
+ ) : (
129
+ <div className="selected-items">
130
+ {props.selectedEntityNames.map((entityName) => (
131
+ <div
132
+ key={entityName}
133
+ className={classnames("selected-item", {
134
+ removable: canRemove,
135
+ })}
136
+ >
137
+ <div className="label">{entityName}</div>
138
+ {canRemove && (
139
+ <div
140
+ className="remove-icon"
141
+ onClick={(): void => onRemove(entityName)}
142
+ >
143
+ <FontAwesomeIcon icon={faTimes} />
144
+ </div>
145
+ )}
146
+ </div>
147
+ ))}
148
+ </div>
149
+ )}
150
+ </div>
151
+ )
152
+ }
153
+
154
+ interface GlobalEntitySelectorProps {
155
+ selection: SelectionArray
156
+ graphersAndExplorersToUpdate?: Set<SelectionArray>
157
+ environment?: string
158
+ }
159
+
160
+ @observer
161
+ export class GlobalEntitySelector extends React.Component<GlobalEntitySelectorProps> {
162
+ refContainer = React.createRef<HTMLDivElement>()
163
+ disposers: IReactionDisposer[] = []
164
+
165
+ mode = GlobalEntitySelectionModes.none
166
+
167
+ private isNarrow = true
168
+ private isOpen = false
169
+ private localEntityName: EntityName | undefined
170
+
171
+ selection = this.props.selection
172
+
173
+ private optionGroups: GroupBase<DropdownEntity>[] = []
174
+
175
+ constructor(props: GlobalEntitySelectorProps) {
176
+ super(props)
177
+
178
+ makeObservable<
179
+ GlobalEntitySelector,
180
+ | "isNarrow"
181
+ | "isOpen"
182
+ | "localEntityName"
183
+ | "optionGroups"
184
+ | "onResizeThrottled"
185
+ >(this, {
186
+ mode: observable,
187
+ isNarrow: observable,
188
+ isOpen: observable,
189
+ localEntityName: observable,
190
+ optionGroups: observable.ref,
191
+ onResizeThrottled: action.bound,
192
+ })
193
+ }
194
+
195
+ override componentDidMount(): void {
196
+ this.onResize()
197
+ window.addEventListener("resize", this.onResizeThrottled)
198
+ this.disposers.push(
199
+ reaction(
200
+ () => this.isOpen,
201
+ () => this.prepareOptionGroups()
202
+ )
203
+ )
204
+ void this.populateLocalEntity()
205
+ }
206
+
207
+ override componentWillUnmount(): void {
208
+ window.removeEventListener("resize", this.onResizeThrottled)
209
+ this.disposers.forEach((dispose): void => dispose())
210
+ }
211
+
212
+ private onResizeThrottled = _.throttle(this.onResize, 200)
213
+ @action.bound private onResize(): void {
214
+ const container = this.refContainer.current
215
+ if (container) this.isNarrow = container.offsetWidth <= 640
216
+ }
217
+
218
+ @action.bound async populateLocalEntity(): Promise<void> {
219
+ try {
220
+ const localCountryCode = await getUserCountryInformation()
221
+ if (!localCountryCode) return
222
+
223
+ const country = getAllEntitiesSortedWithWorld().find(
224
+ (entity): boolean => entity.code === localCountryCode.code
225
+ )
226
+ if (country) this.localEntityName = country.name
227
+ } catch {
228
+ // ignore
229
+ }
230
+ }
231
+
232
+ @action.bound private prepareOptionGroups(): GroupBase<DropdownEntity>[] {
233
+ let optionGroups: GroupBase<DropdownEntity>[] = []
234
+ // We want to include the local country, but not if it's already selected, it adds
235
+ // unnecessary duplication.
236
+ if (
237
+ this.localEntityName &&
238
+ !this.selection.selectedSet.has(this.localEntityName)
239
+ ) {
240
+ optionGroups = optionGroups.concat([
241
+ {
242
+ label: "Suggestions",
243
+ options: [entityNameToOption(this.localEntityName)],
244
+ },
245
+ ])
246
+ }
247
+ if (this.selection.hasSelection) {
248
+ optionGroups = optionGroups.concat([
249
+ {
250
+ label: "Selected",
251
+ options:
252
+ this.selection.selectedEntityNames.map(
253
+ entityNameToOption
254
+ ),
255
+ },
256
+ ])
257
+ }
258
+ optionGroups = optionGroups.concat([
259
+ {
260
+ label: "All countries",
261
+ options: getAllEntitiesSortedWithWorld()
262
+ .map((entity) => entity.name)
263
+ .map(entityNameToOption),
264
+ },
265
+ ])
266
+ this.optionGroups = optionGroups
267
+ return optionGroups
268
+ }
269
+
270
+ private analytics = new GrapherAnalytics(
271
+ this.props.environment ?? "development"
272
+ )
273
+
274
+ @action.bound private updateURL(): void {
275
+ setWindowUrl(
276
+ setSelectedEntityNamesParam(
277
+ getWindowUrl(),
278
+ this.selection.selectedEntityNames
279
+ )
280
+ )
281
+ }
282
+
283
+ @action.bound updateSelection(newSelectedEntities: string[]): void {
284
+ this.selection.setSelectedEntities(newSelectedEntities)
285
+ this.updateAllGraphersAndExplorersOnPage()
286
+ this.updateURL()
287
+ }
288
+
289
+ @action.bound private onChange(options: readonly DropdownEntity[]): void {
290
+ this.updateSelection(
291
+ options.map((option: DropdownEntity) => option.label)
292
+ )
293
+
294
+ this.analytics.logGlobalEntitySelector(
295
+ "change",
296
+ this.selection.selectedEntityNames.join(",")
297
+ )
298
+ }
299
+
300
+ @action.bound private updateAllGraphersAndExplorersOnPage(): void {
301
+ if (!this.props.graphersAndExplorersToUpdate) return
302
+ Array.from(this.props.graphersAndExplorersToUpdate.values()).forEach(
303
+ (value) => {
304
+ value.setSelectedEntities(this.selection.selectedEntityNames)
305
+ }
306
+ )
307
+ }
308
+
309
+ @action.bound private onRemove(option: EntityName): void {
310
+ this.selection.toggleSelection(option)
311
+ this.updateAllGraphersAndExplorersOnPage()
312
+ this.updateURL()
313
+ }
314
+
315
+ @action.bound private onMenuOpen(): void {
316
+ this.isOpen = true
317
+ }
318
+
319
+ @action.bound private onMenuClose(): void {
320
+ this.isOpen = false
321
+ }
322
+
323
+ @action.bound private onButtonOpen(
324
+ event: React.MouseEvent<HTMLButtonElement>
325
+ ): void {
326
+ this.analytics.logGlobalEntitySelector(
327
+ "open",
328
+ event.currentTarget.innerText
329
+ )
330
+ this.onMenuOpen()
331
+ }
332
+
333
+ @action.bound private onButtonClose(
334
+ event: React.MouseEvent<HTMLButtonElement>
335
+ ): void {
336
+ this.analytics.logGlobalEntitySelector(
337
+ "close",
338
+ event.currentTarget.innerText
339
+ )
340
+ this.onMenuClose()
341
+ }
342
+
343
+ @computed private get selectedOptions(): DropdownEntity[] {
344
+ return this.selection.selectedEntityNames.map(entityNameToOption)
345
+ }
346
+
347
+ private renderNarrow(): React.ReactElement {
348
+ return (
349
+ <>
350
+ <div
351
+ className={classnames("narrow-summary", {
352
+ "narrow-summary-selected-items": !this.isOpen,
353
+ })}
354
+ >
355
+ {this.isOpen ? (
356
+ <Select
357
+ {...SelectOptions}
358
+ options={this.optionGroups}
359
+ value={this.selectedOptions}
360
+ onChange={this.onChange}
361
+ menuIsOpen={this.isOpen}
362
+ autoFocus={true}
363
+ />
364
+ ) : (
365
+ <div>
366
+ {!this.selection.hasSelection
367
+ ? "None selected"
368
+ : this.selection.selectedEntityNames
369
+ .map((entityName) => (
370
+ <span
371
+ className="narrow-summary-selected-item"
372
+ key={entityName}
373
+ >
374
+ {entityName}
375
+ </span>
376
+ ))
377
+ .reduce(
378
+ (acc, item) =>
379
+ acc.length === 0
380
+ ? [item]
381
+ : [...acc, ", ", item],
382
+ [] as (React.ReactElement | string)[]
383
+ )}
384
+ </div>
385
+ )}
386
+ </div>
387
+ <div className="narrow-actions">
388
+ {this.isOpen ? (
389
+ <button className="button" onClick={this.onButtonClose}>
390
+ Done
391
+ </button>
392
+ ) : (
393
+ <button className="button" onClick={this.onButtonOpen}>
394
+ {!this.selection.hasSelection
395
+ ? "Select countries"
396
+ : "Edit"}
397
+ </button>
398
+ )}
399
+ </div>
400
+ </>
401
+ )
402
+ }
403
+
404
+ private renderWide(): React.ReactElement {
405
+ return (
406
+ <>
407
+ <div className="select-dropdown-container">
408
+ <Select
409
+ {...SelectOptions}
410
+ options={this.optionGroups}
411
+ onChange={this.onChange}
412
+ value={this.selectedOptions}
413
+ onMenuOpen={this.onMenuOpen}
414
+ onMenuClose={this.onMenuClose}
415
+ />
416
+ </div>
417
+ <SelectedItems
418
+ selectedEntityNames={this.selection.selectedEntityNames}
419
+ onRemove={this.onRemove}
420
+ emptyLabel="Select countries to show on all charts"
421
+ />
422
+ </>
423
+ )
424
+ }
425
+
426
+ override render(): React.ReactElement {
427
+ return (
428
+ <div
429
+ className={classnames("global-entity-control", {
430
+ "is-narrow": this.isNarrow,
431
+ "is-wide": !this.isNarrow,
432
+ })}
433
+ ref={this.refContainer}
434
+ onClick={
435
+ this.isNarrow && !this.isOpen ? this.onMenuOpen : undefined
436
+ }
437
+ >
438
+ {this.isNarrow ? this.renderNarrow() : this.renderWide()}
439
+ </div>
440
+ )
441
+ }
442
+ }
443
+
444
+ export const hydrateGlobalEntitySelectorIfAny = (
445
+ selection: SelectionArray,
446
+ graphersAndExplorersToUpdate: Set<SelectionArray>
447
+ ): void => {
448
+ const element = document.querySelector(GLOBAL_ENTITY_SELECTOR_ELEMENT)
449
+ if (!element) return
450
+
451
+ ReactDOM.hydrateRoot(
452
+ element,
453
+ <GlobalEntitySelector
454
+ selection={selection}
455
+ graphersAndExplorersToUpdate={graphersAndExplorersToUpdate}
456
+ />
457
+ )
458
+ }
459
+
460
+ const entityNameToOption = (label: EntityName): DropdownEntity => ({
461
+ label,
462
+ value: label,
463
+ })
@@ -0,0 +1,3 @@
1
+ export const GLOBAL_ENTITY_SELECTOR_DATA_ATTR = "data-global-entity-control"
2
+ export const GLOBAL_ENTITY_SELECTOR_ELEMENT = `*[${GLOBAL_ENTITY_SELECTOR_DATA_ATTR}]`
3
+ export const GLOBAL_ENTITY_SELECTOR_DEFAULT_COUNTRY = "data-default-country" // Authors can set this attr in their blog posts
@@ -0,0 +1,17 @@
1
+ # Global Entity Control
2
+
3
+ This component allows users to change the Entity Selection across all the Graphers on a single HTML page.
4
+
5
+ ## Context
6
+
7
+ We have a number of Wordpress blog posts that embeds multiple Graphers. If a user wants to see a seleciton like "Canada and France" across all the Graphers on that post, they can use the Global Entity Control to do it, if the author has put one on that page.
8
+
9
+ ## Testing
10
+
11
+ Visit the test page at http://localhost:3030/multiEmbedderTest
12
+
13
+ ## How to use
14
+
15
+ 1. Put multiple Graphers in one HTML page.
16
+ 2. Put a `<div data-global-entity-control />` tag in the page.
17
+ 3. Now when the page loads, our hydrate function will hydrate the component.
@@ -0,0 +1,64 @@
1
+ import * as React from "react"
2
+ import { computed, action, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import {
5
+ GRAPHER_CHART_TYPES,
6
+ GrapherChartType,
7
+ StackMode,
8
+ } from "../../../types/index.js"
9
+ import { LabeledSwitch } from "../../../components/index.js"
10
+
11
+ const { LineChart, ScatterPlot, SlopeChart } = GRAPHER_CHART_TYPES
12
+
13
+ export interface AbsRelToggleManager {
14
+ stackMode?: StackMode
15
+ relativeToggleLabel?: string
16
+ activeChartType?: GrapherChartType
17
+ }
18
+
19
+ @observer
20
+ export class AbsRelToggle extends React.Component<{
21
+ manager: AbsRelToggleManager
22
+ }> {
23
+ constructor(props: { manager: AbsRelToggleManager }) {
24
+ super(props)
25
+ makeObservable(this)
26
+ }
27
+
28
+ @action.bound onToggle(): void {
29
+ this.manager.stackMode = this.isRelativeMode
30
+ ? StackMode.absolute
31
+ : StackMode.relative
32
+ }
33
+
34
+ @computed get isRelativeMode(): boolean {
35
+ return this.manager.stackMode === StackMode.relative
36
+ }
37
+
38
+ @computed get manager(): AbsRelToggleManager {
39
+ return this.props.manager
40
+ }
41
+
42
+ @computed get tooltip(): string {
43
+ const { activeChartType } = this.manager
44
+ return activeChartType === ScatterPlot
45
+ ? "Show the percentage change per year over the the selected time range."
46
+ : activeChartType === LineChart || activeChartType === SlopeChart
47
+ ? "Show proportional changes over time or actual values in their original units."
48
+ : "Show values as their share of the total or as actual values in their original units."
49
+ }
50
+
51
+ override render(): React.ReactElement {
52
+ const label =
53
+ this.manager.relativeToggleLabel ?? "Display relative values"
54
+ return (
55
+ <LabeledSwitch
56
+ label={label}
57
+ value={this.isRelativeMode}
58
+ tooltip={this.tooltip}
59
+ onToggle={this.onToggle}
60
+ tracking="chart_abs_rel_toggle"
61
+ />
62
+ )
63
+ }
64
+ }