I'm wondering if it's possible to add new type of charts, like a radar chart, to the React library plotly/react-pivottable https://github.com/plotly/react-pivottable.
I would like to add a spider chart, always from the chart library plotly, but I can't understand where to start as the documentation is a litle poor and the GitHub repo is quite silence...
Maybe it's not even possible.
Does anyone know if it's possible?
Yes, it's completely possible to add custom charts. You need to copy makeRenderer function from original repo and customised it according to the chart types.
To add a new chart type (radar chart), to React Pivottable, you've to add directly on PlotlyRenderers.
Here's an example of how you could add a radar chart to React Pivottable:
const Plot = createPlotlyComponent(window.Plotly);
const PlotlyRenderers = createPlotlyRenderers(Plot);
const makeRenderer = (
PlotlyComponent,
traceOptions = {},
layoutOptions = {},
transpose = false
) {
class Renderer extends React.PureComponent {
render() {
const pivotData = new PivotData(this.props);
const rowKeys = pivotData.getRowKeys();
const colKeys = pivotData.getColKeys();
const traceKeys = transpose ? colKeys : rowKeys;
if (traceKeys.length === 0) {
traceKeys.push([]);
}
const datumKeys = transpose ? rowKeys : colKeys;
if (datumKeys.length === 0) {
datumKeys.push([]);
}
let fullAggName = this.props.aggregatorName;
const numInputs =
this.props.aggregators[fullAggName]([])().numInputs || 0;
if (numInputs !== 0) {
fullAggName += ` of ${this.props.vals.slice(0, numInputs).join(", ")}`;
}
const data = traceKeys.map((traceKey) => {
const r = [];
const theta = [];
for (const datumKey of datumKeys) {
const val = parseFloat(
pivotData
.getAggregator(
transpose ? datumKey : traceKey,
transpose ? traceKey : datumKey
)
.value()
);
r.push(isFinite(val) ? val : null);
theta.push(datumKey.join("-") || " ");
}
const trace = { name: traceKey.join("-") || fullAggName };
trace.fill = "toself";
trace.r = r;
trace.theta = theta.length > 1 ? theta : [fullAggName];
return Object.assign(trace, traceOptions);
});
const layout = {
polar: {
radialaxis: {
visible: true,
range: [0, 50]
}
},
/* eslint-disable no-magic-numbers */
// width: window.innerWidth / 1.5,
// height: window.innerHeight / 1.4 - 50
// /* eslint-enable no-magic-numbers */
};
return (
<PlotlyComponent
data={data}
layout={Object.assign(
layout,
layoutOptions,
this.props.plotlyOptions
)}
config={this.props.plotlyConfig}
onUpdate={this.props.onRendererUpdate}
/>
);
}
}
return Renderer;
}
const radarChart = () => {
return makeRenderer(
Plot,
{ type: "scatterpolar" },
{},
true
);
}
PlotlyRenderers["Radar Chart"] = radarChart({});
const data = [
{
country: "Spain",
name: "Santiago",
surname: "Ramón y Cajal",
sex: "Male",
age: 57,
subject: "Medicine"
},
{
country: "United Kingdom",
name: "Ada",
surname: "Lovelace",
sex: "Female",
age: 47,
subject: "Computing"
},
{
country: "United Kingdom",
name: "Alan",
surname: "Turing",
sex: "Male",
age: 55,
subject: "Computing"
},
{
country: "France",
name: "Antoine",
surname: "Lavoisier",
sex: "Male",
age: 12,
subject: "Chemistry"
},
{
country: "Poland",
name: "Marie",
surname: "Curie",
sex: "Female",
age: 33,
subject: "Chemistry"
},
{
country: "Austria",
name: "Hedy",
surname: "Lamarr",
sex: "Female",
age: 34,
subject: "Computing"
},
{
country: "Austria",
name: "Erwin",
surname: "Schrödinger",
sex: "Male",
age: 38,
subject: "Physics"
}
];
export default function App() {
const [opts, setOpts] = useState({});
return (
<div className="App">
<PivotTableUI
data={data}
onChange={(e) => {
setOpts(e);
console.log(e);
}}
renderers={Object.assign({}, TableRenderers, PlotlyRenderers)}
cols={["sex"]}
rows={["subject", "country"]}
rendererName="Table Heatmap"
aggregatorName="Average"
vals={["age"]}
derivedAttributes={{ completeName: (el) => el.name + " " + el.surname }}
{...opts}
/>
</div>
);
}
Here is the complete code: https://codesandbox.io/s/react-pivot-table-custom-charts-2utqbt?file=/src/App.js:3511-4468