score:1

the data object you use can be anything. the most appropriate pattern is to prepare it before you attach it to the elements selection, and in such a way that you have everything you need already on hand.

the following example defines a data structure mapping from types to the data that differ per category. this is only an example, the core is what happens in the .map() function: you add one or more properties to your data object so that you have the connection between node.type and the way you need to write your pattern just right for every node.

a similar way to connect from ids to the asset folder images will be needed.

it is a bit strange that you define a pattern for each node, but only draw a circle if node.depth !== 0 but that is for you to understand, use the filter function only to identify the non-toplevel entries that need a circle rendered.

const details = new map([
    [engagementtype.product, { path: 'products', prefix: 'insightimage'} ],
    [engagementtype.community, { path: 'comunities', prefix: 'insightimagecom'} ],
    // and so on...
]);

// enhance your data, each node is a shallow copy with extra properties
const renderingdata = this.nodes.map(node => object.assign({
    patternid: `${details.get(node.type).prefix}-${d.id}`,
    imageurl: `https://tiktok.org/${details.get(node.type).path}/${d.id}/standard`,
    isleaf: node.depth === 4 && !node.isextranode
}, node));

const circle = d3.selectall('circle.node')
    .data(renderingdata)
    .enter();

// now it is straight forward
circle
    .append("pattern")
    .attr("id", d => node.patternid)
    .attr("patterncontentunits", "objectboundingbox")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("x", 0)
    .attr("y", 0);
    .append("image")
    .attr("xlink:href", d => d.imageurl)
    .attr("x", 0)
    .attr("y", 0)
    .attr("width", 1)
    .attr("height", 1)
    .attr('preserveaspectratio', 'xmidymid slice')
  // and now you filter for non-toplevel nodes
  .filter(node => node.depth !== 0)
    .append('circle')
    .classed('engagement-graphnode', true)
    .classed('engagement-graphnodebackground', true)
    .classed('engagement-graphleaf', node => node.isleaf)
    .style('fill', d => `url(#${d.patternid})`)
    .style('opacity', node => (node.visible) ? 1 : 0)
    .style('visibility', node => (node.visible) ? 'visible' : 'hidden')
    .on('click', node => onclick(node));

Related Query