Skip to content

Commit

Permalink
Merge pull request #309 from visualize-admin/fix/discrete-color-scale…
Browse files Browse the repository at this point in the history
…-for-maps
  • Loading branch information
ptbrowne authored Feb 8, 2022
2 parents 4dccb87 + 944da19 commit 1fc33ec
Show file tree
Hide file tree
Showing 15 changed files with 166 additions and 171 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Features

- Page have improved titles now, depending on where you are on the application. Helpful when you have
multiple tabs with visualize.admin or when you bookmark things. [#331](https://github.com/visualize-admin/visualization-tool/pull/331)
- Theme and organization navigation counts take into account the search field now. [#329](https://github.com/visualize-admin/visualization-tool/pull/329)
- Added rivers and lakes through vector layer [#309](https://github.com/visualize-admin/visualization-tool/pull/309)

### Bugs

- Fix selection of optional date filter [#332](https://github.com/visualize-admin/visualization-tool/pull/332)
- Fix discrete color scales with less than 3 observations [#309](https://github.com/visualize-admin/visualization-tool/pull/309)]

## [3.3.0] - 2022-02-07

Expand Down
2 changes: 1 addition & 1 deletion app/charts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ export const getInitialConfig = ({
},
baseLayer: {
showRelief: true,
showLakes: true,
showWater: true,
},
};

Expand Down
35 changes: 5 additions & 30 deletions app/charts/map/chart-map.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { geoCentroid } from "d3";
import React, { memo, useEffect, useMemo, useState } from "react";
import React, { memo, useMemo } from "react";
import { Box } from "theme-ui";
import {
feature as topojsonFeature,
Expand Down Expand Up @@ -32,11 +32,6 @@ import { MapLegend } from "./map-legend";
import { MapChart } from "./map-state";
import { MapTooltip } from "./map-tooltip";

type GeoDataState =
| { state: "fetching" }
| { state: "error" }
| (GeoData & { state: "loaded" });

export const ChartMapVisualization = ({
dataSetIri,
chartConfig,
Expand All @@ -46,7 +41,6 @@ export const ChartMapVisualization = ({
chartConfig: MapConfig;
queryFilters: QueryFilters;
}) => {
const [geoData, setGeoData] = useState<GeoDataState>({ state: "fetching" });
const locale = useLocale();

const areaDimensionIri = chartConfig.fields.areaLayer.componentIri;
Expand Down Expand Up @@ -161,40 +155,21 @@ export const ChartMapVisualization = ({
}
}, [areaLayer, dimensions, observations, symbolDimensionIri, geoCoordinates]);

useEffect(() => {
const loadLakes = async () => {
try {
const res = await fetch(`/topojson/ch-2020.json`);
const topo = await res.json();
const lakes = topojsonFeature(
topo,
topo.objects.lakes
) as any as GeoJSON.FeatureCollection;

setGeoData({ state: "loaded", lakes });
} catch (e) {
setGeoData({ state: "error" });
}
};

loadLakes();
}, []);

if (measures && dimensions && observations && geoData.state === "loaded") {
if (measures && dimensions && observations) {
return (
<ChartMapPrototype
observations={observations}
features={{ ...geoData, areaLayer, symbolLayer }}
features={{ areaLayer, symbolLayer }}
fields={chartConfig.fields}
measures={measures}
dimensions={dimensions}
baseLayer={chartConfig.baseLayer}
geoShapes={geoShapes}
/>
);
} else if (geoData.state === "fetching" || fetching) {
} else if (fetching) {
return <Loading />;
} else if (geoData.state === "error" || error) {
} else if (error) {
return <LoadingDataError />;
} else {
return <NoDataHint />;
Expand Down
7 changes: 6 additions & 1 deletion app/charts/map/map-legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,15 @@ const makeAxis = (

export const MapLegend = () => {
const { areaLayer, symbolLayer } = useChartState() as MapState;
const showAreaLegend =
areaLayer.show &&
areaLayer.data.length >= 3 &&
(areaLayer.colorScaleInterpolationType === "linear" ||
areaLayer.colorScale.range().length >= 3);

return (
<Flex sx={{ minHeight: 100, flexWrap: "wrap" }}>
{areaLayer.show && (
{showAreaLegend && (
<Box sx={{ p: 4 }}>
{areaLayer.measureLabel && (
<Text
Expand Down
6 changes: 3 additions & 3 deletions app/charts/map/map-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export interface MapState {
bounds: Bounds;
features: GeoData;
showRelief: boolean;
showLakes: boolean;
showWater: boolean;
identicalLayerComponentIris: boolean;
areaLayer: {
data: Observation[];
Expand Down Expand Up @@ -118,7 +118,7 @@ const getColorScale = ({
case "jenks":
const ckMeansThresholds = ckmeans(
data.map((d) => getValue(d) ?? NaN),
nbClass
Math.min(nbClass, data.length)
).map((v) => v.pop() || 0);

return scaleThreshold<number, string>()
Expand Down Expand Up @@ -278,7 +278,7 @@ const useMapState = ({
features,
bounds,
showRelief: baseLayer.showRelief,
showLakes: baseLayer.showLakes,
showWater: baseLayer.showWater,
identicalLayerComponentIris,
areaLayer: {
data: areaData,
Expand Down
61 changes: 35 additions & 26 deletions app/charts/map/map.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MapController, WebMercatorViewport } from "@deck.gl/core";
import { TileLayer } from "@deck.gl/geo-layers";
import { MVTLayer, TileLayer } from "@deck.gl/geo-layers";
import { BitmapLayer, GeoJsonLayer, ScatterplotLayer } from "@deck.gl/layers";
import DeckGL from "@deck.gl/react";
import React, { useCallback, useMemo, useState } from "react";
Expand All @@ -21,12 +21,15 @@ type TileData = {
signal: { aborted: boolean };
};

const MIN_ZOOM = 3;
const MAX_ZOOM = 13;

const INITIAL_VIEW_STATE = {
latitude: 46.8182,
longitude: 8.2275,
zoom: 5,
maxZoom: 16,
minZoom: 2,
minZoom: MIN_ZOOM,
maxZoom: MAX_ZOOM,
pitch: 0,
bearing: 0,
};
Expand Down Expand Up @@ -94,7 +97,7 @@ const constrainZoom = (
export const MapComponent = () => {
const {
showRelief,
showLakes,
showWater,
features,
identicalLayerComponentIris,
areaLayer,
Expand Down Expand Up @@ -172,6 +175,7 @@ export const MapComponent = () => {
<ZoomButton iconName="minus" handleClick={zoomOut} />
</Box>
<DeckGL
mapStyle="https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"
viewState={viewState}
onViewStateChange={onViewStateChange}
onResize={onResize}
Expand All @@ -180,17 +184,17 @@ export const MapComponent = () => {
>
{showRelief && (
<TileLayer
getTileData={({ z, x, y }: TileData) =>
`https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.leichte-basiskarte_reliefschattierung/default/current/3857/${z}/${x}/${y}.png`
}
id="relief"
data="https://wmts.geo.admin.ch/1.0.0/ch.swisstopo.leichte-basiskarte_reliefschattierung/default/current/3857/{z}/{x}/{y}.png"
tileSize={256}
pickable={false}
minZoom={2}
maxZoom={16}
maxCacheSize={512}
minZoom={MIN_ZOOM}
maxZoom={MAX_ZOOM}
renderSubLayers={(props: { tile: TileData; data: $FixMe }) => {
const {
bbox: { west, south, east, north },
} = props.tile;

return [
new BitmapLayer(props, {
data: null,
Expand Down Expand Up @@ -248,7 +252,7 @@ export const MapComponent = () => {
if (observation) {
const value = areaLayer.getValue(observation);

if (value) {
if (value !== null) {
return areaLayer.getColor(value);
}
}
Expand All @@ -272,21 +276,26 @@ export const MapComponent = () => {
</>
)}

{showLakes && (
<GeoJsonLayer
id="lakes"
data={features.lakes}
pickable={false}
stroked={true}
filled={true}
extruded={false}
lineWidthMinPixels={0.5}
lineWidthMaxPixels={1}
getLineWidth={100}
getFillColor={[102, 175, 233]}
getLineColor={[255, 255, 255]}
/>
)}
<MVTLayer
id="water"
data={[
"https://vectortiles0.geo.admin.ch/tiles/ch.swisstopo.leichte-basiskarte.vt/v1.0.0/{z}/{x}/{y}.pbf",
"https://vectortiles1.geo.admin.ch/tiles/ch.swisstopo.leichte-basiskarte.vt/v1.0.0/{z}/{x}/{y}.pbf",
"https://vectortiles2.geo.admin.ch/tiles/ch.swisstopo.leichte-basiskarte.vt/v1.0.0/{z}/{x}/{y}.pbf",
"https://vectortiles3.geo.admin.ch/tiles/ch.swisstopo.leichte-basiskarte.vt/v1.0.0/{z}/{x}/{y}.pbf",
"https://vectortiles4.geo.admin.ch/tiles/ch.swisstopo.leichte-basiskarte.vt/v1.0.0/{z}/{x}/{y}.pbf",
]}
tileSize={256}
getLineColor={[255, 255, 255, 0]}
getFillColor={(d: any) => {
return showWater && d.properties.layerName === "water"
? [148, 198, 240]
: [148, 198, 240, 0];
}}
updateTriggers={{
getFillColor: [showWater],
}}
/>

{symbolLayer.show && (
<ScatterplotLayer
Expand Down
4 changes: 2 additions & 2 deletions app/configurator/components/chart-configurator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ const ChartFields = ({
icon="baseLayer"
label={<Trans id="chart.map.layers.base">Base Layer</Trans>}
active={
chartConfig.baseLayer.showLakes ||
chartConfig.baseLayer.showRelief
chartConfig.baseLayer.showRelief ||
chartConfig.baseLayer.showWater
}
/>
) : (
Expand Down
2 changes: 1 addition & 1 deletion app/configurator/config-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ export type MapSymbolLayer = t.TypeOf<typeof MapSymbolLayer>;

const BaseLayer = t.type({
showRelief: t.boolean,
showLakes: t.boolean,
showWater: t.boolean,
});
export type BaseLayer = t.TypeOf<typeof BaseLayer>;
const MapFields = t.type({
Expand Down
6 changes: 3 additions & 3 deletions app/configurator/map/map-chart-options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ export const BaseLayersSettings = memo(() => {
/>
<ChartOptionCheckboxField
label={t({
id: "chart.map.layers.base.show.lakes",
message: "Show lakes",
id: "chart.map.layers.base.show.water",
message: "Show lakes and rivers",
})}
field={null}
path="baseLayer.showLakes"
path="baseLayer.showWater"
/>
</ControlSectionContent>
</ControlSection>
Expand Down
1 change: 0 additions & 1 deletion app/domain/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export type SymbolLayer = {
};

export type GeoData = {
lakes: GeoJSON.FeatureCollection;
areaLayer?: AreaLayer;
symbolLayer?: SymbolLayer;
};
Expand Down
Loading

0 comments on commit 1fc33ec

Please sign in to comment.