From c4c3f4a9935f75f1b939ad0a401ea39dce542561 Mon Sep 17 00:00:00 2001 From: Jianchao Yang Date: Mon, 16 Mar 2020 12:01:58 -0700 Subject: [PATCH 1/8] feat(big-number): format datetime according to granularity (#402) This adds support for "Time Grain" in Superset for Big Number with Trendline chart. --- .../src/BigNumber/BigNumber.jsx | 7 ++- .../src/BigNumber/transformProps.js | 41 ++++++++++++++- .../BigNumber/Stories.tsx | 51 +++++++++++++++++-- .../BigNumber/data.js | 2 +- .../BigNumber/index.js | 2 +- .../BigNumberTotal/Stories.tsx | 2 +- 6 files changed, 91 insertions(+), 14 deletions(-) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx index 6df74a9aa..fdcb37259 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx @@ -24,7 +24,6 @@ import PropTypes from 'prop-types'; import shortid from 'shortid'; import { XYChart, AreaSeries, CrossHair, LinearGradient } from '@data-ui/xy-chart'; import { BRAND_COLOR } from '@superset-ui/color'; -import { smartDateVerboseFormatter } from '@superset-ui/time-format'; import { computeMaxFontSize } from '@superset-ui/dimension'; import './BigNumber.css'; @@ -42,10 +41,10 @@ const PROPORTION = { TRENDLINE: 0.3, }; -export function renderTooltipFactory(formatValue) { +export function renderTooltipFactory(formatDate, formatValue) { function renderTooltip({ datum }) { const { x: rawDate, y: rawValue } = datum; - const formattedDate = smartDateVerboseFormatter(rawDate); + const formattedDate = formatDate(rawDate); const value = formatValue(rawValue); return ( @@ -96,7 +95,7 @@ const defaultProps = { startYAxisAtZero: true, trendLineData: null, mainColor: BRAND_COLOR, - renderTooltip: renderTooltipFactory(identity), + renderTooltip: renderTooltipFactory(identity, identity), }; class BigNumberVis extends React.PureComponent { diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js index 9de9d3812..e8683ad49 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js @@ -18,10 +18,45 @@ */ import * as color from 'd3-color'; import { getNumberFormatter, NumberFormats } from '@superset-ui/number-format'; +import { getTimeFormatter, TimeFormats, smartDateVerboseFormatter } from '@superset-ui/time-format'; import { renderTooltipFactory } from './BigNumber'; const TIME_COLUMN = '__timestamp'; +function getTimeFormatterForGranularity(granularity) { + // Translate time granularity to d3-format + const MINUTE = '%Y-%m-%d %H:%M'; + const SUNDAY_BASED_WEEK = '%Y W%U'; + const MONDAY_BASED_WEEK = '%Y W%W'; + const { DATABASE_DATE, DATABASE_DATETIME } = TimeFormats; + + // search for `builtin_time_grains` in incubator-superset/superset/db_engine_specs/base.py + const formats = { + date: DATABASE_DATE, + PT1S: DATABASE_DATETIME, // second + PT1M: MINUTE, // minute + PT5M: MINUTE, // 5 minute + PT10M: MINUTE, // 10 minute + PT15M: MINUTE, // 15 minute + 'PT0.5H': MINUTE, // half hour + PT1H: '%Y-%m-%d %H:00', // hour + P1D: DATABASE_DATE, // day + P1W: SUNDAY_BASED_WEEK, // week + P1M: 'smart_date_verbose', // month + 'P0.25Y': '%Y Q%q', // quarter + P1Y: '%Y', // year + // d3-time-format weeks does not support weeks start on Sunday + '1969-12-28T00:00:00Z/P1W': SUNDAY_BASED_WEEK, // 'week_start_sunday' + '1969-12-29T00:00:00Z/P1W': MONDAY_BASED_WEEK, // 'week_start_monday' + 'P1W/1970-01-03T00:00:00Z': SUNDAY_BASED_WEEK, // 'week_ending_saturday' + 'P1W/1970-01-04T00:00:00Z': MONDAY_BASED_WEEK, // 'week_ending_sunday' + }; + + return granularity in formats + ? getTimeFormatter(formats[granularity]) + : smartDateVerboseFormatter; +} + export default function transformProps(chartProps) { const { width, height, formData, queryData } = chartProps; const { @@ -36,6 +71,7 @@ export default function transformProps(chartProps) { subheader = '', vizType, } = formData; + const granularity = formData.timeGrainSqla; let { yAxisFormat } = formData; const { data } = queryData; @@ -47,7 +83,7 @@ export default function transformProps(chartProps) { let bigNumber; let trendLineData; - const metricName = metric && metric.label ? metric.label : metric; + const metricName = metric?.label ? metric.label : metric; const compareLag = Number(compareLagInput) || 0; const supportTrendLine = vizType === 'big_number'; const supportAndShowTrendLine = supportTrendLine && showTrendLine; @@ -92,6 +128,7 @@ export default function transformProps(chartProps) { }); } + const formatDate = getTimeFormatterForGranularity(granularity); const formatValue = getNumberFormatter(yAxisFormat); return { @@ -103,7 +140,7 @@ export default function transformProps(chartProps) { headerFontSize, subheaderFontSize, mainColor, - renderTooltip: renderTooltipFactory(formatValue), + renderTooltip: renderTooltipFactory(formatDate, formatValue), showTrendLine: supportAndShowTrendLine, startYAxisAtZero, subheader: formattedSubheader, diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx index 66bc69f79..b879ca491 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx @@ -1,7 +1,20 @@ /* eslint-disable no-magic-numbers, sort-keys */ import React from 'react'; import { SuperChart } from '@superset-ui/chart'; -import data from './data'; +import testData from './data'; + +/** + * Add null values to trendline data + * @param data input data + */ +function withNulls(origData: object[], nullPosition: number = 3) { + const data = [...origData]; + data[nullPosition] = { + ...data[nullPosition], + sum__SP_POP_TOTL: null, + }; + return data; +} export default [ { @@ -10,7 +23,34 @@ export default [ chartType="big-number" width={400} height={400} - queryData={{ data }} + queryData={{ data: testData }} + formData={{ + colorPicker: { + r: 0, + g: 122, + b: 135, + a: 1, + }, + compareLag: 1, + compareSuffix: 'over 10Y', + metric: 'sum__SP_POP_TOTL', + showTrendLine: true, + startYAxisAtZero: true, + vizType: 'big_number', + yAxisFormat: '.3s', + }} + /> + ), + storyName: 'Basic with Trendline', + storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', + }, + { + renderStory: () => ( + ), - storyName: 'Basic', + storyName: 'Null in the middle', storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', }, { @@ -37,7 +77,7 @@ export default [ chartType="big-number" width={400} height={400} - queryData={{ data: [] }} + queryData={{ data: testData.slice(0, 9) }} formData={{ colorPicker: { r: 0, @@ -45,6 +85,7 @@ export default [ b: 135, a: 1, }, + timeGrainSqla: 'P0.25Y', compareLag: 1, compareSuffix: 'over 10Y', metric: 'sum__SP_POP_TOTL', @@ -55,7 +96,7 @@ export default [ }} /> ), - storyName: 'No Data', + storyName: 'Missing head', storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', }, ]; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.js index 72770149b..cf0c78bb0 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.js @@ -54,6 +54,6 @@ export default [ }, { __timestamp: 978307200000.0, - sum__SP_POP_TOTL: 6173339411.0, + sum__SP_POP_TOTL: 617333941.0, }, ]; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js index efd17ed48..13eec8cf7 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js @@ -1,5 +1,5 @@ import { BigNumberChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number'; -import Stories from './Stories'; +import Stories from './Stories.tsx'; new BigNumberChartPlugin().configure({ key: 'big-number' }).register(); diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx index 8991554b4..cd65ee107 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx @@ -37,7 +37,7 @@ export default [ }} /> ), - storyName: 'No Data', + storyName: 'Basic No Data', storyPath: 'legacy-|preset-chart-big-number|BigNumberTotalChartPlugin', }, ]; From 38e6e330351d5810353c1be497f9e34b7b79a867 Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Mon, 16 Mar 2020 01:14:44 -0700 Subject: [PATCH 2/8] feat(big-number): add option to align time range In Superset, when a timeseries query has no data at the beginning period or end period of the filtered time range, there will not no data records at those periods, hence the trendline in Big Number chart would not render those periods. This often causes confusion and misinterpretaiton in dashboards, especially for those with multiple trendline charts aligned with each other. They could all be a very smooth line, but actually showing very different time ranges. This PR adds an option "alignTimeRange" to apply the filtered time range on the xAxis. Date periods for empty data will be rendered, but there will be no connected lines, dots, or tooltips for them. It's possible to still show tooltips for those periods, but I decided not to do that as: 1) it makes things much more complicated; 2) I don't want to confuse zero or nulls with empty data. --- .../src/BigNumber/BigNumber.jsx | 16 +++- .../src/BigNumber/transformProps.js | 23 +++-- .../BigNumber/Stories.tsx | 91 +++++++++---------- 3 files changed, 74 insertions(+), 56 deletions(-) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx index fdcb37259..da88a8289 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx @@ -71,11 +71,14 @@ function identity(x) { } const propTypes = { + alignTimeRange: PropTypes.bool, className: PropTypes.string, width: PropTypes.number.isRequired, height: PropTypes.number.isRequired, bigNumber: PropTypes.number.isRequired, formatBigNumber: PropTypes.func, + fromDatetime: PropTypes.number, + toDatetime: PropTypes.number, headerFontSize: PropTypes.number, subheader: PropTypes.string, subheaderFontSize: PropTypes.number, @@ -86,8 +89,11 @@ const propTypes = { renderTooltip: PropTypes.func, }; const defaultProps = { + alignTimeRange: false, className: '', formatBigNumber: identity, + fromDatetime: null, + toDatetime: null, headerFontSize: PROPORTION.HEADER, subheader: '', subheaderFontSize: PROPORTION.SUBHEADER, @@ -193,13 +199,21 @@ class BigNumberVis extends React.PureComponent { subheader, renderTooltip, startYAxisAtZero, + fromDatetime, + toDatetime, + alignTimeRange, } = this.props; + const xScale = { type: 'timeUtc' }; + if (alignTimeRange && fromDatetime && toDatetime) { + xScale.domain = [fromDatetime, toDatetime]; + } + return ( a[TIME_COLUMN] - b[TIME_COLUMN]); bigNumber = sortedData.length === 0 ? null : sortedData[sortedData.length - 1][metricName]; @@ -145,5 +147,8 @@ export default function transformProps(chartProps) { startYAxisAtZero, subheader: formattedSubheader, trendLineData, + fromDatetime, + toDatetime, + alignTimeRange, }; } diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx index b879ca491..6dd7c6a48 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx @@ -3,6 +3,24 @@ import React from 'react'; import { SuperChart } from '@superset-ui/chart'; import testData from './data'; +const TIME_COLUMN = '__timestamp'; + +const formData = { + colorPicker: { + r: 0, + g: 122, + b: 135, + a: 1, + }, + compareLag: 1, + compareSuffix: 'over 10Y', + metric: 'sum__SP_POP_TOTL', + showTrendLine: true, + startYAxisAtZero: true, + vizType: 'big_number', + yAxisFormat: '.3s', +}; + /** * Add null values to trendline data * @param data input data @@ -24,21 +42,7 @@ export default [ width={400} height={400} queryData={{ data: testData }} - formData={{ - colorPicker: { - r: 0, - g: 122, - b: 135, - a: 1, - }, - compareLag: 1, - compareSuffix: 'over 10Y', - metric: 'sum__SP_POP_TOTL', - showTrendLine: true, - startYAxisAtZero: true, - vizType: 'big_number', - yAxisFormat: '.3s', - }} + formData={formData} /> ), storyName: 'Basic with Trendline', @@ -51,21 +55,7 @@ export default [ width={400} height={400} queryData={{ data: withNulls(testData, 3) }} - formData={{ - colorPicker: { - r: 0, - g: 122, - b: 135, - a: 1, - }, - compareLag: 1, - compareSuffix: 'over 10Y', - metric: 'sum__SP_POP_TOTL', - showTrendLine: true, - startYAxisAtZero: true, - vizType: 'big_number', - yAxisFormat: '.3s', - }} + formData={formData} /> ), storyName: 'Null in the middle', @@ -77,26 +67,35 @@ export default [ chartType="big-number" width={400} height={400} - queryData={{ data: testData.slice(0, 9) }} + queryData={{ + data: testData.slice(0, 9), + from_dttm: testData[testData.length - 1][TIME_COLUMN], + to_dttm: testData[0][TIME_COLUMN], + }} + formData={formData} + /> + ), + storyName: 'Missing range start', + storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', + }, + { + renderStory: () => ( + ), - storyName: 'Missing head', + storyName: `Missing range start (don't align)`, storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', }, ]; From 3f80d848a1cb757af0a685b4bc5649e60e4d46a4 Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Mon, 16 Mar 2020 11:16:42 -0700 Subject: [PATCH 3/8] fix(big-number): disable alignRange by default --- .../legacy-preset-chart-big-number/BigNumber/Stories.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx index 6dd7c6a48..d975bfe23 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx @@ -72,10 +72,13 @@ export default [ from_dttm: testData[testData.length - 1][TIME_COLUMN], to_dttm: testData[0][TIME_COLUMN], }} - formData={formData} + formData={{ + ...formData, + alignTimeRange: true, + }} /> ), - storyName: 'Missing range start', + storyName: 'Missing range start (align time range)', storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', }, { From 14e7c483ac842a15aa7859c9bf99ebe6f7f65c1c Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Mon, 16 Mar 2020 21:06:33 -0700 Subject: [PATCH 4/8] refactor(big-number): migrate to Typescript --- .../package.json | 3 + .../{BigNumber.jsx => BigNumber.tsx} | 141 +++++++++--------- .../src/BigNumber/{index.js => index.ts} | 0 .../{transformProps.js => transformProps.ts} | 69 +++------ .../src/BigNumberTotal/{index.js => index.ts} | 0 .../src/types/external.d.ts | 19 +++ .../utils/getTimeFormatterForGranularity.ts | 70 +++++++++ .../BigNumber/Stories.tsx | 27 +++- .../BigNumber/{data.js => data.ts} | 0 .../BigNumber/index.js | 18 +++ .../BigNumberTotal/Stories.tsx | 19 ++- .../BigNumberTotal/{data.js => data.ts} | 1 - .../BigNumberTotal/index.js | 20 ++- 13 files changed, 259 insertions(+), 128 deletions(-) rename packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/{BigNumber.jsx => BigNumber.tsx} (66%) rename packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/{index.js => index.ts} (100%) rename packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/{transformProps.js => transformProps.ts} (62%) rename packages/superset-ui-legacy-preset-chart-big-number/src/BigNumberTotal/{index.js => index.ts} (100%) create mode 100644 packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts create mode 100644 packages/superset-ui-legacy-preset-chart-big-number/src/utils/getTimeFormatterForGranularity.ts rename packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/{data.js => data.ts} (100%) rename packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/{data.js => data.ts} (63%) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/package.json b/packages/superset-ui-legacy-preset-chart-big-number/package.json index 45d4ad3b1..c58bae232 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/package.json +++ b/packages/superset-ui-legacy-preset-chart-big-number/package.json @@ -42,5 +42,8 @@ "@superset-ui/time-format": "^0.12.0", "@superset-ui/translation": "^0.12.0", "react": "^15 || ^16" + }, + "devDependencies": { + "@types/shortid": "0.0.29" } } diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx similarity index 66% rename from packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx rename to packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx index da88a8289..9a6987f68 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.jsx +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx @@ -16,17 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -/* eslint-disable react/forbid-prop-types */ -/* eslint-disable react/jsx-sort-default-props */ -/* eslint-disable react/sort-prop-types */ import React from 'react'; -import PropTypes from 'prop-types'; import shortid from 'shortid'; +import { NumberFormatFunction } from '@superset-ui/number-format/lib/types'; +import { getNumberFormatter } from '@superset-ui/number-format'; import { XYChart, AreaSeries, CrossHair, LinearGradient } from '@data-ui/xy-chart'; import { BRAND_COLOR } from '@superset-ui/color'; import { computeMaxFontSize } from '@superset-ui/dimension'; import './BigNumber.css'; +import { smartDateVerboseFormatter } from '@superset-ui/time-format'; +import { TimeFormatFunction } from '@superset-ui/time-format/lib/types'; + +const defaultNumberFormatter = getNumberFormatter(undefined); const CHART_MARGIN = { top: 4, @@ -41,71 +43,69 @@ const PROPORTION = { TRENDLINE: 0.3, }; -export function renderTooltipFactory(formatDate, formatValue) { - function renderTooltip({ datum }) { - const { x: rawDate, y: rawValue } = datum; - const formattedDate = formatDate(rawDate); - const value = formatValue(rawValue); +type TimeSeriesDatum = { + x: number; // timestamp as a number + y: number; +}; +export function renderTooltipFactory( + formatDate = smartDateVerboseFormatter.formatFunc, + formatValue = defaultNumberFormatter, +) { + return function renderTooltip({ datum: { x, y } }: { datum: TimeSeriesDatum }) { + // even though `formatDate` supports timestamp as numbers, we need + // `new Date` to pass type check return (
- {formattedDate} + {formatDate(new Date(x))}
- {value} + {formatValue(y)}
); - } - - renderTooltip.propTypes = { - datum: PropTypes.shape({ - x: PropTypes.instanceOf(Date), - y: PropTypes.number, - }).isRequired, }; - - return renderTooltip; -} - -function identity(x) { - return x; } -const propTypes = { - alignTimeRange: PropTypes.bool, - className: PropTypes.string, - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - bigNumber: PropTypes.number.isRequired, - formatBigNumber: PropTypes.func, - fromDatetime: PropTypes.number, - toDatetime: PropTypes.number, - headerFontSize: PropTypes.number, - subheader: PropTypes.string, - subheaderFontSize: PropTypes.number, - showTrendLine: PropTypes.bool, - startYAxisAtZero: PropTypes.bool, - trendLineData: PropTypes.array, - mainColor: PropTypes.string, - renderTooltip: PropTypes.func, -}; -const defaultProps = { - alignTimeRange: false, - className: '', - formatBigNumber: identity, - fromDatetime: null, - toDatetime: null, - headerFontSize: PROPORTION.HEADER, - subheader: '', - subheaderFontSize: PROPORTION.SUBHEADER, - showTrendLine: false, - startYAxisAtZero: true, - trendLineData: null, - mainColor: BRAND_COLOR, - renderTooltip: renderTooltipFactory(identity, identity), +type BigNumberVisProps = { + className?: string; + width: number; + height: number; + bigNumber: number; + formatNumber: NumberFormatFunction; + formatTime: TimeFormatFunction; + fromDatetime: number; + toDatetime: number; + headerFontSize: number; + subheader: string; + subheaderFontSize: number; + showTrendLine: boolean; + startYAxisAtZero: boolean; + trendLineData?: TimeSeriesDatum[]; + mainColor: string; + renderTooltip: ({ datum }: { datum: TimeSeriesDatum }) => React.Component; + useFixedTimeRange: boolean; }; -class BigNumberVis extends React.PureComponent { - constructor(props) { +class BigNumberVis extends React.PureComponent { + private gradientId: string; + + static defaultProps = { + className: '', + formatNumber: (num: number) => String(num), + formatTime: smartDateVerboseFormatter.formatFunc, + fromDatetime: null, + headerFontSize: PROPORTION.HEADER, + mainColor: BRAND_COLOR, + renderTooltip: renderTooltipFactory(), + showTrendLine: false, + startYAxisAtZero: true, + subheader: '', + subheaderFontSize: PROPORTION.SUBHEADER, + toDatetime: null, + trendLineData: null, + useFixedTimeRange: false, + }; + + constructor(props: BigNumberVisProps) { super(props); this.gradientId = shortid.generate(); } @@ -124,14 +124,14 @@ class BigNumberVis extends React.PureComponent { const container = document.createElement('div'); container.className = this.getClassName(); container.style.position = 'absolute'; // so it won't disrupt page layout - container.style.opacity = 0; // and not visible + container.style.opacity = '0'; // and not visible return container; } - renderHeader(maxHeight) { - const { bigNumber, formatBigNumber, width } = this.props; - const text = bigNumber === null ? 'No data' : formatBigNumber(bigNumber); + renderHeader(maxHeight: number) { + const { bigNumber, formatNumber, width } = this.props; + const text = bigNumber === null ? 'No data' : formatNumber(bigNumber); const container = this.createTemporaryContainer(); document.body.append(container); @@ -157,7 +157,7 @@ class BigNumberVis extends React.PureComponent { ); } - renderSubheader(maxHeight) { + renderSubheader(maxHeight: number) { const { bigNumber, subheader, width } = this.props; let fontSize = 0; @@ -191,7 +191,7 @@ class BigNumberVis extends React.PureComponent { ); } - renderTrendline(maxHeight) { + renderTrendline(maxHeight: number) { const { width, trendLineData, @@ -201,11 +201,15 @@ class BigNumberVis extends React.PureComponent { startYAxisAtZero, fromDatetime, toDatetime, - alignTimeRange, + useFixedTimeRange, } = this.props; - const xScale = { type: 'timeUtc' }; - if (alignTimeRange && fromDatetime && toDatetime) { + // Apply a fixed tange range if a time range is specified. + // + // XYChart checks the existence of `domain` property decide whether to apply + // a domain or not, so it must not be `null` or `undefined` + const xScale: { type: string; domain?: number[] } = { type: 'timeUtc' }; + if (useFixedTimeRange && fromDatetime && toDatetime) { xScale.domain = [fromDatetime, toDatetime]; } @@ -267,7 +271,4 @@ class BigNumberVis extends React.PureComponent { } } -BigNumberVis.propTypes = propTypes; -BigNumberVis.defaultProps = defaultProps; - export default BigNumberVis; diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/index.js b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/index.ts similarity index 100% rename from packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/index.js rename to packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/index.ts diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.ts similarity index 62% rename from packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js rename to packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.ts index c72502563..d24e76722 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.js +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/transformProps.ts @@ -18,61 +18,27 @@ */ import * as color from 'd3-color'; import { getNumberFormatter, NumberFormats } from '@superset-ui/number-format'; -import { getTimeFormatter, TimeFormats, smartDateVerboseFormatter } from '@superset-ui/time-format'; -import { renderTooltipFactory } from './BigNumber'; +import { ChartProps } from '@superset-ui/chart'; +import getTimeFormatterForGranularity from '../utils/getTimeFormatterForGranularity'; const TIME_COLUMN = '__timestamp'; -function getTimeFormatterForGranularity(granularity) { - // Translate time granularity to d3-format - const MINUTE = '%Y-%m-%d %H:%M'; - const SUNDAY_BASED_WEEK = '%Y W%U'; - const MONDAY_BASED_WEEK = '%Y W%W'; - const { DATABASE_DATE, DATABASE_DATETIME } = TimeFormats; - - // search for `builtin_time_grains` in incubator-superset/superset/db_engine_specs/base.py - const formats = { - date: DATABASE_DATE, - PT1S: DATABASE_DATETIME, // second - PT1M: MINUTE, // minute - PT5M: MINUTE, // 5 minute - PT10M: MINUTE, // 10 minute - PT15M: MINUTE, // 15 minute - 'PT0.5H': MINUTE, // half hour - PT1H: '%Y-%m-%d %H:00', // hour - P1D: DATABASE_DATE, // day - P1W: SUNDAY_BASED_WEEK, // week - P1M: 'smart_date_verbose', // month - 'P0.25Y': '%Y Q%q', // quarter - P1Y: '%Y', // year - // d3-time-format weeks does not support weeks start on Sunday - '1969-12-28T00:00:00Z/P1W': SUNDAY_BASED_WEEK, // 'week_start_sunday' - '1969-12-29T00:00:00Z/P1W': MONDAY_BASED_WEEK, // 'week_start_monday' - 'P1W/1970-01-03T00:00:00Z': SUNDAY_BASED_WEEK, // 'week_ending_saturday' - 'P1W/1970-01-04T00:00:00Z': MONDAY_BASED_WEEK, // 'week_ending_sunday' - }; - - return granularity in formats - ? getTimeFormatter(formats[granularity]) - : smartDateVerboseFormatter; -} - -export default function transformProps(chartProps) { +export default function transformProps(chartProps: ChartProps) { const { width, height, formData, queryData } = chartProps; const { colorPicker, compareLag: compareLagInput, compareSuffix = '', headerFontSize, - subheaderFontSize, metric, showTrendLine, startYAxisAtZero, subheader = '', + subheaderFontSize, + timeGrainSqla: granularity, vizType, - alignTimeRange = false, + useFixedTimeRange = false, } = formData; - const granularity = formData.timeGrainSqla; let { yAxisFormat } = formData; const { data, from_dttm: fromDatetime, to_dttm: toDatetime } = queryData; const metricName = metric?.label ? metric.label : metric; @@ -123,32 +89,35 @@ export default function transformProps(chartProps) { } if (!yAxisFormat && chartProps.datasource && chartProps.datasource.metrics) { - chartProps.datasource.metrics.forEach(metricEntry => { - if (metricEntry.metric_name === metric && metricEntry.d3format) { - yAxisFormat = metricEntry.d3format; - } - }); + chartProps.datasource.metrics.forEach( + // eslint-disable-next-line camelcase + (metricEntry: { metric_name?: string; d3format: string }) => { + if (metricEntry.metric_name === metric && metricEntry.d3format) { + yAxisFormat = metricEntry.d3format; + } + }, + ); } - const formatDate = getTimeFormatterForGranularity(granularity); - const formatValue = getNumberFormatter(yAxisFormat); + const formatNumber = getNumberFormatter(yAxisFormat); + const formatTime = getTimeFormatterForGranularity(granularity); return { width, height, bigNumber, className, - formatBigNumber: formatValue, + formatNumber, + formatTime, headerFontSize, subheaderFontSize, mainColor, - renderTooltip: renderTooltipFactory(formatDate, formatValue), showTrendLine: supportAndShowTrendLine, startYAxisAtZero, subheader: formattedSubheader, trendLineData, fromDatetime, toDatetime, - alignTimeRange, + useFixedTimeRange, }; } diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumberTotal/index.js b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumberTotal/index.ts similarity index 100% rename from packages/superset-ui-legacy-preset-chart-big-number/src/BigNumberTotal/index.js rename to packages/superset-ui-legacy-preset-chart-big-number/src/BigNumberTotal/index.ts diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts b/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts new file mode 100644 index 000000000..e0d4f71a1 --- /dev/null +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts @@ -0,0 +1,19 @@ +/** + * 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. + */ +declare module '@data-ui/xy-chart'; diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/utils/getTimeFormatterForGranularity.ts b/packages/superset-ui-legacy-preset-chart-big-number/src/utils/getTimeFormatterForGranularity.ts new file mode 100644 index 000000000..42a65417f --- /dev/null +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/utils/getTimeFormatterForGranularity.ts @@ -0,0 +1,70 @@ +/** + * 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 { getTimeFormatter, TimeFormats, smartDateVerboseFormatter } from '@superset-ui/time-format'; + +// Translate time granularity to d3-format +const MINUTE = '%Y-%m-%d %H:%M'; +const SUNDAY_BASED_WEEK = '%Y W%U'; +const MONDAY_BASED_WEEK = '%Y W%W'; +const { DATABASE_DATE, DATABASE_DATETIME } = TimeFormats; + +// search for `builtin_time_grains` in incubator-superset/superset/db_engine_specs/base.py +const formats = { + date: DATABASE_DATE, + PT1S: DATABASE_DATETIME, // second + PT1M: MINUTE, // minute + PT5M: MINUTE, // 5 minute + PT10M: MINUTE, // 10 minute + PT15M: MINUTE, // 15 minute + 'PT0.5H': MINUTE, // half hour + PT1H: '%Y-%m-%d %H:00', // hour + P1D: DATABASE_DATE, // day + P1W: SUNDAY_BASED_WEEK, // week + P1M: 'smart_date_verbose', // month + 'P0.25Y': '%Y Q%q', // quarter + P1Y: '%Y', // year + // d3-time-format weeks does not support weeks start on Sunday + '1969-12-28T00:00:00Z/P1W': SUNDAY_BASED_WEEK, // 'week_start_sunday' + '1969-12-29T00:00:00Z/P1W': MONDAY_BASED_WEEK, // 'week_start_monday' + 'P1W/1970-01-03T00:00:00Z': SUNDAY_BASED_WEEK, // 'week_ending_saturday' + 'P1W/1970-01-04T00:00:00Z': MONDAY_BASED_WEEK, // 'week_ending_sunday' +}; + +type TimeGranularity = + | 'date' + | 'PT1S' + | 'PT1M' + | 'PT5M' + | 'PT10M' + | 'PT15M' + | 'PT0.5H' + | 'PT1H' + | 'P1D' + | 'P1W' + | 'P0.25Y' + | 'P1Y' + | '1969-12-28T00:00:00Z/P1W' + | '1969-12-29T00:00:00Z/P1W' + | 'P1W/1970-01-03T00:00:00Z'; + +export default function getTimeFormatterForGranularity(granularity: TimeGranularity) { + return granularity in formats + ? getTimeFormatter(formats[granularity]) + : smartDateVerboseFormatter.format; +} diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx index d975bfe23..f386f1f16 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/Stories.tsx @@ -1,4 +1,21 @@ -/* eslint-disable no-magic-numbers, sort-keys */ +/** + * 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 React from 'react'; import { SuperChart } from '@superset-ui/chart'; import testData from './data'; @@ -74,11 +91,11 @@ export default [ }} formData={{ ...formData, - alignTimeRange: true, + useFixedTimeRange: true, }} /> ), - storyName: 'Missing range start (align time range)', + storyName: 'Missing range start (fix time range)', storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', }, { @@ -94,11 +111,11 @@ export default [ }} formData={{ ...formData, - alignTimeRange: false, + useFixedTimeRange: false, }} /> ), - storyName: `Missing range start (don't align)`, + storyName: `Missing range start (don't fix range)`, storyPath: 'legacy-|preset-chart-big-number|BigNumberChartPlugin', }, ]; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.ts similarity index 100% rename from packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.js rename to packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/data.ts diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js index 13eec8cf7..560d86f33 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js @@ -1,3 +1,21 @@ +/** + * 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 { BigNumberChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number'; import Stories from './Stories.tsx'; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx index cd65ee107..2fca55ae3 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/Stories.tsx @@ -1,4 +1,21 @@ -/* eslint-disable no-magic-numbers */ +/** + * 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 React from 'react'; import { SuperChart } from '@superset-ui/chart'; import data from './data'; diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/data.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/data.ts similarity index 63% rename from packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/data.js rename to packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/data.ts index 78d96901c..919630768 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/data.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/data.ts @@ -1,4 +1,3 @@ -/* eslint-disable sort-keys */ export default [ { sum__num: 32546308, diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js index 910402e2d..769519124 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js @@ -1,5 +1,23 @@ +/** + * 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 { BigNumberTotalChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number'; -import Stories from './Stories'; +import Stories from './Stories.tsx'; new BigNumberTotalChartPlugin().configure({ key: 'big-number-total' }).register(); From c852f2b308b970e94ee1bbe3b9a8392aff50adb4 Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Mon, 16 Mar 2020 22:36:35 -0700 Subject: [PATCH 5/8] fix(big-number): typescript build --- .../superset-ui-legacy-preset-chart-big-number/package.json | 1 - .../src/types/external.d.ts | 1 + yarn.lock | 5 +++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/package.json b/packages/superset-ui-legacy-preset-chart-big-number/package.json index c58bae232..f18787749 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/package.json +++ b/packages/superset-ui-legacy-preset-chart-big-number/package.json @@ -30,7 +30,6 @@ "dependencies": { "@data-ui/xy-chart": "^0.0.84", "d3-color": "^1.2.3", - "prop-types": "^15.6.2", "shortid": "^2.2.14" }, "peerDependencies": { diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts b/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts index e0d4f71a1..e69639741 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/types/external.d.ts @@ -17,3 +17,4 @@ * under the License. */ declare module '@data-ui/xy-chart'; +declare module '*.png'; diff --git a/yarn.lock b/yarn.lock index 4e30da1f5..e3ba2e31d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3954,6 +3954,11 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/shortid@0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/shortid/-/shortid-0.0.29.tgz#8093ee0416a6e2bf2aa6338109114b3fbffa0e9b" + integrity sha1-gJPuBBam4r8qpjOBCRFLP7/6Dps= + "@types/sizzle@*": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" From 3670f5553762a85c06dba35c75116df385e5a3e4 Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Tue, 17 Mar 2020 11:41:17 -0700 Subject: [PATCH 6/8] fix(big-number): change tooltip trigger; fix storybook --- .../src/BigNumber/BigNumber.tsx | 34 ++++++++++++------- .../storybook/stories/index.js | 2 +- .../BigNumber/{index.js => index.ts} | 4 +-- .../BigNumberTotal/{index.js => index.ts} | 4 +-- 4 files changed, 27 insertions(+), 17 deletions(-) rename packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/{index.js => index.ts} (93%) rename packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/{index.js => index.ts} (92%) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx index 9a6987f68..2608797ef 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx +++ b/packages/superset-ui-legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx @@ -18,6 +18,7 @@ */ import React from 'react'; import shortid from 'shortid'; +import { t } from '@superset-ui/translation'; import { NumberFormatFunction } from '@superset-ui/number-format/lib/types'; import { getNumberFormatter } from '@superset-ui/number-format'; import { XYChart, AreaSeries, CrossHair, LinearGradient } from '@data-ui/xy-chart'; @@ -45,7 +46,7 @@ const PROPORTION = { type TimeSeriesDatum = { x: number; // timestamp as a number - y: number; + y: number | null; }; export function renderTooltipFactory( @@ -59,7 +60,7 @@ export function renderTooltipFactory(
{formatDate(new Date(x))}
- {formatValue(y)} + {y === null ? t('N/A') : formatValue(y)}
); }; @@ -86,7 +87,7 @@ type BigNumberVisProps = { }; class BigNumberVis extends React.PureComponent { - private gradientId: string; + private gradientId: string = shortid.generate(); static defaultProps = { className: '', @@ -105,11 +106,6 @@ class BigNumberVis extends React.PureComponent { useFixedTimeRange: false, }; - constructor(props: BigNumberVisProps) { - super(props); - this.gradientId = shortid.generate(); - } - getClassName() { const { className, showTrendLine } = this.props; const names = `superset-legacy-chart-big-number ${className}`; @@ -204,13 +200,26 @@ class BigNumberVis extends React.PureComponent { useFixedTimeRange, } = this.props; - // Apply a fixed tange range if a time range is specified. + // Apply a fixed X range if a time range is specified. // // XYChart checks the existence of `domain` property decide whether to apply // a domain or not, so it must not be `null` or `undefined` const xScale: { type: string; domain?: number[] } = { type: 'timeUtc' }; - if (useFixedTimeRange && fromDatetime && toDatetime) { - xScale.domain = [fromDatetime, toDatetime]; + const tooltipData = trendLineData?.sort(datum => datum.x); + if (tooltipData && useFixedTimeRange && fromDatetime && toDatetime) { + // xScale.domain = [fromDatetime, toDatetime]; + if (tooltipData[0].x > fromDatetime) { + tooltipData.unshift({ + x: fromDatetime, + y: null, + }); + } + if (tooltipData[tooltipData.length - 1].x < toDatetime) { + tooltipData.unshift({ + x: toDatetime, + y: null, + }); + } } return ( @@ -226,9 +235,10 @@ class BigNumberVis extends React.PureComponent { height={maxHeight} margin={CHART_MARGIN} renderTooltip={renderTooltip} + eventTrigger="container" > - + node } * */ -const requireContext = require.context('./', /* subdirs= */ true, /index\.jsx?$/); +const requireContext = require.context('./', /* subdirs= */ true, /index\.(js|ts)x?$/); requireContext.keys().forEach(packageName => { const packageExport = requireContext(packageName); diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.ts similarity index 93% rename from packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js rename to packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.ts index 560d86f33..8976cf5d2 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumber/index.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { BigNumberChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number'; -import Stories from './Stories.tsx'; +import { BigNumberChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number/src'; +import Stories from './Stories'; new BigNumberChartPlugin().configure({ key: 'big-number' }).register(); diff --git a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.ts similarity index 92% rename from packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js rename to packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.ts index 769519124..229c30d27 100644 --- a/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.js +++ b/packages/superset-ui-plugins-demo/storybook/stories/legacy-preset-chart-big-number/BigNumberTotal/index.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { BigNumberTotalChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number'; -import Stories from './Stories.tsx'; +import { BigNumberTotalChartPlugin } from '../../../../../superset-ui-legacy-preset-chart-big-number/src'; +import Stories from './Stories'; new BigNumberTotalChartPlugin().configure({ key: 'big-number-total' }).register(); From bcf02556fed951380cc7cb2a37f57052fbe21bb7 Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Tue, 17 Mar 2020 11:48:29 -0700 Subject: [PATCH 7/8] fix(big-number): move @types to dependencies --- .../superset-ui-legacy-preset-chart-big-number/package.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/package.json b/packages/superset-ui-legacy-preset-chart-big-number/package.json index f18787749..abd4e9ff6 100644 --- a/packages/superset-ui-legacy-preset-chart-big-number/package.json +++ b/packages/superset-ui-legacy-preset-chart-big-number/package.json @@ -29,6 +29,7 @@ }, "dependencies": { "@data-ui/xy-chart": "^0.0.84", + "@types/shortid": "0.0.29", "d3-color": "^1.2.3", "shortid": "^2.2.14" }, @@ -41,8 +42,5 @@ "@superset-ui/time-format": "^0.12.0", "@superset-ui/translation": "^0.12.0", "react": "^15 || ^16" - }, - "devDependencies": { - "@types/shortid": "0.0.29" } } From af8512eddd36fb67fe9353c3f881dd70d5f012aa Mon Sep 17 00:00:00 2001 From: Jesse Yang Date: Tue, 17 Mar 2020 12:14:13 -0700 Subject: [PATCH 8/8] fix(big-number): move all files to ts --- .../src/{index.js => index.ts} | 0 .../src/{preset.js => preset.ts} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/superset-ui-legacy-preset-chart-big-number/src/{index.js => index.ts} (100%) rename packages/superset-ui-legacy-preset-chart-big-number/src/{preset.js => preset.ts} (100%) diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/index.js b/packages/superset-ui-legacy-preset-chart-big-number/src/index.ts similarity index 100% rename from packages/superset-ui-legacy-preset-chart-big-number/src/index.js rename to packages/superset-ui-legacy-preset-chart-big-number/src/index.ts diff --git a/packages/superset-ui-legacy-preset-chart-big-number/src/preset.js b/packages/superset-ui-legacy-preset-chart-big-number/src/preset.ts similarity index 100% rename from packages/superset-ui-legacy-preset-chart-big-number/src/preset.js rename to packages/superset-ui-legacy-preset-chart-big-number/src/preset.ts