From cecebded1f6e9787b42653772bc3a2a1274456a7 Mon Sep 17 00:00:00 2001 From: Cyprien P Date: Wed, 1 Sep 2021 11:41:30 +0200 Subject: [PATCH] (core) Fix bar chart weirdness when x axis has redundant values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Bar chart was a bit broken when there were redundant values on the X axis: the bars’s height maps to the sum of all the corresponding y values, when the data that shows up on hover is only the last one. It seems that plotly does not support redundant values in the x axis and in all Plotly examples (implementation relies on plotly) x values only have unique values. This diff, fixes by making sure x axis has unique values. If user actually wants to plot groups, they'll have to use a summary charts. Test Plan: tested manually Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3011 --- app/client/components/ChartView.ts | 11 ++++++++++- app/client/lib/chartUtil.ts | 13 +++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/client/components/ChartView.ts b/app/client/components/ChartView.ts index 1c79772a..6343df8d 100644 --- a/app/client/components/ChartView.ts +++ b/app/client/components/ChartView.ts @@ -1,6 +1,6 @@ import * as BaseView from 'app/client/components/BaseView'; import {GristDoc} from 'app/client/components/GristDoc'; -import {sortByXValues} from 'app/client/lib/chartUtil'; +import {sortByXValues, uniqXValues} from 'app/client/lib/chartUtil'; import {Delay} from 'app/client/lib/Delay'; import {Disposable} from 'app/client/lib/dispose'; import {fromKoSave} from 'app/client/lib/fromKoSave'; @@ -352,6 +352,15 @@ function cssCheckboxRow(label: string, value: KoSaveableObservable, ... function basicPlot(series: Series[], options: ChartOptions, dataOptions: Partial): PlotData { trimNonNumericData(series); const errorBars = extractErrorBars(series, options); + + if (dataOptions.type === 'bar') { + // Plotly has weirdness when redundant values shows up on the x-axis: the values that shows + // up on hover is different than the value on the y-axis. It seems that one is the sum of all + // values with same x-axis value, while the other is the last of them. To fix this, we force + // unique values for the x-axis. + series = uniqXValues(series); + } + return { data: series.slice(1).map((line: Series): Data => ({ name: getSeriesName(line, series.length > 2), diff --git a/app/client/lib/chartUtil.ts b/app/client/lib/chartUtil.ts index f183bf60..130841ca 100644 --- a/app/client/lib/chartUtil.ts +++ b/app/client/lib/chartUtil.ts @@ -1,5 +1,7 @@ import {typedCompare} from 'app/common/SortFunc'; import {Datum} from 'plotly.js'; +import range = require('lodash/range'); +import uniqBy = require('lodash/uniqBy'); /** * Sort all values in a list of series according to the values in the first one. @@ -18,3 +20,14 @@ export function sortByXValues(series: Array<{values: Datum[]}>): void { s.values = indices.map((i) => values[i]); } } + +// creates new version of series that has a duplicate free version of the values in the first one. +export function uniqXValues(series: Array): Array { + if (!series[0]) { return []; } + const n = series[0].values.length; + const indexToKeep = new Set(uniqBy(range(n), (i) => series[0].values[i])); + return series.map((line: T) => ({ + ...line, + values: line.values.filter((_val, i) => indexToKeep.has(i)) + })); +}