@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.
- package/LICENSE.md +8 -0
- package/README.md +113 -0
- package/package.json +137 -0
- package/src/components/BodyPortal/BodyPortal.tsx +40 -0
- package/src/components/Button/Button.scss +110 -0
- package/src/components/Button/Button.tsx +101 -0
- package/src/components/Checkbox.scss +93 -0
- package/src/components/Checkbox.tsx +47 -0
- package/src/components/ExpandableToggle/ExpandableToggle.scss +123 -0
- package/src/components/ExpandableToggle/ExpandableToggle.tsx +60 -0
- package/src/components/GrapherTabIcon.tsx +156 -0
- package/src/components/GrapherTrendArrow.scss +16 -0
- package/src/components/GrapherTrendArrow.tsx +30 -0
- package/src/components/Halo/Halo.tsx +44 -0
- package/src/components/LabeledSwitch/LabeledSwitch.scss +109 -0
- package/src/components/LabeledSwitch/LabeledSwitch.tsx +62 -0
- package/src/components/MarkdownTextWrap/MarkdownTextWrap.tsx +1173 -0
- package/src/components/OverlayHeader.scss +18 -0
- package/src/components/OverlayHeader.tsx +29 -0
- package/src/components/RadioButton.scss +69 -0
- package/src/components/RadioButton.tsx +42 -0
- package/src/components/SimpleMarkdownText.tsx +89 -0
- package/src/components/TextInput.scss +17 -0
- package/src/components/TextInput.tsx +19 -0
- package/src/components/TextWrap/TextWrap.tsx +361 -0
- package/src/components/TextWrap/TextWrapUtils.ts +32 -0
- package/src/components/closeButton/CloseButton.scss +40 -0
- package/src/components/closeButton/CloseButton.tsx +27 -0
- package/src/components/index.ts +70 -0
- package/src/components/loadingIndicator/LoadingIndicator.scss +40 -0
- package/src/components/loadingIndicator/LoadingIndicator.tsx +28 -0
- package/src/components/markdown/remarkPlainLinks.ts +36 -0
- package/src/components/reactUtil.ts +20 -0
- package/src/components/stubs/CodeSnippet.tsx +19 -0
- package/src/components/stubs/DataCitation.tsx +16 -0
- package/src/components/stubs/IndicatorKeyData.tsx +45 -0
- package/src/components/stubs/IndicatorProcessing.tsx +15 -0
- package/src/components/stubs/IndicatorSources.tsx +15 -0
- package/src/components/styles/colors.scss +113 -0
- package/src/components/styles/mixins.scss +630 -0
- package/src/components/styles/typography.scss +579 -0
- package/src/components/styles/util.scss +89 -0
- package/src/components/styles/variables.scss +208 -0
- package/src/config/ChartsConfig.ts +163 -0
- package/src/config/ChartsProvider.tsx +157 -0
- package/src/config/index.ts +20 -0
- package/src/core-table/CoreTable.ts +1355 -0
- package/src/core-table/CoreTableColumns.ts +973 -0
- package/src/core-table/CoreTableUtils.ts +793 -0
- package/src/core-table/ErrorValues.ts +73 -0
- package/src/core-table/OwidTable.ts +1175 -0
- package/src/core-table/OwidTableSynthesizers.ts +272 -0
- package/src/core-table/OwidTableUtil.ts +76 -0
- package/src/core-table/Transforms.ts +484 -0
- package/src/core-table/index.ts +82 -0
- package/src/explorer/ColumnGrammar.ts +217 -0
- package/src/explorer/Explorer.sample.ts +212 -0
- package/src/explorer/Explorer.scss +148 -0
- package/src/explorer/Explorer.tsx +1283 -0
- package/src/explorer/ExplorerConstants.ts +85 -0
- package/src/explorer/ExplorerControls.scss +156 -0
- package/src/explorer/ExplorerControls.tsx +210 -0
- package/src/explorer/ExplorerDecisionMatrix.ts +471 -0
- package/src/explorer/ExplorerGrammar.ts +161 -0
- package/src/explorer/ExplorerProgram.ts +568 -0
- package/src/explorer/ExplorerUtils.ts +59 -0
- package/src/explorer/GrapherGrammar.ts +387 -0
- package/src/explorer/gridLang/GrammarUtils.ts +121 -0
- package/src/explorer/gridLang/GridCell.ts +298 -0
- package/src/explorer/gridLang/GridLangConstants.ts +255 -0
- package/src/explorer/gridLang/GridProgram.ts +311 -0
- package/src/explorer/gridLang/readme.md +17 -0
- package/src/explorer/index.ts +69 -0
- package/src/explorer/readme.md +19 -0
- package/src/explorer/urlMigrations/CO2UrlMigration.ts +46 -0
- package/src/explorer/urlMigrations/CovidUrlMigration.ts +37 -0
- package/src/explorer/urlMigrations/EnergyUrlMigration.ts +41 -0
- package/src/explorer/urlMigrations/ExplorerPageUrlMigrationSpec.ts +12 -0
- package/src/explorer/urlMigrations/ExplorerUrlMigrationUtils.ts +45 -0
- package/src/explorer/urlMigrations/ExplorerUrlMigrations.ts +33 -0
- package/src/explorer/urlMigrations/LegacyCovidUrlMigration.ts +144 -0
- package/src/explorer/urlMigrations/readme.md +39 -0
- package/src/grapher/axis/Axis.ts +973 -0
- package/src/grapher/axis/AxisConfig.ts +179 -0
- package/src/grapher/axis/AxisViews.tsx +597 -0
- package/src/grapher/barCharts/DiscreteBarChart.tsx +728 -0
- package/src/grapher/barCharts/DiscreteBarChartConstants.ts +60 -0
- package/src/grapher/barCharts/DiscreteBarChartHelpers.ts +338 -0
- package/src/grapher/barCharts/DiscreteBarChartState.ts +354 -0
- package/src/grapher/barCharts/DiscreteBarChartThumbnail.tsx +34 -0
- package/src/grapher/captionedChart/CaptionedChart.scss +61 -0
- package/src/grapher/captionedChart/CaptionedChart.tsx +523 -0
- package/src/grapher/captionedChart/Logos.tsx +141 -0
- package/src/grapher/captionedChart/LogosSVG.tsx +16 -0
- package/src/grapher/captionedChart/StaticChartRasterizer.tsx +178 -0
- package/src/grapher/captionedChart/assets/buildcanada-logo-square.svg +15 -0
- package/src/grapher/captionedChart/assets/buildcanada-logo.svg +15 -0
- package/src/grapher/captionedChart/assets/canadaspends.svg +7 -0
- package/src/grapher/captionedChart/readme.md +14 -0
- package/src/grapher/chart/Chart.tsx +62 -0
- package/src/grapher/chart/ChartAreaContent.tsx +172 -0
- package/src/grapher/chart/ChartDimension.ts +121 -0
- package/src/grapher/chart/ChartInterface.ts +83 -0
- package/src/grapher/chart/ChartManager.ts +113 -0
- package/src/grapher/chart/ChartTabs.ts +178 -0
- package/src/grapher/chart/ChartTypeMap.tsx +158 -0
- package/src/grapher/chart/ChartTypeSwitcher.tsx +26 -0
- package/src/grapher/chart/ChartUtils.tsx +364 -0
- package/src/grapher/chart/DimensionSlot.ts +45 -0
- package/src/grapher/chart/StaticChartWrapper.tsx +94 -0
- package/src/grapher/chart/guidedChartUtils.ts +82 -0
- package/src/grapher/color/BinningStrategies.ts +484 -0
- package/src/grapher/color/BinningStrategyEqualSizeBins.ts +132 -0
- package/src/grapher/color/BinningStrategyLogarithmic.ts +121 -0
- package/src/grapher/color/CategoricalColorAssigner.ts +97 -0
- package/src/grapher/color/ColorBrewerSchemes.ts +80 -0
- package/src/grapher/color/ColorConstants.ts +20 -0
- package/src/grapher/color/ColorScale.ts +339 -0
- package/src/grapher/color/ColorScaleBin.ts +147 -0
- package/src/grapher/color/ColorScaleConfig.ts +204 -0
- package/src/grapher/color/ColorScheme.ts +137 -0
- package/src/grapher/color/ColorSchemes.ts +149 -0
- package/src/grapher/color/ColorUtils.ts +86 -0
- package/src/grapher/color/CustomSchemes.ts +1772 -0
- package/src/grapher/color/readme.md +84 -0
- package/src/grapher/comparisonLine/ComparisonLine.tsx +31 -0
- package/src/grapher/comparisonLine/ComparisonLineConstants.ts +11 -0
- package/src/grapher/comparisonLine/ComparisonLineGenerator.ts +60 -0
- package/src/grapher/comparisonLine/ComparisonLineHelpers.ts +10 -0
- package/src/grapher/comparisonLine/CustomComparisonLine.tsx +159 -0
- package/src/grapher/comparisonLine/VerticalComparisonLine.tsx +208 -0
- package/src/grapher/controls/ActionButtons.scss +97 -0
- package/src/grapher/controls/ActionButtons.tsx +453 -0
- package/src/grapher/controls/CommandPalette.scss +50 -0
- package/src/grapher/controls/CommandPalette.tsx +74 -0
- package/src/grapher/controls/ContentSwitchers.scss +93 -0
- package/src/grapher/controls/ContentSwitchers.tsx +238 -0
- package/src/grapher/controls/Controls.scss +158 -0
- package/src/grapher/controls/DataTableFilterDropdown.scss +7 -0
- package/src/grapher/controls/DataTableFilterDropdown.tsx +168 -0
- package/src/grapher/controls/DataTableSearchField.scss +3 -0
- package/src/grapher/controls/DataTableSearchField.tsx +76 -0
- package/src/grapher/controls/Dropdown.scss +252 -0
- package/src/grapher/controls/Dropdown.tsx +235 -0
- package/src/grapher/controls/EntitySelectionToggle.tsx +135 -0
- package/src/grapher/controls/MapRegionDropdown.scss +3 -0
- package/src/grapher/controls/MapRegionDropdown.tsx +104 -0
- package/src/grapher/controls/MapResetButton.tsx +115 -0
- package/src/grapher/controls/MapZoomDropdown.scss +9 -0
- package/src/grapher/controls/MapZoomDropdown.tsx +270 -0
- package/src/grapher/controls/MapZoomToSelectionButton.tsx +87 -0
- package/src/grapher/controls/SearchField.scss +78 -0
- package/src/grapher/controls/SearchField.tsx +63 -0
- package/src/grapher/controls/SettingsMenu.scss +191 -0
- package/src/grapher/controls/SettingsMenu.tsx +399 -0
- package/src/grapher/controls/ShareMenu.scss +58 -0
- package/src/grapher/controls/ShareMenu.tsx +304 -0
- package/src/grapher/controls/SortIcon.tsx +39 -0
- package/src/grapher/controls/VerticalScrollContainer.tsx +263 -0
- package/src/grapher/controls/controlsRow/ControlsRow.tsx +168 -0
- package/src/grapher/controls/dropdown-icons.scss +4 -0
- package/src/grapher/controls/entityPicker/EntityPicker.scss +255 -0
- package/src/grapher/controls/entityPicker/EntityPicker.tsx +816 -0
- package/src/grapher/controls/entityPicker/EntityPickerConstants.ts +23 -0
- package/src/grapher/controls/globalEntitySelector/GlobalEntitySelector.scss +129 -0
- package/src/grapher/controls/globalEntitySelector/GlobalEntitySelector.tsx +463 -0
- package/src/grapher/controls/globalEntitySelector/GlobalEntitySelectorConstants.ts +3 -0
- package/src/grapher/controls/globalEntitySelector/readme.md +17 -0
- package/src/grapher/controls/settings/AbsRelToggle.tsx +64 -0
- package/src/grapher/controls/settings/AxisScaleToggle.tsx +53 -0
- package/src/grapher/controls/settings/FacetStrategySelector.tsx +110 -0
- package/src/grapher/controls/settings/FacetYDomainToggle.tsx +51 -0
- package/src/grapher/controls/settings/NoDataAreaToggle.tsx +38 -0
- package/src/grapher/controls/settings/ZoomToggle.tsx +36 -0
- package/src/grapher/core/EntitiesByRegionType.ts +174 -0
- package/src/grapher/core/EntityCodes.ts +19 -0
- package/src/grapher/core/EntityUrlBuilder.ts +200 -0
- package/src/grapher/core/FetchingGrapher.tsx +156 -0
- package/src/grapher/core/Grapher.tsx +760 -0
- package/src/grapher/core/GrapherAnalytics.ts +229 -0
- package/src/grapher/core/GrapherConstants.ts +173 -0
- package/src/grapher/core/GrapherState.tsx +3659 -0
- package/src/grapher/core/GrapherUrl.ts +184 -0
- package/src/grapher/core/GrapherUrlMigrations.ts +29 -0
- package/src/grapher/core/GrapherUseHelpers.tsx +147 -0
- package/src/grapher/core/LegacyToOwidTable.ts +841 -0
- package/src/grapher/core/grapher.entry.ts +5 -0
- package/src/grapher/core/grapher.scss +257 -0
- package/src/grapher/core/loadGrapherTableHelpers.ts +116 -0
- package/src/grapher/core/loadVariable.ts +104 -0
- package/src/grapher/core/relatedQuestion.ts +12 -0
- package/src/grapher/core/typography.scss +206 -0
- package/src/grapher/dataTable/DataTable.sample.ts +206 -0
- package/src/grapher/dataTable/DataTable.scss +249 -0
- package/src/grapher/dataTable/DataTable.tsx +1332 -0
- package/src/grapher/dataTable/DataTableConstants.ts +186 -0
- package/src/grapher/entitySelector/EntitySelector.scss +255 -0
- package/src/grapher/entitySelector/EntitySelector.tsx +1838 -0
- package/src/grapher/facet/FacetChart.tsx +943 -0
- package/src/grapher/facet/FacetChartConstants.ts +24 -0
- package/src/grapher/facet/FacetChartUtils.ts +51 -0
- package/src/grapher/facet/FacetMap.tsx +604 -0
- package/src/grapher/facet/FacetMapConstants.ts +23 -0
- package/src/grapher/facet/readme.md +13 -0
- package/src/grapher/focus/FocusArray.ts +79 -0
- package/src/grapher/footer/Footer.scss +63 -0
- package/src/grapher/footer/Footer.tsx +809 -0
- package/src/grapher/footer/FooterManager.ts +44 -0
- package/src/grapher/fullScreen/FullScreen.scss +11 -0
- package/src/grapher/fullScreen/FullScreen.tsx +61 -0
- package/src/grapher/header/Header.scss +35 -0
- package/src/grapher/header/Header.tsx +372 -0
- package/src/grapher/header/HeaderManager.ts +28 -0
- package/src/grapher/index.ts +157 -0
- package/src/grapher/interaction/InteractionState.ts +60 -0
- package/src/grapher/legend/HorizontalColorLegends.tsx +923 -0
- package/src/grapher/legend/LegendInteractionState.ts +40 -0
- package/src/grapher/legend/VerticalColorLegend.tsx +295 -0
- package/src/grapher/lineCharts/LineChart.tsx +968 -0
- package/src/grapher/lineCharts/LineChartConstants.ts +89 -0
- package/src/grapher/lineCharts/LineChartHelpers.ts +184 -0
- package/src/grapher/lineCharts/LineChartState.ts +394 -0
- package/src/grapher/lineCharts/LineChartThumbnail.tsx +437 -0
- package/src/grapher/lineCharts/Lines.tsx +258 -0
- package/src/grapher/lineLegend/LineLegend.tsx +723 -0
- package/src/grapher/lineLegend/LineLegendConstants.ts +9 -0
- package/src/grapher/lineLegend/LineLegendFilterAlgorithms.ts +143 -0
- package/src/grapher/lineLegend/LineLegendHelpers.ts +253 -0
- package/src/grapher/lineLegend/LineLegendTypes.ts +32 -0
- package/src/grapher/mapCharts/CanadaTopology.ts +17922 -0
- package/src/grapher/mapCharts/ChoroplethGlobe.tsx +949 -0
- package/src/grapher/mapCharts/ChoroplethMap.tsx +662 -0
- package/src/grapher/mapCharts/GeoFeatures.ts +184 -0
- package/src/grapher/mapCharts/GlobeController.ts +496 -0
- package/src/grapher/mapCharts/MapAnnotationPlacements.json +1040 -0
- package/src/grapher/mapCharts/MapAnnotationPlacements.ts +31 -0
- package/src/grapher/mapCharts/MapAnnotations.ts +723 -0
- package/src/grapher/mapCharts/MapChart.sample.ts +59 -0
- package/src/grapher/mapCharts/MapChart.scss +5 -0
- package/src/grapher/mapCharts/MapChart.tsx +720 -0
- package/src/grapher/mapCharts/MapChartConstants.ts +260 -0
- package/src/grapher/mapCharts/MapChartState.ts +416 -0
- package/src/grapher/mapCharts/MapChartThumbnail.tsx +25 -0
- package/src/grapher/mapCharts/MapComponents.tsx +338 -0
- package/src/grapher/mapCharts/MapConfig.ts +156 -0
- package/src/grapher/mapCharts/MapHelpers.ts +181 -0
- package/src/grapher/mapCharts/MapProjections.ts +49 -0
- package/src/grapher/mapCharts/MapSparkline.tsx +257 -0
- package/src/grapher/mapCharts/MapTooltip.scss +49 -0
- package/src/grapher/mapCharts/MapTooltip.tsx +409 -0
- package/src/grapher/mapCharts/MapTopology.ts +1766 -0
- package/src/grapher/mapCharts/d3-bboxCollide.js +204 -0
- package/src/grapher/mapCharts/d3-geo-projection.ts +198 -0
- package/src/grapher/modal/DownloadIcons.tsx +39 -0
- package/src/grapher/modal/DownloadModal.scss +300 -0
- package/src/grapher/modal/DownloadModal.tsx +1226 -0
- package/src/grapher/modal/EmbedModal.scss +40 -0
- package/src/grapher/modal/EmbedModal.tsx +160 -0
- package/src/grapher/modal/EntitySelectorModal.tsx +59 -0
- package/src/grapher/modal/Modal.scss +31 -0
- package/src/grapher/modal/Modal.tsx +90 -0
- package/src/grapher/modal/ModalHeader.scss +12 -0
- package/src/grapher/modal/ModalHeader.tsx +16 -0
- package/src/grapher/modal/SourcesDescriptions.scss +87 -0
- package/src/grapher/modal/SourcesDescriptions.tsx +89 -0
- package/src/grapher/modal/SourcesKeyDataTable.scss +49 -0
- package/src/grapher/modal/SourcesKeyDataTable.tsx +87 -0
- package/src/grapher/modal/SourcesModal.scss +301 -0
- package/src/grapher/modal/SourcesModal.tsx +568 -0
- package/src/grapher/noDataModal/NoDataModal.tsx +125 -0
- package/src/grapher/scatterCharts/ConnectedScatterLegend.tsx +143 -0
- package/src/grapher/scatterCharts/MultiColorPolyline.tsx +129 -0
- package/src/grapher/scatterCharts/NoDataSection.scss +14 -0
- package/src/grapher/scatterCharts/NoDataSection.tsx +56 -0
- package/src/grapher/scatterCharts/ScatterPlotChart.tsx +792 -0
- package/src/grapher/scatterCharts/ScatterPlotChartConstants.ts +157 -0
- package/src/grapher/scatterCharts/ScatterPlotChartState.ts +678 -0
- package/src/grapher/scatterCharts/ScatterPlotChartThumbnail.tsx +155 -0
- package/src/grapher/scatterCharts/ScatterPlotTooltip.tsx +560 -0
- package/src/grapher/scatterCharts/ScatterPoints.tsx +153 -0
- package/src/grapher/scatterCharts/ScatterPointsWithLabels.tsx +708 -0
- package/src/grapher/scatterCharts/ScatterSizeLegend.tsx +327 -0
- package/src/grapher/scatterCharts/ScatterUtils.ts +265 -0
- package/src/grapher/scatterCharts/Triangle.tsx +41 -0
- package/src/grapher/schema/README.md +33 -0
- package/src/grapher/schema/defaultGrapherConfig.ts +100 -0
- package/src/grapher/schema/grapher-schema.009.yaml +781 -0
- package/src/grapher/schema/migrations/helpers.ts +58 -0
- package/src/grapher/schema/migrations/migrate.ts +75 -0
- package/src/grapher/schema/migrations/migrations.ts +158 -0
- package/src/grapher/selection/MapSelectionArray.ts +99 -0
- package/src/grapher/selection/SelectionArray.ts +71 -0
- package/src/grapher/selection/readme.md +16 -0
- package/src/grapher/sidePanel/SidePanel.scss +10 -0
- package/src/grapher/sidePanel/SidePanel.tsx +23 -0
- package/src/grapher/slideInDrawer/SlideInDrawer.scss +57 -0
- package/src/grapher/slideInDrawer/SlideInDrawer.tsx +125 -0
- package/src/grapher/slideshowController/SlideShowController.tsx +43 -0
- package/src/grapher/slideshowController/readme.md +7 -0
- package/src/grapher/slopeCharts/MarkX.tsx +45 -0
- package/src/grapher/slopeCharts/Slope.tsx +102 -0
- package/src/grapher/slopeCharts/SlopeChart.tsx +1152 -0
- package/src/grapher/slopeCharts/SlopeChartConstants.ts +33 -0
- package/src/grapher/slopeCharts/SlopeChartHelpers.ts +73 -0
- package/src/grapher/slopeCharts/SlopeChartState.ts +392 -0
- package/src/grapher/slopeCharts/SlopeChartThumbnail.tsx +368 -0
- package/src/grapher/stackedCharts/AbstractStackedChartState.ts +370 -0
- package/src/grapher/stackedCharts/MarimekkoBars.tsx +190 -0
- package/src/grapher/stackedCharts/MarimekkoBarsForOneEntity.tsx +168 -0
- package/src/grapher/stackedCharts/MarimekkoChart.tsx +1144 -0
- package/src/grapher/stackedCharts/MarimekkoChartConstants.ts +112 -0
- package/src/grapher/stackedCharts/MarimekkoChartHelpers.ts +21 -0
- package/src/grapher/stackedCharts/MarimekkoChartState.ts +465 -0
- package/src/grapher/stackedCharts/MarimekkoChartThumbnail.tsx +168 -0
- package/src/grapher/stackedCharts/MarimekkoInternalLabels.tsx +124 -0
- package/src/grapher/stackedCharts/StackedAreaChart.tsx +678 -0
- package/src/grapher/stackedCharts/StackedAreaChartState.ts +34 -0
- package/src/grapher/stackedCharts/StackedAreaChartThumbnail.tsx +215 -0
- package/src/grapher/stackedCharts/StackedAreas.tsx +223 -0
- package/src/grapher/stackedCharts/StackedBarChart.tsx +619 -0
- package/src/grapher/stackedCharts/StackedBarChartState.ts +80 -0
- package/src/grapher/stackedCharts/StackedBarChartThumbnail.tsx +220 -0
- package/src/grapher/stackedCharts/StackedBarSegment.tsx +87 -0
- package/src/grapher/stackedCharts/StackedBars.tsx +102 -0
- package/src/grapher/stackedCharts/StackedConstants.ts +109 -0
- package/src/grapher/stackedCharts/StackedDiscreteBarChart.tsx +270 -0
- package/src/grapher/stackedCharts/StackedDiscreteBarChartState.ts +296 -0
- package/src/grapher/stackedCharts/StackedDiscreteBarChartThumbnail.tsx +27 -0
- package/src/grapher/stackedCharts/StackedDiscreteBars.tsx +648 -0
- package/src/grapher/stackedCharts/StackedUtils.ts +142 -0
- package/src/grapher/tabs/Tabs.scss +169 -0
- package/src/grapher/tabs/Tabs.tsx +54 -0
- package/src/grapher/tabs/TabsWithDropdown.scss +62 -0
- package/src/grapher/tabs/TabsWithDropdown.tsx +114 -0
- package/src/grapher/testData/OwidTestData.sample.ts +273 -0
- package/src/grapher/testData/OwidTestData.ts +64 -0
- package/src/grapher/timeline/TimelineComponent.scss +139 -0
- package/src/grapher/timeline/TimelineComponent.tsx +658 -0
- package/src/grapher/timeline/TimelineController.ts +368 -0
- package/src/grapher/timeline/readme.md +7 -0
- package/src/grapher/tooltip/Tooltip.scss +510 -0
- package/src/grapher/tooltip/Tooltip.tsx +294 -0
- package/src/grapher/tooltip/TooltipContents.tsx +383 -0
- package/src/grapher/tooltip/TooltipProps.ts +123 -0
- package/src/grapher/tooltip/TooltipState.ts +81 -0
- package/src/grapher/verticalLabels/VerticalLabels.tsx +31 -0
- package/src/grapher/verticalLabels/VerticalLabelsState.ts +154 -0
- package/src/index.ts +226 -0
- package/src/styles/charts.scss +15 -0
- package/src/types/NominalType.ts +30 -0
- package/src/types/OwidOrigin.ts +18 -0
- package/src/types/OwidSource.ts +9 -0
- package/src/types/OwidVariable.ts +133 -0
- package/src/types/OwidVariableDisplayConfigInterface.ts +49 -0
- package/src/types/analyticsTypes.ts +54 -0
- package/src/types/dbTypes/Tags.ts +11 -0
- package/src/types/domainTypes/Archive.ts +139 -0
- package/src/types/domainTypes/Author.ts +28 -0
- package/src/types/domainTypes/ContentGraph.ts +76 -0
- package/src/types/domainTypes/CoreTableTypes.ts +305 -0
- package/src/types/domainTypes/DeployStatus.ts +23 -0
- package/src/types/domainTypes/Layout.ts +34 -0
- package/src/types/domainTypes/Posts.ts +34 -0
- package/src/types/domainTypes/Search.ts +299 -0
- package/src/types/domainTypes/Site.ts +8 -0
- package/src/types/domainTypes/StaticViz.ts +64 -0
- package/src/types/domainTypes/Toc.ts +11 -0
- package/src/types/domainTypes/Tombstone.ts +19 -0
- package/src/types/domainTypes/Various.ts +79 -0
- package/src/types/gdocTypes/Gdoc.ts +280 -0
- package/src/types/grapherTypes/BinningStrategyTypes.ts +46 -0
- package/src/types/grapherTypes/GrapherConstants.ts +53 -0
- package/src/types/grapherTypes/GrapherTypes.ts +743 -0
- package/src/types/index.ts +316 -0
- package/src/types/wordpressTypes/WordpressTypes.ts +9 -0
- package/src/utils/Bounds.ts +439 -0
- package/src/utils/BrowserUtils.ts +12 -0
- package/src/utils/FuzzySearch.ts +74 -0
- package/src/utils/MultiDimDataPageConfig.ts +31 -0
- package/src/utils/OwidVariable.ts +82 -0
- package/src/utils/PointVector.ts +97 -0
- package/src/utils/PromiseCache.ts +36 -0
- package/src/utils/PromiseSwitcher.ts +52 -0
- package/src/utils/TimeBounds.ts +130 -0
- package/src/utils/Tippy.tsx +57 -0
- package/src/utils/Util.ts +2369 -0
- package/src/utils/archival/archivalDate.ts +48 -0
- package/src/utils/dayjs.ts +32 -0
- package/src/utils/formatValue.ts +242 -0
- package/src/utils/grapherConfigUtils.ts +81 -0
- package/src/utils/image.ts +225 -0
- package/src/utils/index.ts +318 -0
- package/src/utils/isPresent.ts +5 -0
- package/src/utils/metadataHelpers.ts +329 -0
- package/src/utils/persistable/Persistable.ts +82 -0
- package/src/utils/persistable/readme.md +50 -0
- package/src/utils/regions.json +5635 -0
- package/src/utils/regions.ts +463 -0
- package/src/utils/serializers.ts +16 -0
- package/src/utils/string.ts +42 -0
- package/src/utils/urls/Url.ts +195 -0
- package/src/utils/urls/UrlMigration.ts +10 -0
- package/src/utils/urls/UrlUtils.ts +54 -0
- 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
|
+
}
|