@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,597 @@
1
+ import * as React from "react"
2
+ import { computed, makeObservable } from "mobx"
3
+ import { observer } from "mobx-react"
4
+ import * as R from "remeda"
5
+ import {
6
+ Bounds,
7
+ HorizontalAlign,
8
+ Position,
9
+ VerticalAlign,
10
+ dyFromAlign,
11
+ textAnchorFromAlign,
12
+ makeIdForHumanConsumption,
13
+ } from "../../utils/index.js"
14
+ import { VerticalAxis, HorizontalAxis, DualAxis } from "./Axis"
15
+ import classNames from "classnames"
16
+ import { GRAPHER_DARK_TEXT } from "../color/ColorConstants"
17
+ import { ScaleType, DetailsMarker } from "../../types/index.js"
18
+ import { ComparisonLine } from "../comparisonLine/ComparisonLine"
19
+ import { DEFAULT_GRAPHER_BOUNDS } from "../core/GrapherConstants"
20
+
21
+ const TICK_COLOR = "#ddd"
22
+ const FAINT_TICK_COLOR = "#eee"
23
+ const SOLID_TICK_COLOR = "#999"
24
+
25
+ interface VerticalAxisGridLinesProps {
26
+ verticalAxis: VerticalAxis
27
+ bounds: Bounds
28
+ strokeWidth?: number
29
+ dashPattern?: string
30
+ }
31
+
32
+ @observer
33
+ export class VerticalAxisGridLines extends React.Component<VerticalAxisGridLinesProps> {
34
+ override render(): React.ReactElement {
35
+ const { bounds, verticalAxis, strokeWidth } = this.props
36
+ const axis = verticalAxis.clone()
37
+ axis.range = bounds.yRange()
38
+
39
+ return (
40
+ <g
41
+ id={makeIdForHumanConsumption("horizontal-grid-lines")}
42
+ className={classNames("AxisGridLines", "horizontalLines")}
43
+ >
44
+ {axis.getTickValues().map((t) => {
45
+ const color = t.faint
46
+ ? FAINT_TICK_COLOR
47
+ : t.solid
48
+ ? SOLID_TICK_COLOR
49
+ : TICK_COLOR
50
+ const dasharray = this.props.dashPattern ?? "4,4"
51
+
52
+ return (
53
+ <line
54
+ id={makeIdForHumanConsumption(
55
+ verticalAxis.formatTick(t.value)
56
+ )}
57
+ key={t.value}
58
+ x1={bounds.left.toFixed(2)}
59
+ y1={axis.place(t.value)}
60
+ x2={bounds.right.toFixed(2)}
61
+ y2={axis.place(t.value)}
62
+ stroke={color}
63
+ strokeWidth={strokeWidth}
64
+ strokeDasharray={t.solid ? undefined : dasharray}
65
+ />
66
+ )
67
+ })}
68
+ </g>
69
+ )
70
+ }
71
+ }
72
+
73
+ interface HorizontalAxisGridLinesProps {
74
+ horizontalAxis: HorizontalAxis
75
+ bounds?: Bounds
76
+ strokeWidth?: number
77
+ dashPattern?: string
78
+ }
79
+
80
+ @observer
81
+ export class HorizontalAxisGridLines extends React.Component<HorizontalAxisGridLinesProps> {
82
+ constructor(props: HorizontalAxisGridLinesProps) {
83
+ super(props)
84
+ makeObservable(this)
85
+ }
86
+
87
+ @computed get bounds(): Bounds {
88
+ return this.props.bounds ?? DEFAULT_GRAPHER_BOUNDS
89
+ }
90
+
91
+ override render(): React.ReactElement {
92
+ const { horizontalAxis, strokeWidth } = this.props
93
+ const { bounds } = this
94
+ const axis = horizontalAxis.clone()
95
+ axis.range = bounds.xRange()
96
+
97
+ return (
98
+ <g
99
+ id={makeIdForHumanConsumption("vertical-grid-lines")}
100
+ className={classNames("AxisGridLines", "verticalLines")}
101
+ >
102
+ {axis.getTickValues().map((t) => {
103
+ const color = t.faint
104
+ ? FAINT_TICK_COLOR
105
+ : t.solid
106
+ ? SOLID_TICK_COLOR
107
+ : TICK_COLOR
108
+ const dasharray = this.props.dashPattern ?? "4,4"
109
+
110
+ return (
111
+ <line
112
+ id={makeIdForHumanConsumption(
113
+ horizontalAxis.formatTick(t.value)
114
+ )}
115
+ key={t.value}
116
+ x1={axis.place(t.value)}
117
+ y1={bounds.bottom.toFixed(2)}
118
+ x2={axis.place(t.value)}
119
+ y2={bounds.top.toFixed(2)}
120
+ stroke={color}
121
+ strokeWidth={strokeWidth}
122
+ strokeDasharray={t.solid ? undefined : dasharray}
123
+ />
124
+ )
125
+ })}
126
+ </g>
127
+ )
128
+ }
129
+ }
130
+
131
+ interface HorizontalAxisZeroLineProps {
132
+ horizontalAxis: HorizontalAxis
133
+ bounds: Bounds
134
+ strokeWidth?: number
135
+ align?: HorizontalAlign
136
+ }
137
+
138
+ @observer
139
+ export class HorizontalAxisZeroLine extends React.Component<HorizontalAxisZeroLineProps> {
140
+ override render(): React.ReactElement {
141
+ const {
142
+ bounds,
143
+ horizontalAxis,
144
+ align = HorizontalAlign.center,
145
+ strokeWidth = 1,
146
+ } = this.props
147
+ const axis = horizontalAxis.clone()
148
+ axis.range = bounds.xRange()
149
+
150
+ // the zero line is either drawn at the center of the zero tick
151
+ // or at the edge of the tick, either to the left or to the right
152
+ const offset =
153
+ align === HorizontalAlign.center
154
+ ? 0
155
+ : align === HorizontalAlign.right
156
+ ? -strokeWidth / 2
157
+ : strokeWidth / 2
158
+ const x = axis.place(0) + offset
159
+
160
+ return (
161
+ <line
162
+ id={makeIdForHumanConsumption("vertical-zero-line")}
163
+ x1={x.toFixed(2)}
164
+ y1={bounds.bottom.toFixed(2)}
165
+ x2={x.toFixed(2)}
166
+ y2={bounds.top.toFixed(2)}
167
+ stroke={SOLID_TICK_COLOR}
168
+ strokeWidth={strokeWidth}
169
+ />
170
+ )
171
+ }
172
+ }
173
+
174
+ interface VerticalAxisZeroLineProps {
175
+ verticalAxis: VerticalAxis
176
+ bounds: Bounds
177
+ stroke?: string
178
+ strokeWidth?: number
179
+ strokeDasharray?: string
180
+ }
181
+
182
+ @observer
183
+ export class VerticalAxisZeroLine extends React.Component<VerticalAxisZeroLineProps> {
184
+ override render(): React.ReactElement {
185
+ const {
186
+ bounds,
187
+ verticalAxis,
188
+ stroke = SOLID_TICK_COLOR,
189
+ strokeWidth = 1,
190
+ strokeDasharray,
191
+ } = this.props
192
+
193
+ const axis = verticalAxis.clone()
194
+ axis.range = bounds.yRange()
195
+
196
+ const y = axis.place(0)
197
+
198
+ return (
199
+ <line
200
+ id={makeIdForHumanConsumption("horizontal-zero-line")}
201
+ x1={bounds.left.toFixed(2)}
202
+ y1={y.toFixed(2)}
203
+ x2={bounds.right.toFixed(2)}
204
+ y2={y.toFixed(2)}
205
+ stroke={stroke}
206
+ strokeWidth={strokeWidth}
207
+ strokeDasharray={strokeDasharray}
208
+ />
209
+ )
210
+ }
211
+ }
212
+
213
+ interface DualAxisViewProps {
214
+ dualAxis: DualAxis
215
+ highlightValue?: { x: number; y: number }
216
+ showTickMarks?: boolean
217
+ labelColor?: string
218
+ tickColor?: string
219
+ lineWidth?: number
220
+ gridDashPattern?: string
221
+ detailsMarker?: DetailsMarker
222
+ backgroundColor?: string
223
+ showEndpointsOnly?: boolean
224
+ }
225
+
226
+ @observer
227
+ export class DualAxisComponent extends React.Component<DualAxisViewProps> {
228
+ override render(): React.ReactElement {
229
+ const {
230
+ dualAxis,
231
+ showTickMarks,
232
+ labelColor,
233
+ tickColor,
234
+ lineWidth,
235
+ gridDashPattern,
236
+ detailsMarker,
237
+ backgroundColor,
238
+ showEndpointsOnly,
239
+ } = this.props
240
+ const { bounds, horizontalAxis, verticalAxis, innerBounds } = dualAxis
241
+
242
+ const verticalGridlines = verticalAxis.hideGridlines ? null : (
243
+ <VerticalAxisGridLines
244
+ verticalAxis={verticalAxis}
245
+ bounds={innerBounds}
246
+ strokeWidth={lineWidth}
247
+ dashPattern={gridDashPattern}
248
+ />
249
+ )
250
+
251
+ const horizontalGridlines = horizontalAxis.hideGridlines ? null : (
252
+ <HorizontalAxisGridLines
253
+ horizontalAxis={horizontalAxis}
254
+ bounds={innerBounds}
255
+ strokeWidth={lineWidth}
256
+ dashPattern={gridDashPattern}
257
+ />
258
+ )
259
+
260
+ const verticalAxisComponent = verticalAxis.hideAxis ? null : (
261
+ <VerticalAxisComponent
262
+ bounds={bounds}
263
+ verticalAxis={verticalAxis}
264
+ labelColor={labelColor}
265
+ tickColor={tickColor}
266
+ detailsMarker={detailsMarker}
267
+ showEndpointsOnly={showEndpointsOnly}
268
+ />
269
+ )
270
+
271
+ const horizontalAxisComponent = horizontalAxis.hideAxis ? null : (
272
+ <HorizontalAxisComponent
273
+ bounds={bounds}
274
+ axis={horizontalAxis}
275
+ showTickMarks={showTickMarks}
276
+ preferredAxisPosition={innerBounds.bottom}
277
+ labelColor={labelColor}
278
+ tickColor={tickColor}
279
+ tickMarkWidth={lineWidth}
280
+ detailsMarker={detailsMarker}
281
+ showEndpointsOnly={showEndpointsOnly}
282
+ />
283
+ )
284
+
285
+ const comparisonLines = dualAxis.comparisonLines.map((line, index) => (
286
+ <ComparisonLine
287
+ key={`${line.label}-${index}`}
288
+ dualAxis={dualAxis}
289
+ comparisonLine={line}
290
+ backgroundColor={backgroundColor}
291
+ />
292
+ ))
293
+
294
+ return (
295
+ <>
296
+ {horizontalAxisComponent}
297
+ {verticalAxisComponent}
298
+ {verticalGridlines}
299
+ {horizontalGridlines}
300
+ {comparisonLines}
301
+ </>
302
+ )
303
+ }
304
+ }
305
+
306
+ interface VerticalAxisComponentProps {
307
+ bounds: Bounds
308
+ verticalAxis: VerticalAxis
309
+ showTickMarks?: boolean
310
+ labelColor?: string
311
+ tickColor?: string
312
+ detailsMarker?: DetailsMarker
313
+ showEndpointsOnly?: boolean
314
+ }
315
+
316
+ @observer
317
+ export class VerticalAxisComponent extends React.Component<VerticalAxisComponentProps> {
318
+ override render(): React.ReactElement {
319
+ const {
320
+ bounds,
321
+ verticalAxis,
322
+ labelColor,
323
+ tickColor,
324
+ detailsMarker,
325
+ showTickMarks,
326
+ showEndpointsOnly,
327
+ } = this.props
328
+ const { tickLabels, labelTextWrap, logNoticeTextWrap, config } =
329
+ verticalAxis
330
+
331
+ let visibleTickLabels = tickLabels
332
+ if (showEndpointsOnly) {
333
+ visibleTickLabels = pickFirstAndLastElement(
334
+ R.sortBy(tickLabels, (label) => label.x)
335
+ )
336
+ }
337
+
338
+ const shouldShowLogNotice =
339
+ verticalAxis.shouldShowLogNotice &&
340
+ // Only show the notice if it fits in the margin
341
+ verticalAxis.logNoticeWidth <= verticalAxis.width
342
+
343
+ const tickX =
344
+ bounds.left + verticalAxis.width - verticalAxis.tickPadding
345
+
346
+ return (
347
+ <g
348
+ id={makeIdForHumanConsumption("vertical-axis")}
349
+ className="VerticalAxis"
350
+ >
351
+ {shouldShowLogNotice && logNoticeTextWrap && (
352
+ <React.Fragment key={logNoticeTextWrap.text}>
353
+ {logNoticeTextWrap.renderSVG(tickX, bounds.top, {
354
+ id: makeIdForHumanConsumption(
355
+ "vertical-axis-log-notice"
356
+ ),
357
+ textProps: {
358
+ fill: tickColor || GRAPHER_DARK_TEXT,
359
+ textAnchor: textAnchorFromAlign(
360
+ HorizontalAlign.right
361
+ ),
362
+ fontStyle: "italic",
363
+ },
364
+ detailsMarker,
365
+ })}
366
+ </React.Fragment>
367
+ )}
368
+ {labelTextWrap && (
369
+ <React.Fragment key={labelTextWrap.text}>
370
+ {labelTextWrap.renderSVG(bounds.left, bounds.top, {
371
+ id: makeIdForHumanConsumption(
372
+ "vertical-axis-label"
373
+ ),
374
+ textProps: {
375
+ fill: labelColor || GRAPHER_DARK_TEXT,
376
+ },
377
+ detailsMarker,
378
+ })}
379
+ </React.Fragment>
380
+ )}
381
+ {showTickMarks && (
382
+ <g id={makeIdForHumanConsumption("tick-marks")}>
383
+ {visibleTickLabels.map((label) => (
384
+ <VerticalAxisTickMark
385
+ id={makeIdForHumanConsumption(
386
+ label.formattedValue
387
+ )}
388
+ key={label.value}
389
+ tickMarkYPosition={verticalAxis.place(
390
+ label.value
391
+ )}
392
+ tickMarkLeftPosition={
393
+ bounds.left + verticalAxis.width
394
+ }
395
+ color={SOLID_TICK_COLOR}
396
+ />
397
+ ))}
398
+ </g>
399
+ )}
400
+ {!config.hideTickLabels && (
401
+ <g id={makeIdForHumanConsumption("tick-labels")}>
402
+ {visibleTickLabels.map((label) => {
403
+ const { value, y, xAlign, yAlign, formattedValue } =
404
+ label
405
+ return (
406
+ <text
407
+ key={value}
408
+ x={tickX.toFixed(2)}
409
+ y={y}
410
+ dy={dyFromAlign(
411
+ yAlign ?? VerticalAlign.middle
412
+ )}
413
+ textAnchor={textAnchorFromAlign(
414
+ xAlign ?? HorizontalAlign.right
415
+ )}
416
+ fill={tickColor || GRAPHER_DARK_TEXT}
417
+ fontSize={verticalAxis.tickFontSize}
418
+ >
419
+ {formattedValue}
420
+ </text>
421
+ )
422
+ })}
423
+ </g>
424
+ )}
425
+ </g>
426
+ )
427
+ }
428
+ }
429
+
430
+ export class HorizontalAxisComponent extends React.Component<{
431
+ bounds: Bounds
432
+ axis: HorizontalAxis
433
+ showTickMarks?: boolean
434
+ preferredAxisPosition?: number
435
+ labelColor?: string
436
+ tickColor?: string
437
+ tickMarkWidth?: number
438
+ detailsMarker?: DetailsMarker
439
+ showEndpointsOnly?: boolean
440
+ }> {
441
+ constructor(props: {
442
+ bounds: Bounds
443
+ axis: HorizontalAxis
444
+ showTickMarks?: boolean
445
+ preferredAxisPosition?: number
446
+ labelColor?: string
447
+ tickColor?: string
448
+ tickMarkWidth?: number
449
+ detailsMarker?: DetailsMarker
450
+ showEndpointsOnly?: boolean
451
+ }) {
452
+ super(props)
453
+ makeObservable(this)
454
+ }
455
+
456
+ @computed get scaleType(): ScaleType {
457
+ return this.props.axis.scaleType
458
+ }
459
+
460
+ set scaleType(scaleType: ScaleType) {
461
+ this.props.axis.config.scaleType = scaleType
462
+ }
463
+
464
+ // for scale selector. todo: cleanup
465
+ @computed get bounds(): Bounds {
466
+ const { bounds, axis } = this.props
467
+ if (axis.orient === Position.top)
468
+ return new Bounds(bounds.right, bounds.top + 30, 100, 100)
469
+ else return new Bounds(bounds.right, bounds.bottom - 30, 100, 100)
470
+ }
471
+
472
+ override render(): React.ReactElement {
473
+ const {
474
+ bounds,
475
+ axis,
476
+ showTickMarks,
477
+ preferredAxisPosition,
478
+ labelColor,
479
+ tickColor,
480
+ tickMarkWidth = 1,
481
+ detailsMarker,
482
+ showEndpointsOnly,
483
+ } = this.props
484
+ const { tickLabels, labelTextWrap: label, labelOffset, orient } = axis
485
+ const tickSize = 5
486
+ const horizontalAxisLabelsOnTop = orient === Position.top
487
+ const labelYPosition = horizontalAxisLabelsOnTop
488
+ ? bounds.top
489
+ : bounds.bottom - (label?.height ?? 0)
490
+
491
+ const tickMarksYPosition = horizontalAxisLabelsOnTop
492
+ ? bounds.top + axis.height - 5
493
+ : (preferredAxisPosition ?? bounds.bottom)
494
+
495
+ const tickLabelYPlacement = horizontalAxisLabelsOnTop
496
+ ? bounds.top + labelOffset + 10
497
+ : bounds.bottom - labelOffset
498
+
499
+ const showTickLabels = !axis.config.hideTickLabels
500
+
501
+ let visibleTickLabels = tickLabels
502
+ if (showEndpointsOnly) {
503
+ visibleTickLabels = pickFirstAndLastElement(
504
+ R.sortBy(tickLabels, (label) => label.x)
505
+ )
506
+ }
507
+
508
+ return (
509
+ <g
510
+ id={makeIdForHumanConsumption("horizontal-axis")}
511
+ className="HorizontalAxis"
512
+ >
513
+ {label && (
514
+ <React.Fragment key={label.text}>
515
+ {label.renderSVG(axis.rangeCenter, labelYPosition, {
516
+ id: makeIdForHumanConsumption(
517
+ "horizontal-axis-label"
518
+ ),
519
+ textProps: {
520
+ fill: labelColor || GRAPHER_DARK_TEXT,
521
+ textAnchor: "middle",
522
+ },
523
+ detailsMarker,
524
+ })}
525
+ </React.Fragment>
526
+ )}
527
+ {showTickMarks && (
528
+ <g id={makeIdForHumanConsumption("tick-marks")}>
529
+ {visibleTickLabels.map((label) => (
530
+ <line
531
+ key={label.value}
532
+ id={makeIdForHumanConsumption(
533
+ label.formattedValue
534
+ )}
535
+ x1={axis.place(label.value)}
536
+ y1={tickMarksYPosition - tickMarkWidth / 2}
537
+ x2={axis.place(label.value)}
538
+ y2={tickMarksYPosition + tickSize}
539
+ stroke={SOLID_TICK_COLOR}
540
+ strokeWidth={tickMarkWidth}
541
+ />
542
+ ))}
543
+ </g>
544
+ )}
545
+ {showTickLabels && (
546
+ <g id={makeIdForHumanConsumption("tick-labels")}>
547
+ {visibleTickLabels.map((label) => (
548
+ <text
549
+ key={label.value}
550
+ x={label.x}
551
+ y={tickLabelYPlacement}
552
+ fill={tickColor || GRAPHER_DARK_TEXT}
553
+ textAnchor={textAnchorFromAlign(
554
+ label.xAlign ?? HorizontalAlign.center
555
+ )}
556
+ fontSize={axis.tickFontSize}
557
+ >
558
+ {label.formattedValue}
559
+ </text>
560
+ ))}
561
+ </g>
562
+ )}
563
+ </g>
564
+ )
565
+ }
566
+ }
567
+
568
+ export class VerticalAxisTickMark extends React.Component<{
569
+ tickMarkLeftPosition: number
570
+ tickMarkYPosition: number
571
+ color: string
572
+ width?: number
573
+ id?: string
574
+ }> {
575
+ override render(): React.ReactElement {
576
+ const { tickMarkYPosition, tickMarkLeftPosition, color, width, id } =
577
+ this.props
578
+ const tickSize = 5
579
+ const tickRight = tickMarkLeftPosition + tickSize
580
+ return (
581
+ <line
582
+ id={id}
583
+ x1={tickMarkLeftPosition}
584
+ y1={tickMarkYPosition}
585
+ x2={tickRight}
586
+ y2={tickMarkYPosition}
587
+ stroke={color}
588
+ strokeWidth={width}
589
+ />
590
+ )
591
+ }
592
+ }
593
+
594
+ function pickFirstAndLastElement<T>(array: T[]): T[] {
595
+ if (array.length < 2) return array
596
+ return [array.at(0), array.at(-1)] as [T, T]
597
+ }