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