繁体   English   中英

当 d3.js 中的单元格尺寸太小时删除文本

[英]Remove text when cell size is too small in d3.js

在 d3 树图中,当一个节点与其他节点相比具有非常大的值时,只会显示较大的节点,而其他节点将不可见或隐藏。 在某些情况下,一个小单元格将可见,但文本边距将被切断。 如何在单元格太小时删除文本或使其在 d3 treemap 中响应。 我的代码在链接https://codesandbox.io/s/d3-treemap-new-n8tix?file=/src/treegraph.js我的代码

import React from "react";
import * as d3 from "d3";

class Treegraph extends React.Component {
  state = {
    width: 400,
    height: 400
  };
  createTreeChart = () => {
    var width = 100, // % units for CSS responsiveness
      height = 100,
      snap = snap || 0.0001,
      x = d3
        .scaleLinear()
        .domain([0, width])
        .range([0, width]),
      y = d3
        .scaleLinear()
        .domain([0, height])
        .range([0, height]),
      //blue = d3.hsl(216, 0.92, 0.68),,
      tile = (node, x0, y0, x1, y1) => {
        d3.treemapBinary(node, 0, 0, width, height);
        for (const child of node.children) {
          child.x0 = x0 + (child.x0 / width) * (x1 - x0);
          child.x1 = x0 + (child.x1 / width) * (x1 - x0);
          child.y0 = y0 + (child.y0 / height) * (y1 - y0);
          child.y1 = y0 + (child.y1 / height) * (y1 - y0);
        }
      },
      treemap = d3
        .treemap()
        .size([width, height])
        .tile(tile)
        .paddingInner(0)
        .round(false),
      data = {
        name: "SEGMENTS",
        columnName: "A",
        children: [
          {
            name: "A1 - subsection of a",
            columnName: "A",
            value: 2100,
            children: [
              {
                name: "B1 - subsection of b",
                columnName: "B",
                value: 520,
                children: [
                  {
                    name: "C1  - subsection of C",
                    columnName: "C",
                    value: 85248197
                  }
                ]
              },
              {
                name: "B2 - subsection of b",
                columnName: "B",
                value: 500,
                children: [
                  {
                    name: "C1 - subsection of c",
                    columnName: "C",
                    value: 500
                  }
                ]
              }
            ]
          },
          {
            name: "A2 - subsection of a",
            columnName: "A",
            value: 2000,
            children: [
              {
                name: "B1 - subsection of a",
                columnName: "B",
                value: 1500,
                children: [
                  {
                    name: "C1 - subsection of a",
                    columnName: "C",
                    value: 1248197
                  }
                ]
              },
              {
                name: "B2 - subsection of a",
                columnName: "B",
                value: 500,
                children: [
                  {
                    name: "C1 - subsection of a",
                    columnName: "C",
                    value: 500
                  }
                ]
              }
            ]
          }
        ]
      },
      pathNames = [],
      nodes = d3
        .hierarchy(data)
        .sum(d => {
          return !d.children && d.value;
        })
        .sort((a, b) => !a.children && a.value - !b.children && b.value),
      resizeTimer,
      currentDepth;

    treemap(nodes);

    var chart = d3.select("#chart");
    var cells = chart
      .selectAll(".node")
      .data(nodes.descendants())
      .enter()
      .append("div")
      .attr("class", function(d) {
        // console.log("The d.depth function", d);
        return "node level-" + d.depth;
      })
      .attr("zndex", function(d) {
        // console.log("The d.depth function", d);
        return 110 - d.depth;
      })
      .attr("title", function(d) {
        return d.data.name ? `${d.data.name} (${d.data.value})` : "null";
      });

    cells
      //.style("transform", function(d) { return "translateY(" + chart.node().clientHeight * y(d.y0) / 100 + ")"; })
      .style("left", function(d) {
        //console.log( x(d.x0) + " => " + nearest(x(d.x0), snap) );
        return nearest(x(d.x0), snap) + "%";
      })
      .style("top", function(d) {
        // console.log(y(d.y0) + " => " + nearest(y(d.y0), snap));
        return nearest(y(d.y0), snap) + "%";
      })
      .style("width", function(d) {
        return nearest(x(d.x1) - x(d.x0), snap) + "%";
      })
      .style("height", function(d) {
        // console.log(
        //   y(d.y1) - y(d.y0) + " => " + nearest(y(d.y1) - y(d.y0), snap)
        // );
        return nearest(y(d.y1) - y(d.y0), snap) + "%";
      })
      .style("z-index", function(d) {
        // dynamic zindex for each node levels
        return d.data.name !== "SEGMENTS" && 110 - d.depth;
      })
      //.style("background-image", function(d) { return d.value ? imgUrl + d.value : ""; })
      .style("background-color", function(d) {
        return "orange";
      })
      .on("click", zoom);

    cells
      .append("p")
      .attr("class", "label")
      .text(function(d) {
        return d.data.name ? d.data.name : "null";
      })
      .attr("text-anchor", "middle");
    var parent = d3
      .select(".logo")
      .datum(nodes)
      .on("click", zoom);

    // can't resquarify as we use 100*100% treemap size. Doh!
    d3.select(window).on("resize", function() {
      clearTimeout(resizeTimer);
      resizeTimer = setTimeout(redraw, 250);
    });

    showPath(nodes.ancestors());

    function zoom(d) {
      // http://jsfiddle.net/ramnathv/amszcymq/

      // console.log("clicked: " + d.data.name + ", depth: " + d.depth);

      showPath(d.ancestors());

      currentDepth = d.depth;
      parent.datum(d.parent || nodes);

      x.domain([d.x0, d.x1]);
      y.domain([d.y0, d.y1]);

      var t = d3
        .transition()
        .duration(800)
        .ease(d3.easeCubicOut);

      cells
        .transition(t)
        .style("left", function(d) {
          return nearest(x(d.x0), snap) + "%";
        })
        .style("top", function(d) {
          return nearest(y(d.y0), snap) + "%";
        })
        .style("width", function(d) {
          return nearest(x(d.x1) - x(d.x0), snap) + "%";
        })
        .style("height", function(d) {
          return nearest(y(d.y1) - y(d.y0), snap) + "%";
        });

      cells // hide this depth and above
        .filter(function(d) {
          return d.ancestors();
        })
        .classed("hide", function(d) {
          return d.children ? true : false;
        });

      cells // show this depth + 1 and below
        .filter(function(d) {
          return d.depth > currentDepth;
        })
        .classed("hide", false);

      // if currentDepth == 3 show prev/next buttons
    }

    function redraw() {
      // console.log("window resized");

      treemap(nodes); //?
      //cells
      //    .datum(nodes)
      //    .call(zoom);
    }

    function showPath(p) {
      console.log("THE PATH", p);
      var path = d3
        .select(".breadcrumb")
        .selectAll("a")
        .data(
          p
            .map(function(d) {
              console.log("LOG the MAP FUNC", d);
              return d;
            })
            .reverse()
        );
      var path1 = d3
        .select(".breadcrumb")
        .selectAll("span")
        .data(
          p
            .map(function(d) {
              console.log("LOG the MAP FUNC", d);
              return d;
            })
            .reverse()
        );
      path.exit().remove();
      path1.exit().remove();

      console.log("THE PATHNAMES LOG", pathNames);
      path1
        .enter()
        .append("span")
        .attr("class", "activeNode")
        .html(function(d) {
          console.log("the d in second html", d);
          if (d.data.name !== "SEGMENTS" && d.data.children) {
            return ` <div> ${d.data.name} </div> <p class="right-symbol">></p>`;
          }
          if (!d.data.children) {
            return `<div > ${d.data.name} </div>`;
          }
        });
      path
        .enter()
        .append("a")
        .attr("href", "#")
        .html(function(d) {
          console.log("the d in html", d.data.columnName);
          return d.data.children && `${d.data.children[0].columnName} /`;
        })
        .on("click", zoom);
    }

    function nearest(x, n) {
      return n * Math.round(x / n);
    }
  };
  componentDidMount() {
    this.createTreeChart();
  }
  render() {
    return (
      <React.Fragment>
        <nav>
          {/* <div class="logo"></div> */}
          <div className="breadcrumb" />
        </nav>
        <div className="feature" id="chart" />
      </React.Fragment>
    );
  }
}

export default Treegraph;
const containerHeight = d3
   .select(".feature")
   .node()
   .getBoundingClientRect().height;

const containerWidth = d3
   .select(".feature")
   .node()
   .getBoundingClientRect().width;

const allLabels = d3.selectAll(".label").nodes();

d3.selectAll(".label").style("display", (d, idx) => {
   const { width, height } = allLabels[idx].getBoundingClientRect();

   const parentWidth = (d.x1 - d.x0) * containerWidth / 100.0;
   const parentHeight = (d.y1 - d.y0) * containerHeight / 100.0;

   if (width > parentWidth || height > parentHeight) return "none";
   return "";
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM