@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,104 @@
1
+ import * as React from "react"
2
+ import { computed, action, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import { MapConfig } from "../mapCharts/MapConfig"
5
+ import { MapRegionName } from "../../types/index.js"
6
+ import { Dropdown } from "./Dropdown"
7
+ import { MAP_REGION_LABELS } from "../mapCharts/MapChartConstants"
8
+ import { GlobeController } from "../mapCharts/GlobeController"
9
+
10
+ export interface MapRegionDropdownManager {
11
+ mapConfig?: MapConfig
12
+ globeController?: GlobeController
13
+ isOnMapTab?: boolean
14
+ isFaceted?: boolean
15
+ }
16
+
17
+ interface MapRegionDropdownOption {
18
+ value: MapRegionName
19
+ label: string
20
+ trackNote: "map_zoom_to_region"
21
+ }
22
+
23
+ @observer
24
+ export class MapRegionDropdown extends React.Component<{
25
+ manager: MapRegionDropdownManager
26
+ }> {
27
+ constructor(props: { manager: MapRegionDropdownManager }) {
28
+ super(props)
29
+ makeObservable(this)
30
+ }
31
+
32
+ static shouldShow(manager: MapRegionDropdownManager): boolean {
33
+ const menu = new MapRegionDropdown({ manager })
34
+ return menu.showMenu
35
+ }
36
+
37
+ @computed private get manager(): MapRegionDropdownManager {
38
+ return this.props.manager
39
+ }
40
+
41
+ @computed private get mapConfig(): MapConfig {
42
+ return this.manager.mapConfig ?? new MapConfig()
43
+ }
44
+
45
+ @computed private get showMenu(): boolean {
46
+ const { isOnMapTab, isFaceted, mapConfig } = this.manager
47
+
48
+ return !!(
49
+ isOnMapTab &&
50
+ // Hide the dropdown when the globe is active
51
+ !mapConfig?.globe.isActive &&
52
+ // Hide the dropdown when the map is not faceted unless a 2d continent is active
53
+ !(this.mapConfig.region === MapRegionName.World && !isFaceted)
54
+ )
55
+ }
56
+
57
+ @action.bound onChange(selected: MapRegionDropdownOption | null): void {
58
+ const value = selected?.value
59
+ if (!value) return
60
+
61
+ // Update the current region
62
+ this.mapConfig.region = value
63
+
64
+ // It's confusing to have regions selected when switching to a continent
65
+ if (this.mapConfig.region !== MapRegionName.World) {
66
+ this.mapConfig.selection.deselectEntities(
67
+ this.mapConfig.selection.selectedRegionNames
68
+ )
69
+ }
70
+ }
71
+
72
+ @computed get options(): MapRegionDropdownOption[] {
73
+ const continentOptions: MapRegionDropdownOption[] = Object.values(
74
+ MapRegionName
75
+ ).map((region) => {
76
+ return {
77
+ value: region,
78
+ label: MAP_REGION_LABELS[region as MapRegionName],
79
+ trackNote: "map_zoom_to_region",
80
+ }
81
+ })
82
+
83
+ return continentOptions
84
+ }
85
+
86
+ @computed get value(): MapRegionDropdownOption | null {
87
+ const { region } = this.mapConfig
88
+ return this.options.find((opt) => opt.value === region) ?? null
89
+ }
90
+
91
+ override render(): React.ReactElement | null {
92
+ if (!this.showMenu) return null
93
+
94
+ return (
95
+ <Dropdown
96
+ className="map-region-dropdown"
97
+ options={this.options}
98
+ onChange={this.onChange}
99
+ value={this.value}
100
+ aria-label="Select continent"
101
+ />
102
+ )
103
+ }
104
+ }
@@ -0,0 +1,115 @@
1
+ import * as React from "react"
2
+ import { computed, action, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import { MapConfig } from "../mapCharts/MapConfig"
5
+ import {
6
+ GrapherWindowType,
7
+ MapRegionName,
8
+ TimeBound,
9
+ } from "../../utils/index.js"
10
+ import { GlobeController } from "../mapCharts/GlobeController"
11
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
12
+ import { faRotateLeft } from "@fortawesome/free-solid-svg-icons"
13
+ import { match } from "ts-pattern"
14
+
15
+ interface MapResetButtonProps {
16
+ manager: MapResetButtonManager
17
+ action: "resetView" | "resetZoom"
18
+ }
19
+
20
+ export interface MapResetButtonManager {
21
+ mapConfig?: MapConfig
22
+ isOnMapTab?: boolean
23
+ globeController?: GlobeController
24
+ isFaceted?: boolean
25
+ shouldShowEntitySelectorAs?: GrapherWindowType
26
+ startHandleTimeBound?: TimeBound
27
+ endHandleTimeBound?: TimeBound
28
+ }
29
+
30
+ @observer
31
+ export class MapResetButton extends React.Component<{
32
+ manager: MapResetButtonManager
33
+ action: "resetView" | "resetZoom"
34
+ }> {
35
+ constructor(props: MapResetButtonProps) {
36
+ super(props)
37
+ makeObservable(this)
38
+ }
39
+
40
+ static shouldShow(
41
+ manager: MapResetButtonManager,
42
+ action: "resetView" | "resetZoom"
43
+ ): boolean {
44
+ const menu = new MapResetButton({ manager, action })
45
+ return menu.showMenu
46
+ }
47
+
48
+ @computed private get showMenu(): boolean {
49
+ const { mapConfig } = this
50
+ const { isOnMapTab, isFaceted, shouldShowEntitySelectorAs } =
51
+ this.props.manager
52
+
53
+ if (!isOnMapTab) return false
54
+
55
+ const shouldShowPanel =
56
+ shouldShowEntitySelectorAs === GrapherWindowType.panel
57
+
58
+ const shouldShowResetViewButton =
59
+ shouldShowPanel && (isFaceted || mapConfig.is2dContinentActive())
60
+
61
+ const shouldShowResetZoomButton =
62
+ mapConfig.globe.isActive && !shouldShowResetViewButton
63
+
64
+ return match(this.props.action)
65
+ .with("resetView", () => shouldShowResetViewButton)
66
+ .with("resetZoom", () => shouldShowResetZoomButton)
67
+ .exhaustive()
68
+ }
69
+
70
+ @computed private get manager(): MapResetButtonManager {
71
+ return this.props.manager
72
+ }
73
+
74
+ @computed private get mapConfig(): MapConfig {
75
+ return this.manager.mapConfig ?? new MapConfig()
76
+ }
77
+
78
+ @computed private get label(): string {
79
+ return match(this.props.action)
80
+ .with("resetView", () => "Reset view")
81
+ .with("resetZoom", () => "Reset zoom")
82
+ .exhaustive()
83
+ }
84
+
85
+ @computed private get trackNote(): string {
86
+ return match(this.props.action)
87
+ .with("resetView", () => "map_reset_view")
88
+ .with("resetZoom", () => "map_reset_zoom")
89
+ .exhaustive()
90
+ }
91
+
92
+ @action.bound private onClick(): void {
93
+ this.mapConfig.region = MapRegionName.World
94
+ this.manager.globeController?.hideGlobe()
95
+ this.manager.globeController?.resetGlobe()
96
+
97
+ if (this.props.action === "resetView") {
98
+ this.manager.startHandleTimeBound = this.manager.endHandleTimeBound
99
+ }
100
+ }
101
+
102
+ override render(): React.ReactElement | null {
103
+ return this.showMenu ? (
104
+ <button
105
+ type="button"
106
+ data-track-note={this.trackNote}
107
+ onClick={this.onClick}
108
+ className="menu-toggle"
109
+ >
110
+ <FontAwesomeIcon icon={faRotateLeft} />
111
+ {this.label}
112
+ </button>
113
+ ) : null
114
+ }
115
+ }
@@ -0,0 +1,9 @@
1
+ .map-zoom-dropdown {
2
+ flex: 0 1 202px;
3
+ }
4
+
5
+ .map-zoom-dropdown-local-icon {
6
+ margin-left: 6px;
7
+ font-size: 0.9em;
8
+ color: #a1a1a1;
9
+ }
@@ -0,0 +1,270 @@
1
+ import * as _ from "lodash-es"
2
+ import * as React from "react"
3
+ import { computed, action, observable, makeObservable } from "mobx"
4
+ import { observer } from "mobx-react"
5
+ import { MapConfig } from "../mapCharts/MapConfig"
6
+ import {
7
+ EntityName,
8
+ FuzzySearch,
9
+ getRegionAlternativeNames,
10
+ getUserNavigatorLanguagesNonEnglish,
11
+ GlobeRegionName,
12
+ mappableCountries,
13
+ MapRegionName,
14
+ checkIsOwidIncomeGroupName,
15
+ getUserCountryInformation,
16
+ regions,
17
+ } from "../../utils/index.js"
18
+ import { GlobeController } from "../mapCharts/GlobeController"
19
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
20
+ import { faLocationArrow } from "@fortawesome/free-solid-svg-icons"
21
+ import {
22
+ Dropdown,
23
+ DropdownCollection,
24
+ DropdownCollectionItem,
25
+ DropdownOptionGroup,
26
+ } from "./Dropdown.js"
27
+ import { MAP_REGION_LABELS } from "../mapCharts/MapChartConstants"
28
+ import { match } from "ts-pattern"
29
+ import * as R from "remeda"
30
+
31
+ export interface MapZoomDropdownManager {
32
+ mapConfig?: MapConfig
33
+ isOnMapTab?: boolean
34
+ isMapSelectionEnabled?: boolean
35
+ globeController?: GlobeController
36
+ }
37
+
38
+ interface DropdownOption {
39
+ type: "country" | "continent"
40
+ label: string
41
+ value: string
42
+ isLocal?: boolean
43
+ alternativeNames?: string[]
44
+ trackNote: "map_zoom_mobile"
45
+ }
46
+
47
+ type GroupedDropdownOption = DropdownOptionGroup<DropdownOption>
48
+
49
+ function isGroupedOption(
50
+ item: DropdownCollectionItem<DropdownOption>
51
+ ): item is GroupedDropdownOption {
52
+ return (item as GroupedDropdownOption).options !== undefined
53
+ }
54
+
55
+ @observer
56
+ export class MapZoomDropdown extends React.Component<{
57
+ manager: MapZoomDropdownManager
58
+ }> {
59
+ private searchInput = ""
60
+ private localEntityNames: EntityName[] | undefined = undefined
61
+
62
+ constructor(props: { manager: MapZoomDropdownManager }) {
63
+ super(props)
64
+
65
+ makeObservable<MapZoomDropdown, "searchInput" | "localEntityNames">(
66
+ this,
67
+ { searchInput: observable, localEntityNames: observable }
68
+ )
69
+ }
70
+
71
+ static shouldShow(manager: MapZoomDropdownManager): boolean {
72
+ const menu = new MapZoomDropdown({ manager })
73
+ return menu.showMenu
74
+ }
75
+
76
+ @computed private get showMenu(): boolean {
77
+ const { isMapSelectionEnabled, isOnMapTab, mapConfig } =
78
+ this.props.manager
79
+ return !!(
80
+ isOnMapTab &&
81
+ !isMapSelectionEnabled &&
82
+ !mapConfig?.globe.isActive
83
+ )
84
+ }
85
+
86
+ @computed private get manager(): MapZoomDropdownManager {
87
+ return this.props.manager
88
+ }
89
+
90
+ @computed private get mapConfig(): MapConfig {
91
+ return this.manager.mapConfig ?? new MapConfig()
92
+ }
93
+
94
+ @computed get fuzzy(): FuzzySearch<DropdownOption> {
95
+ return FuzzySearch.withKeyArray(
96
+ this.flatOptions,
97
+ (entity) => [entity.label, ...(entity.alternativeNames ?? [])],
98
+ (entity) => entity.label
99
+ )
100
+ }
101
+
102
+ @action.bound private onChange(selected: DropdownOption | null): void {
103
+ if (!selected?.value) return
104
+
105
+ match(selected.type)
106
+ .with("country", () => {
107
+ // reset the region if a non-world region is currently selected
108
+ if (this.mapConfig.region !== MapRegionName.World) {
109
+ this.mapConfig.region = MapRegionName.World
110
+ }
111
+
112
+ // rotate to the country on the globe and show its tooltip
113
+ this.manager.globeController?.setFocusCountry(selected.value)
114
+ this.manager.globeController?.rotateToCountry(selected.value)
115
+ })
116
+ .with("continent", () => {
117
+ this.manager.globeController?.rotateToOwidContinent(
118
+ selected.value as GlobeRegionName
119
+ )
120
+ })
121
+ .exhaustive()
122
+
123
+ this.searchInput = ""
124
+ }
125
+
126
+ @computed private get sortedCountries(): EntityName[] {
127
+ return _.sortBy(mappableCountries.map((country) => country.name))
128
+ }
129
+
130
+ @computed private get options(): DropdownCollection<DropdownOption> {
131
+ const { localEntityNames = [] } = this
132
+ const langs = getUserNavigatorLanguagesNonEnglish()
133
+
134
+ const countryOptions: DropdownOption[] = this.sortedCountries.map(
135
+ (country) => ({
136
+ type: "country",
137
+ value: country,
138
+ label: country,
139
+ alternativeNames: getRegionAlternativeNames(country, langs),
140
+ isLocal: this.localEntityNames?.includes(country),
141
+ trackNote: "map_zoom_mobile",
142
+ })
143
+ )
144
+
145
+ const continentOptions: DropdownOption[] = Object.values(MapRegionName)
146
+ .filter((region) => region !== MapRegionName.World)
147
+ .map((region) => {
148
+ return {
149
+ type: "continent",
150
+ value: region,
151
+ label: MAP_REGION_LABELS[region as MapRegionName],
152
+ isLocal: this.localEntityNames?.includes(region),
153
+ trackNote: "map_zoom_mobile",
154
+ }
155
+ })
156
+
157
+ const sortLocalEntitiesToTop = (
158
+ options: DropdownOption[]
159
+ ): DropdownOption[] => {
160
+ if (localEntityNames.length === 0) return options
161
+ const [local, nonLocal] = R.partition(
162
+ options,
163
+ (option) => !!option.isLocal
164
+ )
165
+ return [...local, ...nonLocal]
166
+ }
167
+
168
+ return [
169
+ {
170
+ label: "Continents",
171
+ options: sortLocalEntitiesToTop(continentOptions),
172
+ },
173
+ {
174
+ label: "Countries",
175
+ options: sortLocalEntitiesToTop(countryOptions),
176
+ },
177
+ ]
178
+ }
179
+
180
+ @computed private get flatOptions(): DropdownOption[] {
181
+ return this.options.flatMap((item) =>
182
+ isGroupedOption(item) ? item.options : [item]
183
+ )
184
+ }
185
+
186
+ @computed
187
+ private get filteredOptions(): DropdownCollection<DropdownOption> {
188
+ if (!this.searchInput) return this.options
189
+ return this.fuzzy.search(this.searchInput)
190
+ }
191
+
192
+ @computed private get value(): DropdownOption | null {
193
+ const { region } = this.mapConfig
194
+ const { focusCountry } = this.manager.mapConfig?.globe ?? {}
195
+ const currentValue = focusCountry ?? region
196
+ return (
197
+ this.flatOptions.find((opt) => currentValue === opt.value) ?? null
198
+ )
199
+ }
200
+
201
+ @action.bound async populateLocalCountryName(): Promise<void> {
202
+ try {
203
+ const localCountryInfo = await getUserCountryInformation()
204
+ if (!localCountryInfo) return
205
+
206
+ const countryRegionsWithoutIncomeGroups = localCountryInfo.regions
207
+ ? localCountryInfo.regions.filter(
208
+ (region) => !checkIsOwidIncomeGroupName(region)
209
+ )
210
+ : []
211
+
212
+ const userEntityCodes = [
213
+ localCountryInfo.code,
214
+ ...countryRegionsWithoutIncomeGroups,
215
+ ]
216
+
217
+ const userRegions = regions.filter((region) =>
218
+ userEntityCodes.includes(region.code)
219
+ )
220
+
221
+ const sortedUserRegions = _.sortBy(userRegions, (region) =>
222
+ userEntityCodes.indexOf(region.code)
223
+ )
224
+
225
+ const localEntityNames = sortedUserRegions.map(
226
+ (region) => region.name
227
+ )
228
+
229
+ this.localEntityNames = localEntityNames
230
+ } catch {
231
+ // ignore
232
+ }
233
+ }
234
+
235
+ override componentDidMount(): void {
236
+ void this.populateLocalCountryName()
237
+ }
238
+
239
+ override render(): React.ReactElement | null {
240
+ return this.showMenu ? (
241
+ <div className="map-zoom-dropdown">
242
+ <Dropdown
243
+ options={
244
+ this.searchInput ? this.filteredOptions : this.options
245
+ }
246
+ onChange={this.onChange}
247
+ value={this.value}
248
+ inputValue={this.searchInput}
249
+ onInputChange={(inputValue) =>
250
+ (this.searchInput = inputValue)
251
+ }
252
+ isSearchable
253
+ placeholder="Zoom to..."
254
+ aria-label="Search for country or continent"
255
+ renderMenuOption={(option) => (
256
+ <>
257
+ {option.label}
258
+ {option.isLocal && (
259
+ <FontAwesomeIcon
260
+ className="map-zoom-dropdown-local-icon"
261
+ icon={faLocationArrow}
262
+ />
263
+ )}
264
+ </>
265
+ )}
266
+ />
267
+ </div>
268
+ ) : null
269
+ }
270
+ }
@@ -0,0 +1,87 @@
1
+ import * as React from "react"
2
+ import { computed, action, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import { MapConfig } from "../mapCharts/MapConfig"
5
+ import { GlobeController } from "../mapCharts/GlobeController"
6
+ import { MapRegionName } from "../../types/index.js"
7
+
8
+ export interface MapZoomToSelectionButtonManager {
9
+ mapConfig?: MapConfig
10
+ isOnMapTab?: boolean
11
+ globeController?: GlobeController
12
+ isFaceted?: boolean
13
+ isMapSelectionEnabled?: boolean
14
+ }
15
+
16
+ interface MapZoomToSelectionButtonProps {
17
+ manager: MapZoomToSelectionButtonManager
18
+ }
19
+
20
+ @observer
21
+ export class MapZoomToSelectionButton extends React.Component<MapZoomToSelectionButtonProps> {
22
+ constructor(props: MapZoomToSelectionButtonProps) {
23
+ super(props)
24
+ makeObservable(this)
25
+ }
26
+
27
+ static shouldShow(manager: MapZoomToSelectionButtonManager): boolean {
28
+ const menu = new MapZoomToSelectionButton({ manager })
29
+ return menu.showMenu
30
+ }
31
+
32
+ @computed private get showMenu(): boolean {
33
+ const { isOnMapTab, mapConfig, isMapSelectionEnabled } =
34
+ this.props.manager
35
+ return !!(
36
+ isOnMapTab &&
37
+ mapConfig?.selection.hasSelection &&
38
+ mapConfig?.region === MapRegionName.World &&
39
+ !mapConfig?.globe.isActive &&
40
+ !this.manager.isFaceted &&
41
+ isMapSelectionEnabled
42
+ )
43
+ }
44
+
45
+ @computed private get manager(): MapZoomToSelectionButtonManager {
46
+ return this.props.manager
47
+ }
48
+
49
+ @action.bound private onClick(): void {
50
+ this.manager.globeController?.rotateToSelection()
51
+ if (this.manager.mapConfig)
52
+ this.manager.mapConfig.region = MapRegionName.World
53
+ }
54
+
55
+ override render(): React.ReactElement | null {
56
+ return this.showMenu ? (
57
+ <button
58
+ onClick={this.onClick}
59
+ type="button"
60
+ data-track-note="map_zoom_to_selection"
61
+ className="menu-toggle"
62
+ >
63
+ <GlobeIcon size={16} />
64
+ Zoom to selection
65
+ </button>
66
+ ) : null
67
+ }
68
+ }
69
+
70
+ function GlobeIcon({ size }: { size: number }): React.ReactElement {
71
+ return (
72
+ <svg
73
+ width="16"
74
+ height="16"
75
+ viewBox="0 0 16 16"
76
+ fill="none"
77
+ style={{ width: size, height: size }}
78
+ >
79
+ <path
80
+ fillRule="evenodd"
81
+ clipRule="evenodd"
82
+ d="M8 1.82812C11.4079 1.82814 14.1709 4.59162 14.1709 8C14.1709 11.4079 11.4084 14.1709 8 14.1709C4.59205 14.1709 1.82814 11.4079 1.82812 8C1.82812 4.59204 4.59204 1.82812 8 1.82812ZM9.29102 10.5557C8.44211 10.6265 7.55628 10.6265 6.70703 10.5557C6.79687 10.9936 6.95066 11.5812 7.16113 12.0859C7.28556 12.3843 7.42514 12.6442 7.57617 12.8262C7.72942 13.0108 7.87172 13.0898 8 13.0898C8.12823 13.0898 8.27065 13.0107 8.42383 12.8262C8.57479 12.6442 8.7145 12.3842 8.83887 12.0859C9.04923 11.5813 9.20136 10.9935 9.29102 10.5557ZM3.20117 9.69434C3.71202 11.1414 4.85773 12.2868 6.30469 12.7979C5.94514 12.0915 5.71773 11.221 5.58301 10.416C4.77795 10.2812 3.90745 10.054 3.20117 9.69434ZM12.7979 9.69336C12 10 11.2212 10.2813 10.416 10.416C10.2813 11.2212 10.0531 12.0914 9.69336 12.7979C11.1413 12.2869 12.287 11.1413 12.7979 9.69336ZM9.45508 6.54395C8.50773 6.44784 7.4917 6.44782 6.54492 6.54395C6.44877 7.49128 6.44884 8.50726 6.54492 9.4541C7.49232 9.55025 8.50821 9.55021 9.45508 9.4541C9.55116 8.50712 9.55124 7.49121 9.45508 6.54395ZM10.5557 6.70605C10.6267 7.55585 10.6266 8.44275 10.5557 9.29297C11.0165 9.20187 11.4337 9.08879 11.7949 8.95605C12.2543 8.78723 12.5864 8.6129 12.7998 8.44141C13.015 8.26846 13.0859 8.11873 13.0859 8C13.0859 7.88127 13.0149 7.73157 12.7998 7.55859C12.5864 7.38708 12.2543 7.21281 11.7949 7.04395C11.4336 6.91117 11.0166 6.79684 10.5557 6.70605ZM5.44336 6.70801C5.00545 6.7977 4.41756 6.9508 3.91309 7.16113C3.61495 7.28547 3.35574 7.42525 3.17383 7.57617C2.98922 7.7294 2.91016 7.87173 2.91016 8C2.91023 8.12821 2.98931 8.26969 3.17383 8.42285C3.35579 8.57388 3.61474 8.71445 3.91309 8.83887C4.41751 9.04919 5.00546 9.20131 5.44336 9.29102C5.3726 8.44265 5.37257 7.55635 5.44336 6.70801ZM9.69434 3.20117C10.054 3.9074 10.2812 4.77792 10.416 5.58301C11.221 5.71772 12.0915 5.94515 12.7979 6.30469C12.2867 4.85774 11.1414 3.71198 9.69434 3.20117ZM6.30371 3.20117C4.85759 3.71223 3.71219 4.85758 3.20117 6.30371C3.90732 5.94422 4.77817 5.71775 5.58301 5.58301C5.71775 4.77819 5.94422 3.90736 6.30371 3.20117ZM8 2.91016C7.87172 2.91016 7.7294 2.98922 7.57617 3.17383C7.42527 3.35575 7.28545 3.61497 7.16113 3.91309C6.95079 4.41757 6.7977 5.00545 6.70801 5.44336C7.55685 5.37254 8.44276 5.37255 9.29199 5.44336C9.20211 5.00543 9.04925 4.41752 8.83887 3.91309C8.71452 3.61498 8.57474 3.35575 8.42383 3.17383C8.27059 2.98923 8.12827 2.91017 8 2.91016Z"
83
+ fill="currentColor"
84
+ />
85
+ </svg>
86
+ )
87
+ }
@@ -0,0 +1,78 @@
1
+ .grapher-search-field {
2
+ // search icon
3
+ $svg-margin: 8px;
4
+ $svg-size: 12px;
5
+
6
+ $placeholder: $gray-60;
7
+ $focus: 1px solid $blue-30;
8
+
9
+ position: relative;
10
+
11
+ .search-icon {
12
+ position: absolute;
13
+ top: 50%;
14
+ left: $svg-margin;
15
+ color: $light-text;
16
+ transform: translateY(-50%);
17
+ font-size: $svg-size;
18
+ }
19
+
20
+ .clear {
21
+ margin: 0;
22
+ padding: 0;
23
+ background: none;
24
+ border: none;
25
+ position: absolute;
26
+ top: 50%;
27
+ right: $svg-margin;
28
+ transform: translateY(-50%);
29
+ font-size: $svg-size;
30
+ color: $dark-text;
31
+ cursor: pointer;
32
+ }
33
+
34
+ input[type="search"] {
35
+ @include grapher_label-2-regular;
36
+ width: 100%;
37
+ height: 32px;
38
+ border: 1px solid $gray-20;
39
+ padding-left: $svg-margin + $svg-size + 4px;
40
+ padding-right: $svg-margin + $svg-size + 4px;
41
+ border-radius: 4px;
42
+ background: #fff;
43
+ color: $dark-text;
44
+
45
+ // style focus state
46
+ &:focus {
47
+ outline: none;
48
+ border: $focus;
49
+ }
50
+ &:focus:not(:focus-visible) {
51
+ border: none;
52
+ }
53
+ &:focus-visible {
54
+ border: $focus;
55
+ }
56
+ }
57
+
58
+ .search-placeholder {
59
+ @include grapher_label-2-regular;
60
+ color: $placeholder;
61
+ pointer-events: none;
62
+ position: absolute;
63
+ top: 50%;
64
+ left: $svg-size + $svg-margin + 6px;
65
+ transform: translateY(-50%);
66
+
67
+ white-space: nowrap;
68
+ overflow: hidden;
69
+ text-overflow: ellipsis;
70
+ width: calc(100% - $svg-size - $svg-margin - 2 * 6px);
71
+ }
72
+
73
+ &.grapher-search-field--empty {
74
+ input[type="search"] {
75
+ padding-right: 8px;
76
+ }
77
+ }
78
+ }