(core) Disallow using non numeric type in chart's series

Summary:
We do not support to show non numeric column as chart series.
However we didn't prevent the user from doing it and it could cause unexpected behaviour such as a missing chart.
This diff addresses that issue by doing two following thing:
1) it prevents user from adding non numeric column as series and
2) it makes sure that if there is a non numeric series it does not mess up the chart (it still can happen that a non numeric series ends up in charts even with 1) for instance if users convert a series' column to a non numeric column for instance).

Links to UI discussion:
 - https://grist.quip.com/wb4gAgrQM2aP#TZEADAKPs8n
 - https://grist.quip.com/wb4gAgrQM2aP#TZEADAP8S8N

Test Plan:
 - new behaviour covered in nbrowser/ChartView3.ts
 - Some test were using non-numeric column as series, diff fixes that to.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3206
This commit is contained in:
Cyprien P
2022-01-17 17:08:43 +01:00
parent f9f4245466
commit c714d09eb8
3 changed files with 149 additions and 34 deletions

View File

@@ -28,6 +28,9 @@ interface DraggableFieldsOption {
// the group-by-column in the chart type widget.
skipFirst?: Observable<number>;
// Allows to filter view fields.
filterFunc?: (field: ViewFieldRec, index: number) => boolean;
// Allows to prevent updates of the list. This option is to be used when skipFirst option is used
// and it is useful to prevent the list to update during changes that only affect the skipped
// fields.
@@ -98,19 +101,26 @@ export class VisibleFieldsConfig extends Disposable {
const itemClass = this._useNewUI ? cssDragRow.className : 'view_config_draggable_field';
let fields = this._section.viewFields.peek();
if (options.skipFirst) {
if (options.skipFirst || options.filterFunc) {
const skipFirst = options.skipFirst || Observable.create(this, -1);
const filterFunc = options.filterFunc || (() => true);
const freeze = options.freeze;
const allFields = this._section.viewFields.peek();
const newArray = new KoArray<ViewFieldRec>();
function update() {
if (freeze && freeze.get()) { return; }
const newValues = allFields.peek().filter((_v, i) => i + 1 > options.skipFirst!.get());
const newValues = allFields.peek()
.filter((_v, i) => i + 1 > skipFirst.get())
.filter(filterFunc)
;
if (isEqual(newArray.all(), newValues)) { return; }
newArray.assign(newValues);
}
update();
this.autoDispose(allFields.subscribe(update));
this.autoDispose(subscribe(options.skipFirst, update));
this.autoDispose(subscribe(skipFirst, update));
if (options.freeze) {
this.autoDispose(subscribe(options.freeze, update));
}