【d3】树图-各种效果集合(附效果图)

效果:

包含代码点:

1、动态请求数据并更新

参考链接:https://www.cnblogs.com/shihuc/p/6064448.html

let sideBar= {
    open(type, d) {
        // ...http请求...

        // 数据成功请求后,将数据push到d.children
        d.children.push(data);
        // 然后手动调用重新渲染svg函数
        _this.releSvgUpdate(d);
    }
};
nodeEnter.append("circle")
  .on("click", function (d) {
    // 收缩
    if (d.children) {  
      d._children = d.children;
      d.children = null;
      _this.releSvgUpdate(d);  // 重新渲染svg
    }
    // 展开
    else if (d._children) {  
      d.children = d._children;
      d._children = null;
      _this.releSvgUpdate(d); // 重新渲染svg
    }
    // 侧边框函数(打开侧边框、http请求数据等操作)
    else if (d.key == 'article') {
      sideBar.open('article', d);
    }
    // 侧边框函数(打开侧边框、详情信息展示)
    else if (d.list) {
      sideBar.open('list', d);
    };
  });

2、circle节点图片展示

nodeEnter.append("circle")
  .style("fill", function (d) {
    return `url(#bgImg-${d.id})`;
  })
nodeEnter.append("defs")
  .append("pattern")
  .attr("id", function (d) {
    return `bgImg-${d.id}`
  })
  .attr("height", "100%")
  .attr("width", "100%")
  .attr("patternContentUnits", "objectBoundingBox")
  .append("image")
  .attr("preserveAspectRatio", "none")
  .attr("height", "1")
  .attr("width", "1")
  .attr("xlink:href", function (d) {
    // 判断是+(展开logo)还是-(收缩logo)
    let href = "../../../static/images/search/";
    href += d.children ? "minus.svg" : "add.svg";
    return href;
  });

3、text文字自动换行

参考链接:https://www.jianshu.com/p/263fce04422c

nodeEnter.append("text")
  // .text属性必须赋值,后续的this.getComputedTextLength()才能获取到文字宽高
  .text(function (d) { return d.name; })
  .attr("x", function () {
    let width = this.getComputedTextLength();
    width = (width > 70) ? width + 10 : 80;
    width = (width < 130) ? width : 130;
    let x = width / 2;
    return -x;
  })
  // tspan标签实现换行
  .each(function (d) {
    var text = d3.select(this),
      words = d.name.split('').reverse(),
      word,
      line = [],
      lineNumber = 0,
      x = +text.attr('x'),
      tspan = text.text(null).append('tspan').attr('x', x);
    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(''));
       // 设置了最多显示两行,然后省略号
      if (lineNumber == 0 && tspan.node().getComputedTextLength() > 120) {
        line.pop();
        tspan.text(line.join('')).attr('y', -10);
        line = [word];
        ++lineNumber;
        tspan = text.append('tspan').attr('x', x).attr('y', 10).text(word);
      }
      else if (lineNumber == 1 && tspan.node().getComputedTextLength() > 100) {
        tspan.text(line.join('') + '...');
        words = [];
      };
    }
  });

4、rect标签自适应文字大小

参考链接:https://www.cnblogs.com/fastmover/p/7794519.html

// 在text前插入一个rect,并按照text的属性来设置长宽及坐标
nodeEnter.insert("rect", "text") 
    .datum(function () {
        // 大概计算宽高最大/小值,可实现文字垂直水平居中
        let d = this.nextSibling.getBBox();
        d.width = (d.width > 70) ? d.width + 10 : 80;
        d.width = (d.width < 130) ? d.width : 130;
        d.height = (d.height > 10) ? d.height + 20 : 30;
        d.x = -d.width - 1;
        d.y = -d.height / 2;
        return d;
    })
    .attr("width", function (d) { return d.width; })
    .attr("height", function (d) { return d.height; })
    .style('x', function (d) { return d.x; })
    .style('y', function (d) { return d.y; })

5、text、rect点击事件

d3图形是覆盖形式,故点击如下rect标签时,由于text标签在上方,故点击到text时不能触发rect点击事件(视觉上是点击了rect)

// text、rect加上同样的click事件
nodeEnter.append("text")
  .on("click", function (d) {
    // click函数
    click(d)
  })
nodeEnter.insert("rect", "text")
  .on("click", function () {
    // rect本无数据,故需要获取对应的text数据
    let d = this.nextSibling.__data__;
    // click函数
    click(d)
  });

还可参考此方法:D3.js鼠标悬停失败,并以重叠的对象

6、点击节点+ - logo不变化

// 手动删除该节点,使其重新渲染
d3.selectAll("g.node").each(function (d) {
    if (d.id == source.id) d3.select(this).remove();
});

7、连线 - 折线

//折线
let funLine = function (obj) {
  let s = obj.source,
    t = obj.target;
  return "M" + s.y + "," + s.x + "L" + (s.y + (t.y - s.y) / 4) + "," + s.x + "L" + (s.y + (t.y - s.y) / 4) + "," + t.x + "L" + t.y + "," + t.x;
};
// 增加新连接
link.enter().insert("path", "g")
  .attr("class", "link")
  .attr("d", function (d) {
    var o = { x: source.x0, y: source.y0 };
    return funLine({ source: o, target: o });
  });
// 原有连接更新位置
link.transition()
  .duration(_this.releSvg.duration)
  .attr("d", funLine);
// 折叠的链接,收缩到源节点处
link.exit().transition()
  .duration(_this.releSvg.duration)
  .attr("d", function (d) {
    var o = { x: source.x, y: source.y };
    return funLine({ source: o, target: o });
  })
  .remove();

8、样式设置

g.link {
   fill: none;  // 折线无填充(必须)
}
text {
    text-anchor: middle; // 水平居中
    dominant-baseline: central; // 垂直居中
}
rect {
    stroke-dasharray: 2px; // 虚线
    stroke-width: 1.5px; // 线粗
    stroke: #419AFF; // 线颜色
}
circle {
    r: 8; // 圆半径
}

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值