From bd806520bed9bac20e659b3fcc422987305c08f3 Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Fri, 15 Nov 2019 17:55:09 -0800 Subject: [PATCH 01/11] feat: convert word cloud to use encodable --- .../package.json | 3 +- .../src/Encoder.ts | 24 +++++++++ .../src/WordCloud.tsx | 50 ++++++++++--------- .../src/WordCloudFormData.ts | 10 ++-- .../src/transformProps.ts | 28 +++++++++-- 5 files changed, 83 insertions(+), 32 deletions(-) create mode 100644 packages/superset-ui-plugin-chart-word-cloud/src/Encoder.ts diff --git a/packages/superset-ui-plugin-chart-word-cloud/package.json b/packages/superset-ui-plugin-chart-word-cloud/package.json index 5bf136b8f..fb0fc3d05 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/package.json +++ b/packages/superset-ui-plugin-chart-word-cloud/package.json @@ -32,7 +32,8 @@ "@types/d3-scale": "^2.0.2", "@types/react": "^16.3.0", "d3-cloud": "^1.2.5", - "d3-scale": "^3.0.1" + "d3-scale": "^3.0.1", + "encodable": "^0.0.4" }, "peerDependencies": { "@superset-ui/chart": "^0.12.0", diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/Encoder.ts b/packages/superset-ui-plugin-chart-word-cloud/src/Encoder.ts new file mode 100644 index 000000000..7e73dd34f --- /dev/null +++ b/packages/superset-ui-plugin-chart-word-cloud/src/Encoder.ts @@ -0,0 +1,24 @@ +import { createEncoderFactory } from 'encodable'; +import { DeriveEncoding } from 'encodable/lib/types/Encoding'; + +type WordCloudEncodingConfig = { + color: ['Color', string]; + size: ['Numeric', number]; + text: ['Text', string]; +}; + +// eslint-disable-next-line import/prefer-default-export +export const wordCloudEncoderFactory = createEncoderFactory({ + channelTypes: { + color: 'Color', + size: 'Numeric', + text: 'Text', + }, + defaultEncoding: { + color: { value: 'black' }, + size: { value: 20 }, + text: { value: '' }, + }, +}); + +export type WordCloudEncoding = DeriveEncoding; diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx index 263a4ba58..acdad1af3 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx @@ -1,7 +1,6 @@ import React from 'react'; -import { scaleLinear } from 'd3-scale'; import cloudLayout, { Word } from 'd3-cloud'; -import { CategoricalColorNamespace } from '@superset-ui/color'; +import { WordCloudEncoding, wordCloudEncoderFactory } from './Encoder'; const ROTATION = { flat: () => 0, @@ -16,12 +15,17 @@ interface Datum { text: string; } -export interface Props { - colorScheme: string; +/** + * These props should be stored when saving the chart. + */ +export interface WordCloudVisualProps { + encoding: Partial; + rotation: keyof typeof ROTATION; +} + +export interface WordCloudProps extends WordCloudVisualProps { data: Datum[]; height: number; - rotation: 'flat' | 'random' | 'square'; - sizeRange: number[]; width: number; } @@ -29,26 +33,28 @@ interface State { words: Word[]; } -export default class WordCloud extends React.PureComponent { +export default class WordCloud extends React.PureComponent { isMounted: boolean = false; state: State = { words: [], }; + createEncoder = wordCloudEncoderFactory.createSelector(); + componentDidMount() { this.isMounted = true; this.update(); } - componentDidUpdate(prevProps: Props) { - const { data, width, height, rotation, sizeRange } = this.props; + componentDidUpdate(prevProps: WordCloudProps) { + const { data, encoding, width, height, rotation } = this.props; if ( prevProps.data !== data || + prevProps.encoding !== encoding || prevProps.width !== width || prevProps.height !== height || - prevProps.rotation !== rotation || - prevProps.sizeRange !== sizeRange + prevProps.rotation !== rotation ) { this.update(); } @@ -65,33 +71,29 @@ export default class WordCloud extends React.PureComponent { }; update() { - const { data, width, height, rotation, sizeRange } = this.props; - - const size: [number, number] = [width, height]; - const rotationFn = ROTATION[rotation] || ROTATION.flat; + const { data, width, height, rotation, encoding } = this.props; - const scale = scaleLinear() - .range(sizeRange) - .domain([0, Math.max(...data.map(d => d.size))]); + const encoder = this.createEncoder(encoding); + encoder.channels.size.setDomainFromDataset(data); cloudLayout() - .size(size) + .size([width, height]) .words(data) /* eslint-disable-next-line no-magic-numbers */ .padding(5) - .rotate(rotationFn) + .rotate(ROTATION[rotation] || ROTATION.flat) .font('Helvetica') .fontWeight('bold') - .fontSize(d => scale(d.size)) + .fontSize(d => encoder.channels.size.encodeDatum(d) as number) .on('end', this.setWords) .start(); } render() { - const { width, height, colorScheme } = this.props; + const { width, height, encoding } = this.props; const { words } = this.state; - const colorFn = CategoricalColorNamespace.getScale(colorScheme); + const encoder = this.createEncoder(encoding); return ( @@ -102,7 +104,7 @@ export default class WordCloud extends React.PureComponent { fontSize={`${w.size}px`} fontWeight="bold" fontFamily="Helvetica" - fill={colorFn(w.text)} + fill={encoder.channels.color.encodeDatum(w) as string} textAnchor="middle" transform={`translate(${w.x}, ${w.y}) rotate(${w.rotate})`} > diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts index b3b34bd95..0d0dbd44a 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts @@ -1,9 +1,11 @@ import { QueryFormData } from '@superset-ui/query'; +import { WordCloudVisualProps } from './WordCloud'; // FormData for wordcloud contains both common properties of all form data -// and properties specific to wordcloud vizzes -type WordCloudFormData = QueryFormData & { - series: string; -}; +// and properties specific to wordcloud visualization +type WordCloudFormData = QueryFormData & + WordCloudVisualProps & { + series: string; + }; export default WordCloudFormData; diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts index a26529fe0..e3bcd9558 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts @@ -1,4 +1,6 @@ import { ChartProps } from '@superset-ui/chart'; +import { WordCloudEncoding } from './Encoder'; +import { Props } from './WordCloud'; function transformData(data: ChartProps['queryData'][], formData: ChartProps['formData']) { const { metric, series } = formData; @@ -11,16 +13,36 @@ function transformData(data: ChartProps['queryData'][], formData: ChartProps['fo return transformedData; } -export default function transformProps(chartProps: ChartProps) { +export default function transformProps(chartProps: ChartProps): Props { const { width, height, formData, queryData } = chartProps; const { colorScheme, rotation, sizeTo } = formData; + const encoding: Partial = { + color: { + field: 'text', + scale: { + scheme: colorScheme, + }, + type: 'nominal', + }, + size: { + field: 'size', + scale: { + range: [0, sizeTo], + zero: true, + }, + type: 'quantitative', + }, + text: { + field: 'text', + }, + }; + return { - colorScheme, data: transformData(queryData.data, formData), + encoding, height, rotation, - sizeRange: [0, sizeTo], width, }; } From 5aae2e6c4a12067baabc649e30123fb0bdd4d4f5 Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Fri, 15 Nov 2019 23:31:00 -0800 Subject: [PATCH 02/11] fix: minor bugs --- packages/superset-ui-plugin-chart-word-cloud/package.json | 2 +- .../superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx | 4 ++-- .../superset-ui-plugin-chart-word-cloud/src/transformProps.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/superset-ui-plugin-chart-word-cloud/package.json b/packages/superset-ui-plugin-chart-word-cloud/package.json index fb0fc3d05..0b7cbe096 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/package.json +++ b/packages/superset-ui-plugin-chart-word-cloud/package.json @@ -33,7 +33,7 @@ "@types/react": "^16.3.0", "d3-cloud": "^1.2.5", "d3-scale": "^3.0.1", - "encodable": "^0.0.4" + "encodable": "^0.0.5" }, "peerDependencies": { "@superset-ui/chart": "^0.12.0", diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx index acdad1af3..0449a1421 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx @@ -84,7 +84,7 @@ export default class WordCloud extends React.PureComponent encoder.channels.size.encodeDatum(d) as number) + .fontSize(d => encoder.channels.size.encodeDatum(d, 0)) .on('end', this.setWords) .start(); } @@ -104,7 +104,7 @@ export default class WordCloud extends React.PureComponent diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts index e3bcd9558..a55b7af26 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts @@ -1,6 +1,6 @@ import { ChartProps } from '@superset-ui/chart'; import { WordCloudEncoding } from './Encoder'; -import { Props } from './WordCloud'; +import { WordCloudProps } from './WordCloud'; function transformData(data: ChartProps['queryData'][], formData: ChartProps['formData']) { const { metric, series } = formData; @@ -13,7 +13,7 @@ function transformData(data: ChartProps['queryData'][], formData: ChartProps['fo return transformedData; } -export default function transformProps(chartProps: ChartProps): Props { +export default function transformProps(chartProps: ChartProps): WordCloudProps { const { width, height, formData, queryData } = chartProps; const { colorScheme, rotation, sizeTo } = formData; From c4ed5955bbe05ac22f9df922cbb95770d133dd49 Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 01:11:16 -0800 Subject: [PATCH 03/11] feat: bump dependencies --- packages/superset-ui-plugin-chart-word-cloud/package.json | 2 +- packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/superset-ui-plugin-chart-word-cloud/package.json b/packages/superset-ui-plugin-chart-word-cloud/package.json index 0b7cbe096..42509c717 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/package.json +++ b/packages/superset-ui-plugin-chart-word-cloud/package.json @@ -33,7 +33,7 @@ "@types/react": "^16.3.0", "d3-cloud": "^1.2.5", "d3-scale": "^3.0.1", - "encodable": "^0.0.5" + "encodable": "^0.0.6" }, "peerDependencies": { "@superset-ui/chart": "^0.12.0", diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx index 0449a1421..62996627d 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx @@ -104,7 +104,7 @@ export default class WordCloud extends React.PureComponent From f99e762b7c2b06852455516bf7740bf55e106496 Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 01:25:29 -0800 Subject: [PATCH 04/11] feat: use field --- .../src/WordCloud.tsx | 10 +++------ .../src/transformProps.ts | 21 +++++-------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx index 62996627d..3702246e4 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx @@ -1,5 +1,6 @@ import React from 'react'; import cloudLayout, { Word } from 'd3-cloud'; +import { PlainObject } from 'encodable/lib/types/Data'; import { WordCloudEncoding, wordCloudEncoderFactory } from './Encoder'; const ROTATION = { @@ -10,11 +11,6 @@ const ROTATION = { square: () => Math.floor(Math.random() * 2) * 90, }; -interface Datum { - size: number; - text: string; -} - /** * These props should be stored when saving the chart. */ @@ -24,7 +20,7 @@ export interface WordCloudVisualProps { } export interface WordCloudProps extends WordCloudVisualProps { - data: Datum[]; + data: PlainObject[]; height: number; width: number; } @@ -76,7 +72,7 @@ export default class WordCloud extends React.PureComponent() + cloudLayout() .size([width, height]) .words(data) /* eslint-disable-next-line no-magic-numbers */ diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts index a55b7af26..32b698cb4 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts @@ -2,31 +2,20 @@ import { ChartProps } from '@superset-ui/chart'; import { WordCloudEncoding } from './Encoder'; import { WordCloudProps } from './WordCloud'; -function transformData(data: ChartProps['queryData'][], formData: ChartProps['formData']) { - const { metric, series } = formData; - - const transformedData = data.map(datum => ({ - size: datum[metric.label || metric], - text: datum[series], - })); - - return transformedData; -} - export default function transformProps(chartProps: ChartProps): WordCloudProps { const { width, height, formData, queryData } = chartProps; - const { colorScheme, rotation, sizeTo } = formData; + const { colorScheme, metric, rotation, series, sizeTo } = formData; const encoding: Partial = { color: { - field: 'text', + field: series, scale: { scheme: colorScheme, }, type: 'nominal', }, size: { - field: 'size', + field: metric.label || metric, scale: { range: [0, sizeTo], zero: true, @@ -34,12 +23,12 @@ export default function transformProps(chartProps: ChartProps): WordCloudProps { type: 'quantitative', }, text: { - field: 'text', + field: series, }, }; return { - data: transformData(queryData.data, formData), + data: queryData.data, encoding, height, rotation, From f5e429e34d895d1fdf7ad4a35067461b76deb57b Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 12:56:25 -0800 Subject: [PATCH 05/11] fix: defaultProps --- .../src/WordCloud.tsx | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx index 3702246e4..6963c4960 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx @@ -15,8 +15,8 @@ const ROTATION = { * These props should be stored when saving the chart. */ export interface WordCloudVisualProps { - encoding: Partial; - rotation: keyof typeof ROTATION; + encoding?: Partial; + rotation?: keyof typeof ROTATION; } export interface WordCloudProps extends WordCloudVisualProps { @@ -29,7 +29,15 @@ interface State { words: Word[]; } -export default class WordCloud extends React.PureComponent { +const defaultProps = { + encoding: {}, + rotation: 'flat', +}; + +export default class WordCloud extends React.PureComponent< + WordCloudProps & typeof defaultProps, + State +> { isMounted: boolean = false; state: State = { words: [], @@ -37,6 +45,8 @@ export default class WordCloud extends React.PureComponent encoder.channels.text.getValueFromDatum(d)) .font('Helvetica') .fontWeight('bold') .fontSize(d => encoder.channels.size.encodeDatum(d, 0)) From debd1e4bb4e922150aca41b9253634a48a72cd5a Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 18:30:03 -0800 Subject: [PATCH 06/11] fix: unit test --- .../src/WordCloud.tsx | 6 ++- .../src/buildQuery.ts | 2 +- .../src/index.ts | 2 +- .../src/legacy/index.ts | 25 +++++++++ .../src/legacy/transformProps.ts | 54 +++++++++++++++++++ .../src/legacy/types.ts | 9 ++++ .../src/transformProps.ts | 25 +-------- .../src/{WordCloudFormData.ts => types.ts} | 4 +- .../test/index.test.ts | 5 -- .../test/{ => legacy}/transformProps.test.ts | 26 +++++++-- 10 files changed, 119 insertions(+), 39 deletions(-) create mode 100644 packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts create mode 100644 packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts create mode 100644 packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts rename packages/superset-ui-plugin-chart-word-cloud/src/{WordCloudFormData.ts => types.ts} (79%) delete mode 100644 packages/superset-ui-plugin-chart-word-cloud/test/index.test.ts rename packages/superset-ui-plugin-chart-word-cloud/test/{ => legacy}/transformProps.test.ts (57%) diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx index 6963c4960..cfd3a7e29 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx @@ -3,7 +3,7 @@ import cloudLayout, { Word } from 'd3-cloud'; import { PlainObject } from 'encodable/lib/types/Data'; import { WordCloudEncoding, wordCloudEncoderFactory } from './Encoder'; -const ROTATION = { +export const ROTATION = { flat: () => 0, /* eslint-disable-next-line no-magic-numbers */ random: () => Math.floor(Math.random() * 6 - 3) * 30, @@ -11,12 +11,14 @@ const ROTATION = { square: () => Math.floor(Math.random() * 2) * 90, }; +export type RotationType = keyof typeof ROTATION; + /** * These props should be stored when saving the chart. */ export interface WordCloudVisualProps { encoding?: Partial; - rotation?: keyof typeof ROTATION; + rotation?: RotationType; } export interface WordCloudProps extends WordCloudVisualProps { diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/buildQuery.ts b/packages/superset-ui-plugin-chart-word-cloud/src/buildQuery.ts index 04e034beb..d83f8638a 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/buildQuery.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/buildQuery.ts @@ -1,5 +1,5 @@ import { buildQueryContext } from '@superset-ui/query'; -import WordCloudFormData from './WordCloudFormData'; +import { WordCloudFormData } from './types'; export default function buildQuery(formData: WordCloudFormData) { // Set the single QueryObject's groupby field with series in formData diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/index.ts b/packages/superset-ui-plugin-chart-word-cloud/src/index.ts index d99b772e8..863d623c6 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/index.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/index.ts @@ -1,7 +1,7 @@ import { t } from '@superset-ui/translation'; import { ChartMetadata, ChartPlugin } from '@superset-ui/chart'; import buildQuery from './buildQuery'; -import WordCloudFormData from './WordCloudFormData'; +import { WordCloudFormData } from './types'; import transformProps from './transformProps'; import thumbnail from './images/thumbnail.png'; diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts new file mode 100644 index 000000000..601c73370 --- /dev/null +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts @@ -0,0 +1,25 @@ +import { t } from '@superset-ui/translation'; +import { ChartMetadata, ChartPlugin } from '@superset-ui/chart'; +import buildQuery from '../buildQuery'; +import transformProps from './transformProps'; +import thumbnail from '../images/thumbnail.png'; +import { LegacyWordCloudFormData } from './types'; + +const metadata = new ChartMetadata({ + credits: ['https://github.com/jasondavies/d3-cloud'], + description: '', + name: t('Word Cloud'), + thumbnail, + useLegacyApi: true, +}); + +export default class WordCloudChartPlugin extends ChartPlugin { + constructor() { + super({ + buildQuery, + loadChart: () => import('../WordCloud'), + metadata, + transformProps, + }); + } +} diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts new file mode 100644 index 000000000..86087c40f --- /dev/null +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts @@ -0,0 +1,54 @@ +import { ChartProps } from '@superset-ui/chart'; +import { WordCloudEncoding } from '../Encoder'; +import { WordCloudProps } from '../WordCloud'; +import { LegacyWordCloudFormData } from './types'; + +function getMetricLabel(metric: LegacyWordCloudFormData['metric']): string | undefined { + if (typeof metric === 'string' || typeof metric === 'undefined') { + return metric; + } + if (Array.isArray(metric)) { + return metric.length > 0 ? getMetricLabel(metric[0]) : undefined; + } + + return metric.label; +} + +export default function transformProps(chartProps: ChartProps): WordCloudProps { + const { width, height, formData, queryData } = chartProps; + const { colorScheme, metric, rotation, series, sizeTo } = formData as LegacyWordCloudFormData; + + const metricLabel = getMetricLabel(metric); + + const encoding: Partial = { + color: { + field: series, + scale: { + scheme: colorScheme, + }, + type: 'nominal', + }, + size: + typeof metricLabel === 'undefined' + ? undefined + : { + field: metricLabel, + scale: { + range: [0, sizeTo], + zero: true, + }, + type: 'quantitative', + }, + text: { + field: series, + }, + }; + + return { + data: queryData.data, + encoding, + height, + rotation, + width, + }; +} diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts new file mode 100644 index 000000000..8a70c6d93 --- /dev/null +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts @@ -0,0 +1,9 @@ +import { QueryFormData } from '@superset-ui/query'; +import { RotationType } from '../WordCloud'; + +export type LegacyWordCloudFormData = QueryFormData & { + colorScheme: string; + rotation?: RotationType; + series: string; + sizeTo: number; +}; diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts index 32b698cb4..c3a7f6ad8 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts @@ -1,31 +1,10 @@ import { ChartProps } from '@superset-ui/chart'; -import { WordCloudEncoding } from './Encoder'; import { WordCloudProps } from './WordCloud'; +import { WordCloudFormData } from './types'; export default function transformProps(chartProps: ChartProps): WordCloudProps { const { width, height, formData, queryData } = chartProps; - const { colorScheme, metric, rotation, series, sizeTo } = formData; - - const encoding: Partial = { - color: { - field: series, - scale: { - scheme: colorScheme, - }, - type: 'nominal', - }, - size: { - field: metric.label || metric, - scale: { - range: [0, sizeTo], - zero: true, - }, - type: 'quantitative', - }, - text: { - field: series, - }, - }; + const { encoding, rotation } = formData as WordCloudFormData; return { data: queryData.data, diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts b/packages/superset-ui-plugin-chart-word-cloud/src/types.ts similarity index 79% rename from packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts rename to packages/superset-ui-plugin-chart-word-cloud/src/types.ts index 0d0dbd44a..7cdd44ec1 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloudFormData.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/types.ts @@ -3,9 +3,7 @@ import { WordCloudVisualProps } from './WordCloud'; // FormData for wordcloud contains both common properties of all form data // and properties specific to wordcloud visualization -type WordCloudFormData = QueryFormData & +export type WordCloudFormData = QueryFormData & WordCloudVisualProps & { series: string; }; - -export default WordCloudFormData; diff --git a/packages/superset-ui-plugin-chart-word-cloud/test/index.test.ts b/packages/superset-ui-plugin-chart-word-cloud/test/index.test.ts deleted file mode 100644 index 457263a03..000000000 --- a/packages/superset-ui-plugin-chart-word-cloud/test/index.test.ts +++ /dev/null @@ -1,5 +0,0 @@ -describe('My Test', () => { - it('tests something', () => { - expect(1).toEqual(1); - }); -}); diff --git a/packages/superset-ui-plugin-chart-word-cloud/test/transformProps.test.ts b/packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts similarity index 57% rename from packages/superset-ui-plugin-chart-word-cloud/test/transformProps.test.ts rename to packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts index 0461e07b5..60491fbec 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/test/transformProps.test.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts @@ -1,6 +1,6 @@ import 'babel-polyfill'; import { ChartProps } from '@superset-ui/chart'; -import transformProps from '../src/transformProps'; +import transformProps from '../../src/legacy/transformProps'; describe('WordCloud tranformProps', () => { const formData = { @@ -24,12 +24,30 @@ describe('WordCloud tranformProps', () => { it('should tranform chart props for word cloud viz', () => { expect(transformProps(chartProps)).toEqual({ - colorScheme: 'bnbColors', width: 800, height: 600, + encoding: { + color: { + field: 'name', + scale: { + scheme: 'bnbColors', + }, + type: 'nominal', + }, + size: { + field: 'sum__num', + scale: { + range: [0, 70], + zero: true, + }, + type: 'quantitative', + }, + text: { + field: 'name', + }, + }, rotation: 'square', - sizeRange: [0, 70], - data: [{ size: 1, text: 'Hulk' }], + data: [{ name: 'Hulk', sum__num: 1 }], }); }); }); From 3d4a66fa88b0e3557b234cd414bb76a6fa129dfa Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 22:18:43 -0800 Subject: [PATCH 07/11] docs: update storybook --- .../plugin-chart-word-cloud/Stories.tsx | 41 ++++++++++++++++++- .../stories/plugin-chart-word-cloud/index.js | 4 +- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx index 638848e46..4ad9528bd 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx @@ -8,7 +8,44 @@ export default [ { renderStory: () => ( + ), + storyName: 'Basic', + storyPath: 'plugin-chart-word-cloud|WordCloudChartPlugin', + }, + { + renderStory: () => ( + ), - storyName: 'Basic', + storyName: 'Legacy', storyPath: 'plugin-chart-word-cloud|WordCloudChartPlugin', }, ]; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js index 447eb7c2a..b0e111bee 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js @@ -1,7 +1,9 @@ import WordCloudChartPlugin from '../../../../superset-ui-plugin-chart-word-cloud'; +import LegacyWordCloudChartPlugin from '../../../../superset-ui-plugin-chart-word-cloud/esm/legacy'; import Stories from './Stories'; -new WordCloudChartPlugin().configure({ key: 'word-cloud' }).register(); +new WordCloudChartPlugin().configure({ key: 'word-cloud2' }).register(); +new LegacyWordCloudChartPlugin().configure({ key: 'legacy-word-cloud2' }).register(); export default { examples: [...Stories], From a7046a984de8b034431b9e2535f6e75b542dd3f2 Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 22:31:35 -0800 Subject: [PATCH 08/11] refactor: move files --- .../src/{ => chart}/Encoder.ts | 0 .../src/{ => chart}/WordCloud.tsx | 4 ++-- packages/superset-ui-plugin-chart-word-cloud/src/index.ts | 2 +- .../superset-ui-plugin-chart-word-cloud/src/legacy/index.ts | 2 +- .../src/legacy/transformProps.ts | 4 ++-- .../superset-ui-plugin-chart-word-cloud/src/legacy/types.ts | 2 +- .../superset-ui-plugin-chart-word-cloud/src/transformProps.ts | 2 +- packages/superset-ui-plugin-chart-word-cloud/src/types.ts | 2 +- .../storybook/stories/plugin-chart-word-cloud/Stories.tsx | 4 ++-- .../storybook/stories/plugin-chart-word-cloud/index.js | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) rename packages/superset-ui-plugin-chart-word-cloud/src/{ => chart}/Encoder.ts (100%) rename packages/superset-ui-plugin-chart-word-cloud/src/{ => chart}/WordCloud.tsx (97%) diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/Encoder.ts b/packages/superset-ui-plugin-chart-word-cloud/src/chart/Encoder.ts similarity index 100% rename from packages/superset-ui-plugin-chart-word-cloud/src/Encoder.ts rename to packages/superset-ui-plugin-chart-word-cloud/src/chart/Encoder.ts diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx similarity index 97% rename from packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx rename to packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx index cfd3a7e29..ab4752b4e 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx @@ -111,8 +111,8 @@ export default class WordCloud extends React.PureComponent< constructor() { super({ buildQuery, - loadChart: () => import('./WordCloud'), + loadChart: () => import('./chart/WordCloud'), metadata, transformProps, }); diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts index 601c73370..0eaeefee3 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/index.ts @@ -17,7 +17,7 @@ export default class WordCloudChartPlugin extends ChartPlugin import('../WordCloud'), + loadChart: () => import('../chart/WordCloud'), metadata, transformProps, }); diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts index 86087c40f..b2ae78e8b 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts @@ -1,6 +1,6 @@ import { ChartProps } from '@superset-ui/chart'; -import { WordCloudEncoding } from '../Encoder'; -import { WordCloudProps } from '../WordCloud'; +import { WordCloudEncoding } from '../chart/Encoder'; +import { WordCloudProps } from '../chart/WordCloud'; import { LegacyWordCloudFormData } from './types'; function getMetricLabel(metric: LegacyWordCloudFormData['metric']): string | undefined { diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts index 8a70c6d93..0b4b7482e 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/types.ts @@ -1,5 +1,5 @@ import { QueryFormData } from '@superset-ui/query'; -import { RotationType } from '../WordCloud'; +import { RotationType } from '../chart/WordCloud'; export type LegacyWordCloudFormData = QueryFormData & { colorScheme: string; diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts index c3a7f6ad8..2004ea39e 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/transformProps.ts @@ -1,5 +1,5 @@ import { ChartProps } from '@superset-ui/chart'; -import { WordCloudProps } from './WordCloud'; +import { WordCloudProps } from './chart/WordCloud'; import { WordCloudFormData } from './types'; export default function transformProps(chartProps: ChartProps): WordCloudProps { diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/types.ts b/packages/superset-ui-plugin-chart-word-cloud/src/types.ts index 7cdd44ec1..4ea732426 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/types.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/types.ts @@ -1,5 +1,5 @@ import { QueryFormData } from '@superset-ui/query'; -import { WordCloudVisualProps } from './WordCloud'; +import { WordCloudVisualProps } from './chart/WordCloud'; // FormData for wordcloud contains both common properties of all form data // and properties specific to wordcloud visualization diff --git a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx index 4ad9528bd..ded0d8c77 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx @@ -34,7 +34,7 @@ export default [ }, }, metric: 'sum__num', - rotation: select('Rotation', ['square', 'flat', 'random'], 'square'), + rotation: select('Rotation', ['square', 'flat', 'random'], 'flat'), series: 'name', }} /> @@ -52,7 +52,7 @@ export default [ formData={{ colorScheme: 'd3Category10', metric: 'sum__num', - rotation: select('Rotation', ['square', 'flat', 'random'], 'square'), + rotation: select('Rotation', ['square', 'flat', 'random'], 'flat'), series: 'name', sizeFrom: '10', sizeTo: '70', diff --git a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js index b0e111bee..dd87ab281 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/index.js @@ -1,4 +1,4 @@ -import WordCloudChartPlugin from '../../../../superset-ui-plugin-chart-word-cloud'; +import WordCloudChartPlugin from '../../../../superset-ui-plugin-chart-word-cloud/src'; import LegacyWordCloudChartPlugin from '../../../../superset-ui-plugin-chart-word-cloud/esm/legacy'; import Stories from './Stories'; From 264ef8435fb3cdfaa4abf2bf34a635245528625d Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 23:20:43 -0800 Subject: [PATCH 09/11] docs: update storybook --- .../package.json | 2 +- .../src/chart/Encoder.ts | 12 ++- .../src/chart/WordCloud.tsx | 11 +-- .../src/legacy/transformProps.ts | 2 +- .../plugin-chart-word-cloud/Stories.tsx | 82 ++++++++++++++++++- 5 files changed, 96 insertions(+), 13 deletions(-) diff --git a/packages/superset-ui-plugin-chart-word-cloud/package.json b/packages/superset-ui-plugin-chart-word-cloud/package.json index 42509c717..a47116f4b 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/package.json +++ b/packages/superset-ui-plugin-chart-word-cloud/package.json @@ -33,7 +33,7 @@ "@types/react": "^16.3.0", "d3-cloud": "^1.2.5", "d3-scale": "^3.0.1", - "encodable": "^0.0.6" + "encodable": "^0.0.7" }, "peerDependencies": { "@superset-ui/chart": "^0.12.0", diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/chart/Encoder.ts b/packages/superset-ui-plugin-chart-word-cloud/src/chart/Encoder.ts index 7e73dd34f..0e636e2a3 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/chart/Encoder.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/chart/Encoder.ts @@ -3,7 +3,9 @@ import { DeriveEncoding } from 'encodable/lib/types/Encoding'; type WordCloudEncodingConfig = { color: ['Color', string]; - size: ['Numeric', number]; + fontFamily: ['Category', string]; + fontSize: ['Numeric', number]; + fontWeight: ['Category', string | number]; text: ['Text', string]; }; @@ -11,12 +13,16 @@ type WordCloudEncodingConfig = { export const wordCloudEncoderFactory = createEncoderFactory({ channelTypes: { color: 'Color', - size: 'Numeric', + fontFamily: 'Category', + fontSize: 'Numeric', + fontWeight: 'Category', text: 'Text', }, defaultEncoding: { color: { value: 'black' }, - size: { value: 20 }, + fontFamily: { value: 'Helvetica' }, + fontSize: { value: 20 }, + fontWeight: { value: 'bold' }, text: { value: '' }, }, }); diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx index ab4752b4e..48fd59640 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx @@ -82,7 +82,7 @@ export default class WordCloud extends React.PureComponent< const { data, width, height, rotation, encoding } = this.props; const encoder = this.createEncoder(encoding); - encoder.channels.size.setDomainFromDataset(data); + encoder.channels.fontSize.setDomainFromDataset(data); cloudLayout() .size([width, height]) @@ -91,9 +91,9 @@ export default class WordCloud extends React.PureComponent< .padding(5) .rotate(ROTATION[rotation] || ROTATION.flat) .text(d => encoder.channels.text.getValueFromDatum(d)) - .font('Helvetica') - .fontWeight('bold') - .fontSize(d => encoder.channels.size.encodeDatum(d, 0)) + .font(d => encoder.channels.fontFamily.encodeDatum(d, 'Helvetica')) + .fontWeight(d => encoder.channels.fontWeight.encodeDatum(d, 'normal')) + .fontSize(d => encoder.channels.fontSize.encodeDatum(d, 0)) .on('end', this.setWords) .start(); } @@ -103,6 +103,7 @@ export default class WordCloud extends React.PureComponent< const { words } = this.state; const encoder = this.createEncoder(encoding); + encoder.channels.color.setDomainFromDataset(words); return ( @@ -113,7 +114,7 @@ export default class WordCloud extends React.PureComponent< fontSize={`${w.size}px`} fontWeight={w.weight} fontFamily={w.font} - fill={encoder.channels.color.encodeValue(w.text, '')} + fill={encoder.channels.color.encodeDatum(w, '')} textAnchor="middle" transform={`translate(${w.x}, ${w.y}) rotate(${w.rotate})`} > diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts index b2ae78e8b..08e387796 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/src/legacy/transformProps.ts @@ -28,7 +28,7 @@ export default function transformProps(chartProps: ChartProps): WordCloudProps { }, type: 'nominal', }, - size: + fontSize: typeof metricLabel === 'undefined' ? undefined : { diff --git a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx index ded0d8c77..c0abd83cb 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/plugin-chart-word-cloud/Stories.tsx @@ -15,13 +15,89 @@ export default [ formData={{ encoding: { color: { + value: '#0097e6', + }, + fontSize: { + field: 'sum__num', + scale: { + range: [0, 70], + zero: true, + }, + type: 'quantitative', + }, + text: { field: 'name', + }, + }, + metric: 'sum__num', + rotation: select('Rotation', ['square', 'flat', 'random'], 'flat'), + series: 'name', + }} + /> + ), + storyName: 'Basic', + storyPath: 'plugin-chart-word-cloud|WordCloudChartPlugin', + }, + { + renderStory: () => ( + + ), + storyName: 'encodes color by word length', + storyPath: 'plugin-chart-word-cloud|WordCloudChartPlugin', + }, + { + renderStory: () => ( + ), - storyName: 'Basic', + storyName: 'encodes font family by first letter', storyPath: 'plugin-chart-word-cloud|WordCloudChartPlugin', }, { From 29034e9709e6e712c8dbfd3693f1f1e3d8aec683 Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Sat, 16 Nov 2019 23:41:57 -0800 Subject: [PATCH 10/11] fix: unit test --- .../test/legacy/transformProps.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts b/packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts index 60491fbec..4b28ca7da 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts +++ b/packages/superset-ui-plugin-chart-word-cloud/test/legacy/transformProps.test.ts @@ -34,7 +34,7 @@ describe('WordCloud tranformProps', () => { }, type: 'nominal', }, - size: { + fontSize: { field: 'sum__num', scale: { range: [0, 70], From 06b2e616a6a90184d1b53d97aa402bb559fe498e Mon Sep 17 00:00:00 2001 From: Krist Wongsuphasawat Date: Mon, 18 Nov 2019 23:54:22 -0800 Subject: [PATCH 11/11] fix: address comments --- .../superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx b/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx index 48fd59640..1ea136cbb 100644 --- a/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx +++ b/packages/superset-ui-plugin-chart-word-cloud/src/chart/WordCloud.tsx @@ -5,6 +5,7 @@ import { WordCloudEncoding, wordCloudEncoderFactory } from './Encoder'; export const ROTATION = { flat: () => 0, + // this calculates a random rotation between -90 and 90 degrees. /* eslint-disable-next-line no-magic-numbers */ random: () => Math.floor(Math.random() * 6 - 3) * 30, /* eslint-disable-next-line no-magic-numbers */