@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,471 @@
|
|
|
1
|
+
import * as _ from "lodash-es"
|
|
2
|
+
import { observable, computed, action, makeObservable } from "mobx"
|
|
3
|
+
import {
|
|
4
|
+
queryParamsToStr,
|
|
5
|
+
differenceObj,
|
|
6
|
+
trimObject,
|
|
7
|
+
parseIntOrUndefined,
|
|
8
|
+
} from "../utils/index.js"
|
|
9
|
+
import { ColumnTypeNames, CoreRow } from "../types/index.js"
|
|
10
|
+
import {
|
|
11
|
+
CoreTable,
|
|
12
|
+
detectDelimiter,
|
|
13
|
+
parseDelimited,
|
|
14
|
+
isCellEmpty,
|
|
15
|
+
} from "../core-table/index.js"
|
|
16
|
+
import { GridBoolean } from "./gridLang/GridLangConstants.js"
|
|
17
|
+
import {
|
|
18
|
+
ChoiceMap,
|
|
19
|
+
ChoiceName,
|
|
20
|
+
ChoiceValue,
|
|
21
|
+
ExplorerChoice,
|
|
22
|
+
ExplorerChoiceOption,
|
|
23
|
+
ExplorerChoiceParams,
|
|
24
|
+
ExplorerControlType,
|
|
25
|
+
ExplorerControlTypeRegex,
|
|
26
|
+
} from "./ExplorerConstants.js"
|
|
27
|
+
import { trimAndParseObject } from "./ExplorerProgram.js"
|
|
28
|
+
import { GrapherGrammar } from "./GrapherGrammar.js"
|
|
29
|
+
|
|
30
|
+
function parseVariableIds(value: string): number[] {
|
|
31
|
+
return value
|
|
32
|
+
.split(" ")
|
|
33
|
+
.map((id) => parseInt(id, 10))
|
|
34
|
+
.filter((id) => !isNaN(id))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// todo: cleanup
|
|
38
|
+
const makeChoicesMap = (delimited: string) => {
|
|
39
|
+
const headerLine = delimited.split("\n")[0]
|
|
40
|
+
const map = new Map<ChoiceName, ExplorerControlType>()
|
|
41
|
+
headerLine
|
|
42
|
+
.split(detectDelimiter(headerLine))
|
|
43
|
+
.filter((name) => ExplorerControlTypeRegex.test(name))
|
|
44
|
+
.forEach((choiceNameAndType) => {
|
|
45
|
+
const words = choiceNameAndType.split(" ")
|
|
46
|
+
const [choiceName, choiceType] = [
|
|
47
|
+
words.slice(0, -1).join(" "),
|
|
48
|
+
words[words.length - 1],
|
|
49
|
+
]
|
|
50
|
+
map.set(choiceName as ChoiceName, choiceType as ExplorerControlType)
|
|
51
|
+
})
|
|
52
|
+
return map
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// This strips the "Dropdown" or "Checkbox" from "SomeChoice Dropdown" or "SomeChoice Checkbox"
|
|
56
|
+
const removeChoiceControlTypeInfo = (label: string) =>
|
|
57
|
+
label.replace(ExplorerControlTypeRegex, "")
|
|
58
|
+
|
|
59
|
+
const dropColumnTypes = (delimited: string): string => {
|
|
60
|
+
const rows = delimited.split("\n")
|
|
61
|
+
const delimiter = detectDelimiter(rows[0])
|
|
62
|
+
rows[0] = rows[0]
|
|
63
|
+
.split(delimiter)
|
|
64
|
+
.map(removeChoiceControlTypeInfo)
|
|
65
|
+
.join(delimiter)
|
|
66
|
+
return rows.join("\n")
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const makeCheckBoxOption = (
|
|
70
|
+
options: ExplorerChoiceOption[],
|
|
71
|
+
choiceName: string
|
|
72
|
+
) => {
|
|
73
|
+
const checked = options.some(
|
|
74
|
+
(option) => option.checked === true && option.value === GridBoolean.true
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
const available =
|
|
78
|
+
new Set(options.filter((opt) => opt.available).map((opt) => opt.label))
|
|
79
|
+
.size === 2
|
|
80
|
+
return [
|
|
81
|
+
{
|
|
82
|
+
label: choiceName,
|
|
83
|
+
checked,
|
|
84
|
+
value: GridBoolean.true,
|
|
85
|
+
available,
|
|
86
|
+
} as ExplorerChoiceOption,
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Takes the author's program and the user's current settings and returns an object for
|
|
91
|
+
// allow the user to navigate amongst charts.
|
|
92
|
+
export class DecisionMatrix {
|
|
93
|
+
table: CoreTable
|
|
94
|
+
currentParams: ExplorerChoiceParams = {}
|
|
95
|
+
constructor(delimited: string, hash = "") {
|
|
96
|
+
makeObservable(this, {
|
|
97
|
+
currentParams: observable,
|
|
98
|
+
selectedRow: observable,
|
|
99
|
+
})
|
|
100
|
+
this.choiceNameToControlTypeMap = makeChoicesMap(delimited)
|
|
101
|
+
this.table = new CoreTable(parseDelimited(dropColumnTypes(delimited)), [
|
|
102
|
+
// todo: remove col def?
|
|
103
|
+
{
|
|
104
|
+
slug: GrapherGrammar.grapherId.keyword,
|
|
105
|
+
type: ColumnTypeNames.Integer,
|
|
106
|
+
},
|
|
107
|
+
// yVariableIds, xVariableIds, etc. can either be an indicator ID or a catalog path.
|
|
108
|
+
// If the first row contains a numeric value, the column type is inferred to be
|
|
109
|
+
// numeric, and parsing may fail if subsequent rows contain non-numeric values.
|
|
110
|
+
// In addition, yVariableIds may also contain a space-separated list of multiple
|
|
111
|
+
// indicator IDs or catalog paths.
|
|
112
|
+
...DecisionMatrix.allColumnSlugsWithIndicatorIdsOrCatalogPaths.map(
|
|
113
|
+
(slug) => ({
|
|
114
|
+
slug,
|
|
115
|
+
type: ColumnTypeNames.String,
|
|
116
|
+
})
|
|
117
|
+
),
|
|
118
|
+
])
|
|
119
|
+
this.hash = hash
|
|
120
|
+
this.setValuesFromChoiceParams() // Initialize options
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
allDecisionsAsQueryParams(): ExplorerChoiceParams[] {
|
|
124
|
+
return this.table.rows.map((row) => {
|
|
125
|
+
const choiceParams: ExplorerChoiceParams = {}
|
|
126
|
+
this.choiceNames.forEach((name) => {
|
|
127
|
+
choiceParams[name] = row[name]
|
|
128
|
+
})
|
|
129
|
+
return choiceParams
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
get numRows() {
|
|
134
|
+
return this.table.numRows
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
get requiredGrapherIds() {
|
|
138
|
+
return this.table.get(GrapherGrammar.grapherId.keyword).uniqValues
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Unique variable IDs requiring partial Grapher config to be loaded.
|
|
143
|
+
* Extracts the first (primary) variable ID from the y-dimension of each
|
|
144
|
+
* decision matrix row.
|
|
145
|
+
*/
|
|
146
|
+
get requiredVariableIds() {
|
|
147
|
+
return _.uniq(
|
|
148
|
+
this.table
|
|
149
|
+
.get(GrapherGrammar.yVariableIds.keyword)
|
|
150
|
+
.values.map((value) => parseVariableIds(value))
|
|
151
|
+
.map((ids: number[]) => ids[0])
|
|
152
|
+
.filter(_.identity)
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** All variable IDs referenced in the explorer config */
|
|
157
|
+
get allVariableIds() {
|
|
158
|
+
return _.uniq(
|
|
159
|
+
DecisionMatrix.allColumnSlugsWithIndicatorIdsOrCatalogPaths.flatMap(
|
|
160
|
+
(slug) =>
|
|
161
|
+
this.table
|
|
162
|
+
.get(slug)
|
|
163
|
+
.values.flatMap((value) => parseVariableIds(value))
|
|
164
|
+
.filter(_.identity)
|
|
165
|
+
)
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private static allColumnSlugsWithIndicatorIdsOrCatalogPaths = [
|
|
170
|
+
GrapherGrammar.yVariableIds.keyword,
|
|
171
|
+
GrapherGrammar.xVariableId.keyword,
|
|
172
|
+
GrapherGrammar.colorVariableId.keyword,
|
|
173
|
+
GrapherGrammar.sizeVariableId.keyword,
|
|
174
|
+
GrapherGrammar.sortColumnSlug.keyword,
|
|
175
|
+
]
|
|
176
|
+
|
|
177
|
+
get allColumnsWithIndicatorIdsOrCatalogPaths() {
|
|
178
|
+
return this.table
|
|
179
|
+
.getColumns(
|
|
180
|
+
DecisionMatrix.allColumnSlugsWithIndicatorIdsOrCatalogPaths
|
|
181
|
+
)
|
|
182
|
+
.filter((col) => !col.isMissing)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
get requiredCatalogPaths(): Set<string> {
|
|
186
|
+
const allIndicators = this.allColumnsWithIndicatorIdsOrCatalogPaths
|
|
187
|
+
.flatMap((col) => col.uniqValues)
|
|
188
|
+
.flatMap((value) => value.split(" "))
|
|
189
|
+
.filter((value) => value !== "")
|
|
190
|
+
|
|
191
|
+
// Assume it's a catalog path if it doesn't look like a number
|
|
192
|
+
const catalogPaths = allIndicators.filter(
|
|
193
|
+
(indicator) => parseIntOrUndefined(indicator) === undefined
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
return new Set(catalogPaths)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// This is, basically, the inverse of `dropColumnTypes`.
|
|
200
|
+
// Turns a column named "Metric" back into "Metric Dropdown", for example.
|
|
201
|
+
get tableWithOriginalColumnNames() {
|
|
202
|
+
return this.table.renameColumns(
|
|
203
|
+
Object.fromEntries(
|
|
204
|
+
[...this.choiceNameToControlTypeMap.entries()].map(
|
|
205
|
+
([choiceName, controlType]) => {
|
|
206
|
+
return [choiceName, `${choiceName} ${controlType}`]
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
choiceNameToControlTypeMap: Map<ChoiceName, ExplorerControlType>
|
|
214
|
+
hash: string
|
|
215
|
+
|
|
216
|
+
toConstrainedOptions(): ExplorerChoiceParams {
|
|
217
|
+
const settings = { ...this.currentParams }
|
|
218
|
+
this.choiceNames.forEach((choiceName) => {
|
|
219
|
+
// check if the current choice is valid with the current settings
|
|
220
|
+
if (
|
|
221
|
+
this.isOptionAvailable(
|
|
222
|
+
choiceName,
|
|
223
|
+
settings[choiceName],
|
|
224
|
+
settings
|
|
225
|
+
)
|
|
226
|
+
) {
|
|
227
|
+
// do nothing - we can use settings[choiceName] as-is
|
|
228
|
+
}
|
|
229
|
+
// check if the default choice is valid with the current settings
|
|
230
|
+
else if (
|
|
231
|
+
this.defaultSettings[choiceName] !== undefined &&
|
|
232
|
+
this.isOptionAvailable(
|
|
233
|
+
choiceName,
|
|
234
|
+
this.defaultSettings[choiceName],
|
|
235
|
+
settings
|
|
236
|
+
)
|
|
237
|
+
) {
|
|
238
|
+
settings[choiceName] = this.defaultSettings[choiceName]
|
|
239
|
+
}
|
|
240
|
+
// if both are not valid, find the first valid option
|
|
241
|
+
else {
|
|
242
|
+
settings[choiceName] = this.firstAvailableOptionForChoice(
|
|
243
|
+
choiceName,
|
|
244
|
+
settings
|
|
245
|
+
)!
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
return settings
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
@computed
|
|
252
|
+
private get diffBetweenUserSettingsAndConstrained(): ExplorerChoiceParams {
|
|
253
|
+
return differenceObj(
|
|
254
|
+
this.toConstrainedOptions(),
|
|
255
|
+
this.currentParams
|
|
256
|
+
) as ExplorerChoiceParams
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@action.bound setValueCommand(choiceName: ChoiceName, value: ChoiceValue) {
|
|
260
|
+
this._setValue(choiceName, value)
|
|
261
|
+
const invalidState = this.diffBetweenUserSettingsAndConstrained
|
|
262
|
+
Object.keys(invalidState).forEach((key) => {
|
|
263
|
+
// If a user navigates to a state where an option previously selected is not available,
|
|
264
|
+
// then persist the new option, as long as it isn't the only one available.
|
|
265
|
+
//
|
|
266
|
+
// For example, if the user navigates from metric:Cases interval:Weekly, to
|
|
267
|
+
// metric:Vaccinations, if interval:Weekly is not available for Vaccinations but other
|
|
268
|
+
// (more than one) intervals are available, we will persist whichever we happen to end
|
|
269
|
+
// up on.
|
|
270
|
+
//
|
|
271
|
+
// But if the user navigates from metric:Cases perCapita:true, to
|
|
272
|
+
// metric:Share of positive tests, then the only available perCapita option is false,
|
|
273
|
+
// but it isn't persisted, because the user has no other options. It's non-sensical to
|
|
274
|
+
// ask for "Share of positive tests per capita", so qualitatively it's a different
|
|
275
|
+
// metric, and the perCapita can just be ignored.
|
|
276
|
+
//
|
|
277
|
+
// We assume in every case where the user has only a single option available (therefore
|
|
278
|
+
// has no choice) the option should not be persisted.
|
|
279
|
+
if (this.availableChoiceOptions[key].length > 1) {
|
|
280
|
+
this._setValue(key, invalidState[key])
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@action.bound private _setValue(
|
|
286
|
+
choiceName: ChoiceName,
|
|
287
|
+
value: ChoiceValue
|
|
288
|
+
) {
|
|
289
|
+
if (value === "") delete this.currentParams[choiceName]
|
|
290
|
+
else this.currentParams[choiceName] = value
|
|
291
|
+
this.selectedRow = trimAndParseObject(
|
|
292
|
+
this.table.rowsAt([this.selectedRowIndex])[0],
|
|
293
|
+
GrapherGrammar
|
|
294
|
+
)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
@action.bound setValuesFromChoiceParams(
|
|
298
|
+
choiceParams: ExplorerChoiceParams = {}
|
|
299
|
+
) {
|
|
300
|
+
this.choiceNames.forEach((choiceName) => {
|
|
301
|
+
const choiceValue =
|
|
302
|
+
choiceParams[choiceName] ?? this.defaultSettings[choiceName]
|
|
303
|
+
|
|
304
|
+
if (choiceValue === undefined)
|
|
305
|
+
this._setValue(
|
|
306
|
+
choiceName,
|
|
307
|
+
this.firstAvailableOptionForChoice(choiceName)!
|
|
308
|
+
)
|
|
309
|
+
else this._setValue(choiceName, choiceValue)
|
|
310
|
+
})
|
|
311
|
+
return this
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@computed private get choiceNames(): ChoiceName[] {
|
|
315
|
+
return Array.from(this.choiceNameToControlTypeMap.keys())
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
@computed private get allChoiceOptions(): ChoiceMap {
|
|
319
|
+
const choiceMap: ChoiceMap = {}
|
|
320
|
+
this.choiceNames.forEach((choiceName) => {
|
|
321
|
+
choiceMap[choiceName] = this.table
|
|
322
|
+
.get(choiceName)
|
|
323
|
+
.uniqValues.filter((cell) => !isCellEmpty(cell)) as string[]
|
|
324
|
+
})
|
|
325
|
+
return choiceMap
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
@computed get availableChoiceOptions(): ChoiceMap {
|
|
329
|
+
const result: ChoiceMap = {}
|
|
330
|
+
this.choiceNames.forEach((choiceName) => {
|
|
331
|
+
result[choiceName] = this.allChoiceOptions[choiceName].filter(
|
|
332
|
+
(option) => this.isOptionAvailable(choiceName, option)
|
|
333
|
+
)
|
|
334
|
+
})
|
|
335
|
+
return result
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
getChoiceParamsForRow(row: CoreRow): ExplorerChoiceParams {
|
|
339
|
+
const result: ExplorerChoiceParams = {}
|
|
340
|
+
this.choiceNames.forEach((choiceName) => {
|
|
341
|
+
result[choiceName] = row[choiceName]
|
|
342
|
+
})
|
|
343
|
+
return result
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
private firstAvailableOptionForChoice(
|
|
347
|
+
choiceName: ChoiceName,
|
|
348
|
+
currentState = this.currentParams
|
|
349
|
+
): ChoiceValue | undefined {
|
|
350
|
+
return this.allChoiceOptions[choiceName].find((option) =>
|
|
351
|
+
this.isOptionAvailable(choiceName, option, currentState)
|
|
352
|
+
)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Note: there is a rare bug in here + rowsWith when an author has a complex decision matrix. If the user vists a url
|
|
357
|
+
* with invalid options like Metric="Tests", Interval="Weekly", Aligned="false"
|
|
358
|
+
* we will return first match, which is B1, even though B2 is a better match.
|
|
359
|
+
*
|
|
360
|
+
* graphers
|
|
361
|
+
* title Metric Radio Interval Radio Aligned Checkbox
|
|
362
|
+
* A1 Cases Cumulative true
|
|
363
|
+
* A2 Cases Cumulative false
|
|
364
|
+
* A3 Cases Weekly false
|
|
365
|
+
*
|
|
366
|
+
* B1 Tests Cumulative true
|
|
367
|
+
* B2 Tests Cumulative false
|
|
368
|
+
*/
|
|
369
|
+
isOptionAvailable(
|
|
370
|
+
choiceName: ChoiceName,
|
|
371
|
+
option: ChoiceValue,
|
|
372
|
+
currentState = this.currentParams
|
|
373
|
+
) {
|
|
374
|
+
const query: ExplorerChoiceParams = {}
|
|
375
|
+
this.choiceNames
|
|
376
|
+
.slice(0, this.choiceNames.indexOf(choiceName))
|
|
377
|
+
.forEach((name) => {
|
|
378
|
+
query[name] = currentState[name]
|
|
379
|
+
})
|
|
380
|
+
query[choiceName] = option
|
|
381
|
+
return this.rowsWith(query, choiceName).length > 0
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
private rowsWith(query: ExplorerChoiceParams, choiceName?: ChoiceName) {
|
|
385
|
+
// We allow other options to be blank.
|
|
386
|
+
const modifiedQuery: any = {}
|
|
387
|
+
Object.keys(trimObject(query)).forEach((queryColumn) => {
|
|
388
|
+
if (queryColumn !== choiceName)
|
|
389
|
+
// Blanks are fine if we are not talking about the column of interest
|
|
390
|
+
modifiedQuery[queryColumn] = [query[queryColumn], ""]
|
|
391
|
+
else modifiedQuery[queryColumn] = query[queryColumn]
|
|
392
|
+
})
|
|
393
|
+
return this.table.findRows(modifiedQuery)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// The first row with defaultView column value of "true" determines the default view to use
|
|
397
|
+
get defaultSettings() {
|
|
398
|
+
const hits = this.rowsWith({
|
|
399
|
+
[GrapherGrammar.defaultView.keyword]: "true",
|
|
400
|
+
})
|
|
401
|
+
return hits[0] ?? {}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private get firstMatch() {
|
|
405
|
+
const query = this.toConstrainedOptions()
|
|
406
|
+
const hits = this.rowsWith(query)
|
|
407
|
+
return hits[0]
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
get selectedRowIndex(): number {
|
|
411
|
+
return this.firstMatch === undefined
|
|
412
|
+
? 0
|
|
413
|
+
: this.table.indexOf(this.firstMatch)
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
selectedRow: any = {}
|
|
417
|
+
|
|
418
|
+
private toControlOption(
|
|
419
|
+
choiceName: ChoiceName,
|
|
420
|
+
optionName: string,
|
|
421
|
+
currentValue: ChoiceValue,
|
|
422
|
+
constrainedOptions: ExplorerChoiceParams
|
|
423
|
+
): ExplorerChoiceOption {
|
|
424
|
+
const available = this.isOptionAvailable(
|
|
425
|
+
choiceName,
|
|
426
|
+
optionName,
|
|
427
|
+
constrainedOptions
|
|
428
|
+
)
|
|
429
|
+
return {
|
|
430
|
+
label: optionName,
|
|
431
|
+
value: optionName,
|
|
432
|
+
available,
|
|
433
|
+
checked: currentValue === optionName,
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
@computed get choicesWithAvailability(): ExplorerChoice[] {
|
|
438
|
+
const selectedRow = this.selectedRow
|
|
439
|
+
const constrainedOptions = this.toConstrainedOptions()
|
|
440
|
+
return this.choiceNames.map((title) => {
|
|
441
|
+
const value =
|
|
442
|
+
selectedRow[title] !== undefined
|
|
443
|
+
? selectedRow[title].toString()
|
|
444
|
+
: selectedRow[title]
|
|
445
|
+
const options = this.allChoiceOptions[title].map((optionName) =>
|
|
446
|
+
this.toControlOption(
|
|
447
|
+
title,
|
|
448
|
+
optionName,
|
|
449
|
+
value,
|
|
450
|
+
constrainedOptions
|
|
451
|
+
)
|
|
452
|
+
)
|
|
453
|
+
const type = this.choiceNameToControlTypeMap.get(title)!
|
|
454
|
+
|
|
455
|
+
return {
|
|
456
|
+
title,
|
|
457
|
+
displayTitle: title,
|
|
458
|
+
type,
|
|
459
|
+
value,
|
|
460
|
+
options:
|
|
461
|
+
type === ExplorerControlType.Checkbox
|
|
462
|
+
? makeCheckBoxOption(options, title)
|
|
463
|
+
: options,
|
|
464
|
+
}
|
|
465
|
+
})
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
toString() {
|
|
469
|
+
return queryParamsToStr(this.currentParams)
|
|
470
|
+
}
|
|
471
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { SubNavId } from "../types/index.js"
|
|
2
|
+
import {
|
|
3
|
+
CellDef,
|
|
4
|
+
BooleanCellDef,
|
|
5
|
+
SlugDeclarationCellDef,
|
|
6
|
+
StringCellDef,
|
|
7
|
+
UrlCellDef,
|
|
8
|
+
SubTableHeaderCellDef,
|
|
9
|
+
IntegerCellDef,
|
|
10
|
+
SlugsDeclarationCellDef,
|
|
11
|
+
Grammar,
|
|
12
|
+
EnumCellDef,
|
|
13
|
+
StringDeclarationDef,
|
|
14
|
+
} from "./gridLang/GridLangConstants.js"
|
|
15
|
+
import { GrapherGrammar } from "./GrapherGrammar.js"
|
|
16
|
+
import { ColumnGrammar } from "./ColumnGrammar.js"
|
|
17
|
+
|
|
18
|
+
const ExplorerFormControlCellDeff: CellDef = {
|
|
19
|
+
...StringDeclarationDef,
|
|
20
|
+
description: "A form input for the user.",
|
|
21
|
+
regex: /^.+ (Dropdown|Radio|Checkbox)$/,
|
|
22
|
+
requirementsDescription: `Must end with 'Dropdown', 'Radio', or 'Checkbox'`,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const ExplorerGrammar: Grammar = {
|
|
26
|
+
table: {
|
|
27
|
+
...UrlCellDef,
|
|
28
|
+
keyword: "table",
|
|
29
|
+
valuePlaceholder: "",
|
|
30
|
+
regex: new RegExp(`(${UrlCellDef.regex?.source ?? ""}|^[\\w -()]+$)`), // URL or OWID dataset name
|
|
31
|
+
description: "A link to a CSV or TSV or the name of an OWID dataset.",
|
|
32
|
+
positionalCellDefs: [
|
|
33
|
+
{
|
|
34
|
+
...SlugDeclarationCellDef,
|
|
35
|
+
description:
|
|
36
|
+
"If you have multiple tables, give each one a unique slug.",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
headerCellDef: {
|
|
40
|
+
...SlugDeclarationCellDef,
|
|
41
|
+
cssClass: "SubTableHeaderCellDef",
|
|
42
|
+
grammar: {},
|
|
43
|
+
catchAllCellDef: {
|
|
44
|
+
...SlugDeclarationCellDef,
|
|
45
|
+
description: "A column slug.",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
explorerTitle: {
|
|
50
|
+
...StringCellDef,
|
|
51
|
+
keyword: "explorerTitle",
|
|
52
|
+
valuePlaceholder: "Life Expectancy",
|
|
53
|
+
description:
|
|
54
|
+
"The title will appear in the top left corner of the Explorer.",
|
|
55
|
+
},
|
|
56
|
+
explorerSubtitle: {
|
|
57
|
+
...StringCellDef,
|
|
58
|
+
keyword: "explorerSubtitle",
|
|
59
|
+
valuePlaceholder: "All our data from various sources.",
|
|
60
|
+
description: "The subtitle will appear under the explorerTitle.",
|
|
61
|
+
},
|
|
62
|
+
columns: {
|
|
63
|
+
...SlugDeclarationCellDef,
|
|
64
|
+
keyword: "columns",
|
|
65
|
+
description:
|
|
66
|
+
"Include all your column definitions for one or multiple tables here. If you do not provide a column definition for every column in your table one will be generated for you by the machine (sometimes incorrectly).",
|
|
67
|
+
headerCellDef: {
|
|
68
|
+
...SubTableHeaderCellDef,
|
|
69
|
+
grammar: ColumnGrammar,
|
|
70
|
+
},
|
|
71
|
+
isHorizontalList: true,
|
|
72
|
+
},
|
|
73
|
+
graphers: {
|
|
74
|
+
...SlugDeclarationCellDef,
|
|
75
|
+
keyword: "graphers",
|
|
76
|
+
description: "The decision matrix for your Explorer goes here.",
|
|
77
|
+
headerCellDef: {
|
|
78
|
+
...SubTableHeaderCellDef,
|
|
79
|
+
grammar: GrapherGrammar,
|
|
80
|
+
catchAllCellDef: ExplorerFormControlCellDeff,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
googleSheet: {
|
|
84
|
+
...UrlCellDef,
|
|
85
|
+
keyword: "googleSheet",
|
|
86
|
+
valuePlaceholder: "https://docs.google.com/spreadsheets/d/1qeX...",
|
|
87
|
+
description:
|
|
88
|
+
"Create a Google Sheet, share it with the OWID Group, then put the link here.",
|
|
89
|
+
},
|
|
90
|
+
downloadDataLink: {
|
|
91
|
+
...UrlCellDef,
|
|
92
|
+
keyword: "downloadDataLink",
|
|
93
|
+
valuePlaceholder: "https://example.com/data.csv",
|
|
94
|
+
description:
|
|
95
|
+
"An optional URL for the download button in the Download tab. If blank, the Explorer will instead generate a CSV from the data it has available.",
|
|
96
|
+
},
|
|
97
|
+
isPublished: {
|
|
98
|
+
...BooleanCellDef,
|
|
99
|
+
keyword: "isPublished",
|
|
100
|
+
description: "Set to true to make this Explorer public.",
|
|
101
|
+
},
|
|
102
|
+
wpBlockId: {
|
|
103
|
+
...IntegerCellDef,
|
|
104
|
+
keyword: "wpBlockId",
|
|
105
|
+
description:
|
|
106
|
+
"If present will show the matching Wordpress block ID beneath the Explorer.",
|
|
107
|
+
},
|
|
108
|
+
hideControls: {
|
|
109
|
+
...BooleanCellDef,
|
|
110
|
+
keyword: "hideControls",
|
|
111
|
+
description: "Whether to hide the controls. Default is false.",
|
|
112
|
+
},
|
|
113
|
+
subNavId: {
|
|
114
|
+
...EnumCellDef,
|
|
115
|
+
terminalOptions: Object.values(SubNavId).map((keyword) => ({
|
|
116
|
+
keyword,
|
|
117
|
+
description: "",
|
|
118
|
+
cssClass: "",
|
|
119
|
+
})),
|
|
120
|
+
keyword: "subNavId",
|
|
121
|
+
description: "A subnav to show, if any.",
|
|
122
|
+
},
|
|
123
|
+
subNavCurrentId: {
|
|
124
|
+
// todo: add options here
|
|
125
|
+
...EnumCellDef,
|
|
126
|
+
keyword: "subNavCurrentId",
|
|
127
|
+
description: "The current page in the subnav.",
|
|
128
|
+
},
|
|
129
|
+
thumbnail: {
|
|
130
|
+
...UrlCellDef,
|
|
131
|
+
keyword: "thumbnail",
|
|
132
|
+
description: "URL to the social sharing thumbnail.",
|
|
133
|
+
},
|
|
134
|
+
selection: {
|
|
135
|
+
...StringCellDef,
|
|
136
|
+
keyword: "selection",
|
|
137
|
+
valuePlaceholder: "Canada",
|
|
138
|
+
description: "The default selected entities.",
|
|
139
|
+
isHorizontalList: true,
|
|
140
|
+
},
|
|
141
|
+
entityType: {
|
|
142
|
+
...StringCellDef,
|
|
143
|
+
keyword: "entityType",
|
|
144
|
+
valuePlaceholder: "region",
|
|
145
|
+
description:
|
|
146
|
+
"Default is 'country or region', but you can specify a different one such as 'state' or 'region'.",
|
|
147
|
+
},
|
|
148
|
+
pickerColumnSlugs: {
|
|
149
|
+
...SlugsDeclarationCellDef,
|
|
150
|
+
keyword: "pickerColumnSlugs",
|
|
151
|
+
valuePlaceholder: "gdp population gdp_per_capita",
|
|
152
|
+
description:
|
|
153
|
+
"You can manually set the column slug(s) to show in the entity picker or else they will be automatically chosen.",
|
|
154
|
+
},
|
|
155
|
+
hideAlertBanner: {
|
|
156
|
+
...BooleanCellDef,
|
|
157
|
+
keyword: "hideAlertBanner",
|
|
158
|
+
description: "Set to true to hide the alert banner.",
|
|
159
|
+
},
|
|
160
|
+
...GrapherGrammar,
|
|
161
|
+
} as const
|