diff --git a/package.json b/package.json
index d2317c5..7955314 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"vite-plugin-react": "^3.0.2"
},
"dependencies": {
- "@thoughtspot/ts-chart-sdk": "0.0.2-alpha.14",
+ "@thoughtspot/ts-chart-sdk": "0.0.2-alpha.16",
"chart.js": "3.5.0",
"chartjs-plugin-datalabels": "2.2.0",
"eslint": "8.40.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 753d454..bc06a61 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
dependencies:
'@thoughtspot/ts-chart-sdk':
- specifier: 0.0.2-alpha.12
- version: 0.0.2-alpha.12
+ specifier: 0.0.2-alpha.16
+ version: 0.0.2-alpha.16
chart.js:
specifier: 3.5.0
version: 3.5.0
@@ -752,8 +752,8 @@ packages:
dev: false
optional: true
- /@thoughtspot/ts-chart-sdk@0.0.2-alpha.12:
- resolution: {integrity: sha512-cIK/4d2QXVupA/fKpasXeRkiYn5IghOUVQp4FlWLwr1NUsAb9pTYLVXV6wox/YIumDS1Us0kxOA+3PTgrx32UA==}
+ /@thoughtspot/ts-chart-sdk@0.0.2-alpha.16:
+ resolution: {integrity: sha512-4/SRSOipw224Fg+SsQSuU39QlLWhkcJRYPGJpew9vZajfnTx72HBmM4LZeNYQfLfr3VZp0Ye+l1cI/4hB8evlw==}
dependencies:
lodash: 4.17.21
luxon: 3.5.0
diff --git a/src/v1/tester-chart/tester.ts b/src/v1/tester-chart/tester.ts
index 32340d0..5d6a6af 100644
--- a/src/v1/tester-chart/tester.ts
+++ b/src/v1/tester-chart/tester.ts
@@ -9,18 +9,18 @@
*/
import {
- ChartColumn,
- ChartConfig,
- ChartModel,
- ChartToTSEvent,
- ColumnType,
- CustomChartContext,
- DataPointsArray,
- getChartContext,
- PointVal,
- Query,
- ValidationResponse,
- VisualProps,
+ ChartColumn,
+ ChartConfig,
+ ChartModel,
+ ChartToTSEvent,
+ ColumnType,
+ CustomChartContext,
+ DataPointsArray,
+ getChartContext,
+ PointVal,
+ Query,
+ ValidationResponse,
+ VisualProps,
} from '@thoughtspot/ts-chart-sdk';
import Chart from 'chart.js/auto';
import ChartDataLabels from 'chartjs-plugin-datalabels';
@@ -33,510 +33,513 @@ let globalChartReference: Chart;
const availableColor = ['red', 'green', 'blue'];
const visualPropKeyMap: any = {
- 0: 'color',
- 1: 'accordion.Color2',
- 2: 'accordion.datalabels',
+ 0: 'color',
+ 1: 'accordion.Color2',
+ 2: 'accordion.datalabels',
};
+// To mock authentication
+const TESTER_CHART_ACCESS_TOKEN = 'custom-tester-chart-token';
+
function getDataForColumn(column: ChartColumn, dataArr: DataPointsArray) {
- const idx = _.findIndex(dataArr.columns, colId => column.id === colId);
- return _.map(dataArr.dataValue, row => row[idx]);
+ const idx = _.findIndex(dataArr.columns, (colId) => column.id === colId);
+ return _.map(dataArr.dataValue, (row) => row[idx]);
}
function getColumnDataModel(
- configDimensions: any,
- dataArr: DataPointsArray,
- type: string,
- visualProps: VisualProps | undefined,
+ configDimensions: any,
+ dataArr: DataPointsArray,
+ type: string,
+ visualProps: VisualProps | undefined
) {
- // this should be handled in a better way
- const xAxisColumns = configDimensions?.[0].columns ?? [];
- const yAxisColumns = configDimensions?.[1].columns ?? [];
-
- return {
- getLabels: () => getDataForColumn(xAxisColumns[0], dataArr),
- getDatasets: () =>
- _.map(yAxisColumns, (col, idx: number) => ({
- label: col.name,
- data: getDataForColumn(col, dataArr),
- yAxisID: `${type}-y${idx.toString()}`,
- type: `${type}`,
- backgroundColor: _.get(
- visualProps,
- visualPropKeyMap?.[idx],
- availableColor[idx],
- ),
- borderColor: _.get(
- visualProps,
- visualPropKeyMap?.[idx],
- availableColor[idx],
- ),
- datalabels: {
- anchor: 'end',
- },
- })),
- getScales: () =>
- _.reduce(
- yAxisColumns,
- (obj: any, _val, idx: number) => {
- // eslint-disable-next-line no-param-reassign
- obj[`${type}-y${idx.toString()}`] = {
- grid: {
- display: true,
- },
- position: idx === 0 ? 'left' : 'right',
- title: {
- display: true,
- text: `${_val.name}`,
- },
- };
- return obj;
- },
- {},
- ),
- getPointDetails: (xPos: number, yPos: number): PointVal[] => [
- {
- columnId: xAxisColumns[0].id,
- value: getDataForColumn(xAxisColumns[0], dataArr)[xPos],
+ // this should be handled in a better way
+ const xAxisColumns = configDimensions?.[0].columns ?? [];
+ const yAxisColumns = configDimensions?.[1].columns ?? [];
+
+ return {
+ getLabels: () => getDataForColumn(xAxisColumns[0], dataArr),
+ getDatasets: () =>
+ _.map(yAxisColumns, (col, idx: number) => ({
+ label: col.name,
+ data: getDataForColumn(col, dataArr),
+ yAxisID: `${type}-y${idx.toString()}`,
+ type: `${type}`,
+ backgroundColor: _.get(
+ visualProps,
+ visualPropKeyMap?.[idx],
+ availableColor[idx]
+ ),
+ borderColor: _.get(
+ visualProps,
+ visualPropKeyMap?.[idx],
+ availableColor[idx]
+ ),
+ datalabels: {
+ anchor: 'end',
+ },
+ })),
+ getScales: () =>
+ _.reduce(
+ yAxisColumns,
+ (obj: any, _val, idx: number) => {
+ // eslint-disable-next-line no-param-reassign
+ obj[`${type}-y${idx.toString()}`] = {
+ grid: {
+ display: true,
},
- {
- columnId: yAxisColumns[yPos].id,
- value: getDataForColumn(yAxisColumns[yPos], dataArr)[xPos],
+ position: idx === 0 ? 'left' : 'right',
+ title: {
+ display: true,
+ text: `${_val.name}`,
},
- ],
- };
+ };
+ return obj;
+ },
+ {}
+ ),
+ getPointDetails: (xPos: number, yPos: number): PointVal[] => [
+ {
+ columnId: xAxisColumns[0].id,
+ value: getDataForColumn(xAxisColumns[0], dataArr)[xPos],
+ },
+ {
+ columnId: yAxisColumns[yPos].id,
+ value: getDataForColumn(yAxisColumns[yPos], dataArr)[xPos],
+ },
+ ],
+ };
}
function getDataModel(chartModel: ChartModel) {
- if (!chartModel.data) {
- return null;
- }
- // column chart model
- const columnChartModel = getColumnDataModel(
- chartModel.config?.chartConfig?.[0].dimensions ?? [],
- chartModel.data?.[0].data ?? ([] as any),
- 'bar',
- chartModel.visualProps,
- );
-
- return columnChartModel;
+ if (!chartModel.data) {
+ return null;
+ }
+ // column chart model
+ const columnChartModel = getColumnDataModel(
+ chartModel.config?.chartConfig?.[0].dimensions ?? [],
+ chartModel.data?.[0].data ?? ([] as any),
+ 'bar',
+ chartModel.visualProps
+ );
+
+ return columnChartModel;
}
function getParsedEvent(evt: any) {
- return _.pick(evt.native, ['clientX', 'clientY']);
+ return _.pick(evt.native, ['clientX', 'clientY']);
}
function updateTMLString(ctx: CustomChartContext) {
- const tmlString =
- (document.getElementById('tml-string-input') as any).value ?? '';
- ctx.emitEvent(ChartToTSEvent.SetTMLString, {
- tmlString,
- });
+ const tmlString =
+ (document.getElementById('tml-string-input') as any).value ?? '';
+ ctx.emitEvent(ChartToTSEvent.SetTMLString, {
+ tmlString,
+ });
}
async function renderTML(ctx: CustomChartContext) {
- // debugger;
- const data = await ctx.emitEvent(ChartToTSEvent.GetTMLString);
- const tmlBox: any = document.getElementById('tml-box');
- if (!!tmlBox && !!data) {
- // eslint-disable-next-line no-unsanitized/property
- tmlBox.innerHTML = `
+ // debugger;
+ const data = await ctx.emitEvent(ChartToTSEvent.GetTMLString);
+ const tmlBox: any = document.getElementById('tml-box');
+ if (!!tmlBox && !!data) {
+ // eslint-disable-next-line no-unsanitized/property
+ tmlBox.innerHTML = `
`;
- }
- document.getElementById('submit-button')?.addEventListener('click', () => {
- updateTMLString(ctx);
- });
+ }
+ document.getElementById('submit-button')?.addEventListener('click', () => {
+ updateTMLString(ctx);
+ });
}
async function renderKPIs(ctx: CustomChartContext) {
- const chartModel = ctx.getChartModel();
- const chartConfigs = chartModel.config.chartConfig ?? [];
- const queries = chartConfigs.map(
- (config: ChartConfig): Query =>
- _.reduce(
- config.dimensions,
- (acc: Query, dimension) => ({
- queryColumns: [
- ...acc.queryColumns,
- ...dimension.columns,
- ].filter(col => col.type === ColumnType.MEASURE),
- }),
- {
- queryColumns: [],
- } as Query,
- ),
+ const chartModel = ctx.getChartModel();
+ const chartConfigs = chartModel.config.chartConfig ?? [];
+ const queries = chartConfigs.map(
+ (config: ChartConfig): Query =>
+ _.reduce(
+ config.dimensions,
+ (acc: Query, dimension) => ({
+ queryColumns: [...acc.queryColumns, ...dimension.columns].filter(
+ (col) => col.type === ColumnType.MEASURE
+ ),
+ }),
+ {
+ queryColumns: [],
+ } as Query
+ )
+ );
+ const res = await ctx.emitEvent(ChartToTSEvent.GetDataForQuery, {
+ queries,
+ });
+ console.log('KPI DATA', res);
+ const { columns, dataValue } = res.data[0].data;
+ const kpiBox: any = document.getElementById('kpi-box');
+ if (kpiBox) {
+ const innerHTML = _.reduce(
+ columns,
+ (acc, colId, idx) => {
+ const column = _.find(chartModel.columns, (col) => col.id === colId);
+ if (_.isNil(column)) return acc;
+ return `${acc}
${column.name}: ${dataValue[0][idx]}
`;
+ },
+ ''
);
- const res = await ctx.emitEvent(ChartToTSEvent.GetDataForQuery, {
- queries,
- });
- console.log('KPI DATA', res);
- const { columns, dataValue } = res.data[0].data;
- const kpiBox: any = document.getElementById('kpi-box');
- if (kpiBox) {
- const innerHTML = _.reduce(
- columns,
- (acc, colId, idx) => {
- const column = _.find(
- chartModel.columns,
- col => col.id === colId,
- );
- if (_.isNil(column)) return acc;
- return `${acc}
${column.name}: ${dataValue[0][idx]}
`;
- },
- '',
- );
- // eslint-disable-next-line no-unsanitized/property
- kpiBox.innerHTML = `
+ // eslint-disable-next-line no-unsanitized/property
+ kpiBox.innerHTML = `
${innerHTML}
`;
- }
+ }
}
async function handleAxisMenuButtons(ctx: CustomChartContext) {
- document.getElementById('open-axis-menu')?.addEventListener('click', ev => {
- const chartModel = ctx.getChartModel();
- const colIds = chartModel.columns.map(col => col.id);
-
- ctx.emitEvent(ChartToTSEvent.OpenAxisMenu, {
- event: {
- clientX: ev.clientX,
- clientY: ev.clientY,
- },
- columnIds: colIds,
- customActions: [
- {
- id: 'custom-axis-action',
- label: 'Custom axis action',
- icon: '',
- onClick: (...arg) => {
- console.log('custom axis action triggered', arg);
- },
- },
- ],
- });
+ document.getElementById('open-axis-menu')?.addEventListener('click', (ev) => {
+ const chartModel = ctx.getChartModel();
+ const colIds = chartModel.columns.map((col) => col.id);
+
+ ctx.emitEvent(ChartToTSEvent.OpenAxisMenu, {
+ event: {
+ clientX: ev.clientX,
+ clientY: ev.clientY,
+ },
+ columnIds: colIds,
+ customActions: [
+ {
+ id: 'custom-axis-action',
+ label: 'Custom axis action',
+ icon: '',
+ onClick: (...arg) => {
+ console.log('custom axis action triggered', arg);
+ },
+ },
+ ],
+ });
+ });
+
+ document
+ .getElementById('open-single-column-menu')
+ ?.addEventListener('click', (ev) => {
+ const chartModel = ctx.getChartModel();
+ const colIds = chartModel.columns.map((col) => col.id).slice(0, 1);
+
+ ctx.emitEvent(ChartToTSEvent.OpenAxisMenu, {
+ event: {
+ clientX: ev.clientX,
+ clientY: ev.clientY,
+ },
+ columnIds: colIds,
+ });
});
- document
- .getElementById('open-single-column-menu')
- ?.addEventListener('click', ev => {
- const chartModel = ctx.getChartModel();
- const colIds = chartModel.columns.map(col => col.id).slice(0, 1);
+ document
+ .getElementById('close-axis-menu')
+ ?.addEventListener('click', (ev) => {
+ ctx.emitEvent(ChartToTSEvent.CloseAxisMenu);
+ });
- ctx.emitEvent(ChartToTSEvent.OpenAxisMenu, {
- event: {
- clientX: ev.clientX,
- clientY: ev.clientY,
- },
- columnIds: colIds,
- });
- });
-
- document
- .getElementById('close-axis-menu')
- ?.addEventListener('click', ev => {
- ctx.emitEvent(ChartToTSEvent.CloseAxisMenu);
- })
-
- document
- .getElementById('close-context-menu')
- ?.addEventListener('click', ev => {
- ctx.emitEvent(ChartToTSEvent.CloseContextMenu);
- });
-
- document
- .getElementById('show-event-error')
- ?.addEventListener('click', ev => {
- ctx.emitEvent(ChartToTSEvent.OpenAxisMenu, {
- event: {
- clientX: ev.clientX,
- clientY: ev.clientY,
- x: ev.x,
- } as any,
- columnIds: [],
- });
- });
-
- document
- .getElementById('open-context-menu')
- ?.addEventListener('click', ev => {
- const chartModel = ctx.getChartModel();
- const colIds = chartModel.columns.map(col => col.id);
- ctx.emitEvent(ChartToTSEvent.OpenContextMenu, {
- event: {
- clientX: ev.clientX,
- clientY: ev.clientY,
- },
- clickedPoint: {
- tuple: [
- {
- "columnId": colIds[0],
- "value": "x"
- },
- {
- "columnId": colIds[1],
- "value": "y"
- }
- ],
- },
- customActions: [
- {
- id: 'custom-context-action',
- label: 'Custom context action',
- icon: '',
- onClick: (...arg) => {
- console.log('custom context action triggered', arg);
- },
- },
- ],
- });
- });
+ document
+ .getElementById('close-context-menu')
+ ?.addEventListener('click', (ev) => {
+ ctx.emitEvent(ChartToTSEvent.CloseContextMenu);
+ });
+
+ document
+ .getElementById('show-event-error')
+ ?.addEventListener('click', (ev) => {
+ ctx.emitEvent(ChartToTSEvent.OpenAxisMenu, {
+ event: {
+ clientX: ev.clientX,
+ clientY: ev.clientY,
+ x: ev.x,
+ } as any,
+ columnIds: [],
+ });
+ });
+
+ document
+ .getElementById('open-context-menu')
+ ?.addEventListener('click', (ev) => {
+ const chartModel = ctx.getChartModel();
+ const colIds = chartModel.columns.map((col) => col.id);
+ ctx.emitEvent(ChartToTSEvent.OpenContextMenu, {
+ event: {
+ clientX: ev.clientX,
+ clientY: ev.clientY,
+ },
+ clickedPoint: {
+ tuple: [
+ {
+ columnId: colIds[0],
+ value: 'x',
+ },
+ {
+ columnId: colIds[1],
+ value: 'y',
+ },
+ ],
+ },
+ customActions: [
+ {
+ id: 'custom-context-action',
+ label: 'Custom context action',
+ icon: '',
+ onClick: (...arg) => {
+ console.log('custom context action triggered', arg);
+ },
+ },
+ ],
+ });
+ });
}
async function handleLiveboardContextSection(ctx: CustomChartContext) {
- const {isLiveboardContext = false} = ctx.getAppConfig().appOptions;
- document.getElementById('context-status').style.display = 'inline';
- document.getElementById('context-status').textContent += `${isLiveboardContext}`;
- document.getElementById('context-edit').style.opacity = isLiveboardContext ? '.4': '1';
+ const { isLiveboardContext = false } = ctx.getAppConfig().appOptions;
+ document.getElementById('context-status').style.display = 'inline';
+ document.getElementById('context-status').textContent +=
+ `${isLiveboardContext}`;
+ document.getElementById('context-edit').style.opacity = isLiveboardContext
+ ? '.4'
+ : '1';
}
async function handleLocaleInfo(ctx: CustomChartContext) {
- const {locale = window.navigator.language} = ctx.getAppConfig().localeOptions;
- document.getElementById('locale-info').style.display = 'inline';
- document.getElementById('locale-info').textContent += `${locale}`;
+ const { locale = window.navigator.language } =
+ ctx.getAppConfig().localeOptions;
+ document.getElementById('locale-info').style.display = 'inline';
+ document.getElementById('locale-info').textContent += `${locale}`;
}
async function handlePrintModeInfo(ctx: CustomChartContext) {
- const {isPrintMode = false} = ctx.getAppConfig().appOptions;
- document.getElementById('printmode-info').style.display = 'inline';
- document.getElementById('printmode-info').textContent += `${isPrintMode}`;
+ const { isPrintMode = false } = ctx.getAppConfig().appOptions;
+ document.getElementById('printmode-info').style.display = 'inline';
+ document.getElementById('printmode-info').textContent += `${isPrintMode}`;
}
async function render(ctx: CustomChartContext) {
- const chartModel = ctx.getChartModel();
- const dataModel = getDataModel(chartModel);
- const allowLabels = _.get(
- chartModel.visualProps,
- visualPropKeyMap[2],
- false,
- );
- if (!dataModel) {
- return;
- }
-
- try {
- const canvas = document.getElementById('chart') as any;
- // clear canvas.
- canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
-
- globalChartReference = new Chart(canvas as any, {
- type: 'bar',
- data: {
- labels: dataModel.getLabels(),
- datasets: dataModel.getDatasets() as any,
- },
- options: {
- scales: dataModel.getScales(),
- plugins: {
- // Change options for ALL labels of THIS CHART
- datalabels: {
- display: allowLabels,
- color: 'blue',
- labels: {
- title: {
- font: {
- weight: 'bold',
- },
- },
- value: {
- color: 'green',
- },
- },
- },
- },
- // responsive: true,
- maintainAspectRatio: false,
- interaction: {
- mode: 'point',
- intersect: true,
- },
- onClick: (e: any) => {
- const activeElement = e.chart.getActiveElements()[0];
- const dataX = activeElement.index;
- const dataY = activeElement.datasetIndex;
-
- console.log(
- 'ChartPoint',
- dataX,
- dataY,
- dataModel.getPointDetails(dataX, dataY),
- );
- ctx.emitEvent(ChartToTSEvent.OpenContextMenu, {
- event: getParsedEvent(e),
- clickedPoint: {
- tuple: dataModel.getPointDetails(dataX, dataY),
- },
- });
+ const chartModel = ctx.getChartModel();
+ const dataModel = getDataModel(chartModel);
+ const allowLabels = _.get(chartModel.visualProps, visualPropKeyMap[2], false);
+ if (!dataModel) {
+ return;
+ }
+
+ try {
+ const canvas = document.getElementById('chart') as any;
+ // clear canvas.
+ canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
+
+ globalChartReference = new Chart(canvas as any, {
+ type: 'bar',
+ data: {
+ labels: dataModel.getLabels(),
+ datasets: dataModel.getDatasets() as any,
+ },
+ options: {
+ scales: dataModel.getScales(),
+ plugins: {
+ // Change options for ALL labels of THIS CHART
+ datalabels: {
+ display: allowLabels,
+ color: 'blue',
+ labels: {
+ title: {
+ font: {
+ weight: 'bold',
},
+ },
+ value: {
+ color: 'green',
+ },
},
- });
- } catch (e) {
- console.error('renderfailed', e);
- throw e;
- }
+ },
+ },
+ // responsive: true,
+ maintainAspectRatio: false,
+ interaction: {
+ mode: 'point',
+ intersect: true,
+ },
+ onClick: (e: any) => {
+ const activeElement = e.chart.getActiveElements()[0];
+ const dataX = activeElement.index;
+ const dataY = activeElement.datasetIndex;
+
+ console.log(
+ 'ChartPoint',
+ dataX,
+ dataY,
+ dataModel.getPointDetails(dataX, dataY)
+ );
+ ctx.emitEvent(ChartToTSEvent.OpenContextMenu, {
+ event: getParsedEvent(e),
+ clickedPoint: {
+ tuple: dataModel.getPointDetails(dataX, dataY),
+ },
+ });
+ },
+ },
+ });
+ } catch (e) {
+ console.error('renderfailed', e);
+ throw e;
+ }
}
const renderChart = async (ctx: CustomChartContext): Promise
=> {
- if (globalChartReference) {
- globalChartReference.destroy();
- }
- try {
- ctx.emitEvent(ChartToTSEvent.RenderStart);
- await renderTML(ctx);
- await renderKPIs(ctx);
- await handleAxisMenuButtons(ctx);
- await handleLiveboardContextSection(ctx);
- await handleLocaleInfo(ctx);
- await handlePrintModeInfo(ctx);
- } catch (e) {
- ctx.emitEvent(ChartToTSEvent.RenderError, {
- hasError: true,
- error: e?.message ?? 'Unknown Error',
- });
- } finally {
- ctx.emitEvent(ChartToTSEvent.RenderComplete);
+ if (globalChartReference) {
+ globalChartReference.destroy();
+ }
+
+ try {
+ // Mock authentication logic for playwright tests inside TS.
+ // Should not be taken as a reference to develop authentication logic for custom charts.
+ if (
+ ctx.getAppConfig().chartAppAccessToken &&
+ ctx.getAppConfig().chartAppAccessToken !== TESTER_CHART_ACCESS_TOKEN
+ ) {
+ throw new Error('Chart authentication failed.');
}
+ ctx.emitEvent(ChartToTSEvent.RenderStart);
+ await renderTML(ctx);
+ await renderKPIs(ctx);
+ await handleAxisMenuButtons(ctx);
+ await handleLiveboardContextSection(ctx);
+ await handleLocaleInfo(ctx);
+ await handlePrintModeInfo(ctx);
+ } catch (e) {
+ ctx.emitEvent(ChartToTSEvent.RenderError, {
+ hasError: true,
+ error: e?.message ?? 'Unknown Error',
+ });
+ } finally {
+ ctx.emitEvent(ChartToTSEvent.RenderComplete);
+ }
};
(async () => {
- const ctx = await getChartContext({
- getDefaultChartConfig: (chartModel: ChartModel): ChartConfig[] => {
- const cols = chartModel.columns;
-
- const measureColumns = _.filter(
- cols,
- col => col.type === ColumnType.MEASURE,
- );
-
- const attributeColumns = _.filter(
- cols,
- col => col.type === ColumnType.ATTRIBUTE,
- );
-
- const axisConfig: ChartConfig = {
- key: 'column',
- dimensions: [
- {
- key: 'x',
- columns: [attributeColumns[0]],
- },
- {
- key: 'y',
- columns: measureColumns.slice(0, 2),
- },
- ],
- };
- return [axisConfig];
- },
- getQueriesFromChartConfig: (
- chartConfig: ChartConfig[],
- ): Array => {
- const queries = chartConfig.map(
- (config: ChartConfig): Query =>
- _.reduce(
- config.dimensions,
- (acc: Query, dimension) => ({
- queryColumns: [
- ...acc.queryColumns,
- ...dimension.columns,
- ],
- }),
- {
- queryColumns: [],
- } as Query,
- ),
- );
- return queries;
- },
- renderChart: ctx => renderChart(ctx),
- chartConfigEditorDefinition: [
+ const ctx = await getChartContext({
+ getDefaultChartConfig: (chartModel: ChartModel): ChartConfig[] => {
+ const cols = chartModel.columns;
+
+ const measureColumns = _.filter(
+ cols,
+ (col) => col.type === ColumnType.MEASURE
+ );
+
+ const attributeColumns = _.filter(
+ cols,
+ (col) => col.type === ColumnType.ATTRIBUTE
+ );
+
+ const axisConfig: ChartConfig = {
+ key: 'column',
+ dimensions: [
+ {
+ key: 'x',
+ columns: [attributeColumns[0]],
+ },
+ {
+ key: 'y',
+ columns: measureColumns.slice(0, 2),
+ },
+ ],
+ };
+ return [axisConfig];
+ },
+ getQueriesFromChartConfig: (chartConfig: ChartConfig[]): Array => {
+ const queries = chartConfig.map(
+ (config: ChartConfig): Query =>
+ _.reduce(
+ config.dimensions,
+ (acc: Query, dimension) => ({
+ queryColumns: [...acc.queryColumns, ...dimension.columns],
+ }),
{
- key: 'column',
- label: 'Custom Column',
- descriptionText:
- 'X Axis can only have attributes, Y Axis can only have measures, Color can only have attributes. ' +
- 'Should have just 1 column in Y axis with colors columns.',
- columnSections: [
- {
- key: 'x',
- label: 'Custom X Axis',
- allowAttributeColumns: true,
- allowMeasureColumns: false,
- allowTimeSeriesColumns: true,
- maxColumnCount: 1,
- },
- {
- key: 'y',
- label: 'Custom Y Axis',
- allowAttributeColumns: false,
- allowMeasureColumns: true,
- allowTimeSeriesColumns: false,
- },
- ],
- },
+ queryColumns: [],
+ } as Query
+ )
+ );
+ return queries;
+ },
+ renderChart: (ctx) => renderChart(ctx),
+ chartConfigEditorDefinition: [
+ {
+ key: 'column',
+ label: 'Custom Column',
+ descriptionText:
+ 'X Axis can only have attributes, Y Axis can only have measures, Color can only have attributes. ' +
+ 'Should have just 1 column in Y axis with colors columns.',
+ columnSections: [
+ {
+ key: 'x',
+ label: 'Custom X Axis',
+ allowAttributeColumns: true,
+ allowMeasureColumns: false,
+ allowTimeSeriesColumns: true,
+ maxColumnCount: 1,
+ },
+ {
+ key: 'y',
+ label: 'Custom Y Axis',
+ allowAttributeColumns: false,
+ allowMeasureColumns: true,
+ allowTimeSeriesColumns: false,
+ },
],
- visualPropEditorDefinition: {
- elements: [
- {
- key: 'showError',
- type: 'toggle',
- defaultValue: false,
- label: 'Show Error',
- },
- ],
+ },
+ ],
+ visualPropEditorDefinition: {
+ elements: [
+ {
+ key: 'showError',
+ type: 'toggle',
+ defaultValue: false,
+ label: 'Show Error',
},
- validateConfig: (updatedConfig): ValidationResponse => {
- if (updatedConfig.length !== 1) {
- return {
- isValid: false,
- validationErrorMessage: ['invalid config. no config found'],
- };
- }
- // assuming 0 is x dimension
- const dimensions = updatedConfig[0].dimensions;
- if (
- dimensions[0].columns.length === 0 ||
- dimensions[1].columns.length === 0
- ) {
- return {
- isValid: false,
- validationErrorMessage: [
- 'Invalid config. X or Y axis columns cannot be empty.',
- ],
- };
- }
- return {
- isValid: true,
- };
- },
- validateVisualProps: (updatedVisualProps: any) => {
- if (updatedVisualProps.showError === true) {
- return {
- isValid: false,
- validationErrorMessage: ['Change it to false again!'],
- }
- }
- return {
- isValid: true,
- }
- },
- allowedConfigurations: {
- allowColumnConditionalFormatting: true,
- allowColumnNumberFormatting: true,
- allowMeasureNamesAndValues: true
- }
- });
-
- renderChart(ctx);
+ ],
+ },
+ validateConfig: (updatedConfig): ValidationResponse => {
+ if (updatedConfig.length !== 1) {
+ return {
+ isValid: false,
+ validationErrorMessage: ['invalid config. no config found'],
+ };
+ }
+ // assuming 0 is x dimension
+ const dimensions = updatedConfig[0].dimensions;
+ if (
+ dimensions[0].columns.length === 0 ||
+ dimensions[1].columns.length === 0
+ ) {
+ return {
+ isValid: false,
+ validationErrorMessage: [
+ 'Invalid config. X or Y axis columns cannot be empty.',
+ ],
+ };
+ }
+ return {
+ isValid: true,
+ };
+ },
+ validateVisualProps: (updatedVisualProps: any) => {
+ if (updatedVisualProps.showError === true) {
+ return {
+ isValid: false,
+ validationErrorMessage: ['Change it to false again!'],
+ };
+ }
+ return {
+ isValid: true,
+ };
+ },
+ allowedConfigurations: {
+ allowColumnConditionalFormatting: true,
+ allowColumnNumberFormatting: true,
+ allowMeasureNamesAndValues: true,
+ },
+ });
+
+ renderChart(ctx);
})();