diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js
index 9e8ca246258f4..30e7716b730c2 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js
+++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number.test.js
@@ -16,6 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
+import { interceptChart } from 'cypress/utils';
+
describe('Visualization > Big Number with Trendline', () => {
const BIG_NUMBER_FORM_DATA = {
datasource: '2__table',
@@ -42,21 +44,21 @@ describe('Visualization > Big Number with Trendline', () => {
function verify(formData) {
cy.visitChartByParams(JSON.stringify(formData));
cy.verifySliceSuccess({
- waitAlias: '@getJson',
+ waitAlias: '@chartData',
chartSelector: '.superset-legacy-chart-big-number',
});
}
beforeEach(() => {
cy.login();
- cy.intercept('POST', '/superset/explore_json/**').as('getJson');
+ interceptChart({ legacy: false }).as('chartData');
});
it('should work', () => {
verify(BIG_NUMBER_FORM_DATA);
cy.get('.chart-container .header-line');
cy.get('.chart-container .subheader-line');
- cy.get('.chart-container svg path.vx-linepath');
+ cy.get('.chart-container canvas');
});
it('should work without subheader', () => {
@@ -66,7 +68,7 @@ describe('Visualization > Big Number with Trendline', () => {
});
cy.get('.chart-container .header-line');
cy.get('.chart-container .subheader-line').should('not.exist');
- cy.get('.chart-container svg path.vx-linepath');
+ cy.get('.chart-container canvas');
});
it('should not render trendline when hidden', () => {
@@ -76,6 +78,6 @@ describe('Visualization > Big Number with Trendline', () => {
});
cy.get('[data-test="chart-container"] .header-line');
cy.get('[data-test="chart-container"] .subheader-line');
- cy.get('[data-test="chart-container"] svg').should('not.exist');
+ cy.get('[data-test="chart-container"] canvas').should('not.exist');
});
});
diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js
index b6794c42b741b..e2fcc5a1a1e32 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js
+++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/big_number_total.test.js
@@ -16,6 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
+import { interceptChart } from 'cypress/utils';
import { FORM_DATA_DEFAULTS, NUM_METRIC } from './shared.helper';
describe('Visualization > Big Number Total', () => {
@@ -26,15 +27,15 @@ describe('Visualization > Big Number Total', () => {
beforeEach(() => {
cy.login();
- cy.intercept('POST', '/superset/explore_json/**').as('getJson');
+ interceptChart({ legacy: false }).as('chartData');
});
it('Test big number chart with adhoc metric', () => {
const formData = { ...BIG_NUMBER_DEFAULTS, metric: NUM_METRIC };
- cy.visitChartByParams(JSON.stringify(formData));
+ cy.visitChartByParams(formData);
cy.verifySliceSuccess({
- waitAlias: '@getJson',
+ waitAlias: '@chartData',
querySubstring: NUM_METRIC.label,
});
});
@@ -58,8 +59,8 @@ describe('Visualization > Big Number Total', () => {
adhoc_filters: filters,
};
- cy.visitChartByParams(JSON.stringify(formData));
- cy.verifySliceSuccess({ waitAlias: '@getJson' });
+ cy.visitChartByParams(formData);
+ cy.verifySliceSuccess({ waitAlias: '@chartData' });
});
it('Test big number chart ignores groupby', () => {
@@ -69,11 +70,11 @@ describe('Visualization > Big Number Total', () => {
groupby: ['state'],
};
- cy.visitChartByParams(JSON.stringify(formData));
- cy.wait(['@getJson']).then(async ({ response }) => {
+ cy.visitChartByParams(formData);
+ cy.wait(['@chartData']).then(async ({ response }) => {
cy.verifySliceContainer();
const responseBody = response?.body;
- expect(responseBody.query).not.contains(formData.groupby[0]);
+ expect(responseBody.result[0].query).not.contains(formData.groupby[0]);
});
});
});
diff --git a/superset-frontend/cypress-base/cypress/utils/vizPlugins.ts b/superset-frontend/cypress-base/cypress/utils/vizPlugins.ts
index 850cc09879ba0..36a837476c396 100644
--- a/superset-frontend/cypress-base/cypress/utils/vizPlugins.ts
+++ b/superset-frontend/cypress-base/cypress/utils/vizPlugins.ts
@@ -40,6 +40,8 @@ const V1_PLUGINS = [
'word_cloud',
'pie',
'table',
+ 'big_number',
+ 'big_number_total',
];
export const DASHBOARD_CHART_ALIAS_PREFIX = 'getChartData_';
diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 0ea5b6d87a433..82f2dca65b675 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -41,7 +41,6 @@
"@superset-ui/legacy-plugin-chart-sunburst": "^0.18.25",
"@superset-ui/legacy-plugin-chart-treemap": "^0.18.25",
"@superset-ui/legacy-plugin-chart-world-map": "^0.18.25",
- "@superset-ui/legacy-preset-chart-big-number": "^0.18.25",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.13",
"@superset-ui/legacy-preset-chart-nvd3": "^0.18.25",
"@superset-ui/plugin-chart-echarts": "^0.18.25",
@@ -198,6 +197,7 @@
"@types/redux-localstorage": "^1.0.8",
"@types/redux-mock-store": "^1.0.2",
"@types/rison": "0.0.6",
+ "@types/shortid": "^0.0.29",
"@types/sinon": "^9.0.5",
"@types/yargs": "12 - 15",
"@typescript-eslint/eslint-plugin": "^5.3.0",
@@ -21125,10 +21125,6 @@
"resolved": "plugins/legacy-plugin-chart-world-map",
"link": true
},
- "node_modules/@superset-ui/legacy-preset-chart-big-number": {
- "resolved": "plugins/legacy-preset-chart-big-number",
- "link": true
- },
"node_modules/@superset-ui/legacy-preset-chart-deckgl": {
"resolved": "plugins/legacy-preset-chart-deckgl",
"link": true
@@ -22433,7 +22429,8 @@
"node_modules/@types/shortid": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/shortid/-/shortid-0.0.29.tgz",
- "integrity": "sha1-gJPuBBam4r8qpjOBCRFLP7/6Dps="
+ "integrity": "sha1-gJPuBBam4r8qpjOBCRFLP7/6Dps=",
+ "dev": true
},
"node_modules/@types/sinon": {
"version": "9.0.5",
@@ -60726,7 +60723,6 @@
"@superset-ui/legacy-plugin-chart-time-table": "0.18.25",
"@superset-ui/legacy-plugin-chart-treemap": "0.18.25",
"@superset-ui/legacy-plugin-chart-world-map": "0.18.25",
- "@superset-ui/legacy-preset-chart-big-number": "0.18.25",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.13",
"@superset-ui/legacy-preset-chart-nvd3": "0.18.25",
"@superset-ui/plugin-chart-echarts": "0.18.25",
@@ -61502,6 +61498,7 @@
"plugins/legacy-preset-chart-big-number": {
"name": "@superset-ui/legacy-preset-chart-big-number",
"version": "0.18.25",
+ "extraneous": true,
"license": "Apache-2.0",
"dependencies": {
"@data-ui/xy-chart": "^0.0.84",
@@ -77854,7 +77851,6 @@
"@superset-ui/legacy-plugin-chart-time-table": "0.18.25",
"@superset-ui/legacy-plugin-chart-treemap": "0.18.25",
"@superset-ui/legacy-plugin-chart-world-map": "0.18.25",
- "@superset-ui/legacy-preset-chart-big-number": "0.18.25",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.13",
"@superset-ui/legacy-preset-chart-nvd3": "0.18.25",
"@superset-ui/plugin-chart-echarts": "0.18.25",
@@ -78481,18 +78477,6 @@
}
}
},
- "@superset-ui/legacy-preset-chart-big-number": {
- "version": "file:plugins/legacy-preset-chart-big-number",
- "requires": {
- "@data-ui/xy-chart": "^0.0.84",
- "@superset-ui/chart-controls": "0.18.25",
- "@superset-ui/core": "0.18.25",
- "@types/d3-color": "^1.2.2",
- "@types/shortid": "^0.0.29",
- "d3-color": "^1.2.3",
- "shortid": "^2.2.14"
- }
- },
"@superset-ui/legacy-preset-chart-deckgl": {
"version": "file:plugins/legacy-preset-chart-deckgl",
"requires": {
@@ -79940,7 +79924,8 @@
"@types/shortid": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/shortid/-/shortid-0.0.29.tgz",
- "integrity": "sha1-gJPuBBam4r8qpjOBCRFLP7/6Dps="
+ "integrity": "sha1-gJPuBBam4r8qpjOBCRFLP7/6Dps=",
+ "dev": true
},
"@types/sinon": {
"version": "9.0.5",
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index b72640d802459..07ffcd0ce992c 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -101,7 +101,6 @@
"@superset-ui/legacy-plugin-chart-sunburst": "^0.18.25",
"@superset-ui/legacy-plugin-chart-treemap": "^0.18.25",
"@superset-ui/legacy-plugin-chart-world-map": "^0.18.25",
- "@superset-ui/legacy-preset-chart-big-number": "^0.18.25",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.13",
"@superset-ui/legacy-preset-chart-nvd3": "^0.18.25",
"@superset-ui/plugin-chart-echarts": "^0.18.25",
@@ -258,6 +257,7 @@
"@types/redux-localstorage": "^1.0.8",
"@types/redux-mock-store": "^1.0.2",
"@types/rison": "0.0.6",
+ "@types/shortid": "^0.0.29",
"@types/sinon": "^9.0.5",
"@types/yargs": "12 - 15",
"@typescript-eslint/eslint-plugin": "^5.3.0",
diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts b/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts
index 6c99ca9aa632c..90898fcf1784b 100644
--- a/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts
+++ b/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts
@@ -50,7 +50,7 @@ export interface ChartDataResponseResult {
annotation_data: AnnotationData[] | null;
cache_key: string | null;
cache_timeout: number | null;
- cache_dttm: string | null;
+ cached_dttm: string | null;
/**
* Array of data records as dictionary
*/
@@ -76,6 +76,8 @@ export interface ChartDataResponseResult {
| 'scheduled'
| 'success'
| 'timed_out';
+ from_dttm: number | null;
+ to_dttm: number | null;
}
export interface TimeseriesChartDataResponseResult
diff --git a/superset-frontend/packages/superset-ui-demo/package.json b/superset-frontend/packages/superset-ui-demo/package.json
index d218442670454..90162756821ca 100644
--- a/superset-frontend/packages/superset-ui-demo/package.json
+++ b/superset-frontend/packages/superset-ui-demo/package.json
@@ -61,7 +61,6 @@
"@superset-ui/legacy-plugin-chart-time-table": "0.18.25",
"@superset-ui/legacy-plugin-chart-treemap": "0.18.25",
"@superset-ui/legacy-plugin-chart-world-map": "0.18.25",
- "@superset-ui/legacy-preset-chart-big-number": "0.18.25",
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.13",
"@superset-ui/legacy-preset-chart-nvd3": "0.18.25",
"@superset-ui/plugin-chart-echarts": "0.18.25",
diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumber/BigNumberStories.tsx b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumber/BigNumberStories.tsx
index dd56c58bbf625..18fe9acddb2ea 100644
--- a/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumber/BigNumberStories.tsx
+++ b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumber/BigNumberStories.tsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import { SuperChart } from '@superset-ui/core';
-import { BigNumberChartPlugin } from '@superset-ui/legacy-preset-chart-big-number';
+import { BigNumberChartPlugin } from '@superset-ui/plugin-chart-echarts';
import testData from './data';
new BigNumberChartPlugin().configure({ key: 'big-number' }).register();
@@ -56,7 +56,7 @@ function withNulls(origData: object[], nullPosition = 3) {
}
export default {
- title: 'Legacy Chart Plugins/legacy-preset-big-number/BigNumber',
+ title: 'Legacy Chart Plugins/legacy-preset-big-number/BigNumberWithTrendline',
};
export const basicWithTrendline = () => (
diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumberTotal/BigNumberTotalStories.tsx b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumberTotal/BigNumberTotalStories.tsx
index f99d4f2e0395d..2d1e105f3d7a8 100644
--- a/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumberTotal/BigNumberTotalStories.tsx
+++ b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/legacy-preset-chart-big-number/BigNumberTotal/BigNumberTotalStories.tsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
import { SuperChart } from '@superset-ui/core';
-import { BigNumberTotalChartPlugin } from '@superset-ui/legacy-preset-chart-big-number';
+import { BigNumberTotalChartPlugin } from '@superset-ui/plugin-chart-echarts';
import data from './data';
new BigNumberTotalChartPlugin()
diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-chart/ChartDataProviderStories.tsx b/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-chart/ChartDataProviderStories.tsx
index 14d4d6d8bd48e..ff72aff37db56 100644
--- a/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-chart/ChartDataProviderStories.tsx
+++ b/superset-frontend/packages/superset-ui-demo/storybook/stories/superset-ui-chart/ChartDataProviderStories.tsx
@@ -25,7 +25,7 @@ import {
ChartDataProvider,
SupersetClient,
} from '@superset-ui/core';
-import { BigNumberChartPlugin as LegacyBigNumberPlugin } from '@superset-ui/legacy-preset-chart-big-number';
+import { BigNumberChartPlugin } from '@superset-ui/plugin-chart-echarts';
import LegacySankeyPlugin from '@superset-ui/legacy-plugin-chart-sankey';
import LegacySunburstPlugin from '@superset-ui/legacy-plugin-chart-sunburst';
import { WordCloudChartPlugin } from '@superset-ui/plugin-chart-word-cloud';
@@ -46,7 +46,7 @@ const SUNBURST = sunburstFormData.viz_type;
const WORD_CLOUD_LEGACY = wordCloudFormData.viz_type;
const WORD_CLOUD = 'new_word_cloud';
-new LegacyBigNumberPlugin().configure({ key: BIG_NUMBER }).register();
+new BigNumberChartPlugin().configure({ key: BIG_NUMBER }).register();
// eslint-disable-next-line
new LegacySankeyPlugin().configure({ key: SANKEY }).register();
// eslint-disable-next-line
diff --git a/superset-frontend/packages/superset-ui-demo/tsconfig.json b/superset-frontend/packages/superset-ui-demo/tsconfig.json
index a7983cf472e56..36179f3624078 100644
--- a/superset-frontend/packages/superset-ui-demo/tsconfig.json
+++ b/superset-frontend/packages/superset-ui-demo/tsconfig.json
@@ -16,5 +16,6 @@
"storybook",
"../**/src",
"../../plugins/**/src",
+ "../../plugins/**/types",
]
}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/README.md b/superset-frontend/plugins/legacy-preset-chart-big-number/README.md
deleted file mode 100644
index cceb13a5f6775..0000000000000
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-## @superset-ui/legacy-preset-chart-big-number
-
-[![Version](https://img.shields.io/npm/v/@superset-ui/legacy-preset-chart-big-number.svg?style=flat-square)](https://www.npmjs.com/package/@superset-ui/legacy-preset-chart-big-number)
-[![David (path)](https://img.shields.io/david/apache-superset/superset-ui-plugins.svg?path=packages%2Fsuperset-ui-legacy-preset-chart-big-number&style=flat-square)](https://david-dm.org/apache-superset/superset-ui-plugins?path=plugins/superset-ui-legacy-preset-chart-big-number)
-
-This plugin provides Big Number for Superset.
-
-### Usage
-
-Import the preset and register. This will register the `BigNumber` and `BigNumberTotal` charts with
-key `big-number` and `big-number-total`, respectively.
-
-```js
-import { BigNumberChartPreset } from '@superset-ui/legacy-preset-chart-big-number';
-
-new BigNumberChartPreset().register();
-```
-
-or register charts one by one. Configure `key`, which can be any `string`, and register the plugin.
-This `key` will be used to lookup this chart throughout the app.
-
-```js
-import {
- BigNumberChartPlugin,
- BigNumberTotalChartPlugin,
-} from '@superset-ui/legacy-preset-chart-big-number';
-
-new BigNumberChartPlugin().configure({ key: 'big-number' }).register();
-new BigNumberTotalChartPlugin()
- .configure({ key: 'big-number-total' })
- .register();
-```
-
-Then use it via `SuperChart`. See
-[storybook](https://apache-superset.github.io/superset-ui-plugins/?selectedKind=plugin-chart-big-number)
-for more details.
-
-```js
-
-```
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/package.json b/superset-frontend/plugins/legacy-preset-chart-big-number/package.json
deleted file mode 100644
index 81adb1d545252..0000000000000
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/package.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
- "name": "@superset-ui/legacy-preset-chart-big-number",
- "version": "0.18.25",
- "description": "Superset Legacy Chart - Big Number",
- "sideEffects": [
- "*.css"
- ],
- "main": "lib/index.js",
- "module": "esm/index.js",
- "files": [
- "esm",
- "lib"
- ],
- "repository": {
- "type": "git",
- "url": "git+https://github.com/apache-superset/superset-ui.git"
- },
- "keywords": [
- "superset"
- ],
- "author": "Superset",
- "license": "Apache-2.0",
- "bugs": {
- "url": "https://github.com/apache-superset/superset-ui/issues"
- },
- "homepage": "https://github.com/apache-superset/superset-ui#readme",
- "publishConfig": {
- "access": "public"
- },
- "dependencies": {
- "@data-ui/xy-chart": "^0.0.84",
- "@superset-ui/chart-controls": "0.18.25",
- "@superset-ui/core": "0.18.25",
- "@types/d3-color": "^1.2.2",
- "@types/shortid": "^0.0.29",
- "d3-color": "^1.2.3",
- "shortid": "^2.2.14"
- },
- "peerDependencies": {
- "react": "^15 || ^16"
- }
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/transformProps.ts b/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/transformProps.ts
deleted file mode 100644
index 6e4674dca1dc3..0000000000000
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/transformProps.ts
+++ /dev/null
@@ -1,187 +0,0 @@
-/**
- * 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 * as color from 'd3-color';
-import {
- extractTimegrain,
- getNumberFormatter,
- getTimeFormatter,
- getTimeFormatterForGranularity,
- NumberFormats,
- ChartProps,
- LegacyQueryData,
- QueryFormData,
- smartDateFormatter,
-} from '@superset-ui/core';
-
-const TIME_COLUMN = '__timestamp';
-const formatPercentChange = getNumberFormatter(
- NumberFormats.PERCENT_SIGNED_1_POINT,
-);
-
-// we trust both the x (time) and y (big number) to be numeric
-export interface BigNumberDatum {
- [key: string]: number | null;
-}
-
-export type BigNumberFormData = QueryFormData & {
- colorPicker?: {
- r: number;
- g: number;
- b: number;
- };
- metric?:
- | {
- label: string;
- }
- | string;
- compareLag?: string | number;
- yAxisFormat?: string;
-};
-
-export type BigNumberChartProps = ChartProps & {
- formData: BigNumberFormData;
- queriesData: (LegacyQueryData & {
- data?: BigNumberDatum[];
- })[];
-};
-
-export default function transformProps(chartProps: BigNumberChartProps) {
- const { width, height, queriesData, formData, rawFormData } = chartProps;
- const {
- colorPicker,
- compareLag: compareLag_,
- compareSuffix = '',
- timeFormat,
- headerFontSize,
- metric = 'value',
- showTimestamp,
- showTrendLine,
- startYAxisAtZero,
- subheader = '',
- subheaderFontSize,
- vizType,
- timeRangeFixed = false,
- } = formData;
- const granularity = extractTimegrain(rawFormData as QueryFormData);
- let { yAxisFormat } = formData;
- const { headerFormatSelector, headerTimestampFormat } = formData;
- const {
- data = [],
- from_dttm: fromDatetime,
- to_dttm: toDatetime,
- } = queriesData[0];
- const metricName = typeof metric === 'string' ? metric : metric.label;
- const compareLag = Number(compareLag_) || 0;
- const supportTrendLine = vizType === 'big_number';
- const supportAndShowTrendLine = supportTrendLine && showTrendLine;
- let formattedSubheader = subheader;
-
- let mainColor;
- if (colorPicker) {
- const { r, g, b } = colorPicker;
- mainColor = color.rgb(r, g, b).hex();
- }
-
- let trendLineData;
- let percentChange = 0;
- let bigNumber = data.length === 0 ? null : data[0][metricName];
- let timestamp = data.length === 0 ? null : data[0][TIME_COLUMN];
- let bigNumberFallback;
-
- if (data.length > 0) {
- const sortedData = (data as BigNumberDatum[])
- .map(d => ({ x: d[TIME_COLUMN], y: d[metricName] }))
- // sort in time descending order
- .sort((a, b) => (a.x !== null && b.x !== null ? b.x - a.x : 0));
-
- bigNumber = sortedData[0].y;
- timestamp = sortedData[0].x;
-
- if (bigNumber === null) {
- bigNumberFallback = sortedData.find(d => d.y !== null);
- bigNumber = bigNumberFallback ? bigNumberFallback.y : null;
- timestamp = bigNumberFallback ? bigNumberFallback.x : null;
- }
-
- if (compareLag > 0) {
- const compareIndex = compareLag;
- if (compareIndex < sortedData.length) {
- const compareValue = sortedData[compareIndex].y;
- // compare values must both be non-nulls
- if (bigNumber !== null && compareValue !== null && compareValue !== 0) {
- percentChange = (bigNumber - compareValue) / Math.abs(compareValue);
- formattedSubheader = `${formatPercentChange(
- percentChange,
- )} ${compareSuffix}`;
- }
- }
- }
-
- if (supportTrendLine) {
- // must reverse to ascending order otherwise it confuses tooltip triggers
- sortedData.reverse();
- trendLineData = supportAndShowTrendLine ? sortedData : undefined;
- }
- }
-
- let className = '';
- if (percentChange > 0) {
- className = 'positive';
- } else if (percentChange < 0) {
- className = 'negative';
- }
-
- if (!yAxisFormat && chartProps.datasource && chartProps.datasource.metrics) {
- chartProps.datasource.metrics.forEach(metricEntry => {
- if (metricEntry.metric_name === metric && metricEntry.d3format) {
- yAxisFormat = metricEntry.d3format;
- }
- });
- }
-
- const headerFormatter = headerFormatSelector
- ? getTimeFormatter(headerTimestampFormat)
- : getNumberFormatter(yAxisFormat);
- const formatTime =
- timeFormat === smartDateFormatter.id
- ? getTimeFormatterForGranularity(granularity)
- : getTimeFormatter(timeFormat);
-
- return {
- width,
- height,
- bigNumber,
- bigNumberFallback,
- className,
- headerFormatter,
- formatTime,
- headerFontSize,
- subheaderFontSize,
- mainColor,
- showTimestamp,
- showTrendLine: supportAndShowTrendLine,
- startYAxisAtZero,
- subheader: formattedSubheader,
- timestamp,
- trendLineData,
- fromDatetime,
- toDatetime,
- timeRangeFixed,
- };
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/test/tsconfig.json b/superset-frontend/plugins/legacy-preset-chart-big-number/test/tsconfig.json
deleted file mode 100644
index 481ca5b4db938..0000000000000
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/test/tsconfig.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "compilerOptions": {
- "composite": false,
- "emitDeclarationOnly": false,
- "noEmit": true,
- "rootDir": "."
- },
- "extends": "../../../tsconfig.json",
- "include": [
- "**/*",
- "../types/**/*",
- "../../../types/**/*"
- ],
- "references": [
- {
- "path": ".."
- }
- ]
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/tsconfig.json b/superset-frontend/plugins/legacy-preset-chart-big-number/tsconfig.json
deleted file mode 100644
index b6bfaa2d98446..0000000000000
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/tsconfig.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "compilerOptions": {
- "declarationDir": "lib",
- "outDir": "lib",
- "rootDir": "src"
- },
- "exclude": [
- "lib",
- "test"
- ],
- "extends": "../../tsconfig.json",
- "include": [
- "src/**/*",
- "types/**/*",
- "../../types/**/*"
- ],
- "references": [
- {
- "path": "../../packages/superset-ui-chart-controls"
- },
- {
- "path": "../../packages/superset-ui-core"
- }
- ]
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/types/external.d.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/buildQuery.ts
similarity index 79%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/types/external.d.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/buildQuery.ts
index bd49e0aeeabef..e714898b024ec 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/types/external.d.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/buildQuery.ts
@@ -16,6 +16,8 @@
* specific language governing permissions and limitations
* under the License.
*/
-declare module '@data-ui/xy-chart';
-declare module '*.png';
-declare module '*.jpg';
+import { buildQueryContext, QueryFormData } from '@superset-ui/core';
+
+export default function buildQuery(formData: QueryFormData) {
+ return buildQueryContext(formData, baseQueryObject => [baseQueryObject]);
+}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/controlPanel.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
similarity index 81%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/controlPanel.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
index f6ab2f3c6e577..e30dcbe6bee6d 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/controlPanel.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { t } from '@superset-ui/core';
+import { smartDateFormatter, t } from '@superset-ui/core';
import {
ControlPanelConfig,
D3_FORMAT_DOCS,
@@ -27,7 +27,7 @@ import { headerFontSize, subheaderFontSize } from '../sharedControls';
export default {
controlPanelSections: [
- sections.legacyRegularTime,
+ sections.legacyTimeseriesTime,
{
label: t('Query'),
expanded: true,
@@ -51,44 +51,45 @@ export default {
},
},
],
+ ],
+ },
+ {
+ label: t('Chart Options'),
+ expanded: true,
+ controlSetRows: [
+ [headerFontSize],
+ [subheaderFontSize],
['y_axis_format'],
[
{
- name: 'header_format_selector',
+ name: 'time_format',
config: {
- type: 'CheckboxControl',
- label: t('Timestamp Format'),
+ type: 'SelectControl',
+ freeForm: true,
+ label: t('Date format'),
renderTrigger: true,
- default: false,
- description: t('Whether to format the timestamp'),
+ choices: D3_TIME_FORMAT_OPTIONS,
+ description: D3_FORMAT_DOCS,
+ default: smartDateFormatter.id,
},
},
],
[
{
- name: 'header_timestamp_format',
+ name: 'force_timestamp_formatting',
config: {
- type: 'SelectControl',
- freeForm: true,
- label: t('Date format'),
+ type: 'CheckboxControl',
+ label: t('Force date format'),
renderTrigger: true,
- choices: D3_TIME_FORMAT_OPTIONS,
- default: '%d-%m-%Y %H:%M:%S',
- description: D3_FORMAT_DOCS,
- visibility(props) {
- const { header_format_selector } = props.form_data;
- return !!header_format_selector;
- },
+ default: false,
+ description: t(
+ 'Use date formatting even when metric value is not a timestamp',
+ ),
},
},
],
],
},
- {
- label: t('Chart Options'),
- expanded: true,
- controlSetRows: [[headerFontSize], [subheaderFontSize]],
- },
],
controlOverrides: {
y_axis_format: {
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/BigNumber.jpg b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/BigNumber.jpg
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/BigNumber.jpg
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/BigNumber.jpg
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/BigNumber2.jpg b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/BigNumber2.jpg
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/BigNumber2.jpg
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/BigNumber2.jpg
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/thumbnail.png b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/thumbnail.png
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/thumbnail.png
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/thumbnail.png
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/thumbnailLarge.png b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/thumbnailLarge.png
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/images/thumbnailLarge.png
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/images/thumbnailLarge.png
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/index.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/index.ts
similarity index 86%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/index.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/index.ts
index 7bece7b8c1cbb..3f45db74cfd95 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumberTotal/index.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/index.ts
@@ -18,13 +18,12 @@
*/
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
import controlPanel from './controlPanel';
-import transformProps, {
- BigNumberChartProps,
- BigNumberFormData,
-} from '../BigNumber/transformProps';
+import transformProps from './transformProps';
+import buildQuery from './buildQuery';
import example1 from './images/BigNumber.jpg';
import example2 from './images/BigNumber2.jpg';
import thumbnail from './images/thumbnail.png';
+import { BigNumberTotalChartProps, BigNumberTotalFormData } from '../types';
const metadata = new ChartMetadata({
category: t('KPI'),
@@ -47,17 +46,17 @@ const metadata = new ChartMetadata({
t('Description'),
],
thumbnail,
- useLegacyApi: true,
});
export default class BigNumberTotalChartPlugin extends ChartPlugin<
- BigNumberFormData,
- BigNumberChartProps
+ BigNumberTotalFormData,
+ BigNumberTotalChartProps
> {
constructor() {
super({
- loadChart: () => import('../BigNumber/BigNumber'),
+ loadChart: () => import('../BigNumberViz'),
metadata,
+ buildQuery,
transformProps,
controlPanel,
});
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
new file mode 100644
index 0000000000000..23126739346cb
--- /dev/null
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/transformProps.ts
@@ -0,0 +1,76 @@
+/**
+ * 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 {
+ getNumberFormatter,
+ GenericDataType,
+ getMetricLabel,
+ extractTimegrain,
+ QueryFormData,
+} from '@superset-ui/core';
+import { BigNumberTotalChartProps } from '../types';
+import { getDateFormatter, parseMetricValue } from '../utils';
+
+export default function transformProps(chartProps: BigNumberTotalChartProps) {
+ const { width, height, queriesData, formData, rawFormData } = chartProps;
+ const {
+ headerFontSize,
+ metric = 'value',
+ subheader = '',
+ subheaderFontSize,
+ forceTimestampFormatting,
+ timeFormat,
+ yAxisFormat,
+ } = formData;
+ const { data = [], coltypes = [] } = queriesData[0];
+ const granularity = extractTimegrain(rawFormData as QueryFormData);
+ const metricName = getMetricLabel(metric);
+ const formattedSubheader = subheader;
+ const bigNumber =
+ data.length === 0 ? null : parseMetricValue(data[0][metricName]);
+
+ let metricEntry;
+ if (chartProps.datasource && chartProps.datasource.metrics) {
+ metricEntry = chartProps.datasource.metrics.find(
+ metricItem => metricItem.metric_name === metric,
+ );
+ }
+
+ const formatTime = getDateFormatter(
+ timeFormat,
+ granularity,
+ metricEntry?.d3format,
+ );
+
+ const headerFormatter =
+ coltypes[0] === GenericDataType.TEMPORAL ||
+ coltypes[0] === GenericDataType.STRING ||
+ forceTimestampFormatting
+ ? formatTime
+ : getNumberFormatter(yAxisFormat ?? metricEntry?.d3format ?? undefined);
+
+ return {
+ width,
+ height,
+ bigNumber,
+ headerFormatter,
+ headerFontSize,
+ subheaderFontSize,
+ subheader: formattedSubheader,
+ };
+}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx
similarity index 73%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx
index 6f559f3e71b53..1c650efeea31a 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/BigNumber.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx
@@ -17,7 +17,6 @@
* under the License.
*/
import React from 'react';
-import shortid from 'shortid';
import {
t,
getNumberFormatter,
@@ -28,22 +27,12 @@ import {
BRAND_COLOR,
styled,
} from '@superset-ui/core';
-import {
- XYChart,
- AreaSeries,
- CrossHair,
- LinearGradient,
-} from '@data-ui/xy-chart';
+import { EChartsCoreOption } from 'echarts';
+import Echart from '../components/Echart';
+import { TimeSeriesDatum } from './types';
const defaultNumberFormatter = getNumberFormatter();
-const CHART_MARGIN = {
- top: 4,
- right: 4,
- bottom: 4,
- left: 4,
-};
-
const PROPORTION = {
// text size: proportion of the chart container sans trendline
KICKER: 0.1,
@@ -53,32 +42,6 @@ const PROPORTION = {
TRENDLINE: 0.3,
};
-type TimeSeriesDatum = {
- x: number; // timestamp as a number
- y: number | null;
-};
-
-export function renderTooltipFactory(
- formatDate = smartDateVerboseFormatter,
- 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 (
-
- {formatDate(new Date(x))}
-
- {y === null ? t('N/A') : formatValue(y)}
-
- );
- };
-}
-
type BigNumberVisProps = {
className?: string;
width: number;
@@ -87,8 +50,6 @@ type BigNumberVisProps = {
bigNumberFallback?: TimeSeriesDatum;
headerFormatter: NumberFormatter | TimeFormatter;
formatTime: TimeFormatter;
- fromDatetime?: number;
- toDatetime?: number;
headerFontSize: number;
kickerFontSize: number;
subheader: string;
@@ -100,11 +61,10 @@ type BigNumberVisProps = {
timestamp?: number;
trendLineData?: TimeSeriesDatum[];
mainColor: string;
+ echartOptions: EChartsCoreOption;
};
-class BigNumberVis extends React.PureComponent {
- private gradientId: string = shortid.generate();
-
+class BigNumberVis extends React.PureComponent {
static defaultProps = {
className: '',
headerFormatter: defaultNumberFormatter,
@@ -146,7 +106,7 @@ class BigNumberVis extends React.PureComponent {
role="alert"
title={t(
`Last available value seen on %s`,
- formatTime(bigNumberFallback.x),
+ formatTime(bigNumberFallback[0]),
)}
>
{t('Not up to date')}
@@ -254,79 +214,19 @@ class BigNumberVis extends React.PureComponent {
}
renderTrendline(maxHeight: number) {
- const {
- width,
- trendLineData,
- mainColor,
- subheader,
- startYAxisAtZero,
- headerFormatter,
- formatTime,
- fromDatetime,
- timeRangeFixed,
- } = this.props;
+ const { width, trendLineData, echartOptions } = this.props;
// if can't find any non-null values, no point rendering the trendline
- if (!trendLineData?.some(d => d.y !== null)) {
+ if (!trendLineData?.some(d => d[1] !== null)) {
return null;
}
- // Apply a fixed X range if a time range is specified.
- //
- // XYChart checks the existence of `domain` property and decide whether to
- // apply a domain or not, so it must not be `null` or `undefined`
- const xScale: { type: string; domain?: number[] } = { type: 'timeUtc' };
- const tooltipData = trendLineData && [...trendLineData];
- if (tooltipData && timeRangeFixed && fromDatetime) {
- const toDatetime = this.props.toDatetime ?? Date.now();
- if (tooltipData[0].x > fromDatetime) {
- tooltipData.unshift({
- x: fromDatetime,
- y: null,
- });
- }
- if (tooltipData[tooltipData.length - 1].x < toDatetime) {
- tooltipData.push({
- x: toDatetime,
- y: null,
- });
- }
- xScale.domain = [fromDatetime, toDatetime];
- }
return (
-
-
-
-
-
+ echartOptions={echartOptions}
+ />
);
}
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/buildQuery.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/buildQuery.ts
new file mode 100644
index 0000000000000..1a9096ff77906
--- /dev/null
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/buildQuery.ts
@@ -0,0 +1,92 @@
+/**
+ * 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 {
+ buildQueryContext,
+ DTTM_ALIAS,
+ PostProcessingResample,
+ QueryFormData,
+} from '@superset-ui/core';
+import {
+ rollingWindowOperator,
+ TIME_COLUMN,
+} from '@superset-ui/chart-controls';
+
+const TIME_GRAIN_MAP: Record = {
+ PT1S: 'S',
+ PT1M: 'min',
+ PT5M: '5min',
+ PT10M: '10min',
+ PT15M: '15min',
+ PT30M: '30min',
+ PT1H: 'H',
+ P1D: 'D',
+ P1M: 'M',
+ P3M: 'Q',
+ P1Y: 'A',
+ // TODO: these need to be mapped carefully, as the first day of week
+ // can vary from engine to engine
+ // P1W: 'W',
+ // '1969-12-28T00:00:00Z/P1W': 'W',
+ // '1969-12-29T00:00:00Z/P1W': 'W',
+ // 'P1W/1970-01-03T00:00:00Z': 'W',
+ // 'P1W/1970-01-04T00:00:00Z': 'W',
+};
+
+export default function buildQuery(formData: QueryFormData) {
+ return buildQueryContext(formData, baseQueryObject => {
+ const rollingProc = rollingWindowOperator(formData, baseQueryObject);
+ if (rollingProc) {
+ rollingProc.options = { ...rollingProc.options, is_pivot_df: false };
+ }
+ const { time_grain_sqla } = formData;
+ let resampleProc: PostProcessingResample | undefined;
+ if (rollingProc && time_grain_sqla) {
+ const rule = TIME_GRAIN_MAP[time_grain_sqla];
+ if (rule) {
+ resampleProc = {
+ operation: 'resample',
+ options: {
+ method: 'asfreq',
+ rule,
+ fill_value: null,
+ time_column: TIME_COLUMN,
+ },
+ };
+ }
+ }
+ return [
+ {
+ ...baseQueryObject,
+ is_timeseries: true,
+ post_processing: [
+ {
+ operation: 'sort',
+ options: {
+ columns: {
+ [DTTM_ALIAS]: true,
+ },
+ },
+ },
+ resampleProc,
+ rollingProc,
+ ],
+ },
+ ];
+ });
+}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/controlPanel.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx
similarity index 91%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/controlPanel.tsx
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx
index 045f7fc7bdfb2..c1378543f6b0c 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/controlPanel.tsx
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/controlPanel.tsx
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { t } from '@superset-ui/core';
+import { smartDateFormatter, t } from '@superset-ui/core';
import {
ControlPanelConfig,
D3_FORMAT_DOCS,
@@ -63,20 +63,6 @@ const config: ControlPanelConfig = {
},
},
],
- ['y_axis_format'],
- [
- {
- name: 'time_format',
- config: {
- type: 'SelectControl',
- freeForm: true,
- label: t('Timestamp format'),
- renderTrigger: true,
- choices: D3_TIME_FORMAT_OPTIONS,
- description: D3_FORMAT_DOCS,
- },
- },
- ],
[
{
name: 'show_timestamp',
@@ -142,6 +128,35 @@ const config: ControlPanelConfig = {
['color_picker', null],
[headerFontSize],
[subheaderFontSize],
+ ['y_axis_format'],
+ [
+ {
+ name: 'time_format',
+ config: {
+ type: 'SelectControl',
+ freeForm: true,
+ label: t('Date format'),
+ renderTrigger: true,
+ choices: D3_TIME_FORMAT_OPTIONS,
+ description: D3_FORMAT_DOCS,
+ default: smartDateFormatter.id,
+ },
+ },
+ ],
+ [
+ {
+ name: 'force_timestamp_formatting',
+ config: {
+ type: 'CheckboxControl',
+ label: t('Force date format'),
+ renderTrigger: true,
+ default: false,
+ description: t(
+ 'Use date formatting even when metric value is not a timestamp',
+ ),
+ },
+ },
+ ],
],
},
{
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/images/Big_Number_Trendline.jpg b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/images/Big_Number_Trendline.jpg
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/images/Big_Number_Trendline.jpg
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/images/Big_Number_Trendline.jpg
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/images/thumbnail.png b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/images/thumbnail.png
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/images/thumbnail.png
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/images/thumbnail.png
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/images/thumbnailLarge.png b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/images/thumbnailLarge.png
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/images/thumbnailLarge.png
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/images/thumbnailLarge.png
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/index.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/index.ts
similarity index 80%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/index.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/index.ts
index 2cfee291fc163..e774db4824e06 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/BigNumber/index.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/index.ts
@@ -18,12 +18,14 @@
*/
import { t, ChartMetadata, ChartPlugin } from '@superset-ui/core';
import controlPanel from './controlPanel';
-import transformProps, {
- BigNumberChartProps,
- BigNumberFormData,
-} from './transformProps';
+import transformProps from './transformProps';
+import buildQuery from './buildQuery';
import example from './images/Big_Number_Trendline.jpg';
import thumbnail from './images/thumbnail.png';
+import {
+ BigNumberWithTrendlineChartProps,
+ BigNumberWithTrendlineFormData,
+} from '../types';
const metadata = new ChartMetadata({
category: t('KPI'),
@@ -43,17 +45,17 @@ const metadata = new ChartMetadata({
t('Trend'),
],
thumbnail,
- useLegacyApi: true,
});
-export default class BigNumberChartPlugin extends ChartPlugin<
- BigNumberFormData,
- BigNumberChartProps
+export default class BigNumberWithTrendlineChartPlugin extends ChartPlugin<
+ BigNumberWithTrendlineFormData,
+ BigNumberWithTrendlineChartProps
> {
constructor() {
super({
- loadChart: () => import('./BigNumber'),
+ loadChart: () => import('../BigNumberViz'),
metadata,
+ buildQuery,
transformProps,
controlPanel,
});
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts
new file mode 100644
index 0000000000000..5054d99515ccf
--- /dev/null
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberWithTrendline/transformProps.ts
@@ -0,0 +1,252 @@
+/**
+ * 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 {
+ extractTimegrain,
+ getNumberFormatter,
+ NumberFormats,
+ QueryFormData,
+ GenericDataType,
+ getMetricLabel,
+ t,
+ smartDateVerboseFormatter,
+ NumberFormatter,
+ TimeFormatter,
+} from '@superset-ui/core';
+import { EChartsCoreOption, graphic } from 'echarts';
+import {
+ BigNumberDatum,
+ BigNumberWithTrendlineChartProps,
+ TimeSeriesDatum,
+} from '../types';
+import { getDateFormatter, parseMetricValue } from '../utils';
+
+const defaultNumberFormatter = getNumberFormatter();
+export function renderTooltipFactory(
+ formatDate: TimeFormatter = smartDateVerboseFormatter,
+ formatValue: NumberFormatter | TimeFormatter = defaultNumberFormatter,
+) {
+ return function renderTooltip(params: { data: TimeSeriesDatum }[]) {
+ return `
+ ${formatDate(params[0].data[0])}
+
+
+ ${
+ params[0].data[1] === null ? t('N/A') : formatValue(params[0].data[1])
+ }
+
+ `;
+ };
+}
+
+const TIME_COLUMN = '__timestamp';
+const formatPercentChange = getNumberFormatter(
+ NumberFormats.PERCENT_SIGNED_1_POINT,
+);
+
+export default function transformProps(
+ chartProps: BigNumberWithTrendlineChartProps,
+) {
+ const { width, height, queriesData, formData, rawFormData } = chartProps;
+ const {
+ colorPicker,
+ compareLag: compareLag_,
+ compareSuffix = '',
+ timeFormat,
+ headerFontSize,
+ metric = 'value',
+ showTimestamp,
+ showTrendLine,
+ startYAxisAtZero,
+ subheader = '',
+ subheaderFontSize,
+ forceTimestampFormatting,
+ yAxisFormat,
+ timeRangeFixed,
+ } = formData;
+ const granularity = extractTimegrain(rawFormData as QueryFormData);
+ const {
+ data = [],
+ colnames = [],
+ coltypes = [],
+ from_dttm: fromDatetime,
+ to_dttm: toDatetime,
+ } = queriesData[0];
+ const metricName = getMetricLabel(metric);
+ const compareLag = Number(compareLag_) || 0;
+ let formattedSubheader = subheader;
+
+ const { r, g, b } = colorPicker;
+ const mainColor = `rgb(${r}, ${g}, ${b})`;
+
+ let trendLineData;
+ let percentChange = 0;
+ let bigNumber = data.length === 0 ? null : data[0][metricName];
+ let timestamp = data.length === 0 ? null : data[0][TIME_COLUMN];
+ let bigNumberFallback;
+
+ const metricColtypeIndex = colnames.findIndex(name => name === metricName);
+ const metricColtype =
+ metricColtypeIndex > -1 ? coltypes[metricColtypeIndex] : null;
+
+ if (data.length > 0) {
+ const sortedData = (data as BigNumberDatum[])
+ .map(d => [d[TIME_COLUMN], parseMetricValue(d[metricName])])
+ // sort in time descending order
+ .sort((a, b) => (a[0] !== null && b[0] !== null ? b[0] - a[0] : 0));
+
+ bigNumber = sortedData[0][1];
+ timestamp = sortedData[0][0];
+
+ if (bigNumber === null) {
+ bigNumberFallback = sortedData.find(d => d[1] !== null);
+ bigNumber = bigNumberFallback ? bigNumberFallback[1] : null;
+ timestamp = bigNumberFallback ? bigNumberFallback[0] : null;
+ }
+
+ if (compareLag > 0) {
+ const compareIndex = compareLag;
+ if (compareIndex < sortedData.length) {
+ const compareValue = sortedData[compareIndex][1];
+ // compare values must both be non-nulls
+ if (bigNumber !== null && compareValue !== null && compareValue !== 0) {
+ percentChange = (bigNumber - compareValue) / Math.abs(compareValue);
+ formattedSubheader = `${formatPercentChange(
+ percentChange,
+ )} ${compareSuffix}`;
+ }
+ }
+ }
+ sortedData.reverse();
+ trendLineData = showTrendLine ? sortedData : undefined;
+ }
+
+ let className = '';
+ if (percentChange > 0) {
+ className = 'positive';
+ } else if (percentChange < 0) {
+ className = 'negative';
+ }
+
+ let metricEntry;
+ if (chartProps.datasource && chartProps.datasource.metrics) {
+ metricEntry = chartProps.datasource.metrics.find(
+ metricEntry => metricEntry.metric_name === metric,
+ );
+ }
+
+ const formatTime = getDateFormatter(
+ timeFormat,
+ granularity,
+ metricEntry?.d3format,
+ );
+
+ const headerFormatter =
+ metricColtype === GenericDataType.TEMPORAL ||
+ metricColtype === GenericDataType.STRING ||
+ forceTimestampFormatting
+ ? formatTime
+ : getNumberFormatter(yAxisFormat ?? metricEntry?.d3format ?? undefined);
+
+ if (trendLineData && timeRangeFixed && fromDatetime) {
+ const toDatetimeOrToday = toDatetime ?? Date.now();
+ if (!trendLineData[0][0] || trendLineData[0][0] > fromDatetime) {
+ trendLineData.unshift([fromDatetime, null]);
+ }
+ if (
+ !trendLineData[trendLineData.length - 1][0] ||
+ trendLineData[trendLineData.length - 1][0]! < toDatetimeOrToday
+ ) {
+ trendLineData.push([toDatetimeOrToday, null]);
+ }
+ }
+
+ const echartOptions: EChartsCoreOption = trendLineData
+ ? {
+ series: [
+ {
+ data: trendLineData,
+ type: 'line',
+ smooth: true,
+ symbol: 'circle',
+ showSymbol: false,
+ color: mainColor,
+ areaStyle: {
+ color: new graphic.LinearGradient(0, 0, 0, 1, [
+ {
+ offset: 0,
+ color: mainColor,
+ },
+ {
+ offset: 1,
+ color: 'white',
+ },
+ ]),
+ },
+ },
+ ],
+ xAxis: {
+ min: trendLineData[0][0],
+ max: trendLineData[trendLineData.length - 1][0],
+ show: false,
+ type: 'value',
+ },
+ yAxis: {
+ scale: !startYAxisAtZero,
+ show: false,
+ },
+ grid: {
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ },
+ tooltip: {
+ show: true,
+ trigger: 'axis',
+ confine: true,
+ formatter: renderTooltipFactory(formatTime, headerFormatter),
+ },
+ aria: {
+ enabled: true,
+ label: {
+ description: `Big number visualization ${subheader}`,
+ },
+ },
+ }
+ : {};
+ return {
+ width,
+ height,
+ bigNumber,
+ bigNumberFallback,
+ className,
+ headerFormatter,
+ formatTime,
+ headerFontSize,
+ subheaderFontSize,
+ mainColor,
+ showTimestamp,
+ showTrendLine,
+ startYAxisAtZero,
+ subheader: formattedSubheader,
+ timestamp,
+ trendLineData,
+ echartOptions,
+ };
+}
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/CHANGELOG.md b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/CHANGELOG.md
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/CHANGELOG.md
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/CHANGELOG.md
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/index.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/index.ts
similarity index 85%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/index.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/index.ts
index ec2413cf2ddcb..f9b7f3c8a033f 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/index.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/index.ts
@@ -17,6 +17,5 @@
* under the License.
*/
-export { default as BigNumberChartPlugin } from './BigNumber/index';
-export { default as BigNumberTotalChartPlugin } from './BigNumberTotal/index';
-export { default as BigNumberChartPreset } from './preset';
+export { default as BigNumberChartPlugin } from './BigNumberWithTrendline';
+export { default as BigNumberTotalChartPlugin } from './BigNumberTotal';
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/sharedControls.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/sharedControls.ts
similarity index 98%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/sharedControls.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/sharedControls.ts
index de13c6c844ea8..9cd6032affd98 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/sharedControls.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/sharedControls.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-// These are control configurations that are shared ONLY within the BigNumber viz plugin repo.
+// These are control configurations that are shared ONLY within the BigNumberWithTrendline viz plugin repo.
import { t } from '@superset-ui/core';
import { CustomControlItem } from '@superset-ui/chart-controls';
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts
new file mode 100644
index 0000000000000..49f5ea2bfd98f
--- /dev/null
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/types.ts
@@ -0,0 +1,57 @@
+/**
+ * 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 {
+ ChartDataResponseResult,
+ ChartProps,
+ QueryFormData,
+ QueryFormMetric,
+} from '@superset-ui/core';
+
+export interface BigNumberDatum {
+ [key: string]: number | null;
+}
+
+export type BigNumberTotalFormData = QueryFormData & {
+ metric?: QueryFormMetric;
+ yAxisFormat?: string;
+ forceTimestampFormatting?: boolean;
+};
+
+export type BigNumberWithTrendlineFormData = BigNumberTotalFormData & {
+ colorPicker: {
+ r: number;
+ g: number;
+ b: number;
+ };
+ compareLag?: string | number;
+};
+
+export type BigNumberTotalChartProps = ChartProps & {
+ formData: BigNumberTotalFormData;
+ queriesData: (ChartDataResponseResult & {
+ data?: BigNumberDatum[];
+ })[];
+};
+
+export type BigNumberWithTrendlineChartProps = BigNumberTotalChartProps & {
+ formData: BigNumberWithTrendlineFormData;
+};
+
+export type TimeSeriesDatum = [number, number | null];
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/src/preset.ts b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/utils.ts
similarity index 52%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/src/preset.ts
rename to superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/utils.ts
index 6e330e49fb4eb..b30e13d539f7c 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/src/preset.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/utils.ts
@@ -16,18 +16,31 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Preset } from '@superset-ui/core';
-import BigNumberChartPlugin from './BigNumber';
-import BigNumberTotalChartPlugin from './BigNumberTotal';
-export default class BigNumberChartPreset extends Preset {
- constructor() {
- super({
- name: 'BigNumber charts',
- plugins: [
- new BigNumberChartPlugin().configure({ key: 'big_number' }),
- new BigNumberTotalChartPlugin().configure({ key: 'big_number_total' }),
- ],
- });
+import moment from 'moment';
+import {
+ getTimeFormatter,
+ getTimeFormatterForGranularity,
+ smartDateFormatter,
+ TimeGranularity,
+} from '@superset-ui/core';
+
+export const parseMetricValue = (metricValue: number | string | null) => {
+ if (typeof metricValue === 'string') {
+ const dateObject = moment.utc(metricValue, moment.ISO_8601, true);
+ if (dateObject.isValid()) {
+ return dateObject.valueOf();
+ }
+ return null;
}
-}
+ return metricValue;
+};
+
+export const getDateFormatter = (
+ timeFormat: string,
+ granularity?: TimeGranularity,
+ fallbackFormat?: string | null,
+) =>
+ timeFormat === smartDateFormatter.id
+ ? getTimeFormatterForGranularity(granularity)
+ : getTimeFormatter(timeFormat ?? fallbackFormat);
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/index.ts b/superset-frontend/plugins/plugin-chart-echarts/src/index.ts
index ad9f9113cc574..84a1a3a3dcc39 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/index.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/index.ts
@@ -32,6 +32,7 @@ export { default as EchartsRadarChartPlugin } from './Radar';
export { default as EchartsFunnelChartPlugin } from './Funnel';
export { default as EchartsTreeChartPlugin } from './Tree';
export { default as EchartsTreemapChartPlugin } from './Treemap';
+export { BigNumberChartPlugin, BigNumberTotalChartPlugin } from './BigNumber';
export { default as BoxPlotTransformProps } from './BoxPlot/transformProps';
export { default as FunnelTransformProps } from './Funnel/transformProps';
diff --git a/superset-frontend/plugins/legacy-preset-chart-big-number/test/transformProps.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
similarity index 87%
rename from superset-frontend/plugins/legacy-preset-chart-big-number/test/transformProps.test.ts
rename to superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
index d19139b0fd2a1..4fdb3de8748d8 100644
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/test/transformProps.test.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/test/BigNumber/transformProps.test.ts
@@ -17,10 +17,11 @@
* under the License.
*/
import { DatasourceType, TimeGranularity } from '@superset-ui/core';
-import transformProps, {
- BignumberChartProps,
+import transformProps from '../../src/BigNumber/BigNumberWithTrendline/transformProps';
+import {
BigNumberDatum,
-} from '../src/BigNumber/transformProps';
+ BigNumberWithTrendlineChartProps,
+} from '../../src/BigNumber/types';
const formData = {
metric: 'value',
@@ -33,8 +34,9 @@ const formData = {
compareLag: 1,
timeGrainSqla: 'P3M' as TimeGranularity,
compareSuffix: 'over last quarter',
- vizType: 'big_number',
+ viz_type: 'big_number',
yAxisFormat: '.3s',
+ datasource: 'test_datasource',
};
const rawFormData = {
@@ -56,7 +58,7 @@ function generateProps(
data: BigNumberDatum[],
extraFormData = {},
extraQueryData = {},
-): BignumberChartProps {
+): BigNumberWithTrendlineChartProps {
return {
width: 200,
height: 500,
@@ -84,10 +86,13 @@ function generateProps(
...extraQueryData,
},
],
+ ownState: {},
+ filterState: {},
+ behaviors: [],
};
}
-describe('BigNumber', () => {
+describe('BigNumberWithTrendline', () => {
const props = generateProps(
[
{
@@ -109,8 +114,8 @@ describe('BigNumber', () => {
const lastDatum = transformed.trendLineData?.pop();
// should use last available value
- expect(lastDatum?.x).toStrictEqual(100);
- expect(lastDatum?.y).toBeNull();
+ expect(lastDatum?.[0]).toStrictEqual(100);
+ expect(lastDatum?.[1]).toBeNull();
// should note this is a fallback
expect(transformed.bigNumber).toStrictEqual(1.2345);
diff --git a/superset-frontend/plugins/plugin-chart-table/test/testData.ts b/superset-frontend/plugins/plugin-chart-table/test/testData.ts
index e9eee7e92d493..dd411c932f073 100644
--- a/superset-frontend/plugins/plugin-chart-table/test/testData.ts
+++ b/superset-frontend/plugins/plugin-chart-table/test/testData.ts
@@ -68,7 +68,7 @@ const basicChartProps = {
const basicQueryResult: ChartDataResponseResult = {
annotation_data: null,
cache_key: null,
- cache_dttm: null,
+ cached_dttm: null,
cache_timeout: null,
data: [],
colnames: [],
diff --git a/superset-frontend/src/visualizations/presets/MainPreset.js b/superset-frontend/src/visualizations/presets/MainPreset.js
index 97c14a99d57da..a32fbb2b74f88 100644
--- a/superset-frontend/src/visualizations/presets/MainPreset.js
+++ b/superset-frontend/src/visualizations/presets/MainPreset.js
@@ -17,10 +17,6 @@
* under the License.
*/
import { isFeatureEnabled, Preset, FeatureFlag } from '@superset-ui/core';
-import {
- BigNumberChartPlugin,
- BigNumberTotalChartPlugin,
-} from '@superset-ui/legacy-preset-chart-big-number';
import CalendarChartPlugin from '@superset-ui/legacy-plugin-chart-calendar';
import ChordChartPlugin from '@superset-ui/legacy-plugin-chart-chord';
import CountryMapChartPlugin from '@superset-ui/legacy-plugin-chart-country-map';
@@ -54,6 +50,8 @@ import {
} from '@superset-ui/legacy-preset-chart-nvd3';
import { DeckGLChartPreset } from '@superset-ui/legacy-preset-chart-deckgl';
import {
+ BigNumberChartPlugin,
+ BigNumberTotalChartPlugin,
EchartsPieChartPlugin,
EchartsBoxPlotChartPlugin,
EchartsAreaChartPlugin,
diff --git a/superset/charts/schemas.py b/superset/charts/schemas.py
index f68c4ff4b8c95..225410eb4c9ab 100644
--- a/superset/charts/schemas.py
+++ b/superset/charts/schemas.py
@@ -1240,12 +1240,22 @@ class ChartDataResponseResult(Schema):
description="Amount of rows in result set", allow_none=False,
)
data = fields.List(fields.Dict(), description="A list with results")
+ colnames = fields.List(fields.String(), description="A list of column names")
+ coltypes = fields.List(
+ fields.Integer(), description="A list of generic data types of each column"
+ )
applied_filters = fields.List(
fields.Dict(), description="A list with applied filters"
)
rejected_filters = fields.List(
fields.Dict(), description="A list with rejected filters"
)
+ from_dttm = fields.Integer(
+ desciption="Start timestamp of time range", required=False, allow_none=True
+ )
+ to_dttm = fields.Integer(
+ desciption="End timestamp of time range", required=False, allow_none=True
+ )
class ChartDataResponseSchema(Schema):
diff --git a/superset/common/query_context_processor.py b/superset/common/query_context_processor.py
index 09f991420c60a..9c641cb3ea7c0 100644
--- a/superset/common/query_context_processor.py
+++ b/superset/common/query_context_processor.py
@@ -144,6 +144,8 @@ def get_df_payload(
"status": cache.status,
"stacktrace": cache.stacktrace,
"rowcount": len(cache.df.index),
+ "from_dttm": query_obj.from_dttm,
+ "to_dttm": query_obj.to_dttm,
}
def query_cache_key(self, query_obj: QueryObject, **kwargs: Any) -> Optional[str]:
@@ -201,6 +203,8 @@ def get_query_result(self, query_object: QueryObject) -> QueryResult:
result.df = df
result.query = query
+ result.from_dttm = query_object.from_dttm
+ result.to_dttm = query_object.to_dttm
return result
def normalize_df(self, df: pd.DataFrame, query_object: QueryObject) -> pd.DataFrame:
diff --git a/superset/migrations/versions/fe23025b9441_rename_big_viz_total_form_data_fields.py b/superset/migrations/versions/fe23025b9441_rename_big_viz_total_form_data_fields.py
new file mode 100644
index 0000000000000..d391348ee8c9b
--- /dev/null
+++ b/superset/migrations/versions/fe23025b9441_rename_big_viz_total_form_data_fields.py
@@ -0,0 +1,100 @@
+# 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.
+"""rename_big_viz_total_form_data_fields
+
+Revision ID: fe23025b9441
+Revises: 3ba29ecbaac5
+Create Date: 2021-12-13 14:06:24.426970
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = "fe23025b9441"
+down_revision = "3ba29ecbaac5"
+
+import json
+import logging
+
+from alembic import op
+from sqlalchemy import Column, Integer, String, Text
+from sqlalchemy.ext.declarative import declarative_base
+
+from superset import db
+
+Base = declarative_base()
+
+logger = logging.getLogger("alembic")
+
+
+class Slice(Base):
+ __tablename__ = "slices"
+
+ id = Column(Integer, primary_key=True)
+ params = Column(Text)
+ viz_type = Column(String(250))
+
+
+def upgrade():
+ bind = op.get_bind()
+ session = db.Session(bind=bind)
+
+ slices = session.query(Slice).filter(Slice.viz_type == "big_number_total").all()
+ for slc in slices:
+ try:
+ params = json.loads(slc.params)
+ header_format_selector = params.pop("header_format_selector", None)
+ header_timestamp_format = params.pop("header_timestamp_format", None)
+ if header_format_selector:
+ params["force_timestamp_formatting"] = header_format_selector
+ if header_timestamp_format:
+ params["time_format"] = header_timestamp_format
+ slc.params = json.dumps(params, sort_keys=True)
+ except Exception as e:
+ logger.exception(
+ f"An error occurred: parsing params for slice {slc.id} failed."
+ f"You need to fix it before upgrading your DB."
+ )
+ raise e
+
+ session.commit()
+ session.close()
+
+
+def downgrade():
+ bind = op.get_bind()
+ session = db.Session(bind=bind)
+
+ slices = session.query(Slice).filter(Slice.viz_type == "big_number_total").all()
+ for slc in slices:
+ try:
+ params = json.loads(slc.params)
+ time_format = params.pop("time_format", None)
+ force_timestamp_formatting = params.pop("force_timestamp_formatting", None)
+ if time_format:
+ params["header_timestamp_format"] = time_format
+ if force_timestamp_formatting:
+ params["header_format_selector"] = force_timestamp_formatting
+ slc.params = json.dumps(params, sort_keys=True)
+ except Exception as e:
+ logger.exception(
+ f"An error occurred: parsing params for slice {slc.id} failed. "
+ "You need to fix it before downgrading your DB."
+ )
+ raise e
+
+ session.commit()
+ session.close()
diff --git a/superset/models/helpers.py b/superset/models/helpers.py
index 1875d247dc0a3..42779239985d8 100644
--- a/superset/models/helpers.py
+++ b/superset/models/helpers.py
@@ -446,6 +446,8 @@ def __init__( # pylint: disable=too-many-arguments
status: str = QueryStatus.SUCCESS,
error_message: Optional[str] = None,
errors: Optional[List[Dict[str, Any]]] = None,
+ from_dttm: Optional[datetime] = None,
+ to_dttm: Optional[datetime] = None,
) -> None:
self.df = df
self.query = query
@@ -454,6 +456,8 @@ def __init__( # pylint: disable=too-many-arguments
self.status = status
self.error_message = error_message
self.errors = errors or []
+ self.from_dttm = from_dttm
+ self.to_dttm = to_dttm
class ExtraJSONMixin: