181 lines
5.3 KiB
TypeScript
181 lines
5.3 KiB
TypeScript
/**
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
import {
|
|
ChartProps,
|
|
DataRecord,
|
|
extractTimegrain,
|
|
GenericDataType,
|
|
getTimeFormatter,
|
|
getTimeFormatterForGranularity,
|
|
QueryFormData,
|
|
SMART_DATE_ID,
|
|
TimeFormats,
|
|
} from '@superset-ui/core';
|
|
import { getColorFormatters } from '@superset-ui/chart-controls';
|
|
import { DateFormatter } from '../types';
|
|
|
|
const { DATABASE_DATETIME } = TimeFormats;
|
|
|
|
function isNumeric(key: string, data: DataRecord[] = []) {
|
|
return data.every(
|
|
record =>
|
|
record[key] === null ||
|
|
record[key] === undefined ||
|
|
typeof record[key] === 'number',
|
|
);
|
|
}
|
|
|
|
export default function transformProps(chartProps: ChartProps<QueryFormData>) {
|
|
/**
|
|
* This function is called after a successful response has been
|
|
* received from the chart data endpoint, and is used to transform
|
|
* the incoming data prior to being sent to the Visualization.
|
|
*
|
|
* The transformProps function is also quite useful to return
|
|
* additional/modified props to your data viz component. The formData
|
|
* can also be accessed from your PivotTableChart.tsx file, but
|
|
* doing supplying custom props here is often handy for integrating third
|
|
* party libraries that rely on specific props.
|
|
*
|
|
* A description of properties in `chartProps`:
|
|
* - `height`, `width`: the height/width of the DOM element in which
|
|
* the chart is located
|
|
* - `formData`: the chart data request payload that was sent to the
|
|
* backend.
|
|
* - `queriesData`: the chart data response payload that was received
|
|
* from the backend. Some notable properties of `queriesData`:
|
|
* - `data`: an array with data, each row with an object mapping
|
|
* the column/alias to its value. Example:
|
|
* `[{ col1: 'abc', metric1: 10 }, { col1: 'xyz', metric1: 20 }]`
|
|
* - `rowcount`: the number of rows in `data`
|
|
* - `query`: the query that was issued.
|
|
*
|
|
* Please note: the transformProps function gets cached when the
|
|
* application loads. When making changes to the `transformProps`
|
|
* function during development with hot reloading, changes won't
|
|
* be seen until restarting the development server.
|
|
*/
|
|
const {
|
|
width,
|
|
height,
|
|
queriesData,
|
|
formData,
|
|
rawFormData,
|
|
hooks: { setDataMask = () => {}, onContextMenu },
|
|
filterState,
|
|
datasource: { verboseMap = {}, columnFormats = {}, currencyFormats = {} },
|
|
emitCrossFilters,
|
|
} = chartProps;
|
|
const { data, colnames, coltypes } = queriesData[0];
|
|
const {
|
|
groupbyRows,
|
|
groupbyColumns,
|
|
metrics,
|
|
tableRenderer,
|
|
colOrder,
|
|
rowOrder,
|
|
aggregateFunction,
|
|
transposePivot,
|
|
combineMetric,
|
|
rowSubtotalPosition,
|
|
colSubtotalPosition,
|
|
colTotals,
|
|
colSubTotals,
|
|
rowTotals,
|
|
rowSubTotals,
|
|
valueFormat,
|
|
dateFormat,
|
|
metricsLayout,
|
|
conditionalFormatting,
|
|
timeGrainSqla,
|
|
currencyFormat,
|
|
allowRenderHtml,
|
|
} = formData;
|
|
const { selectedFilters } = filterState;
|
|
const granularity = extractTimegrain(rawFormData);
|
|
|
|
const dateFormatters = colnames
|
|
.filter(
|
|
(colname: string, index: number) =>
|
|
coltypes[index] === GenericDataType.Temporal,
|
|
)
|
|
.reduce(
|
|
(
|
|
acc: Record<string, DateFormatter | undefined>,
|
|
temporalColname: string,
|
|
) => {
|
|
let formatter: DateFormatter | undefined;
|
|
if (dateFormat === SMART_DATE_ID) {
|
|
if (granularity) {
|
|
// time column use formats based on granularity
|
|
formatter = getTimeFormatterForGranularity(granularity);
|
|
} else if (isNumeric(temporalColname, data)) {
|
|
formatter = getTimeFormatter(DATABASE_DATETIME);
|
|
} else {
|
|
// if no column-specific format, print cell as is
|
|
formatter = String;
|
|
}
|
|
} else if (dateFormat) {
|
|
formatter = getTimeFormatter(dateFormat);
|
|
}
|
|
if (formatter) {
|
|
acc[temporalColname] = formatter;
|
|
}
|
|
return acc;
|
|
},
|
|
{},
|
|
);
|
|
const metricColorFormatters = getColorFormatters(conditionalFormatting, data);
|
|
|
|
return {
|
|
width,
|
|
height,
|
|
data,
|
|
groupbyRows,
|
|
groupbyColumns,
|
|
metrics,
|
|
tableRenderer,
|
|
colOrder,
|
|
rowOrder,
|
|
aggregateFunction,
|
|
transposePivot,
|
|
combineMetric,
|
|
rowSubtotalPosition,
|
|
colSubtotalPosition,
|
|
colTotals,
|
|
colSubTotals,
|
|
rowTotals,
|
|
rowSubTotals,
|
|
valueFormat,
|
|
currencyFormat,
|
|
emitCrossFilters,
|
|
setDataMask,
|
|
selectedFilters,
|
|
verboseMap,
|
|
columnFormats,
|
|
currencyFormats,
|
|
metricsLayout,
|
|
metricColorFormatters,
|
|
dateFormatters,
|
|
onContextMenu,
|
|
timeGrainSqla,
|
|
allowRenderHtml,
|
|
};
|
|
}
|