diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/plugin-chart-pivot-table/PivotTableStories.tsx b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/plugin-chart-pivot-table/PivotTableStories.tsx
new file mode 100644
index 0000000000000..54903c013aa25
--- /dev/null
+++ b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/plugin-chart-pivot-table/PivotTableStories.tsx
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import { withKnobs } from '@storybook/addon-knobs';
+import { SuperChart } from '@superset-ui/core';
+import { PivotTableChartPlugin } from '@superset-ui/plugin-chart-pivot-table';
+import { basicFormData, basicData } from './testData';
+import { withResizableChartDemo } from '../../../shared/components/ResizableChartDemo';
+
+export default {
+ title: 'Chart Plugins/plugin-chart-pivot-table',
+ decorators: [withKnobs, withResizableChartDemo],
+};
+
+new PivotTableChartPlugin().configure({ key: 'pivot_table_v2' }).register();
+
+export const basic = ({ width, height }) => (
+
+);
+basic.story = {
+ parameters: {
+ initialSize: {
+ width: 680,
+ height: 420,
+ },
+ },
+};
+
+export const MaximumAggregation = ({ width, height }) => (
+
+);
+basic.story = {
+ parameters: {
+ initialSize: {
+ width: 680,
+ height: 420,
+ },
+ },
+};
diff --git a/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/plugin-chart-pivot-table/testData.ts b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/plugin-chart-pivot-table/testData.ts
new file mode 100644
index 0000000000000..0e6457d0c122e
--- /dev/null
+++ b/superset-frontend/packages/superset-ui-demo/storybook/stories/plugins/plugin-chart-pivot-table/testData.ts
@@ -0,0 +1,126 @@
+/**
+ * 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.
+ */
+export const basicFormData = {
+ datasource: '1__table',
+ viz_type: 'pivot_table_v2',
+ granularity_sqla: 'ts',
+ groupbyColumns: ['location'],
+ groupbyRows: ['program_language'],
+ metrics: [
+ {
+ expressionType: 'SIMPLE',
+ column: {
+ id: 1,
+ column_name: 'count',
+ description: null,
+ expression: null,
+ groupby: true,
+ is_dttm: false,
+ python_date_format: null,
+ type: 'BIGINT',
+ type_generic: 0,
+ },
+ aggregate: 'SUM',
+ sqlExpression: null,
+ isNew: false,
+ hasCustomLabel: true,
+ label: 'Count',
+ },
+ {
+ expressionType: 'SIMPLE',
+ column: {
+ id: 2,
+ column_name: 'ts',
+ description: null,
+ expression: "DATE_PARSE(ds || ' ' || hr, '%Y-%m-%d %H')",
+ groupby: true,
+ is_dttm: true,
+ type: 'TIMESTAMP',
+ type_generic: 2,
+ python_date_format: null,
+ },
+ aggregate: 'MAX',
+ sqlExpression: null,
+ isNew: false,
+ hasCustomLabel: true,
+ label: 'Most Recent Data',
+ },
+ ],
+ metricsLayout: 'COLUMNS',
+ order_desc: true,
+ aggregateFunction: 'Sum',
+ valueFormat: '~g',
+ date_format: 'smart_date',
+ rowOrder: 'key_a_to_z',
+ colOrder: 'key_a_to_z',
+};
+
+export const basicData = {
+ cache_key: 'f2cd2a37b6977e3619ce6c07d0027972',
+ cached_dttm: '2022-07-27T17:42:39',
+ cache_timeout: 129600,
+ applied_template_filters: [],
+ annotation_data: {},
+ error: null,
+ is_cached: true,
+ query: 'SELECT \nFROM\nWHERE',
+ status: 'success',
+ stacktrace: null,
+ rowcount: 5,
+ from_dttm: 1658426268000,
+ to_dttm: 1659031068000,
+ colnames: ['location', 'program_language', 'Count', 'Most Recent Data'],
+ indexnames: [0, 1, 2, 3, 4],
+ coltypes: [1, 1, 0, 1],
+ data: [
+ {
+ location: 'AMEA',
+ program_language: 'Javscript',
+ Count: 134,
+ 'Most Recent Data': '2022-07-25 13:00:00.000',
+ },
+ {
+ location: 'ASIA',
+ program_language: 'python',
+ Count: 19,
+ 'Most Recent Data': '2022-07-25 16:00:00.000',
+ },
+ {
+ location: 'ASIA',
+ program_language: 'Java',
+ Count: 7,
+ 'Most Recent Data': '2022-07-25 15:00:00.000',
+ },
+ {
+ location: 'ASIA',
+ program_language: 'C++',
+ Count: 1,
+ 'Most Recent Data': '2022-07-25 02:00:00.000',
+ },
+ {
+ location: 'ASIA',
+ program_language: 'PHP',
+ Count: 1,
+ 'Most Recent Data': '2022-07-24 00:00:00.000',
+ },
+ ],
+ result_format: 'json',
+ applied_filters: [],
+ rejected_filters: [],
+};
diff --git a/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/utilities.js b/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/utilities.js
index 9ae5888819777..9b47132936b4e 100644
--- a/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/utilities.js
+++ b/superset-frontend/plugins/plugin-chart-pivot-table/src/react-pivottable/utilities.js
@@ -231,7 +231,7 @@ const baseAggregatorTemplates = {
return {
sum: 0,
push(record) {
- if (Number.isNaN(parseFloat(record[attr]))) {
+ if (Number.isNaN(Number(record[attr]))) {
this.sum = record[attr];
} else {
this.sum += parseFloat(record[attr]);
@@ -259,7 +259,7 @@ const baseAggregatorTemplates = {
push(record) {
const x = record[attr];
if (['min', 'max'].includes(mode)) {
- const coercedValue = parseFloat(x);
+ const coercedValue = Number(x);
if (Number.isNaN(coercedValue)) {
this.val =
!this.val ||
@@ -308,7 +308,7 @@ const baseAggregatorTemplates = {
strMap: {},
push(record) {
const val = record[attr];
- const x = parseFloat(val);
+ const x = Number(val);
if (Number.isNaN(x)) {
this.strMap[val] = (this.strMap[val] || 0) + 1;
@@ -354,7 +354,7 @@ const baseAggregatorTemplates = {
s: 0.0,
strValue: null,
push(record) {
- const x = parseFloat(record[attr]);
+ const x = Number(record[attr]);
if (Number.isNaN(x)) {
this.strValue =
typeof record[attr] === 'string' ? record[attr] : this.strValue;
@@ -405,10 +405,10 @@ const baseAggregatorTemplates = {
sumNum: 0,
sumDenom: 0,
push(record) {
- if (!Number.isNaN(parseFloat(record[num]))) {
+ if (!Number.isNaN(Number(record[num]))) {
this.sumNum += parseFloat(record[num]);
}
- if (!Number.isNaN(parseFloat(record[denom]))) {
+ if (!Number.isNaN(Number(record[denom]))) {
this.sumDenom += parseFloat(record[denom]);
}
},