In the example below there is an inline event handler that is not working, because there is something wrong with escaping characters. In general inline handlers are bad practice and difficult to manage. An other option is to attach the handler properly using Javascript instead (see comment part of the snippet). But then I have to write the template in a way that contradicts the usual HTML standard and thus makes it less readable. Is there another option?
Running code:
/*
const divElement = document.createElement('div');
divElement.setAttribute('customId', node.data.customId);
divElement.style.backgroundColor = 'aqua';
divElement.style.width = `${node.width}px`;
divElement.style.height = `${node.height}px`;
divElement.textContent = node.data.customName;
const innerDiv = document.createElement('div');
innerDiv.textContent = 'klick';
innerDiv.addEventListener('click', () => {
test(stringObj);
});
divElement.appendChild(innerDiv);
*/
const data = [
{ customId: 1, customParentId: null, customName: 'node1' },
{ customId: 2, customParentId: 1, customName: 'node2' },
{ customId: 3, customParentId: 1, customName: 'node3' },
];
chart = new d3.OrgChart()
.nodeId((dataItem) => dataItem.customId)
.parentNodeId((dataItem) => dataItem.customParentId)
.nodeWidth((node) => 100)
.nodeHeight((node) => 100)
.nodeContent((node) => {
const obj = {id: node.data.customId, name: node.data.customName};
const stringObj = JSON.stringify(obj);
return `<div customId="${node.data.customId}"
style="background-color:aqua;width:${node.width}px;height:${node.height}px"
>
<div onclick="test('${stringObj}')">klick</div>
${node.data.customName}
</div>`;
})
.container('.chart-container')
.data(data).render();
function test(data){
const dataObj = JSON.parse(data);
console.log(data);
}
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/d3-flextree.js"></script>
<div class="chart-container"></div>
Your primary issue is that the
nodeContentmethod can only return a string, which leads to the hacks you have in place. It would be nice if it could return an html element so that you could build it out programmatically. This feature (see here and here) has been requested but doesn't look implemented in the library.The second github issue I linked details a workaround by using the
nodeUpdatemethod. I've implemented it using your code below. Doesn't look too horrible.