mirror of https://github.com/apache/superset.git
refactor: migrate table chart to new API (#10270)
* refactor: migrate table chart to new API * chore: bump superset-ui to 0.17.0 * Fix Cypress tests * Apply soft-conversion to numeric metrics Fix time column formatting test * Add translation to chart does not exist error * Bump to 0.17.1
This commit is contained in:
parent
bab86abd92
commit
e3db935c62
|
@ -362,7 +362,7 @@ ignored-argument-names=_.*
|
|||
max-locals=15
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
max-returns=10
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
|
|
@ -20,19 +20,20 @@ import {
|
|||
getChartAliases,
|
||||
isLegacyResponse,
|
||||
getSliceIdFromRequestUrl,
|
||||
JsonObject,
|
||||
} from '../../utils/vizPlugins';
|
||||
import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper';
|
||||
|
||||
describe('Dashboard load', () => {
|
||||
let dashboard;
|
||||
let aliases;
|
||||
let aliases: string[];
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
|
||||
cy.visit(WORLD_HEALTH_DASHBOARD);
|
||||
|
||||
cy.get('#app').then(data => {
|
||||
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
|
||||
cy.get('#app').then(nodes => {
|
||||
const bootstrapData = JSON.parse(nodes[0].dataset.bootstrap || '');
|
||||
dashboard = bootstrapData.dashboard_data;
|
||||
const { slices } = dashboard;
|
||||
// then define routes and create alias for each requests
|
||||
|
@ -53,7 +54,7 @@ describe('Dashboard load', () => {
|
|||
sliceId = responseBody.form_data.slice_id;
|
||||
} else {
|
||||
sliceId = getSliceIdFromRequestUrl(request.url);
|
||||
responseBody.result.forEach(element => {
|
||||
responseBody.result.forEach((element: JsonObject) => {
|
||||
expect(element).to.have.property('error', null);
|
||||
expect(element).to.have.property('status', 'success');
|
||||
});
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { interceptChart, parsePostForm } from 'cypress/utils';
|
||||
import { interceptChart, parsePostForm, Slice } from 'cypress/utils';
|
||||
import { TABBED_DASHBOARD } from './dashboard.helper';
|
||||
|
||||
describe('Dashboard tabs', () => {
|
||||
|
@ -40,24 +40,28 @@ describe('Dashboard tabs', () => {
|
|||
cy.visit(TABBED_DASHBOARD);
|
||||
|
||||
cy.get('#app').then(data => {
|
||||
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
|
||||
const dashboard = bootstrapData.dashboard_data;
|
||||
const bootstrapData = JSON.parse(data[0].dataset.bootstrap || '');
|
||||
const dashboard = bootstrapData.dashboard_data as { slices: Slice[] };
|
||||
filterId = dashboard.slices.find(
|
||||
slice => slice.form_data.viz_type === 'filter_box',
|
||||
).slice_id;
|
||||
)?.slice_id;
|
||||
boxplotId = dashboard.slices.find(
|
||||
slice => slice.form_data.viz_type === 'box_plot',
|
||||
).slice_id;
|
||||
)?.slice_id;
|
||||
treemapId = dashboard.slices.find(
|
||||
slice => slice.form_data.viz_type === 'treemap',
|
||||
).slice_id;
|
||||
)?.slice_id;
|
||||
linechartId = dashboard.slices.find(
|
||||
slice => slice.form_data.viz_type === 'line',
|
||||
).slice_id;
|
||||
interceptChart(filterId).as('filterRequest');
|
||||
interceptChart(treemapId).as('treemapRequest');
|
||||
interceptChart(linechartId).as('linechartRequest');
|
||||
interceptChart(boxplotId, false).as('boxplotRequest');
|
||||
)?.slice_id;
|
||||
interceptChart({ sliceId: filterId, legacy: true }).as('filterRequest');
|
||||
interceptChart({ sliceId: treemapId, legacy: true }).as('treemapRequest');
|
||||
interceptChart({ sliceId: linechartId, legacy: true }).as(
|
||||
'linechartRequest',
|
||||
);
|
||||
interceptChart({ sliceId: boxplotId, legacy: false }).as(
|
||||
'boxplotRequest',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -140,7 +144,7 @@ describe('Dashboard tabs', () => {
|
|||
// send new query from same tab
|
||||
cy.wait('@treemapRequest').then(({ request }) => {
|
||||
const requestBody = parsePostForm(request.body);
|
||||
const requestParams = JSON.parse(requestBody.form_data);
|
||||
const requestParams = JSON.parse(requestBody.form_data as string);
|
||||
expect(requestParams.extra_filters[0]).deep.eq({
|
||||
col: 'region',
|
||||
op: '==',
|
||||
|
@ -153,7 +157,7 @@ describe('Dashboard tabs', () => {
|
|||
|
||||
cy.wait('@linechartRequest').then(({ request }) => {
|
||||
const requestBody = parsePostForm(request.body);
|
||||
const requestParams = JSON.parse(requestBody.form_data);
|
||||
const requestParams = JSON.parse(requestBody.form_data as string);
|
||||
expect(requestParams.extra_filters[0]).deep.eq({
|
||||
col: 'region',
|
||||
op: '==',
|
|
@ -20,12 +20,14 @@ import {
|
|||
isLegacyResponse,
|
||||
getChartAliases,
|
||||
parsePostForm,
|
||||
Dashboard,
|
||||
JsonObject,
|
||||
} from 'cypress/utils';
|
||||
import { WORLD_HEALTH_DASHBOARD } from './dashboard.helper';
|
||||
|
||||
describe('Dashboard form data', () => {
|
||||
const urlParams = { param1: '123', param2: 'abc' };
|
||||
let dashboard;
|
||||
let dashboard: Dashboard;
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
|
@ -33,7 +35,7 @@ describe('Dashboard form data', () => {
|
|||
cy.visit(WORLD_HEALTH_DASHBOARD, { qs: urlParams });
|
||||
|
||||
cy.get('#app').then(data => {
|
||||
const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
|
||||
const bootstrapData = JSON.parse(data[0].dataset.bootstrap || '');
|
||||
dashboard = bootstrapData.dashboard_data;
|
||||
});
|
||||
});
|
||||
|
@ -47,13 +49,16 @@ describe('Dashboard form data', () => {
|
|||
const responseBody = response?.body;
|
||||
if (isLegacyResponse(responseBody)) {
|
||||
const requestParams = JSON.parse(
|
||||
parsePostForm(request.body).form_data,
|
||||
parsePostForm(request.body).form_data as string,
|
||||
);
|
||||
expect(requestParams.url_params).deep.eq(urlParams);
|
||||
} else {
|
||||
request.body.queries.forEach(query => {
|
||||
expect(query.url_params).deep.eq(urlParams);
|
||||
});
|
||||
// TODO: export url params to chart data API
|
||||
request.body.queries.forEach(
|
||||
(query: { url_params: JsonObject }) => {
|
||||
expect(query.url_params).deep.eq(urlParams);
|
||||
},
|
||||
);
|
||||
}
|
||||
}),
|
||||
),
|
|
@ -19,6 +19,7 @@
|
|||
// ***********************************************
|
||||
// Tests for setting controls in the UI
|
||||
// ***********************************************
|
||||
import { interceptChart } from 'cypress/utils';
|
||||
import { FORM_DATA_DEFAULTS, NUM_METRIC } from './visualizations/shared.helper';
|
||||
|
||||
describe('Datasource control', () => {
|
||||
|
@ -29,10 +30,10 @@ describe('Datasource control', () => {
|
|||
let numScripts = 0;
|
||||
|
||||
cy.login();
|
||||
cy.intercept('GET', '/superset/explore_json/**').as('getJson');
|
||||
cy.intercept('POST', '/superset/explore_json/**').as('postJson');
|
||||
interceptChart({ legacy: false }).as('chartData');
|
||||
|
||||
cy.visitChartByName('Num Births Trend');
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test="open-datasource-tab').click({ force: true });
|
||||
cy.get('[data-test="datasource-menu-trigger"]').click();
|
||||
|
@ -90,13 +91,13 @@ describe('Datasource control', () => {
|
|||
describe('VizType control', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.intercept('GET', '/superset/explore_json/**').as('getJson');
|
||||
cy.intercept('POST', '/superset/explore_json/**').as('postJson');
|
||||
interceptChart({ legacy: false }).as('tableChartData');
|
||||
interceptChart({ legacy: true }).as('lineChartData');
|
||||
});
|
||||
|
||||
it('Can change vizType', () => {
|
||||
cy.visitChartByName('Daily Totals');
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@tableChartData' });
|
||||
|
||||
let numScripts = 0;
|
||||
cy.get('script').then(nodes => {
|
||||
|
@ -114,27 +115,29 @@ describe('VizType control', () => {
|
|||
});
|
||||
|
||||
cy.get('button[data-test="run-query-button"]').click();
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson', chartSelector: 'svg' });
|
||||
cy.verifySliceSuccess({
|
||||
waitAlias: '@lineChartData',
|
||||
chartSelector: 'svg',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Time range filter', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.intercept('GET', '/superset/explore_json/**').as('getJson');
|
||||
cy.intercept('POST', '/superset/explore_json/**').as('postJson');
|
||||
interceptChart({ legacy: true }).as('chartData');
|
||||
});
|
||||
|
||||
it('Advanced time_range params', () => {
|
||||
const formData = {
|
||||
...FORM_DATA_DEFAULTS,
|
||||
metrics: [NUM_METRIC],
|
||||
viz_type: 'line',
|
||||
time_range: '100 years ago : now',
|
||||
metrics: [NUM_METRIC],
|
||||
};
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=time-range-trigger]')
|
||||
.click()
|
||||
|
@ -152,13 +155,13 @@ describe('Time range filter', () => {
|
|||
it('Common time_range params', () => {
|
||||
const formData = {
|
||||
...FORM_DATA_DEFAULTS,
|
||||
metrics: [NUM_METRIC],
|
||||
viz_type: 'line',
|
||||
metrics: [NUM_METRIC],
|
||||
time_range: 'Last year',
|
||||
};
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=time-range-trigger]')
|
||||
.click()
|
||||
|
@ -172,13 +175,13 @@ describe('Time range filter', () => {
|
|||
it('Previous time_range params', () => {
|
||||
const formData = {
|
||||
...FORM_DATA_DEFAULTS,
|
||||
metrics: [NUM_METRIC],
|
||||
viz_type: 'line',
|
||||
metrics: [NUM_METRIC],
|
||||
time_range: 'previous calendar month',
|
||||
};
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=time-range-trigger]')
|
||||
.click()
|
||||
|
@ -192,13 +195,13 @@ describe('Time range filter', () => {
|
|||
it('Custom time_range params', () => {
|
||||
const formData = {
|
||||
...FORM_DATA_DEFAULTS,
|
||||
metrics: [NUM_METRIC],
|
||||
viz_type: 'line',
|
||||
metrics: [NUM_METRIC],
|
||||
time_range: 'DATEADD(DATETIME("today"), -7, day) : today',
|
||||
};
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=time-range-trigger]')
|
||||
.click()
|
||||
|
@ -215,13 +218,13 @@ describe('Time range filter', () => {
|
|||
it('No filter time_range params', () => {
|
||||
const formData = {
|
||||
...FORM_DATA_DEFAULTS,
|
||||
metrics: [NUM_METRIC],
|
||||
viz_type: 'line',
|
||||
metrics: [NUM_METRIC],
|
||||
time_range: 'No filter',
|
||||
};
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=time-range-trigger]')
|
||||
.click()
|
||||
|
@ -235,16 +238,16 @@ describe('Time range filter', () => {
|
|||
describe('Groupby control', () => {
|
||||
it('Set groupby', () => {
|
||||
cy.login();
|
||||
cy.intercept('GET', '/superset/explore_json/**').as('getJson');
|
||||
cy.intercept('POST', '/superset/explore_json/**').as('postJson');
|
||||
interceptChart({ legacy: true }).as('chartData');
|
||||
|
||||
cy.visitChartByName('Num Births Trend');
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=groupby]').within(() => {
|
||||
cy.get('.Select__control').click();
|
||||
cy.get('input[type=text]').type('state{enter}');
|
||||
});
|
||||
cy.get('button[data-test="run-query-button"]').click();
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson', chartSelector: 'svg' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData', chartSelector: 'svg' });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -22,25 +22,25 @@
|
|||
|
||||
import rison from 'rison';
|
||||
import shortid from 'shortid';
|
||||
import { interceptChart } from 'cypress/utils';
|
||||
import { HEALTH_POP_FORM_DATA_DEFAULTS } from './visualizations/shared.helper';
|
||||
|
||||
const apiURL = (endpoint, queryObject) =>
|
||||
const apiURL = (endpoint: string, queryObject: Record<string, unknown>) =>
|
||||
`${endpoint}?q=${rison.encode(queryObject)}`;
|
||||
|
||||
describe('Test explore links', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.intercept('GET', '/superset/explore_json/**').as('getJson');
|
||||
cy.intercept('POST', '/superset/explore_json/**').as('postJson');
|
||||
interceptChart({ legacy: true }).as('chartData');
|
||||
});
|
||||
|
||||
it('Open and close view query modal', () => {
|
||||
cy.visitChartByName('Growth Rate');
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('button#query').click();
|
||||
cy.get('span').contains('View query').parent().click();
|
||||
cy.wait('@postJson').then(() => {
|
||||
cy.wait('@chartData').then(() => {
|
||||
cy.get('code');
|
||||
});
|
||||
cy.get('.ant-modal-content').within(() => {
|
||||
|
@ -52,7 +52,7 @@ describe('Test explore links', () => {
|
|||
cy.intercept('POST', 'r/shortner/').as('getShortUrl');
|
||||
|
||||
cy.visitChartByName('Growth Rate');
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=short-link-button]').click();
|
||||
|
||||
|
@ -64,12 +64,12 @@ describe('Test explore links', () => {
|
|||
.then(text => {
|
||||
cy.visit(text);
|
||||
});
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
});
|
||||
|
||||
it('Test iframe link', () => {
|
||||
cy.visitChartByName('Growth Rate');
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test=embed-code-button]').click();
|
||||
cy.get('#embed-code-popover').within(() => {
|
||||
|
@ -78,6 +78,8 @@ describe('Test explore links', () => {
|
|||
});
|
||||
|
||||
it('Test chart save as AND overwrite', () => {
|
||||
interceptChart({ legacy: false }).as('tableChartData');
|
||||
|
||||
const formData = {
|
||||
...HEALTH_POP_FORM_DATA_DEFAULTS,
|
||||
viz_type: 'table',
|
||||
|
@ -87,20 +89,20 @@ describe('Test explore links', () => {
|
|||
const newChartName = `Test chart [${shortid.generate()}]`;
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@tableChartData' });
|
||||
cy.url().then(() => {
|
||||
cy.get('[data-test="query-save-button"]').click();
|
||||
cy.get('[data-test="saveas-radio"]').check();
|
||||
cy.get('[data-test="new-chart-name"]').type(newChartName);
|
||||
cy.get('[data-test="btn-modal-save"]').click();
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@tableChartData' });
|
||||
cy.visitChartByName(newChartName);
|
||||
|
||||
// Overwriting!
|
||||
cy.get('[data-test="query-save-button"]').click();
|
||||
cy.get('[data-test="save-overwrite-radio"]').check();
|
||||
cy.get('[data-test="btn-modal-save"]').click();
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@tableChartData' });
|
||||
const query = {
|
||||
filters: [
|
||||
{
|
||||
|
@ -110,6 +112,7 @@ describe('Test explore links', () => {
|
|||
},
|
||||
],
|
||||
};
|
||||
|
||||
cy.request(apiURL('/api/v1/chart/', query)).then(response => {
|
||||
expect(response.body.count).equals(1);
|
||||
cy.request('DELETE', `/api/v1/chart/${response.body.ids[0]}`);
|
||||
|
@ -123,7 +126,7 @@ describe('Test explore links', () => {
|
|||
const dashboardTitle = `Test dashboard [${shortid.generate()}]`;
|
||||
|
||||
cy.visitChartByName(chartName);
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test="query-save-button"]').click();
|
||||
cy.get('[data-test="saveas-radio"]').check();
|
||||
|
@ -134,7 +137,7 @@ describe('Test explore links', () => {
|
|||
.type(`${dashboardTitle}{enter}{enter}`);
|
||||
|
||||
cy.get('[data-test="btn-modal-save"]').click();
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
let query = {
|
||||
filters: [
|
||||
{
|
||||
|
@ -149,7 +152,7 @@ describe('Test explore links', () => {
|
|||
});
|
||||
|
||||
cy.visitChartByName(newChartName);
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
|
||||
cy.get('[data-test="query-save-button"]').click();
|
||||
cy.get('[data-test="save-overwrite-radio"]').check();
|
||||
|
@ -161,7 +164,7 @@ describe('Test explore links', () => {
|
|||
.type(`${dashboardTitle}{enter}{enter}`);
|
||||
|
||||
cy.get('[data-test="btn-modal-save"]').click();
|
||||
cy.verifySliceSuccess({ waitAlias: '@postJson' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData' });
|
||||
query = {
|
||||
filters: [
|
||||
{
|
|
@ -16,6 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { interceptChart } from 'cypress/utils';
|
||||
import {
|
||||
FORM_DATA_DEFAULTS,
|
||||
NUM_METRIC,
|
||||
|
@ -34,7 +35,7 @@ describe('Visualization > Table', () => {
|
|||
|
||||
const PERCENT_METRIC = {
|
||||
expressionType: 'SQL',
|
||||
sqlExpression: 'CAST(SUM(num_girls)+AS+FLOAT)/SUM(num)',
|
||||
sqlExpression: 'CAST(SUM(num_girls) AS FLOAT)/SUM(num)',
|
||||
column: null,
|
||||
aggregate: null,
|
||||
hasCustomLabel: true,
|
||||
|
@ -44,7 +45,7 @@ describe('Visualization > Table', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.intercept('POST', '/superset/explore_json/**').as('getJson');
|
||||
interceptChart({ legacy: false }).as('chartData');
|
||||
});
|
||||
|
||||
it('Use default time column', () => {
|
||||
|
@ -66,8 +67,8 @@ describe('Visualization > Table', () => {
|
|||
});
|
||||
// when format with smart_date, time column use format by granularity
|
||||
cy.get('.chart-container td:nth-child(1)').contains('2008 Q1');
|
||||
// other column with timestamp use raw timestamp
|
||||
cy.get('.chart-container td:nth-child(3)').contains('2008-01-01T00:00:00');
|
||||
// other column with timestamp use adaptive formatting
|
||||
cy.get('.chart-container td:nth-child(3)').contains('2008');
|
||||
cy.get('.chart-container td:nth-child(4)').contains('TX');
|
||||
});
|
||||
|
||||
|
@ -99,7 +100,7 @@ describe('Visualization > Table', () => {
|
|||
groupby: ['name'],
|
||||
});
|
||||
cy.verifySliceSuccess({
|
||||
waitAlias: '@getJson',
|
||||
waitAlias: '@chartData',
|
||||
querySubstring: /group by.*name/i,
|
||||
chartSelector: 'table',
|
||||
});
|
||||
|
@ -115,14 +116,14 @@ describe('Visualization > Table', () => {
|
|||
groupby: ['name'],
|
||||
});
|
||||
cy.verifySliceSuccess({
|
||||
waitAlias: '@getJson',
|
||||
waitAlias: '@chartData',
|
||||
querySubstring: /group by.*name/i,
|
||||
chartSelector: 'table',
|
||||
});
|
||||
|
||||
// should handle sorting correctly
|
||||
cy.get('.chart-container th').contains('name').click();
|
||||
cy.get('.chart-container td:nth-child(2):eq(0)').contains('Abigail');
|
||||
cy.get('.chart-container td:nth-child(2):eq(0)').contains('Aaron');
|
||||
cy.get('.chart-container th').contains('Time').click().click();
|
||||
cy.get('.chart-container td:nth-child(1):eq(0)').contains('2008');
|
||||
});
|
||||
|
@ -134,7 +135,7 @@ describe('Visualization > Table', () => {
|
|||
metrics: [],
|
||||
groupby: ['name'],
|
||||
});
|
||||
cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData', chartSelector: 'table' });
|
||||
});
|
||||
|
||||
it('Test table with groupby order desc', () => {
|
||||
|
@ -144,7 +145,7 @@ describe('Visualization > Table', () => {
|
|||
groupby: ['name'],
|
||||
order_desc: true,
|
||||
});
|
||||
cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData', chartSelector: 'table' });
|
||||
});
|
||||
|
||||
it('Test table with groupby and limit', () => {
|
||||
|
@ -156,9 +157,9 @@ describe('Visualization > Table', () => {
|
|||
row_limit: limit,
|
||||
};
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.wait('@getJson').then(({ response }) => {
|
||||
cy.wait('@chartData').then(({ response }) => {
|
||||
cy.verifySliceContainer('table');
|
||||
expect(response?.body.data.records.length).to.eq(limit);
|
||||
expect(response?.body.result[0].data.length).to.eq(limit);
|
||||
});
|
||||
cy.get('span.label-danger').contains('10 rows');
|
||||
});
|
||||
|
@ -178,7 +179,7 @@ describe('Visualization > Table', () => {
|
|||
cy.get('div[data-test="all_columns"]').should('be.visible');
|
||||
cy.get('div[data-test="groupby"]').should('not.exist');
|
||||
|
||||
cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData', chartSelector: 'table' });
|
||||
|
||||
// should allow switch to aggregate mode
|
||||
cy.get('div[data-test="query_mode"] .btn').contains('Aggregate').click();
|
||||
|
@ -196,14 +197,13 @@ describe('Visualization > Table', () => {
|
|||
all_columns: ['name', 'state', 'ds', 'num'],
|
||||
metrics: [],
|
||||
row_limit: limit,
|
||||
order_by_cols: ['["num",+false]'],
|
||||
order_by_cols: ['["num", false]'],
|
||||
};
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.wait('@getJson').then(({ response }) => {
|
||||
cy.wait('@chartData').then(({ response }) => {
|
||||
cy.verifySliceContainer('table');
|
||||
const responseBody = response?.body;
|
||||
const { records } = responseBody.data;
|
||||
const records = response?.body.result[0].data;
|
||||
expect(records[0].num).greaterThan(records[records.length - 1].num);
|
||||
});
|
||||
});
|
||||
|
@ -215,7 +215,7 @@ describe('Visualization > Table', () => {
|
|||
const formData = { ...VIZ_DEFAULTS, metrics, adhoc_filters: filters };
|
||||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({ waitAlias: '@getJson', chartSelector: 'table' });
|
||||
cy.verifySliceSuccess({ waitAlias: '@chartData', chartSelector: 'table' });
|
||||
});
|
||||
|
||||
it('Tests table number formatting with % in metric name', () => {
|
||||
|
@ -227,7 +227,7 @@ describe('Visualization > Table', () => {
|
|||
|
||||
cy.visitChartByParams(JSON.stringify(formData));
|
||||
cy.verifySliceSuccess({
|
||||
waitAlias: '@getJson',
|
||||
waitAlias: '@chartData',
|
||||
querySubstring: /group by.*state/i,
|
||||
chartSelector: 'table',
|
||||
});
|
||||
|
|
|
@ -90,9 +90,8 @@ Cypress.Commands.add(
|
|||
cy.verifySliceContainer(chartSelector);
|
||||
const responseBody = response?.body;
|
||||
if (querySubstring) {
|
||||
const query = responseBody
|
||||
? (responseBody as { query: string }).query
|
||||
: '';
|
||||
const query: string =
|
||||
responseBody.query || responseBody.result[0].query || '';
|
||||
if (querySubstring instanceof RegExp) {
|
||||
expect(query).to.match(querySubstring);
|
||||
} else {
|
||||
|
|
|
@ -17,7 +17,30 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
const V1_PLUGINS = ['box_plot', 'echarts_timeseries', 'word_cloud', 'pie'];
|
||||
export type JsonPrimitive = string | number | boolean | null;
|
||||
export type JsonValue = JsonPrimitive | JsonObject | JsonArray;
|
||||
export type JsonArray = JsonValue[];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type JsonObject = { [member: string]: any };
|
||||
|
||||
export interface Slice {
|
||||
slice_id: number;
|
||||
form_data: {
|
||||
viz_type: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface Dashboard {
|
||||
slices: Slice[];
|
||||
}
|
||||
|
||||
const V1_PLUGINS = [
|
||||
'box_plot',
|
||||
'echarts_timeseries',
|
||||
'word_cloud',
|
||||
'pie',
|
||||
'table',
|
||||
];
|
||||
export const DASHBOARD_CHART_ALIAS_PREFIX = 'getJson_';
|
||||
|
||||
export function isLegacyChart(vizType: string): boolean {
|
||||
|
@ -34,7 +57,7 @@ export function getSliceIdFromRequestUrl(url: string) {
|
|||
return query?.match(/\d+/)?.[0];
|
||||
}
|
||||
|
||||
export function getChartAliases(slices: any[]): string[] {
|
||||
export function getChartAliases(slices: Slice[]): string[] {
|
||||
const aliases: string[] = [];
|
||||
Array.from(slices).forEach(slice => {
|
||||
const vizType = slice.form_data.viz_type;
|
||||
|
@ -54,11 +77,24 @@ export function getChartAliases(slices: any[]): string[] {
|
|||
return aliases;
|
||||
}
|
||||
|
||||
export function interceptChart(sliceId: number, isLegacy = true) {
|
||||
const formData = { slice_id: sliceId };
|
||||
const encodedFormData = encodeURIComponent(JSON.stringify(formData));
|
||||
const url = isLegacy
|
||||
? `**/superset/explore_json/?form_data=${encodedFormData}*`
|
||||
: `**/api/v1/chart/data?form_data=${encodedFormData}*`;
|
||||
return cy.intercept('POST', url);
|
||||
export function interceptChart({
|
||||
sliceId,
|
||||
legacy = false,
|
||||
method = 'POST',
|
||||
}: {
|
||||
sliceId?: number;
|
||||
legacy?: boolean;
|
||||
method?: 'POST' | 'GET';
|
||||
}) {
|
||||
const urlBase = legacy ? '**/superset/explore_json/' : '**/api/v1/chart/data';
|
||||
let url;
|
||||
if (sliceId) {
|
||||
const encodedFormData = encodeURIComponent(
|
||||
JSON.stringify({ slice_id: sliceId }),
|
||||
);
|
||||
url = `${urlBase}?form_data=${encodedFormData}*`;
|
||||
} else {
|
||||
url = `${urlBase}**`;
|
||||
}
|
||||
return cy.intercept(method, url);
|
||||
}
|
||||
|
|
|
@ -6072,9 +6072,12 @@
|
|||
}
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "2.0.1",
|
||||
|
@ -18549,19 +18552,19 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/chart-controls": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.16.9.tgz",
|
||||
"integrity": "sha512-GTwnJx5AhiYqwed3F3FCz+8Yuc56jlLM/g872zoHYQUejnAXGs/Iomeznga6+281DKfsbCO6ptH6qiOZYDH8PA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.1.tgz",
|
||||
"integrity": "sha512-dfJRoVH0WbG5FQ8smszVtiYLI3NvvLAQxW6HRgOqTLegiKocIIB8hjpMpGrOPxx2G0mBigAubeQowC1VOlpAZQ==",
|
||||
"requires": {
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"lodash": "^4.17.15",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/core": {
|
||||
"version": "0.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.16.7.tgz",
|
||||
"integrity": "sha512-9i/o9ZC+dJibhoWZnoKGvxMMFcz65LjHuYk+hRspuRWA4qwobcdu64piQpfwuFVhw1yh3cbdxq+OSsNmNX9A9g==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.1.tgz",
|
||||
"integrity": "sha512-VnWhb5FjMOrAF2+PJG4WkvscmgtRnnFZBEqG+2g8TSSby2RfIrGB390Dq6abqc9SmBmjNPLj6zkzsvJZv8DsOA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@emotion/core": "^10.0.28",
|
||||
|
@ -18574,7 +18577,7 @@
|
|||
"@types/lodash": "^4.14.149",
|
||||
"@types/rison": "0.0.6",
|
||||
"@types/seedrandom": "^2.4.28",
|
||||
"@vx/responsive": "^0.0.197",
|
||||
"@vx/responsive": "^0.0.199",
|
||||
"csstype": "^2.6.4",
|
||||
"d3-format": "^1.3.2",
|
||||
"d3-interpolate": "^1.4.0",
|
||||
|
@ -18594,9 +18597,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@vx/responsive": {
|
||||
"version": "0.0.197",
|
||||
"resolved": "https://registry.npmjs.org/@vx/responsive/-/responsive-0.0.197.tgz",
|
||||
"integrity": "sha512-Qv15PJ/Hy79LjyfJ/9E8z+zacKAnD43O2Jg9wvB6PFSNs73xPEDy/mHTYxH+FZv94ruAE3scBO0330W29sQpyg==",
|
||||
"version": "0.0.199",
|
||||
"resolved": "https://registry.npmjs.org/@vx/responsive/-/responsive-0.0.199.tgz",
|
||||
"integrity": "sha512-ONrmLUAG+8wzD3cn/EmsuZh6JHeyejqup3ZsV25t04VaVJAVQAJukAfNdH8YiwSJu0zSo+txkBTfrnOmFyQLOw==",
|
||||
"requires": {
|
||||
"@types/lodash": "^4.14.146",
|
||||
"@types/react": "*",
|
||||
|
@ -18606,9 +18609,12 @@
|
|||
}
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "1.4.0",
|
||||
|
@ -18641,12 +18647,12 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-calendar": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.16.9.tgz",
|
||||
"integrity": "sha512-8SbUVhuyXYB4Jh4ucFEonhWwF9/rEVOmR/E28bfS3dVJ3lChRx2T8ijv0pRxXNuPSl619Qm61/ec4637V7I//g==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.1.tgz",
|
||||
"integrity": "sha512-v9Hh2hNdxsu3vSRtx1KjqsDhDYlCStbEQekp2+BKRH55RKitbJzbw+6GgXxA09s/6VgIxji8oEaZVYAWylzJtQ==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3-array": "^2.0.3",
|
||||
"d3-selection": "^1.4.0",
|
||||
"d3-tip": "^0.9.1",
|
||||
|
@ -18654,72 +18660,78 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-chord": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.16.9.tgz",
|
||||
"integrity": "sha512-QK3yJLDzkrIDYAfvAXmZI/nms0fl54WPSQlEN42e17IRe8Z/UNMd7Un4IyAEPjNJqt53uBJq5CEKIBAIB2eTng==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.1.tgz",
|
||||
"integrity": "sha512-xJbr9oyHBOBRp1IWQn1HuLsrArJtADVk2FE6r4QZTVYCKzJoKrQTqQEfkA2roHOHfOZtlcHcD1rlOMt8KpdmDw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"prop-types": "^15.6.2",
|
||||
"react": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-country-map": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.16.9.tgz",
|
||||
"integrity": "sha512-h58JI45Gg/Y7FQEY3v6Wsh07XvYSrH88d+6MJN0Iv72nv9X2iC5h9QVyN0M0jYDpqnfMkoPzsP90Ana8pYqjCw==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.1.tgz",
|
||||
"integrity": "sha512-CCJPFGp0P1lEX4W0JqcSC0Lq43gx8BSUNeE//xz+ZKc9JoERttVCKjwEyFCov6Y++iFM/EfDpg1bRS0XpJxD4A==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"d3-array": "^2.0.3",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-event-flow": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.16.9.tgz",
|
||||
"integrity": "sha512-FWaaXmZXaslb0XlJS3xRcZlFpvGcWtNlGc4x01jrW8vSUzZ16wnQqqPO7b46K6LDJYfgaglXEzNK4gwPWLHKoA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.1.tgz",
|
||||
"integrity": "sha512-pGuo5cVjLRJILKbE2oc7mFoWUTrOIf2ChNLHpULZZeNtpG8H3gXGA97qK+5KgXtslfv2BVi1sbR97VV9IH3gTw==",
|
||||
"requires": {
|
||||
"@data-ui/event-flow": "^0.0.84",
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-force-directed": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.16.9.tgz",
|
||||
"integrity": "sha512-2kryYHT1HqzpYLXkMW5ocCVEJ57K1zGII6mP+piIhqkEgzfSUL1+mUjfzUypuvc+zpKOuWiDxaGwVJqE8gGSbA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.1.tgz",
|
||||
"integrity": "sha512-F8aV/iGBeHOh+9ewE8rfpWN2J/avAvlWl1zIM/PZTMlwimVwBXj8voTWk32LVL+Cb+9DwntB5KA093r8yWHK5Q==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-heatmap": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.16.9.tgz",
|
||||
"integrity": "sha512-sw1/gOzAyZq6ki7ZocM9KH6BfYuT/yO2zfxW8OMB/8HeMVrM2gPkljSgIX6GYwY5Y83g3ZI+dVPXcp0HNTR0yQ==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.1.tgz",
|
||||
"integrity": "sha512-IlItjyVT9Y3aE3qYml+CEbGpwVrPJu68MYb5UNOp+ms5DEETRH0Z61kKvX/egCVouYznyVrxjdc8SvL8tHqQYg==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"d3-svg-legend": "^1.x",
|
||||
"d3-tip": "^0.9.1",
|
||||
|
@ -18727,16 +18739,16 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-histogram": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.16.9.tgz",
|
||||
"integrity": "sha512-8g4NXTxRjojIntF/ovDoXKaDws/cg6G4CHtll3fLmr85eXSvJATtYODF+KsjefBmGmfIXNUr0kdIPAjfyprizA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.1.tgz",
|
||||
"integrity": "sha512-awZCVmpXH5LCOOCktZdaj5PrPUBeAWdK/60A6n/oKufZ2x4eoXVLgBpsj3JCS73XcKu3FwhWRHLujE0pZthKhA==",
|
||||
"requires": {
|
||||
"@data-ui/histogram": "^0.0.84",
|
||||
"@data-ui/theme": "^0.0.84",
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"@vx/legend": "^0.0.198",
|
||||
"@vx/responsive": "^0.0.197",
|
||||
"@vx/responsive": "^0.0.199",
|
||||
"@vx/scale": "^0.0.197",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
|
@ -18766,9 +18778,9 @@
|
|||
}
|
||||
},
|
||||
"@vx/responsive": {
|
||||
"version": "0.0.197",
|
||||
"resolved": "https://registry.npmjs.org/@vx/responsive/-/responsive-0.0.197.tgz",
|
||||
"integrity": "sha512-Qv15PJ/Hy79LjyfJ/9E8z+zacKAnD43O2Jg9wvB6PFSNs73xPEDy/mHTYxH+FZv94ruAE3scBO0330W29sQpyg==",
|
||||
"version": "0.0.199",
|
||||
"resolved": "https://registry.npmjs.org/@vx/responsive/-/responsive-0.0.199.tgz",
|
||||
"integrity": "sha512-ONrmLUAG+8wzD3cn/EmsuZh6JHeyejqup3ZsV25t04VaVJAVQAJukAfNdH8YiwSJu0zSo+txkBTfrnOmFyQLOw==",
|
||||
"requires": {
|
||||
"@types/lodash": "^4.14.146",
|
||||
"@types/react": "*",
|
||||
|
@ -18802,21 +18814,24 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-horizon": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.16.9.tgz",
|
||||
"integrity": "sha512-l5uCO0w1cCcMeI5lJtwhOLZO1509Fj+OCZuvsRCe/pjMncwH8tAwxVljGZ54YLLIWi9Dqo1WFQvA2BLsjQcv6w==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.1.tgz",
|
||||
"integrity": "sha512-1omJPgUSktLCqBXqDMMqb9dFfflxWGmEdl6lxVPMqqCrlRILdNCd1rdsQFsu1cN90FmZav7AMVj7SLvIHWvNnQ==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3-array": "^2.0.3",
|
||||
"d3-scale": "^3.0.1",
|
||||
"prop-types": "^15.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-scale": {
|
||||
"version": "3.2.3",
|
||||
|
@ -18833,12 +18848,12 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-map-box": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.16.9.tgz",
|
||||
"integrity": "sha512-cf7QdN64rAo4UAmzirhHcJMO7IBYvMX+Slu7/LsCX4CnrVmJtO4d+vGFlNS5FaWU+t2A6lVH5QDpSI1WBgcfAA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.1.tgz",
|
||||
"integrity": "sha512-RHI9k3ulGodGjKgX2kBF3muMyTZKCQGPXV6BbNRzV8DJCc6eGrcE1eznC0ipHiy4yBYeKHfMwcWX3jh9dCI/kg==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"immutable": "^3.8.2",
|
||||
"mapbox-gl": "^0.53.0",
|
||||
"prop-types": "^15.6.2",
|
||||
|
@ -18855,118 +18870,118 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-paired-t-test": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.16.9.tgz",
|
||||
"integrity": "sha512-YEVJtqn25SWLr0N33BHzm5CjAOuSkwkOrxl05Lmceyf2z2PwHhrCnnLWXRzEEszQ9IXTsbKT8HYJtPkKNFVIWw==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.1.tgz",
|
||||
"integrity": "sha512-WExiHSMvByu8+weNJoKll82cPrhF4zNRnMGzdiYMewJ6TZLN4Ws3ZLR+b2c26BnWQFyA8qXPpsCcQzX9c9WODw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"distributions": "^1.0.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"reactable-arc": "0.15.0"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-parallel-coordinates": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.16.9.tgz",
|
||||
"integrity": "sha512-zX6uToyBEV5fKh+cpELDQ+xD9c+TtAGqKsc7r1mpY/R2Vfzw7oD5aOrwcxBshtMoJxx72jo9EuC5nzgNQf4+ug==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.1.tgz",
|
||||
"integrity": "sha512-v6HPEyQRKEOhVpydKzVo+HWUDNaYJhgWL/mrr/kDhT+htUPOUqtTqQZ2BsvgpTQiX4qXHUMnAOXAN7eBa4Xf3w==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-partition": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.16.9.tgz",
|
||||
"integrity": "sha512-OEmirurMTPAInqMEjGkMQqJDUsM0TMJ4OCFaJ2vtwbvlwk3Fgar/fm/m/qhaLzDLXfTIgb6TyUkxiBCWmmF0iA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.1.tgz",
|
||||
"integrity": "sha512-Zx7lEjgz0N/MQBmXFrhAsjryIl7QzZc5Gi5bXEi9GYiXcDUaZJmLW0cUnJT5Maqgwt3HCtKgCDZEh/SRj+XBsQ==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"d3-hierarchy": "^1.1.8",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-pivot-table": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.16.9.tgz",
|
||||
"integrity": "sha512-gpEXyC/WlBVeRD2INPx1IfOi3QwmPkr9bdwLfhXe34xU620uj85jO8VKlSU+tGppiyZz6aNaC2WBU4nTRRXUgg==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.1.tgz",
|
||||
"integrity": "sha512-qlXdtaKNQsMibpyJIeQUqaJTLE4Uce9Kn47t9mgB6lCLQc5c+egM9hVwB57P8tUxMBCJePQcjiRIJRnyLKjOTA==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"datatables.net-bs": "^1.10.15",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-rose": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.16.9.tgz",
|
||||
"integrity": "sha512-T6amU5vtlyjohI065OBmLktNW4aNmVsh8UAxSOzKJBRyVDSk0cs1Ntb6FG6jNZLxe7AYh0YVmnYeLI9IVLs2VA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.1.tgz",
|
||||
"integrity": "sha512-dQykgdgrtOTAq4ck/uZ98R8Vhv4UtercXUlNDMTsiJo5nz3/Ka/4Oz3zBf3Pey+3JrsIOQtJP1vKRKt/j37Zkg==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"nvd3": "1.8.6",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-sankey": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.16.9.tgz",
|
||||
"integrity": "sha512-Vkauo64wsuRMznDtpqHWPrP6vohnm119wUlWPYk2y9/0e1PgowlRyv6X0RUqWyk2z4/eUXIzGj5YUebqniYjtA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.1.tgz",
|
||||
"integrity": "sha512-gy5COpeeEHllYFuenXwdZr5OZ8bL1g+C16bGbjACG9/kIaF9ShoTN+Ad5cNTepb78Cox+WhmPHKIzbgPybN3Bw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"d3-sankey": "^0.4.2",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-sankey-loop": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.16.9.tgz",
|
||||
"integrity": "sha512-LtnVsvnoNTrHrOoZcdCuzYX/akCsaiMvWG53KoQis9dsu9+vc4xfKySw0Dct/QpGU+904YbGfFX9qDzh+RCsyw==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.1.tgz",
|
||||
"integrity": "sha512-r46LqceZi1hv6DDiZMinuU/hR+jyAgURcBvXy/5GvEAF+0eVHUzqbQ8SWivmFCNRwVTAEBMYkUa3IKZ6LBeUbw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3-sankey-diagram": "^0.7.3",
|
||||
"d3-selection": "^1.4.0",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-sunburst": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.16.9.tgz",
|
||||
"integrity": "sha512-DTOuXy7fPUvwUM8WjiKGmbydcIynAbXlEGdmi/ObLlh4lACaTPCX8IOGc18eJP0G78pxeXpByK9JoEZuCbQyEA==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.1.tgz",
|
||||
"integrity": "sha512-hyP36lNaLBWCKfRXTMTG/uvJZa1bMjyX0jYDRAY/tNVxPBAjhTrB76SW1eShfpugg6baaqys9XrbVkxiKRcFnA==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-treemap": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.16.9.tgz",
|
||||
"integrity": "sha512-P+IQYjaMrmN2RqmIEJ2V3w8UQG6jxLPGgmsK/KkGMCzl8PAJJtPcRZw2Z/9JGh8u/7B70JCAEL+sRcLQCA/aTQ==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.1.tgz",
|
||||
"integrity": "sha512-z6dQo1ZDb2/drZUJ3nYScBbDXHiIYchtpscYNszyB/jGxJ90ridUniLQicyLxMkjdK4mpuBW9MgidSg0y0I0sw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3-hierarchy": "^1.1.8",
|
||||
"d3-selection": "^1.4.0",
|
||||
"prop-types": "^15.6.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/legacy-plugin-chart-world-map": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.16.9.tgz",
|
||||
"integrity": "sha512-PtYzSKgiaInMt5NYyAmG4b6acffYvN1W8hetpq8TpeMkhuLzA69D3rsAj72ky/dgy5/n14t8wgdfKyfrrt9c6A==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.1.tgz",
|
||||
"integrity": "sha512-S9XuCVUIbgfCH4sG0PWGMdEc14fzunZIiUZOC2hh2JtLV/vU452XO4a9viTzWFvAY75zHNetgkTtuoCsrQdLOw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"d3": "^3.5.17",
|
||||
"d3-array": "^2.4.0",
|
||||
"d3-color": "^1.4.1",
|
||||
|
@ -18975,9 +18990,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-color": {
|
||||
"version": "1.4.1",
|
||||
|
@ -18987,13 +19005,13 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/legacy-preset-chart-big-number": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.16.9.tgz",
|
||||
"integrity": "sha512-Iby3rNcdv+cVy1A/I/Lg/n76v71JdPxKJJc+A4YUil3SalmFFo4mxm0glrX9dex6IYxpZMWbDJKgnHEbhalXlw==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.1.tgz",
|
||||
"integrity": "sha512-961i+DqTNcPNlvH3GAB2ofViEk4CcZFdcjZ/rMdCzlEichmLLrNzKUPfouvhMpMokb4ysEADOkQvE7POlKjDWw==",
|
||||
"requires": {
|
||||
"@data-ui/xy-chart": "^0.0.84",
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"@types/d3-color": "^1.2.2",
|
||||
"@types/shortid": "^0.0.29",
|
||||
"d3-color": "^1.2.3",
|
||||
|
@ -19043,34 +19061,128 @@
|
|||
"nvd3-fork": "^2.0.5",
|
||||
"prop-types": "^15.6.2",
|
||||
"urijs": "^1.18.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@superset-ui/chart-controls": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.16.9.tgz",
|
||||
"integrity": "sha512-GTwnJx5AhiYqwed3F3FCz+8Yuc56jlLM/g872zoHYQUejnAXGs/Iomeznga6+281DKfsbCO6ptH6qiOZYDH8PA==",
|
||||
"requires": {
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"lodash": "^4.17.15",
|
||||
"prop-types": "^15.7.2"
|
||||
}
|
||||
},
|
||||
"@superset-ui/core": {
|
||||
"version": "0.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.16.7.tgz",
|
||||
"integrity": "sha512-9i/o9ZC+dJibhoWZnoKGvxMMFcz65LjHuYk+hRspuRWA4qwobcdu64piQpfwuFVhw1yh3cbdxq+OSsNmNX9A9g==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"@emotion/core": "^10.0.28",
|
||||
"@emotion/styled": "^10.0.27",
|
||||
"@types/d3-format": "^1.3.0",
|
||||
"@types/d3-interpolate": "^1.3.1",
|
||||
"@types/d3-scale": "^2.1.1",
|
||||
"@types/d3-time": "^1.0.9",
|
||||
"@types/d3-time-format": "^2.1.0",
|
||||
"@types/lodash": "^4.14.149",
|
||||
"@types/rison": "0.0.6",
|
||||
"@types/seedrandom": "^2.4.28",
|
||||
"@vx/responsive": "^0.0.197",
|
||||
"csstype": "^2.6.4",
|
||||
"d3-format": "^1.3.2",
|
||||
"d3-interpolate": "^1.4.0",
|
||||
"d3-scale": "^3.0.0",
|
||||
"d3-time": "^1.0.10",
|
||||
"d3-time-format": "^2.2.0",
|
||||
"emotion-theming": "^10.0.27",
|
||||
"fetch-retry": "^4.0.1",
|
||||
"jed": "^1.1.1",
|
||||
"lodash": "^4.17.11",
|
||||
"pretty-ms": "^7.0.0",
|
||||
"react-error-boundary": "^1.2.5",
|
||||
"reselect": "^4.0.0",
|
||||
"rison": "^0.1.1",
|
||||
"seedrandom": "^3.0.5",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"@vx/responsive": {
|
||||
"version": "0.0.197",
|
||||
"resolved": "https://registry.npmjs.org/@vx/responsive/-/responsive-0.0.197.tgz",
|
||||
"integrity": "sha512-Qv15PJ/Hy79LjyfJ/9E8z+zacKAnD43O2Jg9wvB6PFSNs73xPEDy/mHTYxH+FZv94ruAE3scBO0330W29sQpyg==",
|
||||
"requires": {
|
||||
"@types/lodash": "^4.14.146",
|
||||
"@types/react": "*",
|
||||
"lodash": "^4.17.10",
|
||||
"prop-types": "^15.6.1",
|
||||
"resize-observer-polyfill": "1.5.1"
|
||||
}
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
|
||||
"integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
|
||||
"requires": {
|
||||
"d3-color": "1"
|
||||
}
|
||||
},
|
||||
"d3-scale": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz",
|
||||
"integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==",
|
||||
"requires": {
|
||||
"d3-array": "^2.3.0",
|
||||
"d3-format": "1 - 2",
|
||||
"d3-interpolate": "1.2.0 - 2",
|
||||
"d3-time": "1 - 2",
|
||||
"d3-time-format": "2 - 3"
|
||||
}
|
||||
},
|
||||
"d3-time-format": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.3.0.tgz",
|
||||
"integrity": "sha512-guv6b2H37s2Uq/GefleCDtbe0XZAuy7Wa49VGkPVPMfLL9qObgBST3lEHJBMUp8S7NdLQAGIvr2KXk8Hc98iKQ==",
|
||||
"requires": {
|
||||
"d3-time": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@superset-ui/plugin-chart-echarts": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.16.9.tgz",
|
||||
"integrity": "sha512-MC1eEq3BLedRR+tL88BnisSUkqBxAi4t79JuGY2q9Lgg+7yh1wgD6bqKkR8JaH3SdqSK2XpG0dPkjHZXqFpkMQ==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.1.tgz",
|
||||
"integrity": "sha512-+PzvoEbeTfrZ+SkM/bldwGljTjy+VBSz/AoPsDEgKmaJ8UZSG7rXQM01X0so7XkD9WRvAMI5q6+uFjL2zfDJlw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@types/echarts": "^4.6.3",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"@types/echarts": "^4.9.3",
|
||||
"@types/mathjs": "^6.0.7",
|
||||
"echarts": "^5.0.0",
|
||||
"mathjs": "^8.0.1"
|
||||
}
|
||||
},
|
||||
"@superset-ui/plugin-chart-table": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.16.9.tgz",
|
||||
"integrity": "sha512-SA6ypwoJq1A9nG/xaI+xRhSRG34omNakgNv3vgeBqCYuZLHwSCf+a/c7liwAA9PhlSTNB7CuOZHC542SVSe6ZQ==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.1.tgz",
|
||||
"integrity": "sha512-Jkf4nAU2usJUQthRMO5dSdeatlUvI+3QYCWujneTXCbR4MMBXhnlePlD0LO5dTteLNBql56rg2SbD10NDIZGZA==",
|
||||
"requires": {
|
||||
"@emotion/core": "^10.0.28",
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"@types/d3-array": "^2.0.0",
|
||||
"@types/match-sorter": "^4.0.0",
|
||||
"@types/react-table": "^7.0.19",
|
||||
"d3-array": "^2.4.0",
|
||||
"match-sorter": "^4.1.0",
|
||||
"match-sorter": "^6.1.0",
|
||||
"memoize-one": "^5.1.1",
|
||||
"react-icons": "^3.10.0",
|
||||
"react-table": "^7.2.1",
|
||||
|
@ -19078,37 +19190,23 @@
|
|||
"xss": "^1.0.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": {
|
||||
"version": "7.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
|
||||
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
},
|
||||
"match-sorter": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-4.2.1.tgz",
|
||||
"integrity": "sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==",
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.10.5",
|
||||
"remove-accents": "0.4.2"
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@superset-ui/plugin-chart-word-cloud": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.16.9.tgz",
|
||||
"integrity": "sha512-NWbPAqxxF8V16xH3jxhhJu9HAoU9BWRZktvhKePQeAtFrGZQ79nQzU+tHYivWvVmjn2bcfhg3D5V5rJwysN9Uw==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.1.tgz",
|
||||
"integrity": "sha512-jPz/22L3IwIoQqsHEFqwQTGyYdatednazPB3zGUv1KMzkj4AyU/sd5AsnCCDDC7EL10ylhy9NB8EYk12x5Z7vw==",
|
||||
"requires": {
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"@types/d3-cloud": "^1.2.1",
|
||||
"@types/d3-scale": "^2.0.2",
|
||||
"d3-cloud": "^1.2.5",
|
||||
|
@ -19118,9 +19216,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-scale": {
|
||||
"version": "3.2.3",
|
||||
|
@ -19137,14 +19238,14 @@
|
|||
}
|
||||
},
|
||||
"@superset-ui/preset-chart-xy": {
|
||||
"version": "0.16.9",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.16.9.tgz",
|
||||
"integrity": "sha512-hWIuTVcpVINXAlCSEDKKRWiAatx/d15pFmMaaZC7NzpQJ2XfZC6jpCmwgSxbvhbezbduQhwU7DViNINbg2XoZg==",
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.1.tgz",
|
||||
"integrity": "sha512-N1mSF8OE04n+xM8Fh6ZsNLD1ARGnVlh3zzld1YmhasS7rRP8UZ3STGEjLm4IV8mTYeVc+i7+Xg/VI5Fl42Uhow==",
|
||||
"requires": {
|
||||
"@data-ui/theme": "^0.0.84",
|
||||
"@data-ui/xy-chart": "^0.0.84",
|
||||
"@superset-ui/chart-controls": "0.16.9",
|
||||
"@superset-ui/core": "0.16.7",
|
||||
"@superset-ui/chart-controls": "0.17.1",
|
||||
"@superset-ui/core": "0.17.1",
|
||||
"@vx/axis": "^0.0.198",
|
||||
"@vx/legend": "^0.0.198",
|
||||
"@vx/scale": "^0.0.197",
|
||||
|
@ -21002,11 +21103,6 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/match-sorter": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/match-sorter/-/match-sorter-4.0.0.tgz",
|
||||
"integrity": "sha512-JK7HNHXZA7i/nEp6fbNAxoX/1j1ysZXmv2/nlkt2UpX1LiUWKLtyt/dMmDTlMPR6t6PkwMmIr2W2AAyu6oELNw=="
|
||||
},
|
||||
"@types/mathjs": {
|
||||
"version": "6.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/mathjs/-/mathjs-6.0.11.tgz",
|
||||
|
@ -21194,6 +21290,16 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-loadable": {
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-loadable/-/react-loadable-5.5.4.tgz",
|
||||
"integrity": "sha512-otKcjNCfVUzdBMdwOqFITTmBruIXw6GeoZitTBvJ6BMrif8Utu2JLy42GWukNnYI7ewJdncUCooz5Y/1dBz4+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"@types/webpack": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-redux": {
|
||||
"version": "7.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.10.tgz",
|
||||
|
@ -28683,9 +28789,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"d3-array": {
|
||||
"version": "2.9.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
|
||||
"integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
|
||||
"integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
|
||||
"requires": {
|
||||
"internmap": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"d3-interpolate": {
|
||||
"version": "2.0.1",
|
||||
|
@ -33267,6 +33376,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"internmap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.0.tgz",
|
||||
"integrity": "sha512-SdoDWwNOTE2n4JWUsLn4KXZGuZPjPF9yyOGc8bnfWnBQh7BD/l80rzSznKc/r4Y0aQ7z3RTk9X+tV4tHBpu+dA=="
|
||||
},
|
||||
"interpret": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
|
||||
|
|
|
@ -65,34 +65,34 @@
|
|||
"@babel/runtime-corejs3": "^7.12.5",
|
||||
"@data-ui/sparkline": "^0.0.84",
|
||||
"@emotion/core": "^10.0.35",
|
||||
"@superset-ui/chart-controls": "^0.16.9",
|
||||
"@superset-ui/core": "^0.16.7",
|
||||
"@superset-ui/legacy-plugin-chart-calendar": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-chord": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-country-map": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-event-flow": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-force-directed": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-heatmap": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-histogram": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-horizon": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-map-box": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-paired-t-test": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-partition": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-pivot-table": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-rose": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-sankey": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-sankey-loop": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-sunburst": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-treemap": "^0.16.9",
|
||||
"@superset-ui/legacy-plugin-chart-world-map": "^0.16.9",
|
||||
"@superset-ui/legacy-preset-chart-big-number": "^0.16.9",
|
||||
"@superset-ui/chart-controls": "^0.17.1",
|
||||
"@superset-ui/core": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-calendar": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-chord": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-country-map": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-event-flow": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-force-directed": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-heatmap": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-histogram": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-horizon": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-map-box": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-partition": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-rose": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-sankey": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-sunburst": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-treemap": "^0.17.1",
|
||||
"@superset-ui/legacy-plugin-chart-world-map": "^0.17.1",
|
||||
"@superset-ui/legacy-preset-chart-big-number": "^0.17.1",
|
||||
"@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
|
||||
"@superset-ui/legacy-preset-chart-nvd3": "^0.16.10",
|
||||
"@superset-ui/plugin-chart-echarts": "^0.16.9",
|
||||
"@superset-ui/plugin-chart-table": "^0.16.9",
|
||||
"@superset-ui/plugin-chart-word-cloud": "^0.16.9",
|
||||
"@superset-ui/preset-chart-xy": "^0.16.9",
|
||||
"@superset-ui/plugin-chart-echarts": "^0.17.1",
|
||||
"@superset-ui/plugin-chart-table": "^0.17.1",
|
||||
"@superset-ui/plugin-chart-word-cloud": "^0.17.1",
|
||||
"@superset-ui/preset-chart-xy": "^0.17.1",
|
||||
"@vx/responsive": "^0.0.195",
|
||||
"abortcontroller-polyfill": "^1.1.9",
|
||||
"antd": "^4.9.4",
|
||||
|
@ -214,6 +214,7 @@
|
|||
"@types/react-dom": "^16.9.8",
|
||||
"@types/react-gravatar": "^2.6.8",
|
||||
"@types/react-json-tree": "^0.6.11",
|
||||
"@types/react-loadable": "^5.5.4",
|
||||
"@types/react-redux": "^7.1.10",
|
||||
"@types/react-router-dom": "^5.1.5",
|
||||
"@types/react-select": "^3.0.19",
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
],
|
||||
// for supressing errors caused by incompatible @types/react when `npm link`
|
||||
// Ref: https://github.com/Microsoft/typescript/issues/6496#issuecomment-384786222
|
||||
"react": ["./node_modules/@types/react"]
|
||||
"react": ["./node_modules/@types/react", "react"]
|
||||
},
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
|
|
|
@ -65,7 +65,7 @@ from superset.charts.schemas import (
|
|||
from superset.commands.exceptions import CommandInvalidError
|
||||
from superset.commands.importers.v1.utils import get_contents_from_bundle
|
||||
from superset.constants import MODEL_API_RW_METHOD_PERMISSION_MAP, RouteMethod
|
||||
from superset.exceptions import SupersetSecurityException
|
||||
from superset.exceptions import QueryObjectValidationError, SupersetSecurityException
|
||||
from superset.extensions import event_logger
|
||||
from superset.models.slice import Slice
|
||||
from superset.tasks.thumbnails import cache_chart_thumbnail
|
||||
|
@ -566,9 +566,13 @@ class ChartRestApi(BaseSupersetModelRestApi):
|
|||
command = ChartDataCommand()
|
||||
query_context = command.set_query_context(json_body)
|
||||
command.validate()
|
||||
except QueryObjectValidationError as error:
|
||||
return self.response_400(message=error.message)
|
||||
except ValidationError as error:
|
||||
return self.response_400(
|
||||
message=_("Request is incorrect: %(error)s", error=error.messages)
|
||||
message=_(
|
||||
"Request is incorrect: %(error)s", error=error.normalized_messages()
|
||||
)
|
||||
)
|
||||
except SupersetSecurityException:
|
||||
return self.response_401()
|
||||
|
|
|
@ -22,7 +22,7 @@ from typing import Any, cast, ClassVar, Dict, List, Optional, Union
|
|||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from flask_babel import gettext as _
|
||||
from flask_babel import _
|
||||
|
||||
from superset import app, db, is_feature_enabled
|
||||
from superset.annotation_layers.dao import AnnotationLayerDAO
|
||||
|
@ -142,7 +142,9 @@ class QueryContext:
|
|||
"""Converting metrics to numeric when pandas.read_sql cannot"""
|
||||
for col, dtype in df.dtypes.items():
|
||||
if dtype.type == np.object_ and col in query_object.metric_names:
|
||||
df[col] = pd.to_numeric(df[col], errors="coerce")
|
||||
# soft-convert a metric column to numeric
|
||||
# will stay as strings if conversion fails
|
||||
df[col] = df[col].infer_objects()
|
||||
|
||||
def get_data(self, df: pd.DataFrame,) -> Union[str, List[Dict[str, Any]]]:
|
||||
if self.result_format == utils.ChartDataResultFormat.CSV:
|
||||
|
@ -153,15 +155,15 @@ class QueryContext:
|
|||
return df.to_dict(orient="records")
|
||||
|
||||
def get_single_payload(
|
||||
self, query_obj: QueryObject, **kwargs: Any
|
||||
self, query_obj: QueryObject, force_cached: Optional[bool] = False,
|
||||
) -> Dict[str, Any]:
|
||||
"""Returns a payload of metadata and data"""
|
||||
force_cached = kwargs.get("force_cached", False)
|
||||
"""Return results payload for a single quey"""
|
||||
if self.result_type == utils.ChartDataResultType.QUERY:
|
||||
return {
|
||||
"query": self.datasource.get_query_str(query_obj.to_dict()),
|
||||
"language": self.datasource.query_language,
|
||||
}
|
||||
|
||||
if self.result_type == utils.ChartDataResultType.SAMPLES:
|
||||
row_limit = query_obj.row_limit or math.inf
|
||||
query_obj = copy.copy(query_obj)
|
||||
|
@ -173,10 +175,13 @@ class QueryContext:
|
|||
query_obj.row_limit = min(row_limit, config["SAMPLES_ROW_LIMIT"])
|
||||
query_obj.row_offset = 0
|
||||
query_obj.columns = [o.column_name for o in self.datasource.columns]
|
||||
|
||||
payload = self.get_df_payload(query_obj, force_cached=force_cached)
|
||||
df = payload["df"]
|
||||
status = payload["status"]
|
||||
if status != utils.QueryStatus.FAILED:
|
||||
payload["colnames"] = list(df.columns)
|
||||
payload["coltypes"] = utils.serialize_pandas_dtypes(df.dtypes)
|
||||
payload["data"] = self.get_data(df)
|
||||
del payload["df"]
|
||||
|
||||
|
@ -195,13 +200,19 @@ class QueryContext:
|
|||
if col not in columns
|
||||
] + rejected_time_columns
|
||||
|
||||
if self.result_type == utils.ChartDataResultType.RESULTS:
|
||||
if (
|
||||
self.result_type == utils.ChartDataResultType.RESULTS
|
||||
and status != utils.QueryStatus.FAILED
|
||||
):
|
||||
return {"data": payload["data"]}
|
||||
return payload
|
||||
|
||||
def get_payload(self, **kwargs: Any) -> Dict[str, Any]:
|
||||
cache_query_context = kwargs.get("cache_query_context", False)
|
||||
force_cached = kwargs.get("force_cached", False)
|
||||
def get_payload(
|
||||
self,
|
||||
cache_query_context: Optional[bool] = False,
|
||||
force_cached: Optional[bool] = False,
|
||||
) -> Dict[str, Any]:
|
||||
"""Returns the query results with both metadata and data"""
|
||||
|
||||
# Get all the payloads from the QueryObjects
|
||||
query_results = [
|
||||
|
@ -310,7 +321,7 @@ class QueryContext:
|
|||
chart = ChartDAO.find_by_id(annotation_layer["value"])
|
||||
form_data = chart.form_data.copy()
|
||||
if not chart:
|
||||
raise QueryObjectValidationError("The chart does not exist")
|
||||
raise QueryObjectValidationError(_("The chart does not exist"))
|
||||
try:
|
||||
viz_obj = get_viz(
|
||||
datasource_type=chart.datasource.type,
|
||||
|
@ -342,10 +353,9 @@ class QueryContext:
|
|||
return annotation_data
|
||||
|
||||
def get_df_payload( # pylint: disable=too-many-statements,too-many-locals
|
||||
self, query_obj: QueryObject, **kwargs: Any
|
||||
self, query_obj: QueryObject, force_cached: Optional[bool] = False,
|
||||
) -> Dict[str, Any]:
|
||||
"""Handles caching around the df payload retrieval"""
|
||||
force_cached = kwargs.get("force_cached", False)
|
||||
cache_key = self.query_cache_key(query_obj)
|
||||
logger.info("Cache key: %s", cache_key)
|
||||
is_loaded = False
|
||||
|
@ -387,7 +397,7 @@ class QueryContext:
|
|||
for col in query_obj.columns
|
||||
+ query_obj.groupby
|
||||
+ utils.get_column_names_from_metrics(query_obj.metrics)
|
||||
if col not in self.datasource.column_names
|
||||
if col not in self.datasource.column_names and col != DTTM_ALIAS
|
||||
]
|
||||
if invalid_columns:
|
||||
raise QueryObjectValidationError(
|
||||
|
@ -446,5 +456,6 @@ class QueryContext:
|
|||
|
||||
:raises SupersetSecurityException: If the user cannot access the resource
|
||||
"""
|
||||
|
||||
for query in self.queries:
|
||||
query.validate()
|
||||
security_manager.raise_for_access(query_context=self)
|
||||
|
|
|
@ -28,7 +28,12 @@ from superset import app, is_feature_enabled
|
|||
from superset.exceptions import QueryObjectValidationError
|
||||
from superset.typing import Metric
|
||||
from superset.utils import pandas_postprocessing
|
||||
from superset.utils.core import DTTM_ALIAS, get_metric_names, json_int_dttm_ser
|
||||
from superset.utils.core import (
|
||||
DTTM_ALIAS,
|
||||
find_duplicates,
|
||||
get_metric_names,
|
||||
json_int_dttm_ser,
|
||||
)
|
||||
from superset.utils.date_parser import get_since_until, parse_human_timedelta
|
||||
from superset.views.utils import get_time_range_endpoints
|
||||
|
||||
|
@ -106,6 +111,8 @@ class QueryObject:
|
|||
):
|
||||
annotation_layers = annotation_layers or []
|
||||
metrics = metrics or []
|
||||
columns = columns or []
|
||||
groupby = groupby or []
|
||||
extras = extras or {}
|
||||
is_sip_38 = is_feature_enabled("SIP_38_VIZ_REARCHITECTURE")
|
||||
self.annotation_layers = [
|
||||
|
@ -126,19 +133,18 @@ class QueryObject:
|
|||
time_range=time_range,
|
||||
time_shift=time_shift,
|
||||
)
|
||||
# is_timeseries is True if time column is in groupby
|
||||
# is_timeseries is True if time column is in either columns or groupby
|
||||
# (both are dimensions)
|
||||
self.is_timeseries = (
|
||||
is_timeseries
|
||||
if is_timeseries is not None
|
||||
else (DTTM_ALIAS in groupby if groupby else False)
|
||||
else DTTM_ALIAS in columns + groupby
|
||||
)
|
||||
self.time_range = time_range
|
||||
self.time_shift = parse_human_timedelta(time_shift)
|
||||
self.post_processing = [
|
||||
post_proc for post_proc in post_processing or [] if post_proc
|
||||
]
|
||||
if not is_sip_38:
|
||||
self.groupby = groupby or []
|
||||
|
||||
# Support metric reference/definition in the format of
|
||||
# 1. 'metric_name' - name of predefined metric
|
||||
|
@ -162,13 +168,16 @@ class QueryObject:
|
|||
if config["SIP_15_ENABLED"] and "time_range_endpoints" not in self.extras:
|
||||
self.extras["time_range_endpoints"] = get_time_range_endpoints(form_data={})
|
||||
|
||||
self.columns = columns or []
|
||||
if is_sip_38 and groupby:
|
||||
self.columns += groupby
|
||||
logger.warning(
|
||||
"The field `groupby` is deprecated. Viz plugins should "
|
||||
"pass all selectables via the `columns` field"
|
||||
)
|
||||
self.columns = columns
|
||||
if is_sip_38:
|
||||
if groupby:
|
||||
logger.warning(
|
||||
"The field `groupby` is deprecated. Viz plugins should "
|
||||
"pass all selectables via the `columns` field"
|
||||
)
|
||||
self.columns += groupby
|
||||
else:
|
||||
self.groupby = groupby or []
|
||||
|
||||
self.orderby = orderby or []
|
||||
|
||||
|
@ -214,8 +223,34 @@ class QueryObject:
|
|||
|
||||
@property
|
||||
def metric_names(self) -> List[str]:
|
||||
"""Return metrics names (labels), coerce adhoc metrics to strings."""
|
||||
return get_metric_names(self.metrics)
|
||||
|
||||
@property
|
||||
def column_names(self) -> List[str]:
|
||||
"""Return column names (labels). Reserved for future adhoc calculated
|
||||
columns."""
|
||||
return self.columns
|
||||
|
||||
def validate(
|
||||
self, raise_exceptions: Optional[bool] = True
|
||||
) -> Optional[QueryObjectValidationError]:
|
||||
"""Validate query object"""
|
||||
error: Optional[QueryObjectValidationError] = None
|
||||
all_labels = self.metric_names + self.column_names
|
||||
if len(set(all_labels)) < len(all_labels):
|
||||
dup_labels = find_duplicates(all_labels)
|
||||
error = QueryObjectValidationError(
|
||||
_(
|
||||
"Duplicate column/metric labels: %(labels)s. Please make "
|
||||
"sure all columns and metrics have a unique label.",
|
||||
labels=", ".join(f'"{x}"' for x in dup_labels),
|
||||
)
|
||||
)
|
||||
if error and raise_exceptions:
|
||||
raise error
|
||||
return error
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
query_object_dict = {
|
||||
"granularity": self.granularity,
|
||||
|
|
|
@ -939,6 +939,7 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
|||
and (is_sip_38 or (not is_sip_38 and not groupby))
|
||||
):
|
||||
raise QueryObjectValidationError(_("Empty query?"))
|
||||
|
||||
metrics_exprs: List[ColumnElement] = []
|
||||
for metric in metrics:
|
||||
if utils.is_adhoc_metric(metric):
|
||||
|
@ -950,6 +951,7 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
|||
raise QueryObjectValidationError(
|
||||
_("Metric '%(metric)s' does not exist", metric=metric)
|
||||
)
|
||||
|
||||
if metrics_exprs:
|
||||
main_metric_expr = metrics_exprs[0]
|
||||
else:
|
||||
|
@ -960,14 +962,16 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
|||
groupby_exprs_sans_timestamp = OrderedDict()
|
||||
|
||||
assert extras is not None
|
||||
if (is_sip_38 and metrics and columns) or (not is_sip_38 and groupby):
|
||||
# dedup columns while preserving order
|
||||
columns_ = columns if is_sip_38 else groupby
|
||||
assert columns_
|
||||
groupby = list(dict.fromkeys(columns_))
|
||||
|
||||
# filter out the pseudo column __timestamp from columns
|
||||
columns = columns or []
|
||||
columns = [col for col in columns if col != utils.DTTM_ALIAS]
|
||||
|
||||
if (is_sip_38 and metrics and columns) or (not is_sip_38 and metrics):
|
||||
# dedup columns while preserving order
|
||||
columns = columns if is_sip_38 else (groupby or columns)
|
||||
select_exprs = []
|
||||
for selected in groupby:
|
||||
for selected in columns:
|
||||
# if groupby field/expr equals granularity field/expr
|
||||
if selected == granularity:
|
||||
time_grain = extras.get("time_grain_sqla")
|
||||
|
@ -979,7 +983,6 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
|||
else:
|
||||
outer = literal_column(f"({selected})")
|
||||
outer = self.make_sqla_column_compatible(outer, selected)
|
||||
|
||||
groupby_exprs_sans_timestamp[outer.name] = outer
|
||||
select_exprs.append(outer)
|
||||
elif columns:
|
||||
|
@ -1001,7 +1004,8 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at
|
|||
|
||||
if is_timeseries:
|
||||
timestamp = dttm_col.get_timestamp_expression(time_grain)
|
||||
select_exprs += [timestamp]
|
||||
# always put timestamp as the first column
|
||||
select_exprs.insert(0, timestamp)
|
||||
groupby_exprs_with_timestamp[timestamp.name] = timestamp
|
||||
|
||||
# Use main dttm column to support index with secondary dttm columns.
|
||||
|
|
|
@ -158,28 +158,22 @@ class BaseEngineSpec: # pylint: disable=too-many-public-methods
|
|||
try_remove_schema_from_table_name = True # pylint: disable=invalid-name
|
||||
run_multiple_statements_as_one = False
|
||||
|
||||
# default matching patterns for identifying column types
|
||||
db_column_types: Dict[utils.GenericDataType, Tuple[Pattern[Any], ...]] = {
|
||||
# default matching patterns to convert database specific column types to
|
||||
# more generic types
|
||||
db_column_types: Dict[utils.GenericDataType, Tuple[Pattern[str], ...]] = {
|
||||
utils.GenericDataType.NUMERIC: (
|
||||
re.compile(r"BIT", re.IGNORECASE),
|
||||
re.compile(r".*DOUBLE.*", re.IGNORECASE),
|
||||
re.compile(r".*FLOAT.*", re.IGNORECASE),
|
||||
re.compile(r".*INT.*", re.IGNORECASE),
|
||||
re.compile(r".*NUMBER.*", re.IGNORECASE),
|
||||
re.compile(
|
||||
r".*(DOUBLE|FLOAT|INT|NUMBER|REAL|NUMERIC|DECIMAL|MONEY).*",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
re.compile(r".*LONG$", re.IGNORECASE),
|
||||
re.compile(r".*REAL.*", re.IGNORECASE),
|
||||
re.compile(r".*NUMERIC.*", re.IGNORECASE),
|
||||
re.compile(r".*DECIMAL.*", re.IGNORECASE),
|
||||
re.compile(r".*MONEY.*", re.IGNORECASE),
|
||||
),
|
||||
utils.GenericDataType.STRING: (
|
||||
re.compile(r".*CHAR.*", re.IGNORECASE),
|
||||
re.compile(r".*STRING.*", re.IGNORECASE),
|
||||
re.compile(r".*TEXT.*", re.IGNORECASE),
|
||||
re.compile(r".*(CHAR|STRING|TEXT).*", re.IGNORECASE),
|
||||
),
|
||||
utils.GenericDataType.TEMPORAL: (
|
||||
re.compile(r".*DATE.*", re.IGNORECASE),
|
||||
re.compile(r".*TIME.*", re.IGNORECASE),
|
||||
re.compile(r".*(DATE|TIME).*", re.IGNORECASE),
|
||||
),
|
||||
}
|
||||
|
||||
|
|
|
@ -373,7 +373,11 @@ class Database(
|
|||
username = utils.get_username()
|
||||
|
||||
def needs_conversion(df_series: pd.Series) -> bool:
|
||||
return not df_series.empty and isinstance(df_series[0], (list, dict))
|
||||
return (
|
||||
not df_series.empty
|
||||
and isinstance(df_series, pd.Series)
|
||||
and isinstance(df_series[0], (list, dict))
|
||||
)
|
||||
|
||||
def _log_query(sql: str) -> None:
|
||||
if log_query:
|
||||
|
@ -397,9 +401,9 @@ class Database(
|
|||
if mutator:
|
||||
mutator(df)
|
||||
|
||||
for k, v in df.dtypes.items():
|
||||
if v.type == numpy.object_ and needs_conversion(df[k]):
|
||||
df[k] = df[k].apply(utils.json_dumps_w_dates)
|
||||
for col, coltype in df.dtypes.to_dict().items():
|
||||
if coltype == numpy.object_ and needs_conversion(df[col]):
|
||||
df[col] = df[col].apply(utils.json_dumps_w_dates)
|
||||
|
||||
return df
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Utility functions used across Superset"""
|
||||
import collections
|
||||
import decimal
|
||||
import errno
|
||||
import functools
|
||||
|
@ -37,7 +38,7 @@ from email.mime.image import MIMEImage
|
|||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.utils import formatdate
|
||||
from enum import Enum
|
||||
from enum import Enum, IntEnum
|
||||
from timeit import default_timer
|
||||
from types import TracebackType
|
||||
from typing import (
|
||||
|
@ -55,6 +56,7 @@ from typing import (
|
|||
Tuple,
|
||||
Type,
|
||||
TYPE_CHECKING,
|
||||
TypeVar,
|
||||
Union,
|
||||
)
|
||||
from urllib.parse import unquote_plus
|
||||
|
@ -105,6 +107,8 @@ DTTM_ALIAS = "__timestamp"
|
|||
|
||||
JS_MAX_INTEGER = 9007199254740991 # Largest int Java Script can handle 2^53-1
|
||||
|
||||
InputType = TypeVar("InputType")
|
||||
|
||||
|
||||
class LenientEnum(Enum):
|
||||
"""Enums with a `get` method that convert a enum value to `Enum` if it is a
|
||||
|
@ -130,14 +134,15 @@ class AnnotationType(str, Enum):
|
|||
TIME_SERIES = "TIME_SERIES"
|
||||
|
||||
|
||||
class GenericDataType(Enum):
|
||||
class GenericDataType(IntEnum):
|
||||
"""
|
||||
Generic database column type
|
||||
Generic database column type that fits both frontend and backend.
|
||||
"""
|
||||
|
||||
NUMERIC = 0
|
||||
STRING = 1
|
||||
TEMPORAL = 2
|
||||
BOOLEAN = 3
|
||||
|
||||
|
||||
class ChartDataResultFormat(str, Enum):
|
||||
|
@ -1396,6 +1401,21 @@ def get_column_names_from_metrics(metrics: List[Metric]) -> List[str]:
|
|||
return columns
|
||||
|
||||
|
||||
def serialize_pandas_dtypes(dtypes: List[np.dtype]) -> List[GenericDataType]:
|
||||
"""Serialize pandas/numpy dtypes to JavaScript types"""
|
||||
mapping = {
|
||||
"object": GenericDataType.STRING,
|
||||
"category": GenericDataType.STRING,
|
||||
"datetime64[ns]": GenericDataType.TEMPORAL,
|
||||
"int64": GenericDataType.NUMERIC,
|
||||
"in32": GenericDataType.NUMERIC,
|
||||
"float64": GenericDataType.NUMERIC,
|
||||
"float32": GenericDataType.NUMERIC,
|
||||
"bool": GenericDataType.BOOLEAN,
|
||||
}
|
||||
return [mapping.get(str(x), GenericDataType.STRING) for x in dtypes]
|
||||
|
||||
|
||||
def indexed(
|
||||
items: List[Any], key: Union[str, Callable[[Any], Any]]
|
||||
) -> Dict[Any, List[Any]]:
|
||||
|
@ -1481,3 +1501,8 @@ def get_time_filter_status( # pylint: disable=too-many-branches
|
|||
def format_list(items: Sequence[str], sep: str = ", ", quote: str = '"') -> str:
|
||||
quote_escaped = "\\" + quote
|
||||
return sep.join(f"{quote}{x.replace(quote, quote_escaped)}{quote}" for x in items)
|
||||
|
||||
|
||||
def find_duplicates(items: Iterable[InputType]) -> List[InputType]:
|
||||
"""Find duplicate items in an iterable."""
|
||||
return [item for item, count in collections.Counter(items).items() if count > 1]
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# under the License.
|
||||
import logging
|
||||
from functools import partial
|
||||
from typing import Any, Callable, cast, Dict, List, Optional, Set, Tuple, Union
|
||||
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union
|
||||
|
||||
import geohash as geohash_lib
|
||||
import numpy as np
|
||||
|
@ -554,29 +554,53 @@ def geodetic_parse(
|
|||
raise QueryObjectValidationError(_("Invalid geodetic string"))
|
||||
|
||||
|
||||
@validate_column_args("columns")
|
||||
def contribution(
|
||||
df: DataFrame, orientation: PostProcessingContributionOrientation
|
||||
df: DataFrame,
|
||||
orientation: Optional[
|
||||
PostProcessingContributionOrientation
|
||||
] = PostProcessingContributionOrientation.COLUMN,
|
||||
columns: Optional[List[str]] = None,
|
||||
rename_columns: Optional[List[str]] = None,
|
||||
) -> DataFrame:
|
||||
"""
|
||||
Calculate cell contibution to row/column total.
|
||||
Calculate cell contibution to row/column total for numeric columns.
|
||||
Non-numeric columns will be kept untouched.
|
||||
|
||||
If `columns` are specified, only calculate contributions on selected columns.
|
||||
|
||||
:param df: DataFrame containing all-numeric data (temporal column ignored)
|
||||
:param columns: Columns to calculate values from.
|
||||
:param rename_columns: The new labels for the calculated contribution columns.
|
||||
The original columns will not be removed.
|
||||
:param orientation: calculate by dividing cell with row/column total
|
||||
:return: DataFrame with contributions, with temporal column at beginning if present
|
||||
:return: DataFrame with contributions.
|
||||
"""
|
||||
temporal_series: Optional[Series] = None
|
||||
contribution_df = df.copy()
|
||||
if DTTM_ALIAS in df.columns:
|
||||
temporal_series = cast(Series, contribution_df.pop(DTTM_ALIAS))
|
||||
|
||||
if orientation == PostProcessingContributionOrientation.ROW:
|
||||
contribution_dft = contribution_df.T
|
||||
contribution_df = (contribution_dft / contribution_dft.sum()).T
|
||||
else:
|
||||
contribution_df = contribution_df / contribution_df.sum()
|
||||
|
||||
if temporal_series is not None:
|
||||
contribution_df.insert(0, DTTM_ALIAS, temporal_series)
|
||||
numeric_df = contribution_df.select_dtypes(include="number")
|
||||
# verify column selections
|
||||
if columns:
|
||||
numeric_columns = numeric_df.columns.tolist()
|
||||
for col in columns:
|
||||
if col not in numeric_columns:
|
||||
raise QueryObjectValidationError(
|
||||
_(
|
||||
'Column "%(column)s" is not numeric or does not '
|
||||
"exists in the query results.",
|
||||
column=col,
|
||||
)
|
||||
)
|
||||
columns = columns or numeric_df.columns
|
||||
rename_columns = rename_columns or columns
|
||||
if len(rename_columns) != len(columns):
|
||||
raise QueryObjectValidationError(
|
||||
_("`rename_columns` must have the same length as `columns`.")
|
||||
)
|
||||
# limit to selected columns
|
||||
numeric_df = numeric_df[columns]
|
||||
axis = 0 if orientation == PostProcessingContributionOrientation.COLUMN else 1
|
||||
numeric_df = numeric_df / numeric_df.values.sum(axis=axis, keepdims=True)
|
||||
contribution_df[rename_columns] = numeric_df
|
||||
return contribution_df
|
||||
|
||||
|
||||
|
|
|
@ -21,13 +21,17 @@ from superset.utils.core import AnnotationType, DTTM_ALIAS
|
|||
from tests.base_tests import get_table_by_name
|
||||
|
||||
query_birth_names = {
|
||||
"extras": {"where": "", "time_range_endpoints": ["inclusive", "exclusive"]},
|
||||
"granularity": "ds",
|
||||
"extras": {
|
||||
"where": "",
|
||||
"time_range_endpoints": ["inclusive", "exclusive"],
|
||||
"time_grain_sqla": "P1D",
|
||||
},
|
||||
"groupby": ["name"],
|
||||
"metrics": [{"label": "sum__num"}],
|
||||
"order_desc": True,
|
||||
"orderby": [["sum__num", False]],
|
||||
"row_limit": 100,
|
||||
"granularity": "ds",
|
||||
"time_range": "100 years ago : now",
|
||||
"timeseries_limit": 0,
|
||||
"timeseries_limit_metric": None,
|
||||
|
|
|
@ -524,19 +524,40 @@ class TestPostProcessing(SupersetTestCase):
|
|||
"b": [1, 9],
|
||||
}
|
||||
)
|
||||
with pytest.raises(QueryObjectValidationError, match="not numeric"):
|
||||
proc.contribution(df, columns=[DTTM_ALIAS])
|
||||
|
||||
with pytest.raises(QueryObjectValidationError, match="same length"):
|
||||
proc.contribution(df, columns=["a"], rename_columns=["aa", "bb"])
|
||||
|
||||
# cell contribution across row
|
||||
row_df = proc.contribution(df, PostProcessingContributionOrientation.ROW)
|
||||
self.assertListEqual(df.columns.tolist(), [DTTM_ALIAS, "a", "b"])
|
||||
self.assertListEqual(series_to_list(row_df["a"]), [0.5, 0.25])
|
||||
self.assertListEqual(series_to_list(row_df["b"]), [0.5, 0.75])
|
||||
processed_df = proc.contribution(
|
||||
df, orientation=PostProcessingContributionOrientation.ROW,
|
||||
)
|
||||
self.assertListEqual(processed_df.columns.tolist(), [DTTM_ALIAS, "a", "b"])
|
||||
self.assertListEqual(processed_df["a"].tolist(), [0.5, 0.25])
|
||||
self.assertListEqual(processed_df["b"].tolist(), [0.5, 0.75])
|
||||
|
||||
# cell contribution across column without temporal column
|
||||
df.pop(DTTM_ALIAS)
|
||||
column_df = proc.contribution(df, PostProcessingContributionOrientation.COLUMN)
|
||||
self.assertListEqual(df.columns.tolist(), ["a", "b"])
|
||||
self.assertListEqual(series_to_list(column_df["a"]), [0.25, 0.75])
|
||||
self.assertListEqual(series_to_list(column_df["b"]), [0.1, 0.9])
|
||||
processed_df = proc.contribution(
|
||||
df, orientation=PostProcessingContributionOrientation.COLUMN
|
||||
)
|
||||
self.assertListEqual(processed_df.columns.tolist(), ["a", "b"])
|
||||
self.assertListEqual(processed_df["a"].tolist(), [0.25, 0.75])
|
||||
self.assertListEqual(processed_df["b"].tolist(), [0.1, 0.9])
|
||||
|
||||
# contribution only on selected columns
|
||||
processed_df = proc.contribution(
|
||||
df,
|
||||
orientation=PostProcessingContributionOrientation.COLUMN,
|
||||
columns=["a"],
|
||||
rename_columns=["pct_a"],
|
||||
)
|
||||
self.assertListEqual(processed_df.columns.tolist(), ["a", "b", "pct_a"])
|
||||
self.assertListEqual(processed_df["a"].tolist(), [1, 3])
|
||||
self.assertListEqual(processed_df["b"].tolist(), [1, 9])
|
||||
self.assertListEqual(processed_df["pct_a"].tolist(), [0.25, 0.75])
|
||||
|
||||
def test_prophet_valid(self):
|
||||
pytest.importorskip("fbprophet")
|
||||
|
|
|
@ -25,7 +25,6 @@ from superset.utils.core import (
|
|||
AdhocMetricExpressionType,
|
||||
ChartDataResultFormat,
|
||||
ChartDataResultType,
|
||||
FilterOperator,
|
||||
TimeRangeEndpoint,
|
||||
)
|
||||
from tests.base_tests import SupersetTestCase
|
||||
|
|
|
@ -20,7 +20,6 @@ from typing import Any, Dict, NamedTuple, List, Pattern, Tuple, Union
|
|||
from unittest.mock import patch
|
||||
import pytest
|
||||
|
||||
import tests.test_app
|
||||
from superset import db
|
||||
from superset.connectors.sqla.models import SqlaTable, TableColumn
|
||||
from superset.db_engine_specs.druid import DruidEngineSpec
|
||||
|
|
Loading…
Reference in New Issue