diff --git a/packages/superset-ui-preset-chart-xy/src/encodeable/AbstractEncoder.ts b/packages/superset-ui-preset-chart-xy/src/encodeable/AbstractEncoder.ts index 4a290a362..4dd9004b2 100644 --- a/packages/superset-ui-preset-chart-xy/src/encodeable/AbstractEncoder.ts +++ b/packages/superset-ui-preset-chart-xy/src/encodeable/AbstractEncoder.ts @@ -161,7 +161,7 @@ export default abstract class AbstractEncoder< // Only work for nominal channels now // TODO: Add support for numerical scale if (channelEncoder.definition.type === 'nominal') { - const domain = Array.from(new Set(data.map(channelEncoder.get))); + const domain = channelEncoder.getDomain(data) as string[]; return domain.map((value: ChannelInput) => ({ field, diff --git a/packages/superset-ui-preset-chart-xy/src/encodeable/ChannelEncoder.ts b/packages/superset-ui-preset-chart-xy/src/encodeable/ChannelEncoder.ts index 0d56918a9..44b0d3563 100644 --- a/packages/superset-ui-preset-chart-xy/src/encodeable/ChannelEncoder.ts +++ b/packages/superset-ui-preset-chart-xy/src/encodeable/ChannelEncoder.ts @@ -1,9 +1,10 @@ +import { extent as d3Extent } from 'd3-array'; import { Value } from 'vega-lite/build/src/channeldef'; import { extractFormatFromChannelDef } from './parsers/extractFormat'; import extractScale, { ScaleAgent } from './parsers/extractScale'; import extractGetter from './parsers/extractGetter'; import { ChannelOptions, ChannelType, ChannelInput } from './types/Channel'; -import { PlainObject } from './types/Data'; +import { PlainObject, Dataset } from './types/Data'; import { ChannelDef, isScaleFieldDef, @@ -95,6 +96,31 @@ export default class ChannelEncoder, Output exten : (value as T); } + getDomain(data: Dataset) { + if (isTypedFieldDef(this.definition)) { + const { type } = this.definition; + if (type === 'nominal' || type === 'ordinal') { + return Array.from(new Set(data.map(d => this.get(d)))) as string[]; + } else if (type === 'quantitative') { + const extent = d3Extent(data, d => this.get(d)); + if (typeof extent[0] === 'undefined') { + return [0, 1]; + } + + return extent as [number, number]; + } else if (type === 'temporal') { + const extent = d3Extent(data, d => this.get(d)); + if (typeof extent[0] === 'undefined') { + return [0, 1]; + } + + return extent as [number, number] | [Date, Date]; + } + } + + return []; + } + getTitle() { if (isFieldDef(this.definition)) { return this.definition.title || this.definition.field;