首页 > 解决方案 > 从 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.js

解决方案


当我更多地了解 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");
  }
}

推荐阅读