Skip to content

Commit

Permalink
crossfade between charts when filters change
Browse files Browse the repository at this point in the history
  • Loading branch information
macfarlandian committed Feb 5, 2021
1 parent 05042c4 commit 39fec4f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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%;
`;
Expand Down Expand Up @@ -253,7 +255,7 @@ export default function SingleStepSankey({
sourceColors[d.id as $Keys<typeof sourceColors>] ||
targetColor,
})}
size={[Math.max(width, MIN_WIDTH), 500]}
size={[width, CHART_HEIGHT]}
/>
</ResponsiveTooltipController>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -31,6 +42,25 @@ type VizSentenceTypeByLocationProps = {
const VizSentenceTypeByLocation: React.FC<VizSentenceTypeByLocationProps> = ({
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 (
<>
Expand All @@ -40,7 +70,16 @@ const VizSentenceTypeByLocation: React.FC<VizSentenceTypeByLocationProps> = ({
<DemographicFilterSelect metric={metric} />,
]}
/>
<SentenceTypeChart {...metric.dataGraph} />
<ChartWrapper>
{chartTransitions.map(
({ item, key, props }) =>
item.dataGraph && (
<animated.div key={key} style={{ ...props, top: 0 }}>
<SentenceTypeChart {...item.dataGraph} />
</animated.div>
)
)}
</ChartWrapper>
</>
);
}
Expand Down

0 comments on commit 39fec4f

Please sign in to comment.