Skip to content

Commit

Permalink
Highlight unusually low headways in chart
Browse files Browse the repository at this point in the history
  • Loading branch information
devinmatte committed Apr 6, 2024
1 parent 5bbd487 commit e1a38b6
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 10 deletions.
16 changes: 13 additions & 3 deletions common/components/charts/Legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Disclosure } from '@headlessui/react';
import React from 'react';

export const LegendSingleDay: React.FC = () => {
interface LegendProps {
showUnderRatio?: boolean;
}

export const LegendSingleDay: React.FC<LegendProps> = ({ showUnderRatio = false }) => {
return (
<Disclosure>
{({ open }) => (
Expand All @@ -19,15 +23,15 @@ export const LegendSingleDay: React.FC = () => {
'grid w-full grid-cols-2 items-baseline p-1 px-4 text-left text-xs lg:flex lg:flex-row lg:gap-4'
}
>
<LegendSingle />
<LegendSingle showUnderRatio={showUnderRatio} />
</Disclosure.Panel>
</div>
)}
</Disclosure>
);
};

const LegendSingle: React.FC = () => {
const LegendSingle: React.FC<LegendProps> = ({ showUnderRatio = false }) => {
return (
<>
<div className="col-span-2 flex flex-row items-baseline gap-2 pb-1 italic lg:pb-0">
Expand All @@ -37,6 +41,12 @@ const LegendSingle: React.FC = () => {
MBTA benchmark:
</p>
</div>
{showUnderRatio && (
<p>
<span className="mr-1 inline-block h-2.5 w-2.5 rounded-full border border-[#0066ff] bg-[#0096FF]"></span>
{'50%+ early'}
</p>
)}
<p>
<span className="mr-1 inline-block h-2.5 w-2.5 rounded-full border border-[#57945B] bg-[#64b96a]"></span>
{'On time'}
Expand Down
39 changes: 32 additions & 7 deletions common/components/charts/SingleDayLineChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,19 @@ import { LegendSingleDay } from './Legend';
import { ChartDiv } from './ChartDiv';
import { ChartBorder } from './ChartBorder';

const pointColors = (data: DataPoint[], metric_field: string, benchmark_field?: string) => {
const pointColors = (
data: DataPoint[],
metric_field: string,
benchmark_field?: string,
showUnderRatio?: boolean
) => {
return data.map((point: DataPoint) => {
if (benchmark_field) {
const ratio = point[metric_field] / point[benchmark_field];
if (point[benchmark_field] === null) {
return CHART_COLORS.GREY; //grey
} else if (ratio <= 0.5 && showUnderRatio) {
return CHART_COLORS.BLUE; //blue
} else if (ratio <= 1.25) {
return CHART_COLORS.GREEN; //green
} else if (ratio <= 1.5) {
Expand All @@ -41,9 +48,11 @@ const pointColors = (data: DataPoint[], metric_field: string, benchmark_field?:
});
};

const departureFromNormalString = (metric: number, benchmark: number) => {
const departureFromNormalString = (metric: number, benchmark: number, showUnderRatio?: boolean) => {
const ratio = metric / benchmark;
if (!isFinite(ratio) || ratio <= 1.25) {
if (showUnderRatio && ratio <= 0.5) {
return '50%+ under schedule';
} else if (!isFinite(ratio) || ratio <= 1.25) {
return '';
} else if (ratio <= 1.5) {
return '25%+ over schedule';
Expand All @@ -67,6 +76,7 @@ export const SingleDayLineChart: React.FC<SingleDayLineProps> = ({
location,
units,
showLegend = true,
showUnderRatio = false,
}) => {
const ref = useRef();
const alerts = useAlertStore((store) => store.alerts)?.filter((alert) => alert.applied);
Expand Down Expand Up @@ -104,9 +114,19 @@ export const SingleDayLineChart: React.FC<SingleDayLineProps> = ({
label: `Actual`,
fill: false,
borderColor: '#a0a0a030',
pointBackgroundColor: pointColors(data, metricField, benchmarkField),
pointBackgroundColor: pointColors(
data,
metricField,
benchmarkField,
showUnderRatio
),
pointHoverRadius: 3,
pointHoverBackgroundColor: pointColors(data, metricField, benchmarkField),
pointHoverBackgroundColor: pointColors(
data,
metricField,
benchmarkField,
showUnderRatio
),
pointRadius: 3,
pointHitRadius: 10,
data: convertedData,
Expand Down Expand Up @@ -148,7 +168,8 @@ export const SingleDayLineChart: React.FC<SingleDayLineProps> = ({
afterBody: (tooltipItems) => {
return departureFromNormalString(
tooltipItems[0].parsed.y,
tooltipItems[1]?.parsed.y
tooltipItems[1]?.parsed.y,
showUnderRatio
);
},
},
Expand Down Expand Up @@ -223,7 +244,11 @@ export const SingleDayLineChart: React.FC<SingleDayLineProps> = ({
<div className="flex flex-col">
{alerts && <AlertsDisclaimer alerts={alerts} />}
<div className="flex flex-row items-end gap-4 ">
{showLegend && benchmarkField ? <LegendSingleDay /> : <div className="w-full" />}
{showLegend && benchmarkField ? (
<LegendSingleDay showUnderRatio={showUnderRatio} />
) : (
<div className="w-full" />
)}
{date && (
<DownloadButton
data={data}
Expand Down
1 change: 1 addition & 0 deletions common/constants/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const COLORS = {
// Colors for charts
export const CHART_COLORS = {
GREY: '#1c1c1c',
BLUE: '#0096FF',
GREEN: '#64b96a',
YELLOW: '#f5ed00',
RED: '#c33149',
Expand Down
2 changes: 2 additions & 0 deletions common/types/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ export interface LineProps {
includeBothStopsForLocation?: boolean;
fname: DataName;
showLegend?: boolean;
/** Show ratios under 1.00 differently in chart */
showUnderRatio?: boolean;
}

export interface AggregateLineProps extends LineProps {
Expand Down
1 change: 1 addition & 0 deletions modules/headways/charts/HeadwaysSingleChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const HeadwaysSingleChart: React.FC<HeadwaysChartProps> = ({
fname={'headways'}
units={'Minutes'}
showLegend={showLegend && anyHeadwayBenchmarks}
showUnderRatio={true}
/>
);
}, [linePath, headways, date, fromStation, toStation, showLegend, anyHeadwayBenchmarks]);
Expand Down

0 comments on commit e1a38b6

Please sign in to comment.