? null : d.value + "人" ); return enter; }, function (update) { update .transition() .duration(500) .attr("transform", (d) => d === root ? `translate(0,-25)` : `translate(${x(d.x0)},${y(d.y0)})` ); update .select("rect") .attr("fill", function (d) { if (d == root) { return "#f0f0f0"; } else if (d.depth == 3) { return color2(d.data.name); } else if (d.depth == 4) { return color_mw(d.data.name); } else { while (d.depth > 1) { d = d.parent; } return color(d.data.name); } }) .transition() .duration(500) .attr("width", (d) => d === root ? width : x(d.x1) - x(d.x0) ) .attr("height", (d) => (d === root ? 25 : y(d.y1) - y(d.y0))); update .select(".classLogo") .transition() .duration(500) .attr("width", (d) => logoSize(d, root).size) .attr("height", (d) => logoSize(d, root).size) .attr( "transform", (d) => `translate(${logoSize(d, root).xOffset},${ logoSize(d, root).yOffset })` ); update .select(".className") .attr("text-anchor", (d) => (d === root ? null : "middle")) .attr("font-size", (d) => d.depth == 2 && type == "allMajors" ? "0.6em" : "0.8em" ) .text((d) => d === root ? d.data.name + data.year + "年毕业生分布" : labelText(d, type) ) .attr("fill", (d) => (d === root ? "#000" : "#fff")) .transition() .duration(500) .attr("x", (d) => (d === root ? 10 : x(d.x1) - x(d.x0)) / 2) .attr("y", (d) => (d === root ? 35 : y(d.y1) - y(d.y0)) / 2); update .select(".classValue") .text((d) => d === root || x(d.x1) - x(d.x0) < 20 || y(d.y1) - y(d.y0) < 30 ? null : d.value + "人" ) .attr("font-size", (d) => d.depth == 2 && type == "allMajors" ? "0.6em" : "0.8em" ) .transition() .duration(500) .attr("x", (d) => (d === root ? 10 : x(d.x1) - x(d.x0)) / 2) .attr( "y", (d) => (d === root ? 35 : y(d.y1) - y(d.y0)) / 2 + 15 ); return update; }, (remove) => remove.remove() ); } function labelText(d, type) { const nodeWidth = x(d.x1) - x(d.x0), nodeHeight = y(d.y1) - y(d.y0), k = type == "allMajors" ? 12 : 20; const maxLength = Math.floor(nodeWidth / k); if (nodeHeight > 20 && maxLength > 0) { return d.data.name.length > maxLength ? d.data.name.slice(0, maxLength) + "..." : d.data.name; } else { return null; } } function 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); } } function position(group, root) { group .selectAll("g") .attr("transform", (d) => d === root ? `translate(0,-25)` : `translate(${x(d.x0)},${y(d.y0)})` ) .select("rect") .attr("width", (d) => (d === root ? width : x(d.x1) - x(d.x0))) .attr("height", (d) => (d === root ? 25 : y(d.y1) - y(d.y0))); group .selectAll(".classLogo") .attr("width", (d) => logoSize(d, root).size) .attr("height", (d) => logoSize(d, root).size) .attr( "transform", (d) => `translate(${logoSize(d, root).xOffset},${ logoSize(d, root).yOffset })` ); group .selectAll(".className") .attr("x", (d) => (d === root ? 10 : x(d.x1) - x(d.x0)) / 2) .attr("y", (d) => (d === root ? 35 : y(d.y1) - y(d.y0)) / 2) .text(function (d) { if (d.depth === 0) { return d.data.name + data.year + "年毕业生分布"; } else { return d === root ? d .ancestors() .reverse() .map((d) => d.data.name) .join("≫") : labelText(d, null); } }); group .selectAll(".classValue") .attr("x", (d) => (d === root ? 10 : x(d.x1) - x(d.x0)) / 2) .attr("y", (d) => (d === root ? 35 : y(d.y1) - y(d.y0)) / 2 + 15) .text((d) => d === root || x(d.x1) - x(d.x0) < 20 || y(d.y1) - y(d.y0) < 30 ? null : d.value + "人" ); } function logoSize(d, root) { let size, xOffset, yOffset; if (d === root) { size = Math.min(x(d.x1) - x(d.x0), y(d.y1) - y(d.y0)) * 0.9; xOffset = (x(d.x1) + x(d.x0) - size) / 2; yOffset = (y(d.y1) + y(d.y0) - size) / 2 + 25; } else { size = Math.min(x(d.x1) - x(d.x0), y(d.y1) - y(d.y0)) * 0.9; xOffset = (x(d.x1) - x(d.x0) - size) / 2; yOffset = (y(d.y1) - y(d.y0) - size) / 2; } return { size: size, xOffset: xOffset, yOffset: yOffset, }; } function zoomin(d) { g_tooltip.attr("display", "none"); const group0 = group.attr("pointer-events", "none"); const group1 = (group = g.append("g").call(render, d, "clickMajors")); x.domain([d.x0, d.x1]); y.domain([d.y0, d.y1]); g.transition() .duration(500) .call((t) => group0.transition(t).call(position, d.parent).remove()) .call((t) => group1 .transition(t) .attrTween("opacity", () => d3.interpolate(0, 1)) .call(position, d) ); group1 .append("text") .attr("text-anchor", "end") .attr("font-size", "0.8em") .attr("x", width - 10) .attr("y", -7) .attr("pointer-events", "none") .text("点击返回上一层"); } function zoomout(d) { const group0 = group.attr("pointer-events", "none"); const group1 = (group = g .insert("g", "g") .call(render, d.parent, "clickMajors")); x.domain([d.parent.x0, d.parent.x1]); y.domain([d.parent.y0, d.parent.y1]); g.transition() .duration(500) .call((t) => group0 .transition(t) .attrTween("opacity", () => d3.interpolate(1, 0)) .call(position, d) .remove() ) .call((t) => group1.transition(t).call(position, d.parent)); if (d.depth > 1) { group1 .append("text") .attr("text-anchor", "end") .attr("font-size", "0.8em") .attr("x", width - 10) .attr("y", -7) .attr("pointer-events", "none") .text("点击返回上一层"); } } function mouseover() { g_tooltip.attr("display", null); } function mouseout() { g_tooltip.attr("display", "none"); } function mousemove(event, d) { const levelName = levelNameArray[ d3 .selectAll("#major_switchButton label.active input") .attr("class") ]; const mouse = d3.pointer(event, svg.node()); let selectedData, selectedLevel, tooltipX, tooltipY; if (d.depth == 1) { tooltipText .text(data.name) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "bold") .text(d.data.name) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text(d.data.ename) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "normal") .text( data.year + "年共毕业" + levelName + d.value + "人(" + d3.format(".2%")(d.value / d.parent.value) + ")" ) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text("点击查看下属专业毕业生详情"); } else if (d.depth == 2) { const type = d3 .select("#major_displayType label.active input") .attr("class"); tooltipText .text(d.parent.data.name) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "bold") .text(d.data.name + "专业") .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text(d.data.ename) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "normal") .text( data.year + "年共毕业" + levelName + d.value + "人(" + d3.format(".2%")( d.value / (type == "clickMajors" ? d.parent.value : d.parent.parent.value) ) + ")" ); if (type == "clickMajors") { tooltipText .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text("点击查看该专业毕业生详情"); } } else if (d.depth == 3) { tooltipText .text(d.parent.data.name + "专业") .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "bold") .text(d.data.name) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text(d.data.ename) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "normal") .text( data.year + "年共毕业" + levelName + d.value + "人(" + d3.format(".2%")(d.value / d.parent.value) + ")" ) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text("点击查看男女生比例"); } else if (d.depth == 4) { tooltipText .text(d.parent.parent.data.name + "专业") .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .text(d.parent.data.name) .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "bold") .text(d.data.name + " (" + d.data.ename + ")") .append("tspan") .attr("x", 0) .attr("dy", "1.3em") .attr("font-weight", "normal") .text( data.year + "年共毕业" + levelName + d.value + "人(" + d3.format(".2%")(d.value / d.parent.value) + ")" ); } const tooltipBox = tooltipText.node().getBBox(); tooltipRect .attr("x", tooltipBox.x - 10) .attr("y", tooltipBox.y - 5) .attr("width", tooltipBox.width + 20) .attr("height", tooltipBox.height + 10) .attr("fill", function (dd = d) { if (dd.depth == 3) { return d3.color(color2(dd.data.name)).darker(); } else if (dd.depth == 4) { return d3.color(color_mw(dd.data.name)).darker(); } else { while (dd.depth > 1) { dd = dd.parent; } return d3.color(color(dd.data.name)).darker(); } }); if (mouse[0] + tooltipBox.width + 20 > width) { tooltipX = mouse[0] - tooltipBox.width - 20; } else { tooltipX = mouse[0] + 25; } if (mouse[1] + tooltipBox.height + 20 > height) { tooltipY = mouse[1] - tooltipBox.height + 20; } else { tooltipY = mouse[1] + 30; } g_tooltip.attr("transform", `translate(${tooltipX},${tooltipY})`); } }; } catch (err) { console.log(err); } major_create(); // 大学毕业生人数统计 }, error:function(data){} });