d3.js - 从 hive 样式图转换为并行绘制轴
问题描述
长话短说。我需要显示目标源项目的图表,我发现 d3.js 可以完成这项工作。我已经花了很多时间从那里得到一些东西,我完成了使用这样的 Hive Plot:
https ://bost.ocks.org/mike/hive/
但问题是我将只有一对项目,我想显示节点并与它们相对应的项目不是以循环方式而是更传统的并行方式(如下图所示,左边是实际结果,右边是所需的) [
我尝试了很多东西,但不幸的是我迷路了。我也尝试让 jsfiddle 启动并运行,但由于未知原因,我没有显示任何内容。这是jsfiddle:
https://jsfiddle.net/a7yrjfgc/2/
代码:
var width = 200,
height = 200,
innerRadius = 10,
outerRadius = 100,
majorAngle = 1 * Math.PI / 1,
minorAngle = 1 * Math.PI / 2;
var angle = d3.scaleOrdinal()
.domain(["source", "source-target", "target-source", "target"])
.range([0, majorAngle - minorAngle, majorAngle + minorAngle, 2 * majorAngle]);
radius = d3.scaleLinear()
.range([innerRadius, outerRadius]),
color = d3.scaleOrdinal(d3.schemeCategory10),
formatNumber = d3.format(",d");
var nodes = [
{x: 0, y: .4, name: "node1", color: "#0000FF"},
{x: 0, y: .2, name: "node2", color: "#FFA500"},
{x: 1, y: .2, name: "node3", color: "#008000"},
{x: 1, y: .3, name: "node4", color: "#A52A2A"},
];
var links = [
{source: nodes[0], target: nodes[2]},
{source: nodes[1], target: nodes[3]},
];
var info = d3.select("#info")
.text(defaultInfo = "Showing " + formatNumber(links.length) + " splices " + formatNumber(nodes.length) + " strands.");
console.log(info);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + height/2 + ")");
svg.selectAll(".axis")
.data(d3.range(2))
.enter().append("line")
.attr("class", "axis")
.attr("transform", function(d) { return "rotate(" + degrees(angle(d)) + ")" })
.attr("x1", radius.range()[0])
.attr("x2", radius.range()[1]);
// draw links
svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", link()
.angle(function(d) { return angle(d.x); })
.radius(function(d) { return radius(d.y); }))
.style("stroke", function(d) { return color(d.color); })
.on("mouseover", linkMouseover)
.on("mouseout", mouseout);
// draw nodes
svg.selectAll(".node")
.data(nodes)
.enter().append("circle")
.attr("class", "node")
.attr("transform", function(d) { return "rotate(" + degrees(angle(d.x)) + ")"; })
.attr("cx", function(d) { return radius(d.y); })
.attr("r", 5)
.style("fill", function(d) { return d3.color(d.color); })
.on("mouseover", nodeMouseover)
.on("mouseout", mouseout);
非常非常感谢您在这个话题上的帮助。
解决方案
当我更多地了解 d3 的工作原理时,我意识到我需要简单地从头开始绘制所有内容。
function DisplayGraph(){
//D3 Configuration
var width = 400,
height = 50,
color = d3.scaleOrdinal(d3.schemeCategory10),
formatNumber = d3.format(",d"),
defaultInfo ="";
var nodes = [
{x: 0, y: 0, name: "node1", color: "#0000FF"},
{x: 0, y: 15, name: "node2", color: "#FFA500"},
{x: 100, y: 15, name: "node3", color: "#008000"},
{x: 100, y: 0, name: "node4", color: "#A52A2A"},
];
var links = [
{source: nodes[0], target: nodes[2]},
{source: nodes[1], target: nodes[3]},
];
var info = d3.select("#info")
.text(defaultInfo = "Showing " + formatNumber(links.length) + " splices " + formatNumber(nodes.length) + " strands.");
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/2 + "," + height/2 + ")");
var diagonal = function link(d) {
let sourceX = (d.source.x + 50);
let sourceY = (d.source.y + 5);
let targetX = (d.target.x);
let targetY = (d.target.y + 5);
var output = "M" + sourceX + "," + sourceY
+ "C" + (sourceX + targetX) / 2 + "," + sourceY
+ " " + (sourceX + targetX) / 2 + "," + targetY
+ " " + targetX + "," + targetY;
return output;
};
//draw squares
svg.selectAll(".node")
.data(nodes)
.enter().append("rect")
.attr("class", "node")
.attr("width", 50)
.attr("height", 10)
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.style("fill", function(d) { return d3.color(d.color); })
.on("mouseover", nodeMouseover)
.on("mouseout", mouseout);
// draw links
svg.selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", diagonal)
.style("stroke", function(d) { return color(d.color); })
.on("mouseover", linkMouseover)
.on("mouseout", mouseout);
//Helpers
function linkMouseover(d) {
svg.selectAll(".link")
.classed("turnedOn", function(dl) {
return dl === d;
})
.classed("turnedOff", function(dl) {
return !(dl === d);
})
svg.selectAll(".node")
.classed("turnedOn", function(dl) {
return dl === d.source || dl === d.target;
})
info.text(d.source.name + " → " + d.target.name);
}
// Highlight the node and connected links on mouseover.
function nodeMouseover(d) {
svg.selectAll(".node")
.classed("turnedOn", function(dl) {
return dl.source === d || dl.target === d;
})
.classed("turnedOff", function(dl) {
return !(dl.source === d || dl.target === d)
});
d3.select(this)
.classed("turnedOn", true);
info.text(d.name);
}
// Clear any highlighted nodes or links.
function mouseout() {
svg.selectAll(".turnedOn").classed("turnedOn", false);
svg.selectAll(".turnedOff").classed("turnedOff", false);
info.text("Hover to node or link");
}
}
推荐阅读
- javascript - 如何从渲染方法之外的反应导航中获取导航参数?
- python - 为什么添加两个具有 timedelta 值的计数器会引发 TypeError?
- dart - 在 Flutter 应用程序中的 ListView 滚动上隐藏/关闭键盘
- linux - 即使安装后也没有名为 numpy 的模块
- python - 从列表列表中删除所有匹配值
- python - 无法通过 selenium 驱动程序单击 javascript 元素
- android-studio - 升级后无法在android studio上打开flutter项目
- node.js - Twilio 功能:收到来电时发送 WhatsApp 消息
- templates - Vue JS 内联模板中的表单字符集错误
- ng-zorro-antd - 如何使用 nz-tabset 实现离开前的保存?