Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 68 additions & 53 deletions front_end/src/components/charts/fan_chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const FanChart: FC<Props> = ({
const { ref: chartContainerRef, width: chartWidth } =
useContainerSize<HTMLDivElement>();

const filteredOptions = [...options].filter((o) => o.resolved || o.quartiles);
const { theme, getThemeColor } = useAppTheme();
const chartTheme = theme === "dark" ? darkTheme : lightTheme;
const actualTheme = extraTheme
Expand All @@ -79,7 +80,11 @@ const FanChart: FC<Props> = ({
[options]
);

const labels = adjustLabelsForDisplay(options, chartWidth, actualTheme);
const labels = adjustLabelsForDisplay(
filteredOptions,
chartWidth,
actualTheme
);
const yScale = generateScale({
displayType: options[0].question.type,
axisLength: height,
Expand All @@ -93,10 +98,13 @@ const FanChart: FC<Props> = ({

const tooltipItems = useMemo(
() =>
options.reduce<
filteredOptions.reduce<
Record<
string,
{ quartiles: Quartiles; question: QuestionWithNumericForecasts }
{
quartiles: Quartiles | undefined;
question: QuestionWithNumericForecasts;
}
>
>(
(acc, el) => ({
Expand All @@ -105,7 +113,7 @@ const FanChart: FC<Props> = ({
}),
{}
),
[options]
[filteredOptions]
);

const shouldDisplayChart = !!chartWidth;
Expand Down Expand Up @@ -252,7 +260,7 @@ function buildChartData(options: FanOption[]) {
[];
const zeroPoints: number[] = [];
options.forEach((option) => {
if (option.question.scaling.zero_point !== null) {
if (option.question.scaling.zero_point !== null && !!option.quartiles) {
zeroPoints.push(option.question.scaling.zero_point);
}
});
Expand Down Expand Up @@ -282,20 +290,22 @@ function buildChartData(options: FanOption[]) {

if (options[0].question.type === QuestionType.Binary) {
for (const option of options) {
line.push({
x: option.name,
y: option.quartiles.median,
});
area.push({
x: option.name,
y0: option.quartiles.lower25,
y: option.quartiles.upper75,
});
points.push({
x: option.name,
y: option.quartiles.median,
resolved: false,
});
if (!!option.quartiles) {
line.push({
x: option.name,
y: option.quartiles.median,
});
area.push({
x: option.name,
y0: option.quartiles.lower25,
y: option.quartiles.upper75,
});
points.push({
x: option.name,
y: option.quartiles.median,
resolved: false,
});
}
if (option.resolved) {
resolutionPoints.push({
x: option.name,
Expand All @@ -306,41 +316,46 @@ function buildChartData(options: FanOption[]) {
}
} else {
for (const option of options) {
// scale up the values to nominal values
// then unscale by the derived scaling
const median = unscaleNominalLocation(
scaleInternalLocation(option.quartiles.median, option.question.scaling),
scaling
);
const lower25 = unscaleNominalLocation(
scaleInternalLocation(
option.quartiles.lower25,
option.question.scaling
),
scaling
);
const upper75 = unscaleNominalLocation(
scaleInternalLocation(
option.quartiles.upper75,
option.question.scaling
),
scaling
);
if (!!option.quartiles) {
// scale up the values to nominal values
// then unscale by the derived scaling
const median = unscaleNominalLocation(
scaleInternalLocation(
option.quartiles.median,
option.question.scaling
),
scaling
);
const lower25 = unscaleNominalLocation(
scaleInternalLocation(
option.quartiles.lower25,
option.question.scaling
),
scaling
);
const upper75 = unscaleNominalLocation(
scaleInternalLocation(
option.quartiles.upper75,
option.question.scaling
),
scaling
);

line.push({
x: option.name,
y: median,
});
area.push({
x: option.name,
y0: lower25,
y: upper75,
});
points.push({
x: option.name,
y: median,
resolved: false,
});
line.push({
x: option.name,
y: median,
});
area.push({
x: option.name,
y0: lower25,
y: upper75,
});
points.push({
x: option.name,
y: median,
resolved: false,
});
}
if (option.resolved) {
resolutionPoints.push({
x: option.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const HEIGHT = 70;
type Props = ComponentProps<typeof VictoryLabel> & {
items: Record<
string,
{ quartiles: Quartiles; question: QuestionWithNumericForecasts }
{ quartiles: Quartiles | undefined; question: QuestionWithNumericForecasts }
>;
width: number;
chartHeight: number;
Expand Down Expand Up @@ -43,6 +43,9 @@ const ChartFanTooltip: FC<Props> = ({

const padding = 10;
const position = y + padding + HEIGHT > chartHeight ? "top" : "bottom";
if (!quartiles) {
return null;
}

return (
<g style={{ pointerEvents: "none" }}>
Expand Down
2 changes: 1 addition & 1 deletion front_end/src/types/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type NumericChartType = "date" | "numeric" | "binary";

export type FanOption = {
name: string;
quartiles: Quartiles;
quartiles: Quartiles | undefined;
resolved: boolean;
question: QuestionWithNumericForecasts;
};
Expand Down
14 changes: 8 additions & 6 deletions front_end/src/utils/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ export function getFanOptionsFromContinuousGroup(
.sort((a, b) => differenceInMilliseconds(a.resolvedAt, b.resolvedAt))
.map(({ name, cdf, resolved, question }) => ({
name,
quartiles: computeQuartilesFromCDF(cdf),
quartiles: cdf.length > 0 ? computeQuartilesFromCDF(cdf) : undefined,
resolved,
question,
}));
Expand All @@ -649,11 +649,13 @@ export function getFanOptionsFromBinaryGroup(
const resolved = q.resolution !== null;
return {
name: q.label,
quartiles: {
median: aggregation?.centers?.[0] ?? 0,
lower25: aggregation?.interval_lower_bounds?.[0] ?? 0,
upper75: aggregation?.interval_upper_bounds?.[0] ?? 0,
},
quartiles: !!aggregation
? {
median: aggregation.centers?.[0] ?? 0,
lower25: aggregation.interval_lower_bounds?.[0] ?? 0,
upper75: aggregation.interval_upper_bounds?.[0] ?? 0,
}
: undefined,
resolved,
question: q,
resolvedAt: new Date(q.scheduled_resolve_time),
Expand Down