Closed matter13311 closed 4 months ago
@matter13311 this is not a React component, thus you cannot use it directly in a React environment directly. The manner to instantiate this module is specified in the docs, so you'll need to write a React wrapper around it if you want to use it in a JSX context.
react-kapsule offers a means to do that easily, but there are other ways you can achieve the same.
Could you give an example with react-kapsule?
Something along these lines:
import fromKapsule from 'react-kapsule';
import sunburstKapsule from 'sunburst-chart';
const Sunburst = fromKapsule(sunburstKapsule);
then use it in React:
<Sunburst data={myData} />
Thanks for the fast reply!
Your example was also my intuition but trying it out in yields the following typeerror:
Argument of type '(configOptions?: ConfigOptions | undefined) => SunburstChartInstance' is not assignable to parameter of type 'KapsuleClosure'.
Property 'resetProps' is missing in type 'SunburstChartGenericInstance<SunburstChartInstance>' but required in type 'KapsuleInstance'.ts(2345)
did you figured it out?
No, I ended up not using react-kapsule. Just generated the chart and applied it to a div with an id, something to this effect:
import sunburst from "sunburst-chart";
export type SunburstLeaf = {
name: string;
size: number;
color: string;
};
export type SunburstNode = {
name: string;
color: string;
size: number;
children: (SunburstNode | SunburstLeaf)[];
};
interface SunburstElementProps {
data: SunburstNode | undefined
}
export const SunburstElement = (props: SunburstElementProps) => {
const { data } = props;
useEffect(() => {
if (data) {
sunburst()
.data(data)
.label("name")
.size("size")
.height(200)
.width(200)
.color("color")(document.getElementById("chart")!);
}
}, [data]);
return <div id="chart" />
}
And some extra logic to delete the children of the div when data
changes.
I ended up with an implementation similar to above, but was still getting the chart duplication error.
As @hallundbaek hints here,
And some extra logic to delete the children of the div when data changes.
we need to provide a cleanup function to the useEffect. This StackOverflow says exactly what to do, and I found it to be correct.
Here's my final useEffect implementation. I used explicit props coming from the parent component and passed them to the chart.
useEffect(() => {
if (treeData) {
sunburstChart
.data(treeData)
.width(width || chartRef.current.offsetWidth)
.height(height || chartRef.current.offsetWidth) // makes it square if no height provided
.label(getLabel)
.size(getSize)
.color(getColor)
.strokeColor(getStrokeColor)
.nodeClassName(getNodeClassName)
.minSliceAngle(minSliceAngle)
.maxLevels(maxLevels)
.excludeRoot(excludeRoot)
.centerRadius(centerRadius)
.radiusScaleExponent(radiusScaleExponent)
.sort(getSortOrder)
.showLabels(showLabels)
.labelOrientation(labelOrientation)
.handleNonFittingLabel(handleNonFittingLabel)
.showTooltip(getShowTooltip)
.tooltipTitle(getTooltipTitle)
.tooltipContent(getTooltipContent)
.onHover(onHover)
.onClick(onClick)
.transitionDuration(transitionDuration)(
document.getElementById('sunburst')
);
}
return () => {
if (chartRef.current?.children[0]) {
chartRef.current.removeChild(chartRef.current.children[0]);
}
};
}, [treeData]);
where the component returns
return <div id='sunburst' className={classes.root} ref={chartRef} />;
@vasturiano I think we can mark this issue as closed.
How do I use this npm package with React? ` import React from 'react' import Sunburst from 'sunburst-chart';
return( < Sunburst/ > ) `
I get an error saying Sunburst can't be used in JSX.