block by curran ad6d4eaa6cf39bf58769697307ec5f3a

Demo of d3-boxes

Full Screen

An example of d3-boxes in action. Responds to resize.

forked from curran‘s block: Responding to Resize

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Dynamic Size Example</title>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://unpkg.com/d3-boxes@0.0.2/build/d3-boxes.js"></script>
    <style>

      /* Make the chart container fill the page using CSS. */
      #chart {
        position: fixed;
        left: 0px;
        right: 0px;
        top: 0px;
        bottom: 0px;
      }
    </style>
  </head>
  <body>

    <div id="chart"></div>

    <script>

      var chartDiv = document.getElementById("chart");
      var svg = d3.select(chartDiv).append("svg");
      var color = d3.scaleOrdinal().range(d3.schemeCategory10);
      
      function drawBox(name, box){
        const x = box.x;
        const y = box.y;
        const width = box.width;
        const height = box.height;
        
        // Setup a group for this box.
        var g = svg.selectAll('.' + name).data([null]);
        var gEnter = g.enter().append('g').attr('class', name);
        gEnter.merge(g)
            .attr('transform', 'translate(' + x + ',' + y + ')');
        
        // Draw a box.
        gEnter
          .append('rect')
            .attr('fill', color(name))
            .attr('stroke', 'white')
          .merge(g.select('rect'))
            .attr('width', width)
            .attr('height', height);
        
        // Draw an X to show the size of the box.
        var lines = gEnter.merge(g).selectAll("line").data([
          {x1: 0, y1: 0, x2: width, y2: height},
          {x1: 0, y1: height, x2: width, y2: 0}
        ]);
        lines
          .enter().append("line")
            .style("stroke-width", 5)
            .style("stroke-opacity", 0.4)
            .style("stroke", "black")
          .merge(lines)
            .attr("x1", function (d) { return d.x1; })
            .attr("y1", function (d) { return d.y1; })
            .attr("x2", function (d) { return d.x2; })
            .attr("y2", function (d) { return d.y2; })
        ;
        
        // Add a text label.
        var text = gEnter
          .append('text')
            .style('font-size', '5em')
            .style('font-family', 'sans-serif')
            .style('text-anchor', 'middle')
            .style('alignment-baseline', 'middle')
            .attr('fill', 'white')
          .merge(g.select('text'))
            .attr('x', width / 2)
            .attr('y', height / 2)
            .text(name);
      }

      function redraw(){

        // Extract the width and height that was computed by CSS.
        var width = chartDiv.clientWidth;
        var height = chartDiv.clientHeight;

        // Use the extracted size to set the size of an SVG element.
        svg
          .attr("width", width)
          .attr("height", height);
        
        var layout = {
          orientation: "vertical",
          children: [
            "A",
            {
              orientation: "horizontal",
              children: [
                "B",
                "C"
              ],
              size: 2 // Make this layer have a size weight of 2 (default is 1)
            },
            "D"
          ]
        };
        
        var sizes = {
          A: {
            size: 2 // Make the "A" box have a size weight of 2 (default is 1)
          }
        };
        
        var box = {
          width: width,
          height: height
        };
        
        var boxes = d3.boxes(layout, sizes, box);
        
        // Have a look in the console!
        console.log(boxes);
        
        Object.keys(boxes).forEach(function (name) {
          drawBox(name, boxes[name]);
        });
      }

      // Draw for the first time to initialize.
      redraw();

      // Redraw based on the new size whenever the browser window is resized.
      window.addEventListener("resize", redraw);

    </script>
  </body>
</html>