@hackoregon/component-library
Version:
Official repo for Hack Oregon React component library
401 lines (377 loc) • 10.7 kB
JavaScript
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable no-nested-ternary */
import React from "react";
import { storiesOf } from "@storybook/react";
import {
withKnobs,
select,
object,
boolean,
number,
text
} from "@storybook/addon-knobs";
import { action } from "@storybook/addon-actions";
import { checkA11y } from "@storybook/addon-a11y";
import { scaleQuantize, extent } from "d3";
import { at } from "lodash";
import { BaseMap, MapOverlay, MapTooltip, DemoJSONLoader } from "../src";
import notes from "./mapOverlay.notes.md";
const GROUP_IDS = {
MARKER: "Design",
DATA: "Data",
CUSTOM: "Custom"
};
const opacityOptions = {
range: true,
min: 0,
max: 1,
step: 0.05
};
const strokeWidthOptions = {
range: true,
min: 0,
max: 200,
step: 1
};
const colorSchemeOptions = {
Thermal: [
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
Planet: [
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
Space: [
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
Earth: [
[],
[],
[],
[],
[],
[],
[],
[],
[]
],
Ocean: [
[],
[],
[],
[],
[],
[],
[],
[],
[]
]
};
const CIVIC_API_URL =
"http://service.civicpdx.org/disaster-resilience/api/DisasterNeighborhoodView/?format=json&limit=100";
export default () =>
storiesOf("Component Lib|Maps/Map Overlay", module)
.addDecorator(checkA11y)
.addDecorator(withKnobs)
.add(
"Standard",
() => {
const getFillColor = object(
"Fill Color:",
[],
GROUP_IDS.MARKER
);
const getLineColor = object(
"Stroke Color",
[],
GROUP_IDS.MARKER
);
const getLineWidth = number(
"Stroke Width",
1,
strokeWidthOptions,
GROUP_IDS.MARKER
);
const opacity = number(
"Opacity:",
0.9,
opacityOptions,
GROUP_IDS.MARKER
);
return (
<DemoJSONLoader urls={[CIVIC_API_URL]}>
{data => {
return (
<BaseMap>
<MapOverlay
data={data.results.features}
getFillColor={getFillColor}
getLineColor={getLineColor}
getLineWidth={getLineWidth}
opacity={opacity}
/>
</BaseMap>
);
}}
</DemoJSONLoader>
);
},
{ notes }
)
.add(
"Custom",
() => {
const getFillColor = object(
"Fill Color:",
[],
GROUP_IDS.MARKER
);
const getLineColor = object(
"Stroke Color",
[],
GROUP_IDS.MARKER
);
const getLineWidth = number(
"Stroke Width",
1,
strokeWidthOptions,
GROUP_IDS.MARKER
);
const opacity = number(
"Opacity:",
0.9,
opacityOptions,
GROUP_IDS.MARKER
);
const filled = boolean("Filled:", true, GROUP_IDS.CUSTOM);
const stroked = boolean("Stroked:", true, GROUP_IDS.CUSTOM);
const autoHighlight = boolean(
"Auto Highlight:",
true,
GROUP_IDS.CUSTOM
);
const highlightColor = object(
"Highlight Color:",
[],
GROUP_IDS.CUSTOM
);
const onLayerClick = info => action("Layer Clicked:")(info);
const fetchURL = text("Data API URL:", CIVIC_API_URL, GROUP_IDS.DATA);
return (
<DemoJSONLoader urls={[fetchURL]}>
{data => {
const featuresArrayPath = text(
"Features Array Path:",
"results.features",
GROUP_IDS.DATA
);
const featuresData = at(data, featuresArrayPath)[0];
return (
<BaseMap initialZoom={9.99} updateViewport={false}>
<MapOverlay
data={featuresData}
filled={filled}
getFillColor={getFillColor}
stroked={stroked}
getLineColor={getLineColor}
getLineWidth={getLineWidth}
opacity={opacity}
autoHighlight={autoHighlight}
highlightColor={highlightColor}
onLayerClick={onLayerClick}
/>
</BaseMap>
);
}}
</DemoJSONLoader>
);
},
{ notes }
)
.add(
"Example: Choropleth Map",
() => {
const colorOptions = {
Thermal: "Thermal",
Planet: "Planet",
Space: "Space",
Earth: "Earth",
Ocean: "Ocean"
};
const colorScheme = select(
"Fill Color:",
colorOptions,
colorOptions.Ocean,
GROUP_IDS.MARKER
);
const fetchURL = text("Data API URL:", CIVIC_API_URL, GROUP_IDS.DATA);
return (
<DemoJSONLoader urls={[fetchURL]}>
{data => {
const featuresArrayPath = text(
"Features Array Path:",
"results.features",
GROUP_IDS.DATA
);
const featuresData = at(data, featuresArrayPath)[0];
const polygonFieldName = text(
"Field Name - Polygons:",
"injuriestotal_day",
GROUP_IDS.DATA
);
const findDataMinMax = extent(featuresData, f =>
parseFloat(f.properties[polygonFieldName])
);
const colorScale = scaleQuantize()
.domain(findDataMinMax)
.range(colorSchemeOptions[colorScheme]);
return (
<BaseMap initialZoom={9.9} updateViewport={false}>
<MapOverlay
data={featuresData}
getFillColor={f =>
colorScale(f.properties[polygonFieldName])
}
/>
</BaseMap>
);
}}
</DemoJSONLoader>
);
},
{ notes }
)
.add(
"Example: Choropleth + Circle Map",
() => {
const opacity = number(
"Opacity:",
0.9,
opacityOptions,
GROUP_IDS.MARKER
);
const colorOptions = {
Thermal: "Thermal",
Planet: "Planet",
Space: "Space",
Earth: "Earth",
Ocean: "Ocean"
};
const colorScheme = select(
"Fill Color - Polygons:",
colorOptions,
colorOptions.Ocean,
GROUP_IDS.MARKER
);
const circleFillColor = object(
"Fill Color - Circles:",
[],
GROUP_IDS.MARKER
);
const radiusScaleKnob = number(
"Radius Scale:",
50,
{},
GROUP_IDS.MARKER
);
const radiusScale = radiusScaleKnob || 1;
const onLayerClick = info => action("Layer Clicked:")(info);
const fetchURL = text("Data API URL:", CIVIC_API_URL, GROUP_IDS.DATA);
return (
<DemoJSONLoader urls={[fetchURL]}>
{data => {
const featuresArrayPath = text(
"Features Array Path:",
"results.features",
GROUP_IDS.DATA
);
const featuresData = at(data, featuresArrayPath)[0];
const polygonFieldName = text(
"Field Name - Polygons:",
"casualtiestotal_day",
GROUP_IDS.DATA
);
const circleFieldName = text(
"Field Name - Circles:",
"casualtiestotal_night",
GROUP_IDS.DATA
);
const polygonMinMax = extent(featuresData, f =>
parseFloat(f.properties[polygonFieldName])
);
const polygonColorScale = scaleQuantize()
.domain(polygonMinMax)
.range(colorSchemeOptions[colorScheme]);
return (
<BaseMap initialZoom={9.99} updateViewport={false}>
<MapOverlay
data={featuresData}
opacity={opacity}
getFillColor={f => {
return f.geometry.type === "Point"
? circleFillColor
: f.geometry.type === "Polygon" ||
f.geometry.type === "MultiPolygon"
? polygonColorScale(f.properties[polygonFieldName])
: [0, 0, 0];
}}
radiusScale={radiusScale}
circleFieldName={circleFieldName}
onLayerClick={onLayerClick}
/>
</BaseMap>
);
}}
</DemoJSONLoader>
);
},
{ notes }
)
.add(
"Example: With Tooltip",
() => {
return (
<DemoJSONLoader urls={[CIVIC_API_URL]}>
{data => (
<BaseMap>
<MapOverlay
data={data.results.features}
getFillColor={[25, 183, 170]}
>
<MapTooltip
primaryName="Earthquake - Total Day Injuries"
primaryField="injuriestotal_day"
secondaryName="Earthquake - Total Night Injuries"
secondaryField="injuriestotal_night"
/>
</MapOverlay>
</BaseMap>
)}
</DemoJSONLoader>
);
},
{ notes }
);