From 6c7533b565ad13fe3004e7448072f5a2013d003c Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Tue, 7 May 2019 11:50:07 -0700 Subject: [PATCH] feat: add box plot (#78) Squashed commits: [23ad0d6] feat: working box plot [a7ed565] fix: typings [57a62b7] feat: clarify horizontal/vertical mode [6312737] fix: typings [2734de3] feat: box plot types [cb3c239] fix: typings [7e2dcda] feat: add box plot --- .../preset-chart-xy/BoxPlot/constants.ts | 2 + .../stories/preset-chart-xy/BoxPlot/data.js | 80 ++++++++++ .../stories/preset-chart-xy/BoxPlot/index.js | 12 ++ .../preset-chart-xy/BoxPlot/stories/Basic.tsx | 109 +++++++++++++ .../BoxPlot/stories/Legacy.tsx | 31 ++++ .../src/BoxPlot/BoxPlot.tsx | 148 ++++++++++++++++++ .../src/BoxPlot/Encoder.ts | 42 +++++ .../src/BoxPlot/createMetadata.ts | 12 ++ .../src/BoxPlot/createTooltip.tsx | 44 ++++++ .../src/BoxPlot/images/thumbnail.png | Bin 0 -> 9717 bytes .../src/BoxPlot/images/thumbnailLarge.png | Bin 0 -> 64899 bytes .../src/BoxPlot/index.ts | 31 ++++ .../src/BoxPlot/legacy/index.ts | 31 ++++ .../src/BoxPlot/legacy/transformProps.ts | 94 +++++++++++ .../src/BoxPlot/transformProps.ts | 68 ++++++++ .../src/BoxPlot/types.ts | 23 +++ .../src/Line/createTooltip.tsx | 6 +- .../src/components/tooltip/TooltipTable.tsx | 4 +- .../superset-ui-preset-chart-xy/src/index.ts | 2 +- .../superset-ui-preset-chart-xy/src/legacy.ts | 2 +- .../types/@data-ui/xy-chart/index.d.ts | 9 +- 21 files changed, 738 insertions(+), 12 deletions(-) create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/constants.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/data.js create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/index.js create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Basic.tsx create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Legacy.tsx create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.tsx create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/Encoder.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createMetadata.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createTooltip.tsx create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/images/thumbnail.png create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/images/thumbnailLarge.png create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/index.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/index.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/transformProps.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/transformProps.ts create mode 100644 superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/types.ts diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/constants.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/constants.ts new file mode 100644 index 000000000000..7e3c8404c60c --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/constants.ts @@ -0,0 +1,2 @@ +export const BOX_PLOT_PLUGIN_TYPE = 'v2-box-plot'; +export const BOX_PLOT_PLUGIN_LEGACY_TYPE = 'v2-box-plot/legacy'; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/data.js b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/data.js new file mode 100644 index 000000000000..fc1ee8f5d7d1 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/data.js @@ -0,0 +1,80 @@ +/* eslint-disable sort-keys, no-magic-numbers */ +export default [ + { + label: 'East Asia & Pacific', + values: { + Q1: 1384725172.5, + Q2: 1717904169.0, + Q3: 2032724922.5, + whisker_high: 2240687901.0, + whisker_low: 1031863394.0, + outliers: [], + }, + }, + { + label: 'Europe & Central Asia', + values: { + Q1: 751386460.5, + Q2: 820716895.0, + Q3: 862814192.5, + whisker_high: 903095786.0, + whisker_low: 660881033.0, + outliers: [], + }, + }, + { + label: 'Latin America & Caribbean', + values: { + Q1: 313690832.5, + Q2: 421490233.0, + Q3: 529668114.5, + whisker_high: 626270167.0, + whisker_low: 220564224.0, + outliers: [], + }, + }, + { + label: 'Middle East & North Africa', + values: { + Q1: 152382756.5, + Q2: 232066828.0, + Q3: 318191071.5, + whisker_high: 417451428.0, + whisker_low: 105512645.0, + outliers: [], + }, + }, + { + label: 'North America', + values: { + Q1: 235506847.5, + Q2: 268896849.0, + Q3: 314553651.5, + whisker_high: 354462656.0, + whisker_low: 198624409.0, + outliers: [], + }, + }, + { + label: 'South Asia', + values: { + Q1: 772373036.5, + Q2: 1059570231.0, + Q3: 1398841234.0, + whisker_high: 1720976995.0, + whisker_low: 572036107.0, + outliers: [], + }, + }, + { + label: 'Sub-Saharan Africa', + values: { + Q1: 320037758.0, + Q2: 467337821.0, + Q3: 676768689.0, + whisker_high: 974315323.0, + whisker_low: 228268752.0, + outliers: [], + }, + }, +]; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/index.js b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/index.js new file mode 100644 index 000000000000..5ce989c0fab5 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/index.js @@ -0,0 +1,12 @@ +import { BoxPlotChartPlugin as LegacyBoxPlotChartPlugin } from '../../../../../superset-ui-preset-chart-xy/src/legacy'; +import { BoxPlotChartPlugin } from '../../../../../superset-ui-preset-chart-xy/src'; +import Stories from './stories/Basic'; +import LegacyStories from './stories/Legacy'; +import { BOX_PLOT_PLUGIN_LEGACY_TYPE, BOX_PLOT_PLUGIN_TYPE } from './constants'; + +new LegacyBoxPlotChartPlugin().configure({ key: BOX_PLOT_PLUGIN_LEGACY_TYPE }).register(); +new BoxPlotChartPlugin().configure({ key: BOX_PLOT_PLUGIN_TYPE }).register(); + +export default { + examples: [...Stories, ...LegacyStories], +}; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Basic.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Basic.tsx new file mode 100644 index 000000000000..55776a9374ab --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Basic.tsx @@ -0,0 +1,109 @@ +/* eslint-disable no-magic-numbers, sort-keys */ +import React from 'react'; +import { SuperChart, ChartProps } from '@superset-ui/chart'; +import data from '../data'; + +export default [ + { + renderStory: () => ( + + ), + storyName: 'Basic', + storyPath: 'preset-chart-xy|BoxPlotChartPlugin', + }, + { + renderStory: () => ( + + ), + storyName: 'Horizontal', + storyPath: 'preset-chart-xy|BoxPlotChartPlugin', + }, +]; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Legacy.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Legacy.tsx new file mode 100644 index 000000000000..59fbb55c33c9 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-plugins-demo/storybook/stories/preset-chart-xy/BoxPlot/stories/Legacy.tsx @@ -0,0 +1,31 @@ +/* eslint-disable no-magic-numbers, sort-keys */ +import React from 'react'; +import { SuperChart, ChartProps } from '@superset-ui/chart'; +import data from '../data'; + +export default [ + { + renderStory: () => ( + + ), + storyName: 'Use Legacy API shim', + storyPath: 'preset-chart-xy|BoxPlotChartPlugin', + }, +]; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.tsx new file mode 100644 index 000000000000..a46036e4a21a --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/BoxPlot.tsx @@ -0,0 +1,148 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +/* eslint-disable sort-keys, no-magic-numbers, complexity */ +import React from 'react'; +import { BoxPlotSeries, XYChart } from '@data-ui/xy-chart'; +import { chartTheme, ChartTheme } from '@data-ui/theme'; +import { Margin, Dimension } from '@superset-ui/dimension'; +import { createSelector } from 'reselect'; +import createTooltip from './createTooltip'; +import XYChartLayout from '../utils/XYChartLayout'; +import WithLegend from '../components/WithLegend'; +import ChartLegend from '../components/ChartLegend'; +import Encoder, { ChannelTypes, Encoding, Outputs } from './Encoder'; +import { Dataset, PlainObject } from '../encodeable/types/Data'; + +chartTheme.gridStyles.stroke = '#f1f3f5'; + +const DEFAULT_MARGIN = { top: 20, right: 20, left: 20, bottom: 20 }; + +const defaultProps = { + className: '', + margin: DEFAULT_MARGIN, + theme: chartTheme, +} as const; + +type Props = { + className?: string; + width: string | number; + height: string | number; + margin?: Margin; + encoding: Encoding; + data: Dataset; + theme?: ChartTheme; +} & Readonly; + +export default class BoxPlot extends React.PureComponent { + static defaultProps = defaultProps; + + constructor(props: Props) { + super(props); + + const createEncoder = createSelector( + (enc: Encoding) => enc, + (enc: Encoding) => new Encoder({ encoding: enc }), + ); + + this.createEncoder = () => { + this.encoder = createEncoder(this.props.encoding); + }; + + this.encoder = createEncoder(this.props.encoding); + this.renderChart = this.renderChart.bind(this); + } + + encoder: Encoder; + private createEncoder: () => void; + + renderChart(dim: Dimension) { + const { width, height } = dim; + const { data, encoding, margin, theme } = this.props; + const { channels } = this.encoder; + + const isHorizontal = encoding.y.type === 'nominal'; + + const children = [ + ({ ...row, y: channels.y.get(row) })) + : data.map(row => ({ ...row, x: channels.x.get(row) })) + } + fill={(datum: PlainObject) => channels.color.encode(datum, '#55acee')} + fillOpacity={0.4} + stroke={(datum: PlainObject) => channels.color.encode(datum)} + strokeWidth={1} + widthRatio={0.6} + horizontal={encoding.y.type === 'nominal'} + />, + ]; + + const layout = new XYChartLayout({ + width, + height, + margin: { ...DEFAULT_MARGIN, ...margin }, + theme, + xEncoder: channels.x, + yEncoder: channels.y, + children, + }); + + return layout.renderChartWithFrame((chartDim: Dimension) => ( + + {children} + {layout.renderXAxis()} + {layout.renderYAxis()} + + )); + } + + render() { + const { className, data, width, height } = this.props; + + this.createEncoder(); + const renderLegend = this.encoder.hasLegend() + ? // eslint-disable-next-line react/jsx-props-no-multi-spaces + () => data={data} encoder={this.encoder} /> + : undefined; + + return ( + + ); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/Encoder.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/Encoder.ts new file mode 100644 index 000000000000..74c5342220a9 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/Encoder.ts @@ -0,0 +1,42 @@ +import AbstractEncoder from '../encodeable/AbstractEncoder'; +import { PartialSpec } from '../encodeable/types/Specification'; +import { EncodingFromChannelsAndOutputs } from '../encodeable/types/Channel'; + +/** + * Define channel types + */ +const channelTypes = { + color: 'Color', + x: 'XBand', + y: 'YBand', +} as const; + +export type ChannelTypes = typeof channelTypes; + +/** + * Define output type for each channel + */ +export interface Outputs { + x: number | null; + y: number | null; + color: string; +} + +/** + * Derive encoding config + */ +export type Encoding = EncodingFromChannelsAndOutputs; + +export default class Encoder extends AbstractEncoder { + static readonly DEFAULT_ENCODINGS: Encoding = { + color: { value: '#222' }, + x: { field: 'x', type: 'nominal' }, + y: { field: 'y', type: 'quantitative' }, + }; + + static readonly CHANNEL_OPTIONS = {}; + + constructor(spec: PartialSpec) { + super(channelTypes, spec, Encoder.DEFAULT_ENCODINGS, Encoder.CHANNEL_OPTIONS); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createMetadata.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createMetadata.ts new file mode 100644 index 000000000000..52fd28fc88d7 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createMetadata.ts @@ -0,0 +1,12 @@ +import { t } from '@superset-ui/translation'; +import { ChartMetadata } from '@superset-ui/chart'; +import thumbnail from './images/thumbnail.png'; + +export default function createMetadata(useLegacyApi = false) { + return new ChartMetadata({ + description: '', + name: t('Box Plot'), + thumbnail, + useLegacyApi, + }); +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createTooltip.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createTooltip.tsx new file mode 100644 index 000000000000..b3efd5070f7f --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/createTooltip.tsx @@ -0,0 +1,44 @@ +import { isDefined } from '@superset-ui/core'; +import React from 'react'; +import TooltipFrame from '../components/tooltip/TooltipFrame'; +import TooltipTable from '../components/tooltip/TooltipTable'; +import Encoder from './Encoder'; +import { BoxPlotDataRow } from './types'; + +export default function createBoxPlotTooltip(encoder: Encoder) { + const { channels } = encoder; + + return function BoxPlotTooltip({ datum, color }: { datum: BoxPlotDataRow; color: string }) { + const { label, min, max, median, firstQuartile, thirdQuartile, outliers } = datum; + + const data = []; + if (isDefined(min)) { + data.push({ key: 'Min', valueColumn: channels.y.formatValue(min) }); + } + if (isDefined(max)) { + data.push({ key: 'Max', valueColumn: channels.y.formatValue(max) }); + } + if (isDefined(median)) { + data.push({ key: 'Median', valueColumn: channels.y.formatValue(median) }); + } + if (isDefined(firstQuartile)) { + data.push({ key: '1st Quartile', valueColumn: channels.y.formatValue(firstQuartile) }); + } + if (isDefined(thirdQuartile)) { + data.push({ key: '3rd Quartile', valueColumn: channels.y.formatValue(thirdQuartile) }); + } + if (isDefined(outliers) && outliers.length > 0) { + data.push({ key: '# Outliers', valueColumn: outliers.length }); + } + + return ( + +
+ {label} +
+ {data.length > 0 &&
} + +
+ ); + }; +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/images/thumbnail.png b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/images/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..c6f8fdcfd616012a34fbedf01b0965cd1bfb1a61 GIT binary patch literal 9717 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

+C!o<@xPaUfaDZ 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�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 U*SYsh{()rP9K+wE^j7crUmTSPl>h($ literal 0 HcmV?d00001 diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/index.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/index.ts new file mode 100644 index 000000000000..ee02dbbbe428 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/index.ts @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { ChartPlugin } from '@superset-ui/chart'; +import createMetadata from './createMetadata'; +import transformProps from './transformProps'; + +export default class BoxPlotChartPlugin extends ChartPlugin { + constructor() { + super({ + loadChart: () => import('./BoxPlot'), + metadata: createMetadata(), + transformProps, + }); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/index.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/index.ts new file mode 100644 index 000000000000..6667d5ccff7d --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/index.ts @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { ChartPlugin } from '@superset-ui/chart'; +import createMetadata from '../createMetadata'; +import transformProps from './transformProps'; + +export default class BoxPlotChartPlugin extends ChartPlugin { + constructor() { + super({ + loadChart: () => import('../BoxPlot'), + metadata: createMetadata(true), + transformProps, + }); + } +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/transformProps.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/transformProps.ts new file mode 100644 index 000000000000..183230c94639 --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/legacy/transformProps.ts @@ -0,0 +1,94 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +/* eslint-disable sort-keys, no-magic-numbers */ +import { ChartProps } from '@superset-ui/chart'; +import { RawBoxPlotDataRow, BoxPlotDataRow } from '../types'; + +export default function transformProps(chartProps: ChartProps) { + const { width, height, datasource = {}, formData, payload } = chartProps; + const { verboseMap = {} } = datasource; + const { colorScheme, groupby, metrics } = formData; + + const data = (payload.data as RawBoxPlotDataRow[]).map(({ label, values }) => ({ + label, + min: values.whisker_low, + max: values.whisker_high, + firstQuartile: values.Q1, + median: values.Q2, + thirdQuartile: values.Q3, + outliers: values.outliers, + })); + + const xAxisLabel = groupby.join('/'); + const yAxisLabel = metrics.length > 0 ? verboseMap[metrics[0]] || metrics[0] : ''; + + const boxPlotValues = data.reduce((r: number[], e: BoxPlotDataRow) => { + r.push(e.min, e.max, ...e.outliers); + + return r; + }, []); + + const minBoxPlotValue = Math.min(...boxPlotValues); + const maxBoxPlotValue = Math.max(...boxPlotValues); + const valueDomain = [ + minBoxPlotValue - 0.1 * Math.abs(minBoxPlotValue), + maxBoxPlotValue + 0.1 * Math.abs(maxBoxPlotValue), + ]; + + return { + data, + width, + height, + encoding: { + x: { + field: 'label', + type: 'nominal', + scale: { + type: 'band', + paddingInner: 0.15, + paddingOuter: 0.3, + }, + axis: { + title: xAxisLabel, + }, + }, + y: { + field: 'value', + type: 'quantitative', + scale: { + type: 'linear', + domain: valueDomain, + }, + axis: { + title: yAxisLabel, + numTicks: 5, + format: 'SMART_NUMBER', + }, + }, + color: { + field: 'label', + type: 'nominal', + scale: { + scheme: colorScheme, + }, + legend: false, + }, + }, + }; +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/transformProps.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/transformProps.ts new file mode 100644 index 000000000000..959ca29b61db --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/transformProps.ts @@ -0,0 +1,68 @@ +import { ChartProps } from '@superset-ui/chart'; +import { BoxPlotDataRow, RawBoxPlotDataRow } from './types'; + +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* eslint-disable sort-keys, no-magic-numbers */ + +export default function transformProps(chartProps: ChartProps) { + const { width, height, formData, payload } = chartProps; + const { encoding, margin, theme } = formData; + + const data = (payload.data as RawBoxPlotDataRow[]).map(({ label, values }) => ({ + label, + min: values.whisker_low, + max: values.whisker_high, + firstQuartile: values.Q1, + median: values.Q2, + thirdQuartile: values.Q3, + outliers: values.outliers, + })); + + const isHorizontal = encoding.y.type === 'nominal'; + + const boxPlotValues = data.reduce((r: number[], e: BoxPlotDataRow) => { + r.push(e.min, e.max, ...e.outliers); + + return r; + }, []); + + const minBoxPlotValue = Math.min(...boxPlotValues); + const maxBoxPlotValue = Math.max(...boxPlotValues); + const valueDomain = [ + minBoxPlotValue - 0.1 * Math.abs(minBoxPlotValue), + maxBoxPlotValue + 0.1 * Math.abs(maxBoxPlotValue), + ]; + + if (isHorizontal) { + encoding.x.scale.domain = valueDomain; + } else { + encoding.y.scale.domain = valueDomain; + } + + return { + data, + width, + height, + margin, + theme, + encoding, + }; +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/types.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/types.ts new file mode 100644 index 000000000000..8b1839ee3c9c --- /dev/null +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/BoxPlot/types.ts @@ -0,0 +1,23 @@ +export interface RawBoxPlotDataRow { + label: string; + values: { + Q1: number; + Q2: number; + Q3: number; + outliers: number[]; + // eslint-disable-next-line camelcase + whisker_high: number; + // eslint-disable-next-line camelcase + whisker_low: number; + }; +} + +export interface BoxPlotDataRow { + label: string; + min: number; + max: number; + firstQuartile: number; + median: number; + thirdQuartile: number; + outliers: number[]; +} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.tsx index d1de33e0d939..a373a021c9b5 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.tsx +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/Line/createTooltip.tsx @@ -9,7 +9,7 @@ import Encoder from './Encoder'; const MARK_STYLE = { marginRight: 4 }; export default function createTooltip(encoder: Encoder, allSeries: Series[]) { - function LineTooltip({ + return function LineTooltip({ datum, series = {}, }: { @@ -57,7 +57,5 @@ export default function createTooltip(encoder: Encoder, allSeries: Series[]) { ); - } - - return LineTooltip; + }; } diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx index b106a876b5cb..e0fc6c4d63c5 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/components/tooltip/TooltipTable.tsx @@ -4,7 +4,7 @@ type Props = { className?: string; data: { key: string | number; - keyColumn: ReactNode; + keyColumn?: ReactNode; keyStyle?: CSSProperties; valueColumn: ReactNode; valueStyle?: CSSProperties; @@ -27,7 +27,7 @@ export default class TooltipTable extends PureComponent { {data.map(({ key, keyColumn, keyStyle, valueColumn, valueStyle }, i) => ( - {keyColumn} + {keyColumn || key} {valueColumn} diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/index.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/index.ts index ce786e69281a..498637196f70 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/index.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/index.ts @@ -1,2 +1,2 @@ -/* eslint-disable import/prefer-default-export */ +export { default as BoxPlotChartPlugin } from './BoxPlot'; export { default as LineChartPlugin } from './Line'; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/legacy.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/legacy.ts index 6a9010bda4c6..c0403f479c96 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/legacy.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/src/legacy.ts @@ -1,2 +1,2 @@ -/* eslint-disable import/prefer-default-export */ +export { default as BoxPlotChartPlugin } from './BoxPlot/legacy'; export { default as LineChartPlugin } from './Line/legacy'; diff --git a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/types/@data-ui/xy-chart/index.d.ts b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/types/@data-ui/xy-chart/index.d.ts index 3e48cb665a7e..504be9e51650 100644 --- a/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/types/@data-ui/xy-chart/index.d.ts +++ b/superset-frontend/temporary_superset_ui/superset-ui/plugins/superset-ui-plugins/packages/superset-ui-preset-chart-xy/types/@data-ui/xy-chart/index.d.ts @@ -20,15 +20,16 @@ declare module '@data-ui/xy-chart' { onMouseMove?: (...args: any[]) => void; onMouseLeave?: (...args: any[]) => void; renderTooltip: any; - showYGrid: boolean; - snapTooltipToDataX: boolean; - theme: any; - tooltipData: any; + showYGrid?: boolean; + snapTooltipToDataX?: boolean; + theme?: any; + tooltipData?: any; xScale: any; yScale: any; } export class AreaSeries extends React.PureComponent {} + export class BoxPlotSeries extends React.PureComponent {} export class CrossHair extends React.PureComponent {} export class LinearGradient extends React.PureComponent {} export class LineSeries extends React.PureComponent {}