[英]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.