| | |
| | | nodeWidth: |
| | | { |
| | | type: Number, |
| | | default: 160 |
| | | default: 180 |
| | | }, |
| | | nodeHeight: |
| | | { |
| | | type: Number, |
| | | default: 40 |
| | | default: 80 |
| | | }, |
| | | active: |
| | | { |
| | |
| | | disabled: true, |
| | | "children": |
| | | [ |
| | | {"label": "杭州"}, |
| | | {"label": "宁波"}, |
| | | {"label": "温州"}, |
| | | {"label": "绍兴"} |
| | | {"label1": "杭州"}, |
| | | {"label1": "宁波"}, |
| | | {"label1": "温州"}, |
| | | {"label1": "绍兴"} |
| | | ] |
| | | }, |
| | | { |
| | |
| | | let leafNum = leafList.length |
| | | let TreeDeep = getDepth(data) |
| | | // 左右内边距 |
| | | let mapPaddingLR = 10 |
| | | let mapPaddingLR = 30 |
| | | // 上下内边距 |
| | | let mapPaddingTB =10 |
| | | let mapPaddingTB =30 |
| | | let mapWidth = this.nodeWidth * TreeDeep + mapPaddingLR * 2; |
| | | let mapHeight = (this.nodeHeight - 4) * leafNum + mapPaddingTB * 2; |
| | | let mapHeight = (this.nodeHeight - 4) * leafNum + mapPaddingTB * 3.5; |
| | | // 定义画布—— 外边距 10px |
| | | let svgMap = d3.select('#' + this.id).append('svg').attr("width", mapWidth).attr("height", mapHeight).style("margin", "0px") |
| | | // 定义树状图画布 |
| | |
| | | // 样式一:节点间等间距 |
| | | // return (a.parent == b.parent ? 1: 2) / a.depth; |
| | | // 样式二:根据节点子节点的数量,动态调整节点间的间距 |
| | | let rate = (a.parent == b.parent ? (b.children ? b.children.length / 2 : 1) : 2) / a.depth |
| | | // 间距比例不能小于0.7,避免间距太小而重叠 |
| | | let rate = (a.parent == b.parent ? (b.children ? b.children.length / 2 : 1) : 2) / a.depth; |
| | | // 间距比例不能小于0.7,避免间距太小而重叠 |
| | | if (rate < 0.7) { |
| | | rate = 0.7 |
| | | } |
| | | return rate; |
| | | return rate * 1.1; |
| | | })( |
| | | // 创建层级布局,对源数据进行数据转换 |
| | | d3.hierarchy(data).sum(function (node) { |
| | |
| | | }) |
| | | ) |
| | | // 贝塞尔曲线生成器 |
| | | let Bézier_curve_generator = d3.linkHorizontal() |
| | | .x(function (d) { |
| | | return d.y; |
| | | }) |
| | | .y(function (d) { |
| | | return d.x; |
| | | }); |
| | | // let Bézier_curve_generator = d3.linkHorizontal() |
| | | // .x(function (d) { |
| | | // return d.y; |
| | | // }) |
| | | // .y(function (d) { |
| | | // return d.x; |
| | | // }); |
| | | let lineGenerator = d3.line() |
| | | .x(function(d) { return d.y; }) |
| | | .y(function(d) { return d.x; }) |
| | | .curve(d3.curveStep); |
| | | //绘制边 |
| | | treeMap.selectAll("path") |
| | | // 节点的关系 links |
| | |
| | | x: d.source.x, |
| | | // 连线起点的x坐标 |
| | | // 第1个10为与红圆圈的间距,第2个10为link内文字与边框的间距,第3个10为标签文字与连线起点的间距 |
| | | y: d.source.y + 10 + (d.source.data.link ? (getPXwidth(d.source.data.link) + 10) : 0) + getPXwidth(d.source.data.label) + 10 |
| | | y: d.source.y + 10 + (d.source.data.link ? (getPXwidth(d.source.data.link) + 25) : 0) + getPXwidth(d.source.data.label) + 25 |
| | | }; |
| | | var end = {x: d.target.x, y: d.target.y}; |
| | | return Bézier_curve_generator({source: start, target: end}); |
| | | return lineGenerator([start, end]); |
| | | }) |
| | | .attr("fill", "none") |
| | | .attr("stroke", "#c3c3c3") |
| | | .attr("stroke", "#EBA4AA") |
| | | // 虚线 |
| | | // .attr("stroke-dasharray", "8") |
| | | .attr("stroke-width", 1); |
| | |
| | | .attr("r", 4) |
| | | .attr("fill", function (d) { |
| | | if (d.data.childrenTemp) { |
| | | return 'red' |
| | | return '#EBA4AA' |
| | | } else { |
| | | return 'white' |
| | | } |
| | | }) |
| | | .attr("stroke", "red") |
| | | .attr("stroke-width", 1); |
| | | .attr("stroke", "#EBA4AA") |
| | | .attr("stroke-width", 2); |
| | | // 添加头像 |
| | | groups.append("image") |
| | | .attr("xlink:href", function (d) { |
| | | return d.data.url; // 头像图片的路径 |
| | | }) |
| | | .attr("x", 12) // 头像相对于节点的水平位置 |
| | | .attr("y", -28) // 头像相对于节点的垂直位置 |
| | | .attr("width", 24) // 头像的宽度 |
| | | .attr("height", 24); // 头像的高度 |
| | | //绘制标注(节点前的矩形) |
| | | groups.append("rect") |
| | | .attr("x", 8) |
| | | .attr("y", -10) |
| | | .attr("x", 37) |
| | | .attr("y", -28) |
| | | .attr("width", |
| | | function (d) { |
| | | return d.data.link ? (getPXwidth(d.data.link) + 10) : 0 |
| | | return d.data.link ? (getPXwidth(d.data.link) + 30) : 0 |
| | | } |
| | | ) |
| | | .attr("height", 22) |
| | | .attr("fill", "grey") |
| | | .attr("height", 26) |
| | | .attr("fill", "#FFFFFF") |
| | | // 添加圆角 |
| | | .attr("rx", 4) |
| | | //绘制链接方式 |
| | | groups.append("text") |
| | | .attr("x", 12) |
| | | .attr("y", -5) |
| | | .attr("x", 42) |
| | | .attr("y", -22) |
| | | .attr("dy", 10) |
| | | .attr("fill", 'white') |
| | | .attr("font-size", 12) |
| | | .attr("fill", '#F6739F') |
| | | .attr("font-size", 16) |
| | | .text(function (d) { |
| | | return d.data.link; |
| | | return d.depth+1 + ' ' +d.data.link; |
| | | }) |
| | | .on("click",function (event, node) { |
| | | let data = node.data |
| | |
| | | return 'pointer' |
| | | } |
| | | }) |
| | | //绘制文字 |
| | | // 添加头像 |
| | | groups.append("image") |
| | | .attr("xlink:href", function (d) { |
| | | return d.data.url; // 头像图片的路径 |
| | | }) |
| | | .attr("x", 12) // 头像相对于节点的水平位置 |
| | | .attr("y", 3) // 头像相对于节点的垂直位置 |
| | | .attr("width", 24) // 头像的宽度 |
| | | .attr("height", 24); // 头像的高度 |
| | | //绘制标注(节点前的矩形) |
| | | groups.append("rect") |
| | | .attr("x", 37) |
| | | .attr("y", 3) |
| | | .attr("width", |
| | | function (d) { |
| | | return d.data.link ? (getPXwidth(d.data.link) + 30) : 0 |
| | | } |
| | | ) |
| | | .attr("height", 26) |
| | | .attr("fill", "#FFFFFF") |
| | | // 添加圆角 |
| | | .attr("rx", 4) |
| | | //绘制文字 |
| | | groups.append("text") |
| | | .on("click", function (event, node) { |
| | | let data = node.data |
| | |
| | | } |
| | | }) |
| | | .attr("x", function (d) { |
| | | return 12 + (d.data.link ? (getPXwidth(d.data.link) + 10) : 0) |
| | | return 5+ (d.data.link ? (getPXwidth(d.data.link) + 15) : 0); |
| | | }) |
| | | .attr("fill", |
| | | function (d) { |
| | | if (d.data.prop === that.active) { |
| | | return '#409EFF' |
| | | }else{ |
| | | return '#8296C5' |
| | | } |
| | | } |
| | | ) |
| | |
| | | return 'bold' |
| | | } |
| | | }) |
| | | .attr("font-size", 14) |
| | | .attr("font-size", 16) |
| | | .attr("cursor", |
| | | function (d) { |
| | | if (d.data.disabled) { |
| | |
| | | return 'pointer' |
| | | } |
| | | }) |
| | | .attr("y", -5) |
| | | .attr("y", 10) |
| | | .attr("dy", 10) |
| | | .attr("slot", function (d) { |
| | | return d.data.prop; |
| | | }) |
| | | .text(function (d) { |
| | | return d.data.label; |
| | | return ' ' + d.data.label; |
| | | }) |
| | | }, |
| | | }, |