diff --git a/spotlight-client/src/VizSentenceTypeByLocation/SentenceTypeChart.tsx b/spotlight-client/src/VizSentenceTypeByLocation/SentenceTypeChart.tsx index 52d0be6b..ccd17372 100644 --- a/spotlight-client/src/VizSentenceTypeByLocation/SentenceTypeChart.tsx +++ b/spotlight-client/src/VizSentenceTypeByLocation/SentenceTypeChart.tsx @@ -28,20 +28,22 @@ import { formatAsNumber } from "../utils"; import MeasureWidth from "../MeasureWidth"; import { animation, colors, typefaces } from "../UiLibrary"; +export const CHART_HEIGHT = 500; +export const CHART_BOTTOM_PADDING = 80; const MARGIN = { top: 10, bottom: 10, left: 140 }; /** * Adjust right margin based on label length */ const getRightMargin = scaleLinear().domain([5, 15]).range([60, 140]); -const MIN_WIDTH = 600; const NODE_WIDTH = 72; const ChartWrapper = styled.figure` /* labels have a tendency to overflow the bottom of this container; - this padding should ensure they have enough space to do so + this padding should ensure they have enough space to do so. + (px rather than rem for consistency with Semiotic) */ - padding-bottom: ${rem(80)}; + padding-bottom: ${CHART_BOTTOM_PADDING}px; position: relative; width: 100%; `; @@ -253,7 +255,7 @@ export default function SingleStepSankey({ sourceColors[d.id as $Keys] || targetColor, })} - size={[Math.max(width, MIN_WIDTH), 500]} + size={[width, CHART_HEIGHT]} /> )} diff --git a/spotlight-client/src/VizSentenceTypeByLocation/VizSentenceTypeByLocation.tsx b/spotlight-client/src/VizSentenceTypeByLocation/VizSentenceTypeByLocation.tsx index 32af4aec..e0397633 100644 --- a/spotlight-client/src/VizSentenceTypeByLocation/VizSentenceTypeByLocation.tsx +++ b/spotlight-client/src/VizSentenceTypeByLocation/VizSentenceTypeByLocation.tsx @@ -17,12 +17,23 @@ import { observer } from "mobx-react-lite"; import React from "react"; +import { animated, useTransition } from "react-spring/web.cjs"; +import styled from "styled-components/macro"; import SentenceTypeByLocationMetric from "../contentModels/SentenceTypeByLocationMetric"; import DemographicFilterSelect from "../DemographicFilterSelect"; import FiltersWrapper from "../FiltersWrapper"; import LocalityFilterSelect from "../LocalityFilterSelect"; import NoMetricData from "../NoMetricData"; -import SentenceTypeChart from "./SentenceTypeChart"; +import SentenceTypeChart, { + CHART_BOTTOM_PADDING, + CHART_HEIGHT, +} from "./SentenceTypeChart"; + +const ChartWrapper = styled.div` + /* px rather than rem for consistency with Semiotic */ + height: ${CHART_HEIGHT + CHART_BOTTOM_PADDING}px; + position: relative; +`; type VizSentenceTypeByLocationProps = { metric: SentenceTypeByLocationMetric; @@ -31,6 +42,25 @@ type VizSentenceTypeByLocationProps = { const VizSentenceTypeByLocation: React.FC = ({ metric, }) => { + const { demographicView, dataGraph, localityId } = metric; + + if (demographicView === "nofilter") + throw new Error( + "Unable to display this metric without demographic filter." + ); + + const chartTransitions = useTransition( + { demographicView, dataGraph, localityId }, + (item) => `${item.demographicView} ${item.localityId}`, + { + initial: { opacity: 1 }, + from: { opacity: 0 }, + enter: { opacity: 1 }, + leave: { opacity: 0, position: "absolute" }, + config: { friction: 40, tension: 280 }, + } + ); + if (metric.dataGraph) { return ( <> @@ -40,7 +70,16 @@ const VizSentenceTypeByLocation: React.FC = ({ , ]} /> - + + {chartTransitions.map( + ({ item, key, props }) => + item.dataGraph && ( + + + + ) + )} + ); }