Skip to main content

08-Creating dataModel from Input data

Pre-conditions

If you’ve followed the steps in the previous sections, you should have a copy of the code and be able to run it with an error on renderChart. If not, please revisit the previous lessons to get set up.

Create a Data Model from input data

The data model is unique to every chart. It defines how each point will be plotted on the chart. In this step we will deal with thoughtspot ChartModel to create dataModel and feed that dataModel to to new Charts in render function that we will be create in next step in chart.js required format.

Let's create dataModel with the following steps:

  1. Create the function getDataModel that will take chartModel and return columnchartModel object. Code snippet is as follow-
function getDataModel(
chartModel: ChartModel,
customStyleConfig: ChartSdkCustomStylingConfig | undefined
) {
// column chart model
const columnChartModel = getColumnDataModel(
chartModel.config?.chartConfig?.[0].dimensions ?? [],
chartModel.data?.[0].data ?? [],
"bar",
chartModel.visualProps,
customStyleConfig
);

return columnChartModel;
}
  1. Create two global array that will have with name availableColor and visualPropKeyMap that will be used to provide default color configurations and mapping key value pair that we will be getting from in visualProp. The code snippet is as follow-
Chart.register(ChartDataLabels);

let globalChartReference: Chart;

const availableColor = ["red", "green", "blue"];

const visualPropKeyMap = {
0: "color",
1: "accordion.Color2",
2: "accordion.datalabels",
};
  1. In this we will be implementing getColumnDataModel that is there in getDataModel. This will chartConfig,chartData(data),typeand visualprop(current prop key and value) and return object with function such as getLabel,getDatasets(axisId,type,colorConfiguration),getScales(chart.js display configurations) and getPointDetails. Code snippet is given below-
function getColumnDataModel(
configDimensions,
dataArr: DataPointsArray,
type,
visualProps: VisualProps
) {
// 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) => {
const coldata = getDataForColumn(col, dataArr);
const CFforColumn = getCfForColumn(col);
const axisId = `${type}-y${idx.toString()}`;
const color = coldata.map((value, index) =>
getBackgroundColor(
customStyleConfig,
visualProps,
idx,
dataArr,
CFforColumn,
index,
col.id
)
);

return {
label: col.name,
data: coldata,
yAxisID: axisId,
type: `${type}`,
backgroundColor: color,
borderColor: color,
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],
},
{
columnId: yAxisColumns[yPos].id,
value: getDataForColumn(yAxisColumns[yPos], dataArr)[xPos],
},
],
};
}
  1. In the above implementation you will be getting error inside getPointsdetails beacuse we have a undefined function getDataForColumn. This function will take the column ids and return the specific cloumn data. Implement this function in with the following code snippet->
function getDataForColumn(column: ChartColumn, dataArr: DataPointsArray) {
const idx = _.findIndex(dataArr.columns, (colId) => column.id === colId);
return _.map(dataArr.dataValue, (row) => row[idx]);
}
  1. In the above implementation, you will need to implement the following functions to ensure that the conditional formatting and background colors are correctly applied, and that the plotlines and plotbands are drawn on the chart.

    getBackgroundColor: This function determines the background color for each data point based on custom style configurations, visual properties, and any applicable conditional formatting rules. Implement this function with the following code snippet:

    export function getBackgroundColor(
    customStyleConfig: ChartSdkCustomStylingConfig,
    visualProps: VisualProps,
    idx: any,
    dataArr: any,
    CFforColumn: any,
    index: number,
    colId: any
    ) {
    const color =
    customStyleConfig?.chartColorPalettes?.length &&
    customStyleConfig?.chartColorPalettes[0].colors.length > 0
    ? customStyleConfig?.chartColorPalettes[0].colors
    : _.get(visualProps, visualPropKeyMap?.[idx], availableColor[idx]);
    return color;
    }