@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,89 @@
1
+ import { DualAxis } from "../axis/Axis"
2
+ import { ChartManager } from "../chart/ChartManager"
3
+ import { CoreValueType, EntityName, Time } from "../../types/index.js"
4
+ import { ChartSeries } from "../chart/ChartInterface"
5
+ import { Color } from "../../utils/index.js"
6
+ import { InteractionState } from "../interaction/InteractionState"
7
+ import { LegendStyleConfig } from "../legend/LegendInteractionState"
8
+ import { GRAPHER_OPACITY_MUTE } from "../core/GrapherConstants"
9
+
10
+ export const LINE_CHART_CLASS_NAME = "LineChart"
11
+
12
+ // Line color
13
+ export const DEFAULT_LINE_COLOR = "#000"
14
+
15
+ // Stroke width
16
+ export const DEFAULT_STROKE_WIDTH = 1.5
17
+ export const VARIABLE_COLOR_STROKE_WIDTH = 2.5
18
+
19
+ // Marker radius
20
+ export const DEFAULT_MARKER_RADIUS = 1.8
21
+ export const VARIABLE_COLOR_MARKER_RADIUS = 2.2
22
+ export const DISCONNECTED_DOTS_MARKER_RADIUS = 2.6
23
+ export const STATIC_SMALL_MARKER_RADIUS = 3
24
+
25
+ // Line outline
26
+ export const DEFAULT_LINE_OUTLINE_WIDTH = 0.5
27
+ export const VARIABLE_COLOR_LINE_OUTLINE_WIDTH = 1.0
28
+
29
+ // Legend
30
+ export const LEGEND_PADDING = 25
31
+ export const NUMERIC_LEGEND_STYLE: LegendStyleConfig = {
32
+ marker: { default: { stroke: "#ffffff", strokeWidth: 1 } },
33
+ }
34
+ export const CATEGORICAL_LEGEND_STYLE: LegendStyleConfig = {
35
+ marker: {
36
+ default: { opacity: 1 },
37
+ muted: { opacity: GRAPHER_OPACITY_MUTE },
38
+ },
39
+ text: { muted: { opacity: GRAPHER_OPACITY_MUTE } },
40
+ }
41
+
42
+ export interface LinePoint {
43
+ x: number
44
+ y: number
45
+ colorValue?: CoreValueType
46
+ }
47
+
48
+ export interface PlacedPoint {
49
+ x: number
50
+ y: number
51
+ color: Color
52
+ time: number
53
+ }
54
+
55
+ export interface LineChartSeries extends ChartSeries {
56
+ displayName: string
57
+ isProjection?: boolean
58
+ plotMarkersOnly?: boolean
59
+ points: LinePoint[]
60
+ entityName: EntityName
61
+ columnName: string
62
+ focus: InteractionState
63
+ }
64
+
65
+ export interface PlacedLineChartSeries extends LineChartSeries {
66
+ placedPoints: PlacedPoint[]
67
+ }
68
+
69
+ export interface RenderLineChartSeries extends PlacedLineChartSeries {
70
+ hover: InteractionState
71
+ }
72
+
73
+ export interface LinesProps {
74
+ dualAxis: DualAxis
75
+ series: RenderLineChartSeries[]
76
+ hidePoints?: boolean
77
+ lineStrokeWidth?: number
78
+ lineOutlineWidth?: number
79
+ markerRadius?: number
80
+ isStatic?: boolean
81
+ multiColor?: boolean
82
+ backgroundColor?: string
83
+ }
84
+
85
+ export interface LineChartManager extends ChartManager {
86
+ highlightedTimesInLineChart?: Time[]
87
+ lineStrokeWidth?: number
88
+ canSelectMultipleEntities?: boolean // used to pick an appropriate series name
89
+ }
@@ -0,0 +1,184 @@
1
+ import * as _ from "lodash-es"
2
+ import { OwidTable } from "../../core-table/index.js"
3
+ import {
4
+ AxisAlign,
5
+ AxisConfigInterface,
6
+ ColumnSlug,
7
+ EntityName,
8
+ PrimitiveType,
9
+ ScaleType,
10
+ SeriesName,
11
+ SeriesStrategy,
12
+ } from "../../types/index.js"
13
+ import {
14
+ LineChartSeries,
15
+ PlacedLineChartSeries,
16
+ PlacedPoint,
17
+ RenderLineChartSeries,
18
+ } from "./LineChartConstants"
19
+ import { DualAxis } from "../axis/Axis"
20
+ import { LineChartState } from "./LineChartState"
21
+ import { darkenColorForLine } from "../color/ColorUtils"
22
+ import {
23
+ byHoverThenFocusState,
24
+ getHoverStateForSeries,
25
+ } from "../chart/ChartUtils"
26
+
27
+ export type AnnotationsMap = Map<PrimitiveType, Set<PrimitiveType>>
28
+
29
+ export interface GetSeriesNameArgs {
30
+ entityName: EntityName
31
+ columnName: string
32
+ seriesStrategy: SeriesStrategy
33
+ hasMultipleEntitiesSelected?: boolean
34
+ allowsMultiEntitySelection?: boolean
35
+ }
36
+
37
+ /**
38
+ * Unique identifier for a series that is shared between line and slope charts
39
+ * since focus states are built on top of it.
40
+ */
41
+ export function getSeriesName({
42
+ entityName,
43
+ columnName,
44
+ seriesStrategy,
45
+ hasMultipleEntitiesSelected,
46
+ allowsMultiEntitySelection,
47
+ }: GetSeriesNameArgs): SeriesName {
48
+ // When plotting entities as series, use the entity name as the unique identifier
49
+ if (seriesStrategy === SeriesStrategy.entity) return entityName
50
+
51
+ // When plotting columns as series, use the column name. Prepend the entity
52
+ // name if multiple entities can be selected or are currently selected to
53
+ // ensure unique series names across all possible selection states
54
+ return allowsMultiEntitySelection || hasMultipleEntitiesSelected
55
+ ? `${entityName} - ${columnName}`
56
+ : columnName
57
+ }
58
+
59
+ export function getDisplayName({
60
+ entityName,
61
+ columnName,
62
+ seriesStrategy,
63
+ hasMultipleEntitiesSelected,
64
+ }: Omit<GetSeriesNameArgs, "canSelectMultipleEntities">): SeriesName {
65
+ // When plotting entities as series, each series represents one entity
66
+ if (seriesStrategy === SeriesStrategy.entity) return entityName
67
+
68
+ // When plotting columns as series, show just the column name by default.
69
+ // Only prepend the entity name when multiple entities are currently selected
70
+ // (this is different from series names that always include the entity name)
71
+ return hasMultipleEntitiesSelected
72
+ ? `${entityName} – ${columnName}` // Uses en dash for display
73
+ : columnName
74
+ }
75
+
76
+ export function getColorKey({
77
+ entityName,
78
+ columnName,
79
+ seriesStrategy,
80
+ hasMultipleEntitiesSelected,
81
+ }: Omit<GetSeriesNameArgs, "canSelectMultipleEntities">): SeriesName {
82
+ // When plotting entities as series, each entity gets its own color
83
+ if (seriesStrategy === SeriesStrategy.entity) return entityName
84
+
85
+ // When plotting columns as series, show just the column name by default.
86
+ // Only prepend the entity name when multiple entities are currently selected
87
+ // (this is different from series names that always include the entity name)
88
+ return hasMultipleEntitiesSelected
89
+ ? `${entityName} - ${columnName}`
90
+ : columnName
91
+ }
92
+
93
+ export function getAnnotationsMap(
94
+ table: OwidTable,
95
+ slug: ColumnSlug
96
+ ): AnnotationsMap | undefined {
97
+ return table
98
+ .getAnnotationColumnForColumn(slug)
99
+ ?.getUniqueValuesGroupedBy(table.entityNameSlug)
100
+ }
101
+
102
+ export function getAnnotationsForSeries(
103
+ annotationsMap: AnnotationsMap | undefined,
104
+ seriesName: SeriesName
105
+ ): string | undefined {
106
+ const annotations = annotationsMap?.get(seriesName)
107
+ if (!annotations) return undefined
108
+ return Array.from(annotations.values())
109
+ .filter((anno) => anno)
110
+ .join(" & ")
111
+ }
112
+
113
+ export function getYAxisConfigDefaults(
114
+ config?: AxisConfigInterface
115
+ ): AxisConfigInterface {
116
+ return {
117
+ nice: config?.scaleType !== ScaleType.log,
118
+ // if we only have a single y value (probably 0), we want the
119
+ // horizontal axis to be at the bottom of the chart.
120
+ // see https://github.com/owid/owid-grapher/pull/975#issuecomment-890798547
121
+ singleValueAxisPointAlign: AxisAlign.start,
122
+ // default to 0 if not set
123
+ min: 0,
124
+ }
125
+ }
126
+
127
+ export function toPlacedLineChartSeries(
128
+ series: readonly LineChartSeries[],
129
+ { chartState, dualAxis }: { chartState: LineChartState; dualAxis: DualAxis }
130
+ ): PlacedLineChartSeries[] {
131
+ const { horizontalAxis, verticalAxis } = dualAxis
132
+
133
+ return series.toReversed().map((series) => {
134
+ const placedPoints = series.points.map((point): PlacedPoint => {
135
+ const color = chartState.hasColorScale
136
+ ? darkenColorForLine(
137
+ chartState.getColorScaleColor(point.colorValue)
138
+ )
139
+ : series.color
140
+
141
+ return {
142
+ time: point.x,
143
+ x: _.round(horizontalAxis.place(point.x), 1),
144
+ y: _.round(verticalAxis.place(point.y), 1),
145
+ color,
146
+ }
147
+ })
148
+ return { ...series, placedPoints }
149
+ })
150
+ }
151
+
152
+ export function toRenderLineChartSeries(
153
+ placedSeries: PlacedLineChartSeries[],
154
+ {
155
+ isFocusModeActive = false,
156
+ isHoverModeActive = false,
157
+ hoveredSeriesNames = [],
158
+ }: {
159
+ isFocusModeActive?: boolean
160
+ isHoverModeActive?: boolean
161
+ hoveredSeriesNames?: SeriesName[]
162
+ }
163
+ ): RenderLineChartSeries[] {
164
+ let series: RenderLineChartSeries[] = placedSeries.map((series) => {
165
+ return {
166
+ ...series,
167
+ hover: getHoverStateForSeries(series, {
168
+ isHoverModeActive,
169
+ hoveredSeriesNames,
170
+ }),
171
+ }
172
+ })
173
+
174
+ // draw lines on top of markers-only series
175
+ series = _.sortBy(series, (series) => !series.plotMarkersOnly)
176
+
177
+ // sort by interaction state so that foreground series
178
+ // are drawn on top of background series
179
+ if (isFocusModeActive || isHoverModeActive) {
180
+ series = _.sortBy(series, byHoverThenFocusState)
181
+ }
182
+
183
+ return series
184
+ }
@@ -0,0 +1,394 @@
1
+ import * as _ from "lodash-es"
2
+ import * as R from "remeda"
3
+ import { Color } from "../../utils/index.js"
4
+ import { computed, makeObservable } from "mobx"
5
+ import {
6
+ ScaleType,
7
+ EntityName,
8
+ SeriesStrategy,
9
+ FacetStrategy,
10
+ CoreValueType,
11
+ MissingDataStrategy,
12
+ ColorScaleConfigInterface,
13
+ ColorSchemeName,
14
+ ChartErrorInfo,
15
+ } from "../../types/index.js"
16
+ import { ColorSchemes } from "../color/ColorSchemes"
17
+ import { ChartState } from "../chart/ChartInterface"
18
+ import {
19
+ LineChartSeries,
20
+ LineChartManager,
21
+ LinePoint,
22
+ DEFAULT_LINE_COLOR,
23
+ } from "./LineChartConstants"
24
+ import {
25
+ OwidTable,
26
+ CoreColumn,
27
+ isNotErrorValue,
28
+ } from "../../core-table/index.js"
29
+ import {
30
+ autoDetectSeriesStrategy,
31
+ autoDetectYColumnSlugs,
32
+ getDefaultFailMessage,
33
+ getShortNameForEntity,
34
+ makeSelectionArray,
35
+ } from "../chart/ChartUtils"
36
+ import { ColorScheme } from "../color/ColorScheme"
37
+ import { SelectionArray } from "../selection/SelectionArray"
38
+ import { ColorScale, ColorScaleManager } from "../color/ColorScale"
39
+ import { ColorScaleConfig } from "../color/ColorScaleConfig"
40
+ import { OWID_NO_DATA_GRAY } from "../color/ColorConstants"
41
+ import { CategoricalColorAssigner } from "../color/CategoricalColorAssigner"
42
+ import { getColorKey, getDisplayName, getSeriesName } from "./LineChartHelpers"
43
+ import { FocusArray } from "../focus/FocusArray"
44
+ import { AxisConfig } from "../axis/AxisConfig"
45
+ import { HorizontalAxis, VerticalAxis } from "../axis/Axis"
46
+
47
+ export class LineChartState implements ChartState, ColorScaleManager {
48
+ manager: LineChartManager
49
+
50
+ colorScale: ColorScale
51
+ defaultBaseColorScheme = ColorSchemeName.OwidDistinctLines
52
+ defaultNoDataColor = OWID_NO_DATA_GRAY
53
+
54
+ constructor({ manager }: { manager: LineChartManager }) {
55
+ this.manager = manager
56
+ this.colorScale = manager.colorScaleOverride ?? new ColorScale(this)
57
+ makeObservable(this)
58
+ }
59
+
60
+ @computed get inputTable(): OwidTable {
61
+ return this.manager.table
62
+ }
63
+
64
+ @computed get transformedTableFromGrapher(): OwidTable {
65
+ return (
66
+ this.manager.transformedTable ??
67
+ this.transformTable(this.inputTable)
68
+ )
69
+ }
70
+
71
+ @computed get transformedTable(): OwidTable {
72
+ let table = this.transformedTableFromGrapher
73
+ // The % growth transform cannot be applied in transformTable() because it will filter out
74
+ // any rows before startHandleTimeBound and change the timeline bounds.
75
+ const { isRelativeMode, startTime } = this.manager
76
+ if (isRelativeMode && startTime !== undefined) {
77
+ table = table.toTotalGrowthForEachColumnComparedToStartTime(
78
+ startTime,
79
+ this.manager.yColumnSlugs ?? []
80
+ )
81
+ }
82
+ return table
83
+ }
84
+
85
+ transformTable(table: OwidTable): OwidTable {
86
+ table = table.filterByEntityNames(
87
+ this.selectionArray.selectedEntityNames
88
+ )
89
+
90
+ // TODO: remove this filter once we don't have mixed type columns in datasets
91
+ // Currently we set skipParsing=true on these columns to be backwards-compatible
92
+ table = table.replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
93
+
94
+ if (this.isLogScale)
95
+ table = table.replaceNonPositiveCellsForLogScale(this.yColumnSlugs)
96
+
97
+ if (this.colorColumnSlug) {
98
+ table = table
99
+ // TODO: remove this filter once we don't have mixed type columns in datasets
100
+ // Currently we set skipParsing=true on these columns to be backwards-compatible
101
+ .replaceNonNumericCellsWithErrorValues([this.colorColumnSlug])
102
+ .interpolateColumnWithTolerance(this.colorColumnSlug)
103
+ }
104
+
105
+ // drop all data when the author chose to hide entities with missing data and
106
+ // at least one of the variables has no data for the current entity
107
+ if (
108
+ this.missingDataStrategy === MissingDataStrategy.hide &&
109
+ table.hasAnyColumnNoValidValue(this.yColumnSlugs)
110
+ ) {
111
+ table = table.dropAllRows()
112
+ }
113
+
114
+ return table
115
+ }
116
+
117
+ transformTableForSelection(table: OwidTable): OwidTable {
118
+ // if entities with partial data are not plotted,
119
+ // make sure they don't show up in the entity selector
120
+ if (this.missingDataStrategy === MissingDataStrategy.hide) {
121
+ table = table
122
+ .replaceNonNumericCellsWithErrorValues(this.yColumnSlugs)
123
+ .dropEntitiesThatHaveNoDataInSomeColumn(this.yColumnSlugs)
124
+ }
125
+
126
+ return table
127
+ }
128
+
129
+ @computed get selectionArray(): SelectionArray {
130
+ return makeSelectionArray(this.manager.selection)
131
+ }
132
+
133
+ @computed get focusArray(): FocusArray {
134
+ return this.manager.focusArray ?? new FocusArray()
135
+ }
136
+
137
+ @computed get isFocusModeActive(): boolean {
138
+ return this.focusArray.hasFocusedSeries
139
+ }
140
+
141
+ @computed get yColumnSlugs(): string[] {
142
+ return autoDetectYColumnSlugs(this.manager)
143
+ }
144
+
145
+ @computed get colorColumnSlug(): string | undefined {
146
+ // Line charts only support numeric variables as color dimension
147
+ return this.manager.numericColorColumnSlug
148
+ }
149
+
150
+ @computed get yColumns(): CoreColumn[] {
151
+ return this.yColumnSlugs.map((slug) => this.transformedTable.get(slug))
152
+ }
153
+
154
+ @computed get formatColumn(): CoreColumn {
155
+ return this.yColumns[0]
156
+ }
157
+
158
+ @computed get colorColumn(): CoreColumn {
159
+ return this.transformedTable.get(this.colorColumnSlug)
160
+ }
161
+
162
+ @computed get isLogScale(): boolean {
163
+ return this.manager.yAxisConfig?.scaleType === ScaleType.log
164
+ }
165
+
166
+ @computed get colorScheme(): ColorScheme {
167
+ return (
168
+ (this.manager.baseColorScheme
169
+ ? ColorSchemes.get(this.manager.baseColorScheme)
170
+ : null) ?? ColorSchemes.get(this.defaultBaseColorScheme)
171
+ )
172
+ }
173
+
174
+ @computed get colorScaleColumn(): CoreColumn {
175
+ return (
176
+ // For faceted charts, we have to get the values of inputTable before it's filtered by
177
+ // the faceting logic.
178
+ this.manager.colorScaleColumnOverride ?? // We need to use inputTable in order to get consistent coloring for a variable across
179
+ // charts, e.g. each continent being assigned to the same color.
180
+ // inputTable is unfiltered, so it contains every value that exists in the variable.
181
+ this.inputTable.get(this.colorColumnSlug)
182
+ )
183
+ }
184
+
185
+ @computed get colorScaleConfig(): ColorScaleConfigInterface | undefined {
186
+ return (
187
+ ColorScaleConfig.fromDSL(this.colorColumn.def) ??
188
+ this.manager.colorScale
189
+ )
190
+ }
191
+
192
+ @computed get categoricalColorAssigner(): CategoricalColorAssigner {
193
+ return new CategoricalColorAssigner({
194
+ colorScheme: this.colorScheme,
195
+ invertColorScheme: this.manager.invertColorScheme,
196
+ colorMap:
197
+ this.seriesStrategy === SeriesStrategy.entity
198
+ ? this.inputTable.entityNameColorIndex
199
+ : this.inputTable.columnDisplayNameToColorMap,
200
+ autoColorMapCache: this.manager.seriesColorMap,
201
+ })
202
+ }
203
+
204
+ @computed get hasColorScale(): boolean {
205
+ return !this.colorColumn.isMissing
206
+ }
207
+
208
+ getColorScaleColor(value: CoreValueType | undefined): Color {
209
+ return this.colorScale.getColor(value) ?? DEFAULT_LINE_COLOR
210
+ }
211
+
212
+ @computed get hasNoDataBin(): boolean {
213
+ if (!this.hasColorScale) return false
214
+ return this.colorColumn.valuesIncludingErrorValues.some(
215
+ (value) => !isNotErrorValue(value)
216
+ )
217
+ }
218
+
219
+ @computed get missingDataStrategy(): MissingDataStrategy {
220
+ return this.manager.missingDataStrategy || MissingDataStrategy.auto
221
+ }
222
+
223
+ @computed get seriesStrategy(): SeriesStrategy {
224
+ return autoDetectSeriesStrategy(this.manager, true)
225
+ }
226
+
227
+ @computed get series(): readonly LineChartSeries[] {
228
+ const series = this.yColumns.flatMap((col) =>
229
+ col.uniqEntityNames.map(
230
+ (entityName): LineChartSeries =>
231
+ this.constructSingleSeries(entityName, col)
232
+ )
233
+ )
234
+
235
+ // The lines should be plotted in the order of the selected entities
236
+ const { selectedEntityNames } = this.selectionArray
237
+ const entityIndex = new Map(
238
+ selectedEntityNames.map((name, index) => [name, index])
239
+ )
240
+ const sortedSeries = _.sortBy(series, (series) =>
241
+ entityIndex.get(series.seriesName)
242
+ )
243
+
244
+ return sortedSeries
245
+ }
246
+
247
+ @computed get availableFacetStrategies(): FacetStrategy[] {
248
+ const strategies: FacetStrategy[] = [FacetStrategy.none]
249
+
250
+ if (this.selectionArray.numSelectedEntities > 1)
251
+ strategies.push(FacetStrategy.entity)
252
+
253
+ const numNonProjectionColumns = this.yColumns.filter(
254
+ (c) => !c.display?.isProjection
255
+ ).length
256
+ if (numNonProjectionColumns > 1) strategies.push(FacetStrategy.metric)
257
+
258
+ return strategies
259
+ }
260
+
261
+ private constructSingleSeries(
262
+ entityName: EntityName,
263
+ column: CoreColumn
264
+ ): LineChartSeries {
265
+ const {
266
+ manager: { canSelectMultipleEntities },
267
+ transformedTable: { availableEntityNames },
268
+ seriesStrategy,
269
+ hasColorScale,
270
+ colorColumn,
271
+ } = this
272
+
273
+ // Construct the points
274
+ const timeValues = column.originalTimeColumn.valuesIncludingErrorValues
275
+ const values = column.valuesIncludingErrorValues
276
+ const colorValues = colorColumn.valuesIncludingErrorValues
277
+ // If Y and Color are the same column, we need to get rid of any duplicate rows.
278
+ // Duplicates occur because Y doesn't have tolerance applied, but Color does.
279
+ const rowIndexes = _.sortedUniqBy(
280
+ this.transformedTable.rowIndicesByEntityName
281
+ .get(entityName)!
282
+ .filter((index) => _.isNumber(values[index])),
283
+ (index) => timeValues[index]
284
+ )
285
+ const points = rowIndexes.map((index) => {
286
+ const point: LinePoint = {
287
+ x: timeValues[index] as number,
288
+ y: values[index] as number,
289
+ }
290
+ if (hasColorScale) {
291
+ const colorValue = colorValues[index]
292
+ point.colorValue = isNotErrorValue(colorValue)
293
+ ? colorValue
294
+ : undefined
295
+ }
296
+ return point
297
+ })
298
+
299
+ // Construct series properties
300
+ const columnName = column.nonEmptyDisplayName
301
+ const hasMultipleEntitiesSelected = availableEntityNames.length > 1
302
+ const seriesName = getSeriesName({
303
+ entityName,
304
+ columnName,
305
+ seriesStrategy,
306
+ hasMultipleEntitiesSelected,
307
+ allowsMultiEntitySelection: canSelectMultipleEntities,
308
+ })
309
+ const shortEntityName = getShortNameForEntity(entityName)
310
+ const displayName = getDisplayName({
311
+ entityName: shortEntityName ?? entityName,
312
+ columnName,
313
+ seriesStrategy,
314
+ hasMultipleEntitiesSelected,
315
+ })
316
+
317
+ let seriesColor: Color
318
+ if (hasColorScale) {
319
+ const colorValue = R.last(points)?.colorValue
320
+ seriesColor = this.getColorScaleColor(colorValue)
321
+ } else {
322
+ seriesColor = this.categoricalColorAssigner.assign(
323
+ getColorKey({
324
+ entityName,
325
+ columnName,
326
+ seriesStrategy,
327
+ hasMultipleEntitiesSelected,
328
+ })
329
+ )
330
+ }
331
+
332
+ return {
333
+ points,
334
+ seriesName,
335
+ entityName,
336
+ columnName,
337
+ displayName,
338
+ isProjection: column.isProjection,
339
+ plotMarkersOnly: column.display?.plotMarkersOnlyInLineChart,
340
+ color: seriesColor,
341
+ focus: this.focusArray.state(seriesName),
342
+ }
343
+ }
344
+
345
+ toHorizontalAxis(config: AxisConfig): HorizontalAxis {
346
+ const axis = config.toHorizontalAxis()
347
+
348
+ // Update domain
349
+ axis.updateDomainPreservingUserSettings(
350
+ this.transformedTable.timeDomainFor(this.yColumnSlugs)
351
+ )
352
+
353
+ axis.scaleType = ScaleType.linear
354
+ axis.formatColumn = this.inputTable.timeColumn
355
+ axis.hideFractionalTicks = true
356
+
357
+ return axis
358
+ }
359
+
360
+ toVerticalAxis(config: AxisConfig): VerticalAxis {
361
+ const axis = config.toVerticalAxis()
362
+
363
+ // Update domain
364
+ const yDomain = this.transformedTable.domainFor(this.yColumnSlugs)
365
+ axis.updateDomainPreservingUserSettings([
366
+ Math.min(axis.domain[0], yDomain[0]),
367
+ Math.max(axis.domain[1], yDomain[1]),
368
+ ])
369
+
370
+ // All y axis points are integral, don't show fractional ticks in that case
371
+ axis.hideFractionalTicks = this.yColumns.every(
372
+ (yColumn) => yColumn.isAllIntegers
373
+ )
374
+
375
+ // Line charts don't have a y-axis label
376
+ axis.label = ""
377
+
378
+ axis.formatColumn = this.formatColumn
379
+
380
+ return axis
381
+ }
382
+
383
+ @computed get errorInfo(): ChartErrorInfo {
384
+ const message = getDefaultFailMessage(this.manager)
385
+ if (message) return { reason: message }
386
+
387
+ const { entityTypePlural = "entities" } = this.manager
388
+ if (!this.series.length)
389
+ return {
390
+ reason: `No data for the selected ${entityTypePlural}`,
391
+ }
392
+ return { reason: "" }
393
+ }
394
+ }