Zoomable Icicle Javascript Example

Why don’t this show anything on the screen and there is no error?

<!DOCTYPE html>
<html>

<head>
  <title>Zoomable Icicle</title>
</head>

<body>Velcome
  <h1 class="thechart"></h1>
  <script src="https://d3js.org/d3.v6.min.js"></script>
  <script>
    JsonData = {
      "name": "flare",
      "children": [
        {
          "name": "analytics",
          "children": [
            {
              "name": "cluster",
              "children": [
                {
                  "name": "AgglomerativeCluster",
                  "value": 3938
                },
                {
                  "name": "CommunityStructure",
                  "value": 3812
                },
                {
                  "name": "HierarchicalCluster",
                  "value": 6714
                },
                {
                  "name": "MergeEdge",
                  "value": 743
                }
              ]
            },
            {
              "name": "Visualization",
              "value": 16540
            }
          ]
        }
      ]
    }
    height = 1200;
    width = 975;
    format = d3.format(",d");
    color = d3.scaleOrdinal(d3.quantize(d3.interpolateRainbow, JsonData.children.length + 1));
    partition = data => {
      const root = d3.hierarchy(data)
        .sum(d => d.value)
        .sort((a, b) => b.height - a.height || b.value - a.value);
      return d3.partition()
        .size([height, (root.height + 1) * width / 3])
        (root);
    }
    function chart(data) {
      const root = partition(data);
      let focus = root;

      const svg = d3.create("svg")
        .attr("viewBox", [0, 0, width, height])
        .style("font", "10px sans-serif");

      const cell = svg
        .selectAll("g")
        .data(root.descendants())
        .join("g")
        .attr("transform", d => `translate(${d.y0},${d.x0})`);

      const rect = cell.append("rect")
        .attr("width", d => d.y1 - d.y0 - 1)
        .attr("height", d => rectHeight(d))
        .attr("fill-opacity", 0.6)
        .attr("fill", d => {
          if (!d.depth) return "#ccc";
          while (d.depth > 1) d = d.parent;
          return color(d.data.name);
        })
        .style("cursor", "pointer")
        .on("click", clicked);

      const text = cell.append("text")
        .style("user-select", "none")
        .attr("pointer-events", "none")
        .attr("x", 4)
        .attr("y", 13)
        .attr("fill-opacity", d => +labelVisible(d));

      text.append("tspan")
        .text(d => d.data.name);

      const tspan = text.append("tspan")
        .attr("fill-opacity", d => labelVisible(d) * 0.7)
        .text(d => ` ${format(d.value)}`);

      cell.append("title")
        .text(d => `${d.ancestors().map(d => d.data.name).reverse().join("/")}\n${format(d.value)}`);

      function clicked(event, p) {
        focus = focus === p ? p = p.parent : p;

        root.each(d => d.target = {
          x0: (d.x0 - p.x0) / (p.x1 - p.x0) * height,
          x1: (d.x1 - p.x0) / (p.x1 - p.x0) * height,
          y0: d.y0 - p.y0,
          y1: d.y1 - p.y0
        });

        const t = cell.transition().duration(750)
          .attr("transform", d => `translate(${d.target.y0},${d.target.x0})`);

        rect.transition(t).attr("height", d => rectHeight(d.target));
        text.transition(t).attr("fill-opacity", d => +labelVisible(d.target));
        tspan.transition(t).attr("fill-opacity", d => labelVisible(d.target) * 0.7);
      }

      function rectHeight(d) {
        return d.x1 - d.x0 - Math.min(1, (d.x1 - d.x0) / 2);
      }

      function labelVisible(d) {
        return d.y1 <= width && d.y0 >= 0 && d.x1 - d.x0 > 16;
      }

      return svg.node();
    }

    chart(JsonData);
    console.log("OK");

  </script>
</body>

</html>

The line chart(JsonData) calls the function chart, which returns an SVG. However, you aren’t displaying that SVG anywhere, so it simply evaporates into nothing.

You need to add that SVG element to the page. For example, you could say

let svg = chart(JsonData);
document.body.appendChild(svg);
1 Like

Thanks a lot. That I have looking for in a long time.