d3.v4.js数据可视化 力导向图 force 产业链

PC和APP(手机网页版均可)静态图(我录好的视频不能上传)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
d3.v4 中文API文档地址https://github.com/xswei/d3js_doc/blob/master/API_Reference/API.md
d3.js 力导向图中默认提供了 5 种作用力:

中心力(Centering)
中心力作用于所有的节点而不是某些单独节点,可以将所有的节点的中心一致的向指定的位置移动,而且这种移动不会修改速度也不会影响节点间的相对位置。
碰撞力(Collision)
碰撞力将每个节点视为一个具有一定半径的圆,这个力会阻止代表节点的这个圆相互重叠,即两个节点间会相互碰撞,可以通过设置 strength 设置这个碰撞力的强度。
弹簧力(Links)
当两个节点通过设置 link 连接到一起后,可以设置弹簧力,这个力将根据两个节点间的距离将两个节点拉近或推远,力的强度和这个距离成比例就和弹簧一样。
电荷力(Many-Body)
通过设置 strength 来模拟所有节点间的相互作用力,如果为正节点间就会相互吸引,可以用来模拟电荷吸引力,如果为负节点间就会相互排斥。这个力的大小也和节点间的距离有关。
定位力(Positioning)
这个力可以将节点沿着指定的维度推向一个指定位置,比如通过设置 forceX 和 forceY 就可以在 X轴 和 Y轴 方向推或者拉所有的节点,forceRadial 则可以形成一个圆环把所有的节点都往这个圆环上相应的位置推。

部分代码

var simulation = d3.forceSimulation()
            .alpha(1.5)
            .alphaMin(0.001)
            .alphaDecay(0.0228)
            .alphaTarget(0)
            .force("link", d3.forceLink()
                .links(links)
                .id(function (d) {
                    return d.index;
                })
            )
            .force("charge", d3.forceManyBody().strength(stren))
            .force("collide", d3.forceCollide(function (d) {
                var v = 0
                if (grade(d.type) === 1) {
                    v = bigW - 60
                } else if (d.is_back === 0 || d.is_back === 1) {
                    v = 20
                } else if (grade(d.type) === 2) {
                    v = cv + 20
                } else if (grade(d.type) === 3) {
                    v = cv
                }
                return v
            })
                .strength(0.2)
                .iterations(5))
            .nodes(nodes)
            .on('tick', tick)
        if (!isPc) {
            simulation.force("center", d3.forceCenter(width / divW, height / divH))
        }
        var zooms = d3.zoom()
            .scaleExtent([0.5, 1.5])
            .on("zoom", zoomed);
        function zoomed () {
            svg.selectAll(".svg_g").attr("transform",d3.event.transform)
            if (!isforbid) {
                var x = d3.event.transform.x
                var y = d3.event.transform.y
                var s = d3.event.transform.k
                if (s === scaled ) {
                    if (x - sumX > 10) {
                        animation(img_name_l, 1.3)
                        animation(img_name_r, 1)
                    } else if (x - sumX < -10) {
                        animation(img_name_r, 1.3)
                        animation(img_name_l, 1)
                    } else if (y - sumY > 10 && Math.abs(x - sumX) < 10) {
                        animation(img_name_t, 1.3)
                        animation(img_name_b, 1)
                    } else if (y - sumY < -10 && Math.abs(x - sumX) < 10) {
                        animation(img_name_b, 1.3)
                        animation(img_name_t, 1)
                    }
                }
                scaled = s
                sumX = x
                sumY = y
            }
        }
        function animation (className, sl) {
            var u = navigator.userAgent
            var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
            if (isiOS) {
                if ($('.' + className).length > 0) {
                    $('.' + className).animate({'transform': 'scale(' + sl + ')', 'transform-origin': 'center center'},250)
                }
            } else {
                d3.selectAll('.' + className)
                    .transition().duration(250)
                    .attr('transform', 'scale(' + sl + ')')
                    .attr('transform-origin', 'center center')
            }
        }
        var drags = d3.drag()
            .on('start', function (d) {
                d3.event.sourceEvent.stopPropagation()
                if (!d3.event.active) simulation.alphaTarget(0.3).restart()
                d.fx = d.x
                d.fy = d.y
            })
            .on('drag', function (d) {
                d.fx = d3.event.x
                d.fy = d3.event.y
                var tag = d3.event.sourceEvent.srcElement.tagName
                if (tag != 'image' && tag != 'text' && tag != 'tspan' && tag != 'g' && tag != 'svg') {
                    simulation.alphaTarget(0);
                    d.fx = null
                    d.fy = null
                    return false
                }
            })
            .on('end', function (d) {
                if (!d3.event.active) simulation.alphaTarget(0)
                d.fx = null
                d.fy = null
            })

设置fx和fy可以固定位置

手机网页版兼容很麻烦
监听横竖屏事件

window.addEventListener(evt, function() {
                            if (vm.isiOS && (Math.abs(window.orientation) === 90)) {
                                // 横屏
                                setTimeout(function () {
                                    vm.widths = $(document).width()
                                    vm.heights = $(document).height()
                                 }, 250)
                            } else if (vm.isiOS && (Math.abs(window.orientation) === 0)) {
                                // 竖屏
                                setTimeout(function () {
                                    vm.widths = $(document).width()
                                    vm.heights = $(document).height()
                                }, 250)
                            }
                        })

横竖屏切换时,获取的width和height还是切换前的宽高,所以加了一个定时器

时间有限我先粗略的写吧,扣扣交流1979751899

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值