Closed makepado closed 1 year ago
Hi, did not exactly understand the issue, can you rephrase it differently?
In short, when I redraw a chart, I did 'chart.data(datas...).render()' to redraw the chart. However, the old data is being exposed.
Therefore, I would like to ask if there is a feature that allows me to reset the chart.
I uploaded a temporary CSV to my GitHub repo. My CSV and your CSV have different data.
https://raw.githubusercontent.com/dr-hongjae/test-d3-org-chart-csv/main/temp_hongjae.csv
I tested it with the site here. https://stackblitz.com/edit/web-platform-jyncb9?file=index.html
on this site is fetching and rendering data like this.
d3.csv(
'https://raw.githubusercontent.com/bumbeishvili/sample-data/main/org.csv'
).then((dataFlattened) => {
chart = new d3.OrgChart()
.container('.chart-container')
.data(dataFlattened)
.nodeWidth((d) => 250)
.initialZoom(0.7)
.nodeHeight((d) => 175)
.childrenMargin((d) => 40)
.compactMarginBetween((d) => 15)
.compactMarginPair((d) => 80)
.nodeContent(function (d, i, arr, state) {
return `
<div style="padding-top:30px;background-color:none;margin-left:1px;height:${
d.height
}px;border-radius:2px;overflow:visible">
<div style="height:${
d.height - 32
}px;padding-top:0px;background-color:white;border:1px solid lightgray;">
<img src=" ${
d.data.imageUrl
}" style="margin-top:-30px;margin-left:${d.width / 2 - 30}px;border-radius:100px;width:60px;height:60px;" />
<div style="margin-right:10px;margin-top:15px;float:right">${
d.data.id
}</div>
<div style="margin-top:-30px;background-color:#3AB6E3;height:10px;width:${
d.width - 2
}px;border-radius:1px"></div>
<div style="padding:20px; padding-top:35px;text-align:center">
<div style="color:#111672;font-size:16px;font-weight:bold"> ${
d.data.name
} </div>
<div style="color:#404040;font-size:16px;margin-top:4px"> ${
d.data.positionName
} </div>
</div>
<div style="display:flex;justify-content:space-between;padding-left:15px;padding-right:15px;">
<div > Manages: ${d.data._directSubordinates} 👤</div>
<div > Oversees: ${d.data._totalSubordinates} 👤</div>
</div>
</div>
</div>
`;
})
.render();
I opened the bottom right console, and typed in the code to load my CSV.
d3.csv(
'https://raw.githubusercontent.com/dr-hongjae/test-d3-org-chart-csv/main/temp_hongjae.csv'
).then((dataFlattened) => {
chart = new d3.OrgChart()
.container('.chart-container')
.data(dataFlattened)
.nodeWidth((d) => 250)
.initialZoom(0.7)
.nodeHeight((d) => 175)
.childrenMargin((d) => 40)
.compactMarginBetween((d) => 15)
.compactMarginPair((d) => 80)
.nodeContent(function (d, i, arr, state) {
return `
<div style="padding-top:30px;background-color:none;margin-left:1px;height:${
d.height
}px;border-radius:2px;overflow:visible">
<div style="height:${
d.height - 32
}px;padding-top:0px;background-color:white;border:1px solid lightgray;">
<img src=" ${
d.data.imageUrl
}" style="margin-top:-30px;margin-left:${d.width / 2 - 30}px;border-radius:100px;width:60px;height:60px;" />
<div style="margin-right:10px;margin-top:15px;float:right">${
d.data.id
}</div>
<div style="margin-top:-30px;background-color:#3AB6E3;height:10px;width:${
d.width - 2
}px;border-radius:1px"></div>
<div style="padding:20px; padding-top:35px;text-align:center">
<div style="color:#111672;font-size:16px;font-weight:bold"> ${
d.data.name
} </div>
<div style="color:#404040;font-size:16px;margin-top:4px"> ${
d.data.positionName
} </div>
</div>
<div style="display:flex;justify-content:space-between;padding-left:15px;padding-right:15px;">
<div > Manages: ${d.data._directSubordinates} 👤</div>
<div > Oversees: ${d.data._totalSubordinates} 👤</div>
</div>
</div>
</div>
`;
})
.render();
});
If you look at the name and positionName, these were originally written as test, but have been replaced with the old data.
I was having a similar problem. Looks like it's an underlying issue with d3. Whenever I reload the data, I have to clear the d3 canvas first.
d3.select('svg').selectAll('*').remove();
You can reload the data just by using the same chart reference
d3.csv( 'https://raw.githubusercontent.com/dr-hongjae/test-d3-org-chart-csv/main/temp_hongjae.csv')
.then((dataFlattened) => {
chart.data(dataFlattened).render()
})
When you are creating the new OrgChart()
this does not clear the old org chart reference and it causes undesirable consequences
You can reload the data just by using the same chart reference
d3.csv( 'https://raw.githubusercontent.com/dr-hongjae/test-d3-org-chart-csv/main/temp_hongjae.csv') .then((dataFlattened) => { chart.data(dataFlattened).render() })
When you are creating the
new OrgChart()
this does not clear the old org chart reference and it causes undesirable consequences
2024 December on React - I solved the same issue by preventing reinitialization of OrChart
instance as stated by @bumbeishvili (huge thanks!).
As I use react and keep the chart in a shareable state (useState), I had to first initialize it on an independent useEffect
since DOM manipulation is done at ctor level, and config the shared chart
instance on a different useEffect
with chart
dependency
Something like:
import React, { useRef, useEffect, useState } from "react";
const d3Container = useRef(null);
const [chart, setChart] = useState(null);
useEffect(() => {
// initial chart set
setChart(new OrgChart());
}, []);
useEffect(() => {
// chart config
if (!chart) return;
// fetchUsers returns an array of user objects
fetchUsers(...).then((users) => {
chart
.container(d3Container.current)
.layout("top")
.data(users)
.render()
.fit();
}, [
chart,
// other dependencies
]);
});
// (...)
return (
// (...)
<div ref={d3Container} />
// (...)
);
The second time I plotted the d3-org-chart, I used the it references the previous dataset, whether it collapsed or not, how can we prevent this?
It will be replaced with a chart of the previous situation.
Not because it's the same data, If you've added other data you'll see a chart with the old data when you press the expand button.
https://user-images.githubusercontent.com/76645966/234821656-a0dcea99-c0ca-4e78-8236-f9c8455fbc8a.mp4