Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 具有异常数据点的蜂巢图_Javascript_D3.js - Fatal编程技术网

Javascript 具有异常数据点的蜂巢图

Javascript 具有异常数据点的蜂巢图,javascript,d3.js,Javascript,D3.js,下面的json数据短数组就是这个问题所基于的数据集。请注意,pink仅显示在imports数组中,而不是“name”键的值。由于这个事实,我得到了这个错误 Uncaught TypeError: Cannot read property 'target' of undefined 当试图根据d3的创建者创建蜂巢图时 var dataset = [ {"name":"red","imports":["blue, green"]}, {"name":"blue","imports":["yello

下面的json数据短数组就是这个问题所基于的数据集。请注意,
pink
仅显示在imports数组中,而不是“name”键的值。由于这个事实,我得到了这个错误

Uncaught TypeError: Cannot read property 'target' of undefined
当试图根据d3的创建者创建蜂巢图时

var dataset = [
{"name":"red","imports":["blue, green"]},
{"name":"blue","imports":["yellow"]},
{"name":"green","imports":["blue", "pink"]},
{"name":"yellow","imports":["red"]}
];
问:有没有一种方法可以创建一个具有上述异常数据点的蜂巢图,或者,如果没有,可以使用另一种类型的图

jsfiddle:

代码

var-width=960,
高度=850,
内半径=40,
外层=640,
majorAngle=2*Math.PI/3,
minorAngle=1*Math.PI/12;
变量角度=d3.scale.ordinal()
.domain([“源”、“源目标”、“目标源”、“目标”])
.range([0,majorAngle-minorAngle,majorAngle+minorAngle,2*majorAngle]);
变量半径=d3.scale.linear()
.范围([内半径,外半径]);
var color=d3.scale.category10();
var svg=d3.选择(“图表”).追加(“svg”)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.附加(“g”)
.attr(“转换”、“转换”(+outerRadius*.20+)、“+outerRadius*.57+”);
//加载数据并显示绘图!
d3.json(“./fl.json”),函数(节点){
//d3.json(“./flare imports.json”),函数(节点){
日志(节点,“节点”);
var nodesByName={},
链接=[],
formatNumber=d3.格式(“,d”),
defaultInfo;
//按节点名构造索引。
nodes.forEach(函数(d){
d、 连接器=[];
d、 packageName=d.name.split(“.”[1];
nodesByName[d.name]=d;
//log(d,nodesByName,“在nodes.forEach第72行中,生成连接器和packageName”);
});
//将导入列表转换为具有源和目标的链接。
nodes.forEach(函数(源){
//日志(源,“源?”);
source.imports.forEach(函数(targetName){
var target=nodesByName[targetName];
//log(target,nodesByName,targetName,“寻找目标”);
if(!source.source)source.connectors.push(source.source={node:source,degree:0});
if(!target.target)target.connectors.push(target.target={node:target,degree:0});
push({source:source.source,target:target.target});
});
});
//根据传入和传出链接确定每个节点的类型。
forEach(函数(节点){
if(node.source&&node.target){
node.type=node.source.type=“目标源”;
node.target.type=“源目标”;
}else if(node.source){
node.type=node.source.type=“source”;
}else if(node.target){
node.type=node.target.type=“target”;
}否则{
node.connectors=[{node:node}];
node.type=“源”;
}
//日志(节点,“检查节点类型”);
});
//初始化信息显示。
var info=d3。选择(“信息”)
.text(defaultInfo=“显示”+formatNumber(links.length)+“+formatNumber(nodes.length)+”类之间的依赖关系”);
//通常情况下,配置单元会沿着每个轴按度对节点进行排序
//这个例子可视化了一个包层次结构,我们变得更有趣了
//如果我们按包对节点进行分组,则返回结果。我们不需要显式排序
//因为数据文件已按类名排序。
//按类型嵌套节点,用于计算秩。
var nodesByType=d3.nest()
.key(函数(d){返回d.type;})
.排序键(d3.升序)
.条目(节点);
//将目标源轴复制为源目标。
log(nodesByType,“nodesByType”);
//nodesByType.push({key:“源目标”,值:nodesByType[2].values});
nodesByType.push({key:“源目标”,值:nodesByType[1].values});
//计算每种类型的排名,并在包之间填充。
forEach(函数(类型){
var lastName=type.values[0].packageName,count=0;
type.values.forEach(函数(d,i){
如果(d.packageName!=lastName)lastName=d.packageName,则计数+=2;
d、 索引=计数++;
});
type.count=计数-1;
});
//设置半径域。
域(d3.extent(节点,函数(d){返回d.index;}));
//画轴。
svg.selectAll(“.axis”)
.数据(节点按类型)
.enter().append(“行”)
.attr(“类”、“轴”)
.attr(“变换”,函数(d){return“旋转”(+度(角度(d键))+”);})
.attr(“x1”,半径(-2))
.attr(“x2”,函数(d){返回半径(d.count+2);});
//绘制链接。
svg.append(“g”)
.attr(“类”、“链接”)
.selectAll(“.link”)
.数据(链接)
.enter().append(“路径”)
.attr(“类”、“链接”)
.attr(“d”,link()
.angle(函数(d){返回角(d.type);})
.radius(函数(d){返回半径(d.node.index);}))
.on(“鼠标悬停”,链接鼠标悬停)
.on(“mouseout”,mouseout);
//绘制节点。请注意,每个节点最多可以有两个连接器,
//表示源(传出)和目标(传入)链接。
svg.append(“g”)
.attr(“类”、“节点”)
.selectAll(“.node”)
.数据(节点)
.enter().append(“g”)
.attr(“类”、“节点”)
.style(“fill”,函数(d){返回颜色(d.packageName);})
.selectAll(“圆圈”)
.data(函数(d){返回d.connectors;})
.enter().append(“圆”)
.attr(“变换”,函数(d){return“旋转”(+度(角度(d.type))+”);})
.attr(“cx”,函数(d){返回半径(d.node.index);})
.attr(“r”,4)
.on(“鼠标悬停”,nodeMouseover)
.on(“mouseout”,mouseout);
//在鼠标悬停时高亮显示链接和连接的节点。
函数linkMouseover(d){
selectAll(“.link”).classed(“active”,函数(p){return p==d;});
selectAll(“.node circle”).classed(“active”,函数(p){return p==d.source | | p==d.target;});
info.text(d.source.node.name+)→ " + d、 target.node.name);
}
//在鼠标上方突出显示节点和连接的链接。
函数nodeMouseover(d){
svg.selectAll(
var width = 960,
    height = 850,
    innerRadius = 40,
    outerRadius = 640,
    majorAngle = 2 * Math.PI / 3,
    minorAngle = 1 * Math.PI / 12;

var angle = d3.scale.ordinal()
    .domain(["source", "source-target", "target-source", "target"])
    .range([0, majorAngle - minorAngle, majorAngle + minorAngle, 2 * majorAngle]);

var radius = d3.scale.linear()
    .range([innerRadius, outerRadius]);

var color = d3.scale.category10();

var svg = d3.select("#chart").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + outerRadius * .20 + "," + outerRadius * .57 + ")");

// Load the data and display the plot!
d3.json("./fl.json", function(nodes) {
// d3.json("./flare-imports.json", function(nodes) {
  console.log(nodes, "nodes");
  var nodesByName = {},
      links = [],
      formatNumber = d3.format(",d"),
      defaultInfo;

  // Construct an index by node name.
  nodes.forEach(function(d) {
    d.connectors = [];
    d.packageName = d.name.split(".")[1];
    nodesByName[d.name] = d;
    // console.log(d, nodesByName, "in nodes.forEach line 72, making connectors and packageName");
  });

  // Convert the import lists into links with sources and targets.
  nodes.forEach(function(source) {
    // console.log(source, "source?");
    source.imports.forEach(function(targetName) {
      var target = nodesByName[targetName];
      // console.log(target, nodesByName, targetName, "looking for target");
      if (!source.source) source.connectors.push(source.source = {node: source, degree: 0});
      if (!target.target) target.connectors.push(target.target = {node: target, degree: 0});
      links.push({source: source.source, target: target.target});

    });

  });

  // Determine the type of each node, based on incoming and outgoing links.
  nodes.forEach(function(node) {
    if (node.source && node.target) {
      node.type = node.source.type = "target-source";
      node.target.type = "source-target";
    } else if (node.source) {
      node.type = node.source.type = "source";
    } else if (node.target) {
      node.type = node.target.type = "target";
    } else {
      node.connectors = [{node: node}];
      node.type = "source";
    }
    // console.log(node, "checking node type");
  });

  // Initialize the info display.
  var info = d3.select("#info")
      .text(defaultInfo = "Showing " + formatNumber(links.length) + " dependencies among " + formatNumber(nodes.length) + " classes.");

  // Normally, Hive Plots sort nodes by degree along each axis. However, since
  // this example visualizes a package hierarchy, we get more interesting
  // results if we group nodes by package. We don't need to sort explicitly
  // because the data file is already sorted by class name.

  // Nest nodes by type, for computing the rank.
  var nodesByType = d3.nest()
      .key(function(d) { return d.type; })
      .sortKeys(d3.ascending)
      .entries(nodes);

  // Duplicate the target-source axis as source-target.
  console.log(nodesByType, "nodes by type");
  // nodesByType.push({key: "source-target", values: nodesByType[2].values});

  nodesByType.push({key: "source-target", values: nodesByType[1].values});

  // Compute the rank for each type, with padding between packages.
  nodesByType.forEach(function(type) {
    var lastName = type.values[0].packageName, count = 0;
    type.values.forEach(function(d, i) {
      if (d.packageName != lastName) lastName = d.packageName, count += 2;
      d.index = count++;
    });
    type.count = count - 1;
  });

  // Set the radius domain.
  radius.domain(d3.extent(nodes, function(d) { return d.index; }));

  // Draw the axes.
  svg.selectAll(".axis")
      .data(nodesByType)
    .enter().append("line")
      .attr("class", "axis")
      .attr("transform", function(d) { return "rotate(" + degrees(angle(d.key)) + ")"; })
      .attr("x1", radius(-2))
      .attr("x2", function(d) { return radius(d.count + 2); });

  // Draw the links.
  svg.append("g")
      .attr("class", "links")
    .selectAll(".link")
      .data(links)
    .enter().append("path")
      .attr("class", "link")
      .attr("d", link()
      .angle(function(d) { return angle(d.type); })
      .radius(function(d) { return radius(d.node.index); }))
      .on("mouseover", linkMouseover)
      .on("mouseout", mouseout);

  // Draw the nodes. Note that each node can have up to two connectors,
  // representing the source (outgoing) and target (incoming) links.
  svg.append("g")
      .attr("class", "nodes")
    .selectAll(".node")
      .data(nodes)
    .enter().append("g")
      .attr("class", "node")
      .style("fill", function(d) { return color(d.packageName); })
    .selectAll("circle")
      .data(function(d) { return d.connectors; })
    .enter().append("circle")
      .attr("transform", function(d) { return "rotate(" + degrees(angle(d.type)) + ")"; })
      .attr("cx", function(d) { return radius(d.node.index); })
      .attr("r", 4)
      .on("mouseover", nodeMouseover)
      .on("mouseout", mouseout);

  // Highlight the link and connected nodes on mouseover.
  function linkMouseover(d) {
    svg.selectAll(".link").classed("active", function(p) { return p === d; });
    svg.selectAll(".node circle").classed("active", function(p) { return p === d.source || p === d.target; });
    info.text(d.source.node.name + " → " + d.target.node.name);
  }

  // Highlight the node and connected links on mouseover.
  function nodeMouseover(d) {
    svg.selectAll(".link").classed("active", function(p) { return p.source === d || p.target === d; });
    d3.select(this).classed("active", true);
    info.text(d.node.name);
  }

  // Clear any highlighted nodes or links.
  function mouseout() {
    svg.selectAll(".active").classed("active", false);
    info.text(defaultInfo);
  }
});

// A shape generator for Hive links, based on a source and a target.
// The source and target are defined in polar coordinates (angle and radius).
// Ratio links can also be drawn by using a startRadius and endRadius.
// This class is modeled after d3.svg.chord.
function link() {
  var source = function(d) { return d.source; },
      target = function(d) { return d.target; },
      angle = function(d) { return d.angle; },
      startRadius = function(d) { return d.radius; },
      endRadius = startRadius,
      arcOffset = -Math.PI / 2;

  function link(d, i) {
    var s = node(source, this, d, i),
        t = node(target, this, d, i),
        x;
    if (t.a < s.a) x = t, t = s, s = x;
    if (t.a - s.a > Math.PI) s.a += 2 * Math.PI;
    var a1 = s.a + (t.a - s.a) / 3,
        a2 = t.a - (t.a - s.a) / 3;
    return s.r0 - s.r1 || t.r0 - t.r1
        ? "M" + Math.cos(s.a) * s.r0 + "," + Math.sin(s.a) * s.r0
        + "L" + Math.cos(s.a) * s.r1 + "," + Math.sin(s.a) * s.r1
        + "C" + Math.cos(a1) * s.r1 + "," + Math.sin(a1) * s.r1
        + " " + Math.cos(a2) * t.r1 + "," + Math.sin(a2) * t.r1
        + " " + Math.cos(t.a) * t.r1 + "," + Math.sin(t.a) * t.r1
        + "L" + Math.cos(t.a) * t.r0 + "," + Math.sin(t.a) * t.r0
        + "C" + Math.cos(a2) * t.r0 + "," + Math.sin(a2) * t.r0
        + " " + Math.cos(a1) * s.r0 + "," + Math.sin(a1) * s.r0
        + " " + Math.cos(s.a) * s.r0 + "," + Math.sin(s.a) * s.r0
        : "M" + Math.cos(s.a) * s.r0 + "," + Math.sin(s.a) * s.r0
        + "C" + Math.cos(a1) * s.r1 + "," + Math.sin(a1) * s.r1
        + " " + Math.cos(a2) * t.r1 + "," + Math.sin(a2) * t.r1
        + " " + Math.cos(t.a) * t.r1 + "," + Math.sin(t.a) * t.r1;
  }

  function node(method, thiz, d, i) {
    var node = method.call(thiz, d, i),
        a = +(typeof angle === "function" ? angle.call(thiz, node, i) : angle) + arcOffset,
        r0 = +(typeof startRadius === "function" ? startRadius.call(thiz, node, i) : startRadius),
        r1 = (startRadius === endRadius ? r0 : +(typeof endRadius === "function" ? endRadius.call(thiz, node, i) : endRadius));
    return {r0: r0, r1: r1, a: a};
  }

  link.source = function(_) {
    if (!arguments.length) return source;
    source = _;
    return link;
  };

  link.target = function(_) {
    if (!arguments.length) return target;
    target = _;
    return link;
  };

  link.angle = function(_) {
    if (!arguments.length) return angle;
    angle = _;
    return link;
  };

  link.radius = function(_) {
    if (!arguments.length) return startRadius;
    startRadius = endRadius = _;
    return link;
  };

  link.startRadius = function(_) {
    if (!arguments.length) return startRadius;
    startRadius = _;
    return link;
  };

  link.endRadius = function(_) {
    if (!arguments.length) return endRadius;
    endRadius = _;
    return link;
  };

  return link;
}

function degrees(radians) {
  return radians / Math.PI * 180 - 90;
}