mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Treating x axis as category for bar chart
Summary: Forcing category xaxis type for bar chart when labels are not numerical. Test Plan: Added new and updated existing Reviewers: paulfitz Reviewed By: paulfitz Differential Revision: https://phab.getgrist.com/D4297
This commit is contained in:
parent
e30a090a4e
commit
8162a6d959
@ -106,8 +106,9 @@ type RowPropGetter = (rowId: number) => Datum;
|
|||||||
// We convert Grist data to a list of Series first, from which we then construct Plotly traces.
|
// We convert Grist data to a list of Series first, from which we then construct Plotly traces.
|
||||||
interface Series {
|
interface Series {
|
||||||
label: string; // Corresponds to the column name.
|
label: string; // Corresponds to the column name.
|
||||||
group?: Datum; // The group value, when grouped.
|
|
||||||
values: Datum[];
|
values: Datum[];
|
||||||
|
pureType?: string; // The pure type of the column.
|
||||||
|
group?: Datum; // The group value, when grouped.
|
||||||
isInSortSpec?: boolean; // Whether this series is present in sort spec for this chart.
|
isInSortSpec?: boolean; // Whether this series is present in sort spec for this chart.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +274,7 @@ export class ChartView extends Disposable {
|
|||||||
const pureType = field.displayColModel().pureType();
|
const pureType = field.displayColModel().pureType();
|
||||||
const fullGetter = (pureType === 'Date' || pureType === 'DateTime') ? dateGetter(getter) : getter;
|
const fullGetter = (pureType === 'Date' || pureType === 'DateTime') ? dateGetter(getter) : getter;
|
||||||
return {
|
return {
|
||||||
|
pureType,
|
||||||
label: field.label(),
|
label: field.label(),
|
||||||
values: rowIds.map(fullGetter),
|
values: rowIds.map(fullGetter),
|
||||||
isInSortSpec: Boolean(Sort.findCol(this._sortSpec, field.colRef.peek())),
|
isInSortSpec: Boolean(Sort.findCol(this._sortSpec, field.colRef.peek())),
|
||||||
@ -1121,7 +1123,15 @@ function basicPlot(series: Series[], options: ChartOptions, dataOptions: Data):
|
|||||||
export const chartTypes: {[name: string]: ChartFunc} = {
|
export const chartTypes: {[name: string]: ChartFunc} = {
|
||||||
// TODO There is a lot of code duplication across chart types. Some refactoring is in order.
|
// TODO There is a lot of code duplication across chart types. Some refactoring is in order.
|
||||||
bar(series: Series[], options: ChartOptions): PlotData {
|
bar(series: Series[], options: ChartOptions): PlotData {
|
||||||
return basicPlot(series, options, {type: 'bar'});
|
// If the X axis is not from numerical column, treat it as category.
|
||||||
|
const data = basicPlot(series, options, {type: 'bar'});
|
||||||
|
const useCategory = series[0]?.pureType && !['Numeric', 'Int', 'Any'].includes(series[0].pureType);
|
||||||
|
const xaxisName = options.orientation === 'h' ? 'yaxis' : 'xaxis';
|
||||||
|
if (useCategory && data.layout && data.layout[xaxisName]) {
|
||||||
|
const axisConfig = data.layout[xaxisName]!;
|
||||||
|
axisConfig.type = 'category';
|
||||||
|
}
|
||||||
|
return data;
|
||||||
},
|
},
|
||||||
line(series: Series[], options: ChartOptions): PlotData {
|
line(series: Series[], options: ChartOptions): PlotData {
|
||||||
sortByXValues(series);
|
sortByXValues(series);
|
||||||
|
@ -21,6 +21,47 @@ describe('ChartView1', function() {
|
|||||||
gu.bigScreen();
|
gu.bigScreen();
|
||||||
afterEach(() => gu.checkForErrors());
|
afterEach(() => gu.checkForErrors());
|
||||||
|
|
||||||
|
it('should treat text as category', async function() {
|
||||||
|
const revert = await gu.begin();
|
||||||
|
await gu.sendActions([
|
||||||
|
['AddTable', 'Text', [
|
||||||
|
{id: 'X', type: 'Int'},
|
||||||
|
{id: 'Y', type: 'Int'}
|
||||||
|
]],
|
||||||
|
['AddRecord', 'Text', null, {X: 1, Y: 1}],
|
||||||
|
['AddRecord', 'Text', null, {X: 100, Y: 2}],
|
||||||
|
['AddRecord', 'Text', null, {X: 101, Y: 3}],
|
||||||
|
['AddRecord', 'Text', null, {X: 102, Y: 4}],
|
||||||
|
]);
|
||||||
|
await gu.openPage('Text');
|
||||||
|
await gu.addNewSection('Chart', 'Text');
|
||||||
|
|
||||||
|
const layout = () => getChartData().then(d => d.layout);
|
||||||
|
|
||||||
|
await gu.waitToPass(async () => {
|
||||||
|
// Check to make sure initial values are correct.
|
||||||
|
assert.deepEqual((await layout()).xaxis.type, 'linear');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Now convert X to text.
|
||||||
|
await gu.sendActions([
|
||||||
|
['ModifyColumn', 'Text', 'X', {type: 'Text'}],
|
||||||
|
]);
|
||||||
|
assert.deepEqual((await layout()).xaxis.type, 'category');
|
||||||
|
|
||||||
|
// Invert the chart.
|
||||||
|
await gu.selectSectionByTitle('Text Chart');
|
||||||
|
await gu.toggleSidePanel('right', 'open');
|
||||||
|
await driver.find('.test-chart-orientation .test-select-open').click();
|
||||||
|
await driver.findContent('.test-select-menu', 'Horizontal').click();
|
||||||
|
await gu.waitForServer();
|
||||||
|
assert.deepEqual((await layout()).yaxis.type, 'category');
|
||||||
|
assert.deepEqual((await layout()).xaxis.type, 'linear');
|
||||||
|
|
||||||
|
await revert();
|
||||||
|
await gu.toggleSidePanel('right', 'close');
|
||||||
|
});
|
||||||
|
|
||||||
it('should allow adding and removing chart viewsections', async function() {
|
it('should allow adding and removing chart viewsections', async function() {
|
||||||
// Starting out with one section
|
// Starting out with one section
|
||||||
assert.lengthOf(await driver.findAll('.test-gristdoc .view_leaf'), 1);
|
assert.lengthOf(await driver.findAll('.test-gristdoc .view_leaf'), 1);
|
||||||
@ -133,7 +174,7 @@ describe('ChartView1', function() {
|
|||||||
|
|
||||||
it('should update chart when new columns are included', async function() {
|
it('should update chart when new columns are included', async function() {
|
||||||
const chartDom = await driver.find('.test-chart-container');
|
const chartDom = await driver.find('.test-chart-container');
|
||||||
// Check to make sure intial values are correct.
|
// Check to make sure initial values are correct.
|
||||||
let data = (await getChartData(chartDom)).data;
|
let data = (await getChartData(chartDom)).data;
|
||||||
assert.deepEqual(data[0].type, 'bar');
|
assert.deepEqual(data[0].type, 'bar');
|
||||||
assert.deepEqual(data[0].x, [ 61, 5, 4, 3, 2, 1 ]);
|
assert.deepEqual(data[0].x, [ 61, 5, 4, 3, 2, 1 ]);
|
||||||
|
Loading…
Reference in New Issue
Block a user