You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by kg...@apache.org on 2021/12/15 09:16:51 UTC

[superset] branch master updated: chore(explore): Migrate BigNumber to v1 api [ID-28][ID-55] (#17587)

This is an automated email from the ASF dual-hosted git repository.

kgabryje pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 124af4c  chore(explore): Migrate BigNumber to v1 api [ID-28][ID-55] (#17587)
124af4c is described below

commit 124af4c566af8c13dd1ee029144dd9a77c40e851
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Wed Dec 15 10:15:14 2021 +0100

    chore(explore): Migrate BigNumber to v1 api [ID-28][ID-55] (#17587)
    
    * chore(explore): Migrate BigNumber to v1 api
    
    * Move to echarts
    
    * Use Echarts trendline
    
    * Fix imports
    
    * Fix parsing dates as strings
    
    * Add from_dttm and to_dttm to v1 chart response
    
    * Fix post processing
    
    * Fix timeRangeFixed
    
    * Fix tests
    
    * Remove from and to dttm from cache
    
    * Cleanup date formatting
    
    * Fix storybook
    
    * Fix missing types
    
    * Fix timestamp with timezone
    
    * Add types to demo's tsconfig
    
    * bug fix
    
    * fix import
    
    * Fix cypress tests
    
    * add sort
    
    * add resample to handle missing values properly
    
    * Sync ChartDataResponseResult schema with ts interface
    
    * Lint fix
    
    * Add migration
    
    * Fix migration
    
    * Remove pass
    
    * Re-raise the exception in migration
    
    * Typo fix
    
    * Update revision
    
    Co-authored-by: Ville Brofeldt <vi...@gmail.com>
---
 .../explore/visualizations/big_number.test.js      |  12 +-
 .../visualizations/big_number_total.test.js        |  17 +-
 .../cypress-base/cypress/utils/vizPlugins.ts       |   2 +
 superset-frontend/package-lock.json                |  27 +--
 superset-frontend/package.json                     |   2 +-
 .../src/query/types/QueryResponse.ts               |   4 +-
 .../packages/superset-ui-demo/package.json         |   1 -
 .../BigNumber/BigNumberStories.tsx                 |   4 +-
 .../BigNumberTotal/BigNumberTotalStories.tsx       |   2 +-
 .../superset-ui-chart/ChartDataProviderStories.tsx |   4 +-
 .../packages/superset-ui-demo/tsconfig.json        |   1 +
 .../legacy-preset-chart-big-number/README.md       |  67 ------
 .../legacy-preset-chart-big-number/package.json    |  42 ----
 .../src/BigNumber/transformProps.ts                | 187 ---------------
 .../test/tsconfig.json                             |  19 --
 .../legacy-preset-chart-big-number/tsconfig.json   |  25 --
 .../src/BigNumber/BigNumberTotal/buildQuery.ts}    |   8 +-
 .../src/BigNumber}/BigNumberTotal/controlPanel.ts  |  47 ++--
 .../BigNumber}/BigNumberTotal/images/BigNumber.jpg | Bin
 .../BigNumberTotal/images/BigNumber2.jpg           | Bin
 .../BigNumber}/BigNumberTotal/images/thumbnail.png | Bin
 .../BigNumberTotal/images/thumbnailLarge.png       | Bin
 .../src/BigNumber}/BigNumberTotal/index.ts         |  15 +-
 .../src/BigNumber/BigNumberTotal/transformProps.ts |  76 +++++++
 .../src/BigNumber/BigNumberViz.tsx}                | 122 +---------
 .../BigNumber/BigNumberWithTrendline/buildQuery.ts |  92 ++++++++
 .../BigNumberWithTrendline}/controlPanel.tsx       |  45 ++--
 .../images/Big_Number_Trendline.jpg                | Bin
 .../BigNumberWithTrendline}/images/thumbnail.png   | Bin
 .../images/thumbnailLarge.png                      | Bin
 .../src/BigNumber/BigNumberWithTrendline}/index.ts |  20 +-
 .../BigNumberWithTrendline/transformProps.ts       | 252 +++++++++++++++++++++
 .../src/BigNumber}/CHANGELOG.md                    |   0
 .../src/BigNumber}/index.ts                        |   5 +-
 .../src/BigNumber}/sharedControls.ts               |   2 +-
 .../plugin-chart-echarts/src/BigNumber/types.ts    |  57 +++++
 .../src/BigNumber/utils.ts}                        |  39 ++--
 .../plugins/plugin-chart-echarts/src/index.ts      |   1 +
 .../test/BigNumber}/transformProps.test.ts         |  21 +-
 .../plugins/plugin-chart-table/test/testData.ts    |   2 +-
 .../src/visualizations/presets/MainPreset.js       |   6 +-
 superset/charts/schemas.py                         |  10 +
 superset/common/query_context_processor.py         |   4 +
 ...5b9441_rename_big_viz_total_form_data_fields.py | 100 ++++++++
 superset/models/helpers.py                         |   4 +
 45 files changed, 763 insertions(+), 581 deletions(-)

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 9e8ca24..30e7716 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 b6794c4..e2fcc5a 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 850cc09..36a8374 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 0ea5b6d..82f2dca 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 b72640d..07ffcd0 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 6c99ca9..90898fc 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 d218442..9016275 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 dd56c58..18fe9ac 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 f99d4f2..2d1e105 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 14d4d6d..ff72aff 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 a7983cf..36179f3 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 cceb13a..0000000
--- a/superset-frontend/plugins/legacy-preset-chart-big-number/README.md
+++ /dev/null
@@ -1,67 +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.
--->
-
-## @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
-<SuperChart
-  chartType="big-number"
-  width={600}
-  height={600}
-  formData={...}
-  queriesData={[{
-    data: {...},
-  }]}
-/>
-```
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 81adb1d..0000000
--- 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 6e4674d..0000000
--- 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 481ca5b..0000000
--- 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 b6bfaa2..0000000
--- 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 bd49e0a..e714898 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 f6ab2f3..e30dcbe 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 7bece7b..3f45db7 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 0000000..2312673
--- /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 6f559f3..1c650ef 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 (
-      <div style={{ padding: '4px 8px' }}>
-        {formatDate(new Date(x))}
-        <br />
-        <strong>{y === null ? t('N/A') : formatValue(y)}</strong>
-      </div>
-    );
-  };
-}
-
 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<BigNumberVisProps, {}> {
-  private gradientId: string = shortid.generate();
-
+class BigNumberVis extends React.PureComponent<BigNumberVisProps> {
   static defaultProps = {
     className: '',
     headerFormatter: defaultNumberFormatter,
@@ -146,7 +106,7 @@ class BigNumberVis extends React.PureComponent<BigNumberVisProps, {}> {
         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<BigNumberVisProps, {}> {
   }
 
   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 (
-      <XYChart
-        snapTooltipToDataX
-        ariaLabel={`Big number visualization ${subheader}`}
-        // headerFormatter always NumberFormatter in BigNumber with treadline
-        renderTooltip={renderTooltipFactory(
-          formatTime,
-          headerFormatter as NumberFormatter,
-        )}
-        xScale={xScale}
-        yScale={{
-          type: 'linear',
-          includeZero: startYAxisAtZero,
-        }}
+      <Echart
         width={Math.floor(width)}
         height={maxHeight}
-        margin={CHART_MARGIN}
-        eventTrigger="container"
-      >
-        <LinearGradient id={this.gradientId} from={mainColor} to="#fff" />
-        <AreaSeries
-          data={tooltipData}
-          fill={`url(#${this.gradientId})`}
-          stroke={mainColor}
-        />
-        <CrossHair
-          fullHeight
-          stroke={mainColor}
-          circleFill={mainColor}
-          circleStroke="#fff"
-          showHorizontalLine={false}
-          strokeDasharray="5,2"
-        />
-      </XYChart>
+        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 0000000..1a9096f
--- /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<string, string> = {
+  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 045f7fc7..c137854 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 2cfee29..e774db4 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 0000000..5054d99
--- /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])}
+      <br />
+      <strong>
+        ${
+          params[0].data[1] === null ? t('N/A') : formatValue(params[0].data[1])
+        }
+      </strong>
+    `;
+  };
+}
+
+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 ec2413c..f9b7f3c 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 de13c6c..9cd6032 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 0000000..49f5ea2
--- /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 6e330e4..b30e13d 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 ad9f911..84a1a3a 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 d19139b..4fdb3de 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 e9eee7e..dd411c9 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 97c14a9..a32fbb2 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 f68c4ff..225410e 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 09f9914..9c641cb 100644
--- a/superset/common/query_context_processor.py
+++ b/superset/common/query_context_processor.py
@@ -144,6 +144,8 @@ class QueryContextProcessor:
             "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 @@ class QueryContextProcessor:
 
         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 0000000..d391348
--- /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 1875d24..4277923 100644
--- a/superset/models/helpers.py
+++ b/superset/models/helpers.py
@@ -446,6 +446,8 @@ class QueryResult:  # pylint: disable=too-few-public-methods
         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 @@ class QueryResult:  # pylint: disable=too-few-public-methods
         self.status = status
         self.error_message = error_message
         self.errors = errors or []
+        self.from_dttm = from_dttm
+        self.to_dttm = to_dttm
 
 
 class ExtraJSONMixin: