Skip to content

Commit

Permalink
Merge branch 'charting/declarativeCharts' of https://github.com/micro…
Browse files Browse the repository at this point in the history
…soft/fluentui into charting/declarativeCharts
  • Loading branch information
AtishayMsft committed Nov 27, 2024
2 parents 54db5ea + bcd2da9 commit 45bd286
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,18 @@ import {
transformPlotlyJsonToColumnProps,
transformPlotlyJsonToScatterChartProps,
transformPlotlyJsonToHorizontalBarWithAxisProps,
isDateArray,
isNumberArray,
transformPlotlyJsonToHeatmapProps,
transformPlotlyJsonToSankeyProps,
transformPlotlyJsonToGaugeProps,
} from './PlotlySchemaAdapter';
import { LineChart } from '../LineChart/index';
import { HorizontalBarChartWithAxis } from '../HorizontalBarChartWithAxis/index';
import { AreaChart } from '../AreaChart/index';
import { HeatMapChart } from '../HeatMapChart/index';

const isDate = (value: any): boolean => !isNaN(Date.parse(value));
const isNumber = (value: any): boolean => !isNaN(parseFloat(value)) && isFinite(value);
export const isDateArray = (array: any[]): boolean => Array.isArray(array) && array.every(isDate);
export const isNumberArray = (array: any[]): boolean => Array.isArray(array) && array.every(isNumber);
import { SankeyChart } from '../SankeyChart/SankeyChart';
import { GaugeChart } from '../GaugeChart/index';

/**
* DeclarativeChart props.
Expand Down Expand Up @@ -68,6 +67,11 @@ export const DeclarativeChart: React.FunctionComponent<DeclarativeChartProps> =
return <HeatMapChart {...transformPlotlyJsonToHeatmapProps(props.chartSchema)} />;
case 'sankey':
return <SankeyChart {...transformPlotlyJsonToSankeyProps(props.chartSchema)} />;
case 'indicator':
if (props.chartSchema?.data?.[0]?.mode?.includes('gauge')) {
return <GaugeChart {...transformPlotlyJsonToGaugeProps(props.chartSchema)} />;
}
return <div>Unsupported Schema</div>;
default:
return <div>Unsupported Schema</div>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import {
IHeatMapChartDataPoint,
} from '../../types/IDataPoint';
import { ISankeyChartProps } from '../SankeyChart/index';
import { getNextColor, DataVizPalette } from '../../utilities/colors';
import { getNextColor, DataVizPalette, getColorFromToken } from '../../utilities/colors';
import { IVerticalStackedBarChartProps } from '../VerticalStackedBarChart/index';
import { IHorizontalBarChartWithAxisProps } from '../HorizontalBarChartWithAxis/index';
import { ILineChartProps } from '../LineChart/index';
import { IAreaChartProps } from '../AreaChart/index';
import { IHeatMapChartProps } from '../HeatMapChart/index';
import { IGaugeChartProps, IGaugeChartSegment } from '../GaugeChart/index';

const isDate = (value: any): boolean => !isNaN(Date.parse(value));
const isNumber = (value: any): boolean => !isNaN(parseFloat(value)) && isFinite(value);
Expand Down Expand Up @@ -157,15 +158,31 @@ export const transformPlotlyJsonToHorizontalBarWithAxisProps = (jsonObj: any): I
return series.y.map((yValue: string, i: number) => ({
x: series.x[i],
y: yValue,
legend: series.name,
legend: yValue,
color: series.marker?.color || getNextColor(index),
}));
})
.flat();

const chartHeight = layout.height || 350;
const margin = layout.margin?.l || 0;
const padding = layout.margin?.pad || 0;
const availableHeight = chartHeight - margin - padding;
const numberOfBars = data[0].y.length;
const gapFactor = 0.5;
const barHeight = availableHeight / (numberOfBars * (1 + gapFactor));

return {
data: chartData,
chartTitle: layout.title || '',
barHeight,
showYAxisLables: true,
styles: {
root: {
height: chartHeight,
width: layout.width || 600,
},
},
};
};

Expand Down Expand Up @@ -254,6 +271,53 @@ export const transformPlotlyJsonToSankeyProps = (jsonObj: any): ISankeyChartProp
};
};

export const transformPlotlyJsonToGaugeProps = (jsonObj: any): IGaugeChartProps => {
const { data, layout } = jsonObj;
const firstData = data[0];

const segments = firstData.gauge?.steps?.map((step: any, index: number): IGaugeChartSegment => {
return {
legend: step.name || `Segment ${index + 1}`,
size: step.range?.[1] - step.range?.[0],
color: step.color || getNextColor(index),
};
});

let sublabel: string | undefined;
let sublabelColor: string | undefined;
if (typeof firstData.delta?.reference === 'number') {
const diff = firstData.value - firstData.delta.reference;
if (diff >= 0) {
sublabel = `\u25B2 ${diff}`;
sublabelColor = firstData.delta.increasing?.color || getColorFromToken(DataVizPalette.success);
} else {
sublabel = `\u25BC ${Math.abs(diff)}`;
sublabelColor = firstData.delta.decreasing?.color || getColorFromToken(DataVizPalette.error);
}
}

const styles: IGaugeChartProps['styles'] = {
sublabel: {
fill: sublabelColor,
},
};

return {
segments,
chartValue: firstData.value,
chartTitle: firstData.title?.text,
sublabel,
// range values can be null
minValue: firstData.gauge?.axis?.range?.[0] ?? undefined,
maxValue: firstData.gauge?.axis?.range?.[1] ?? undefined,
chartValueFormat: () => firstData.value,
width: layout?.width,
height: layout?.height,
hideLegend: true,
styles,
};
};

function isTypedArray(a: any) {
return ArrayBuffer.isView(a) && !(a instanceof DataView);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,35 @@
"visualizer": "plotly",
"data": [
{
"name": "speed",
"text": 2468,
"type": "scatter",
"x": [0],
"y": [0],
"marker": {
"size": 28,
"color": "850000"
},
"hoverinfo": "text+name",
"showlegend": false
},
{
"hole": 0.5,
"type": "pie",
"marker": {
"colors": [
"rgba(14, 127, 0, .5)",
"rgba(110, 154, 22, .5)",
"rgba(170, 202, 42, .5)",
"rgba(202, 209, 95, .5)",
"rgba(210, 206, 145, .5)",
"rgba(232, 226, 202, .5)",
"rgba(255, 255, 255, 0)"
]
},
"text": ["60% +", "50%", "40%", "30%", "20%", "10%", ""],
"rotation": 90,
"textinfo": "text",
"hoverinfo": "label",
"labels": ["151-180", "121-150", "91-120", "61-90", "31-60", "0-30", ""],
"values": [
8.333333333333334, 8.333333333333334, 8.333333333333334, 8.333333333333334, 8.333333333333334,
8.333333333333334, 50
],
"showlegend": false,
"textposition": "inside"
"type": "indicator",
"mode": "gauge+number+delta",
"value": 420,
"title": { "text": "Speed", "font": { "size": 24 } },
"delta": { "reference": 400, "increasing": { "color": "RebeccaPurple" } },
"gauge": {
"axis": { "range": [null, 500], "tickwidth": 1, "tickcolor": "darkblue" },
"bar": { "color": "darkblue" },
"bgcolor": "white",
"borderwidth": 2,
"bordercolor": "gray",
"steps": [
{ "range": [0, 250], "color": "cyan" },
{ "range": [250, 400], "color": "royalblue" }
],
"threshold": {
"line": { "color": "red", "width": 4 },
"thickness": 0.75,
"value": 490
}
}
}
],
"layout": {
"title": "Gauge",
"width": 1000,
"xaxis": {
"range": [-1, 1],
"showgrid": false,
"zeroline": false,
"showticklabels": false
},
"yaxis": {
"range": [-1, 1],
"showgrid": false,
"zeroline": false,
"showticklabels": false
},
"height": 1000,
"shapes": [
{
"line": {
"color": "850000"
},
"path": "M -.0 -0.025 L .0 0.025 L -0.659197688992 0.751969684779 Z",
"type": "path",
"fillcolor": "850000"
}
]
"width": 500,
"height": 400,
"margin": { "t": 25, "r": 25, "l": 25, "b": 25 },
"paper_bgcolor": "lavender",
"font": { "color": "darkblue", "family": "Arial" }
},
"frames": []
}

0 comments on commit 45bd286

Please sign in to comment.