From 580f380f56b538680329fbf009658191dbfd104e Mon Sep 17 00:00:00 2001 From: Anush Gupta <74965306+Anush2303@users.noreply.github.com> Date: Mon, 23 Dec 2024 03:33:04 +0000 Subject: [PATCH] plotly examples bug fixes --- .../DeclarativeChart/DeclarativeChart.tsx | 36 +++++++---- .../DeclarativeChart/PlotlySchemaAdapter.ts | 64 +++++++++++++++---- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx index 54c940caab29d6..fb2d2f0bcfc47c 100644 --- a/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx +++ b/packages/charts/react-charting/src/components/DeclarativeChart/DeclarativeChart.tsx @@ -10,6 +10,8 @@ import { transformPlotlyJsonToHorizontalBarWithAxisProps, isDateArray, isNumberArray, + isMonthArray, + updateXValues, transformPlotlyJsonToHeatmapProps, transformPlotlyJsonToSankeyProps, transformPlotlyJsonToGaugeProps, @@ -76,6 +78,7 @@ export const DeclarativeChart: React.FunctionComponent = const xValues = data[0].x; const isXDate = isDateArray(xValues); const isXNumber = isNumberArray(xValues); + const isXMonth = isMonthArray(xValues); const colorMap = useColorMapping(); const isDarkTheme = UseIsDarkTheme(); @@ -128,21 +131,28 @@ export const DeclarativeChart: React.FunctionComponent = } case 'scatter': const isAreaChart = data.some((series: any) => series.fill === 'tonexty' || series.fill === 'tozeroy'); - if (isXDate || isXNumber) { + const renderChart = (chartProps: any) => { if (isAreaChart) { - return ( - - ); + return ; } - return ( - - ); + return ; + }; + if (isXDate || isXNumber) { + const chartProps = { + ...transformPlotlyJsonToScatterChartProps({ data, layout }, isAreaChart, colorMap, isDarkTheme), + legendProps, + }; + return renderChart(chartProps); + } else if (isXMonth) { + const updatedData = data.map((dataPoint: any) => ({ + ...dataPoint, + x: updateXValues(dataPoint.x), + })); + const chartProps = { + ...transformPlotlyJsonToScatterChartProps({ updatedData, layout }, isAreaChart, colorMap, isDarkTheme), + legendProps, + }; + return renderChart(chartProps); } return ( !isNaN(Date.parse(value)); const isNumber = (value: any): boolean => !isNaN(parseFloat(value)) && isFinite(value); export const isDateArray = (array: any[]): boolean => isArrayOrTypedArray(array) && array.every(isDate); export const isNumberArray = (array: any[]): boolean => isArrayOrTypedArray(array) && array.every(isNumber); +export const isMonthArray = (array: any[]): boolean => { + if (array && array.length > 0) { + const presentYear = new Date().getFullYear(); + return array.every(monthValue => { + return isDate(`${monthValue} 01, ${presentYear}`); + }); + } + return false; +}; +export const updateXValues = (xValues: any[]): any[] => { + const presentYear = new Date().getFullYear(); + const dates = xValues.map(monthValue => { + const parsedDate = `${monthValue} 01, ${presentYear}`; + return isDate(parsedDate) ? new Date(parsedDate) : null; + }); + for (let i = dates.length - 1; i > 0; i--) { + const currentMonth = dates[i]!.getMonth(); + const previousMonth = dates[i - 1]!.getMonth(); + const currentYear = dates[i]!.getFullYear(); + const previousYear = dates[i - 1]!.getFullYear(); + if (previousMonth >= currentMonth) { + dates[i - 1]!.setFullYear(dates[i]!.getFullYear() - 1); + } else if (previousYear > currentYear) { + dates[i - 1]!.setFullYear(currentYear); + } + } + xValues = xValues.map((month, index) => { + return `${month} 01, ${dates[index]!.getFullYear()}`; + }); + return xValues; +}; export const getColor = ( legendLabel: string, colorMap: React.MutableRefObject>, @@ -112,7 +143,7 @@ export const transformPlotlyJsonToVSBCProps = ( mapXToDataPoints[x] = { xAxisPoint: x, chartData: [], lineData: [] }; } const legend: string = series.name || `Series ${index1 + 1}`; - if (series.type === 'bar') { + if (series.type === 'bar' || series.type === 'scatter') { const color = getColor(legend, colorMap, isDarkTheme); mapXToDataPoints[x].chartData.push({ legend, @@ -162,6 +193,7 @@ export const transformPlotlyJsonToGVBCProps = ( mapXToDataPoints[x].series.push({ key: legend, data: series.y?.[index2], + xAxisCalloutData: x as string, color, legend, }); @@ -271,8 +303,8 @@ export const transformPlotlyJsonToScatterChartProps = ( colorMap: React.MutableRefObject>, isDarkTheme?: boolean, ): ILineChartProps | IAreaChartProps => { - const { data, layout } = jsonObj; - + const { layout } = jsonObj; + const data = jsonObj.updatedData ? jsonObj.updatedData : jsonObj.data; const chartData: ILineChartPoints[] = data.map((series: any, index: number) => { const xValues = series.x; const isString = typeof xValues[0] === 'string'; @@ -458,15 +490,23 @@ export const transformPlotlyJsonToGaugeProps = ( const { data, layout } = jsonObj; const firstData = data[0]; - const segments = firstData.gauge?.steps?.map((step: any, index: number): IGaugeChartSegment => { - const legend = step.name || `Segment ${index + 1}`; - const color = getColor(legend, colorMap, isDarkTheme); - return { - legend, - size: step.range?.[1] - step.range?.[0], - color, - }; - }); + const segments = firstData.gauge?.steps?.length + ? firstData.gauge.steps.map((step: any, index: number): IGaugeChartSegment => { + const legend = step.name || `Segment ${index + 1}`; + const color = getColor(legend, colorMap, isDarkTheme); + return { + legend, + size: step.range?.[1] - step.range?.[0], + color, + }; + }) + : [ + { + legend: 'Segment 1', + size: (firstData.gauge?.range?.[1] ?? 0) - (firstData.gauge?.range?.[0] ?? 0), + color: getColor('Segment 1', colorMap, isDarkTheme), + }, + ]; let sublabel: string | undefined; let sublabelColor: string | undefined;