d3线/圆图

时间:2017-03-29 07:39:39

标签: javascript d3.js

是否有人知道如何使用JavaScript SVG创建一条线条/圆形图表,其中的线条扩展到代表不同数据点的不同象限?

下面的图片展示了我正在寻找的东西。

enter image description here

首先将dougnut图表与占位符进行映射,其中行可以跳出来。

//最新小提琴

http://jsfiddle.net/Qh9X5/10152/

下一步是绘制一条线以反射标记。

  var slice = svg.select(".slices").selectAll("path.slice")
    .data(pie(data));

  slice.enter()
    .insert("path")
    .attr('fill', function(d, i) {
      console.log("d", d);
      return colores_google(i);
    })
    .attr("class", "slice");

  slice
    .transition().duration(1000)
    .attrTween("d", function(d) {
      this._current = this._current || d;
      var interpolate = d3.interpolate(this._current, d);
      this._current = interpolate(0);
      return function(t) {
        return arc(interpolate(t));
      };
    })

  slice.exit()
    .remove();




  var placeholders = svg.select(".placeholders").selectAll("circle.placeholder")
    .data(pie(data));

  placeholders.enter()
    .insert("circle")
    .style("fill", function(d) {
      return "white";
    })
    .attr("transform", function(d) {
      return "translate(" + arc.centroid(d) + ")";
    })
    .attr("r", "3")
    .attr("class", function(d) {
      return "placeholder " + d.data.group;
    });

  placeholders
    .transition().duration(1000)

  placeholders.exit()
    .remove();

  var gapplaceholders = svg.select(".placeholders").selectAll("circle.placeholder.gap");

  gapplaceholders.remove();

2 个答案:

答案 0 :(得分:3)

我已经设法开始在这个圆环图的节点上绘制多条线。

enter image description here http://jsfiddle.net/Qh9X5/10208/

  var slice = svg.select(".slices").selectAll("path.slice")
    .data(pie(data));

  slice.enter()
    .insert("path")
    .attr('fill', function(d, i) {
      return colores_google(i);
    })
    .attr("class", "slice");

  slice
    .transition().duration(1000)
    .attrTween("d", function(d) {
      this._current = this._current || d;
      var interpolate = d3.interpolate(this._current, d);
      this._current = interpolate(0);
      return function(t) {
        return arc(interpolate(t));
      };
    })

  slice.exit()
    .remove();



  var placeholders = svg.select(".placeholders").selectAll("circle.placeholder")
    .data(pie(data));

  placeholders.enter()
    .insert("circle")
    .style("fill", function(d) {
      return "white";
    })
    .attr("transform", function(d) {
      return "translate(" + arc.centroid(d) + ")";
    })
    .attr("x", function(d) {
      return arc.centroid(d)[0];
    })
    .attr("y", function(d) {
      return arc.centroid(d)[1];
    })
    .attr("r", "3")
    .attr("id", function(d) {
      return "p" + d.data.id;
    })
    .attr("class", function(d) {
      return "placeholder " + d.data.group;
    });

  placeholders
    .transition().duration(1000)

  placeholders.exit()
    .remove();



  var labelholders = svg.select(".labelholders").selectAll("text.labelholder")
    .data(pie(data));

  labelholders.enter()
    .insert("text")
    .attr("transform", function(d) {
      return "translate(" + arc.centroid(d) + ")";
    })
    .attr("dy", -5)
    .text(function(d) {
      return d.data.id;
    })
    .attr("class", function(d) {
      return "labelholder " + d.data.group;
    });

  labelholders
    .transition().duration(1000)

  labelholders.exit()
    .remove();




  var gapplaceholders = svg.select(".placeholders").selectAll("circle.placeholder.gap");

  gapplaceholders.remove();


var lineColors = ["e2d7c7",
    "d7b093",
    "c04830",
    "fffcef",
    "4aaba2",
    "c94f42",
    "52b0a2"
  ];


  var lineData = [{
      group: 1,
      plots: [21, 22, 18, 1]
    }, {
      group: 2,
      plots: [20, 23, 17, 9]
    }, {
      group: 3,
      plots: [21, 24, 16, 15]
    }, {
      group: 3,
      plots: [19, 23, 16, 0]
    }, {
      group: 5,
      plots: [19, 24, 18, 6]
    }, {
      group: 6,
      plots: [19, 24, 17, 14]
    }, {
      group: 3,
      plots: [20, 23, 16, 2]
    }, {
      group: 5,
      plots: [19, 23, 16, 4]
    }

  ]



  $.each(lineData, function(index, value) {

    var coords = [];

    var group = value.group;

    $.each(value.plots, function(i, v) {
      $("#p" + v).each(function() {
        var x = $(this).attr("x");
        var y = $(this).attr("y");

        var obj = {
          "x": x,
          "y": y
        };
        coords.push(obj);
      });
    });


    var first = {
      "x": 5 * index,
      "y": radius - 35
    };
    coords.push(first);

    var first = {
      "x": 5 * index,
      "y": radius + 200
    };
    coords.push(first);

    var maxLeng = coords.length - 2;

    $.each(coords, function(i, v) {

      var line = svg.append("line")
        .style("stroke", function(d) {
          return lineColors[group];
        })
        .attr("x1", coords[i]["x"])
        .attr("y1", coords[i]["y"])
        .attr("x2", coords[i + 1]["x"])
        .attr("y2", coords[i + 1]["y"]);

      if (i == maxLeng) {
        return false;
      }
    });

  });

答案 1 :(得分:0)

最新的jsfiddle。

http://jsfiddle.net/Qh9X5/10276/

图表现在响应人文数据 - 虽然需要进一步考虑调整底角以将下面的字符串束缚在底部间隙中。

baseX2Angle = 0.5

var svg = d3.select("#pies")
  .append("svg")
  .append("g")

svg.append("g")
  .attr("class", "slices");
svg.append("g")
  .attr("class", "placeholders");

svg.append("g")
  .attr("class", "gapplaceholders");

svg.append("g")
  .attr("class", "labelholders");

var width = 560,
  height = 450,
  radius = Math.min(width, height) / 2;

var pie = d3.layout.pie()
  .sort(null)
  .value(function(d) {
    return d.value;
  });

var arc = d3.svg.arc()
  .outerRadius(radius * 0.85)
  .innerRadius(radius * 0.83);

var outerArc = d3.svg.arc()
  .innerRadius(radius * 0.9)
  .outerRadius(radius * 0.9);

svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ") rotate(7)");

var key = function(d) {
  return d.data.label;
};

function colores_google(n) {
  var colores_g = ["#e9168a", "#f8dd2f", "#448875", "#c3bd75", "#2b2d39", "#311854", "#553814", "#f7b363", "#89191d", "#c12f34", "#2b2a2c", "#c5b8a6", "#57585b"];
  return colores_g[n % colores_g.length];
}

var data = [
/*
{
  "group": "g1",
  "set": [
    "skill1",
    "skill2",
    "skill3",
    "skill4",
    "skill5",
    "skill6",
    "skill7",
    "skill8",
    "skill9",
    "skill10",
    "skill11",
    "skill12",
    "skill13",
    "skill14",
    "skill15",
    "skill16",
    "skill17",
    "skill18",
    "skill19",
    "skill20",
    "skill21",
    "skill22",
    "skill23",
    "skill24",
    "skill25",
    "skill26",
    "skill27",
    "skill28",
    "skill29",
    "skill30",
    "skill31",
    "skill32",
    "skill33",
    "skill34",
    "skill35",
    "skill36",
    "skill37",
    "skill38",
    "skill39",
    "skill40",
    "skill41",
    "skill42",
    "skill43",
    "skill44",
    "skill45",
    "skill46"
  ]
},
*/
/*
{
  "group": "g2",
  "set": [
    "<5secs",
    "<1min",
    "<1hour",
    "<1day"
  ]
},
*/
{
  "group": "g3",
  "set": [
    "unsure, unanserablem impossible",
    "philiosophical, optimistic, vague, open",
    "measurable, mathmatical, logical",
    "clever, funny, sarcastic"
  ]
}, {
  "group": "g4",
  "set": [
    "Facebook",
    "Email",
    "Twitter",
    "Telephone",
    "Linkedin"
  ]
}];


var id = 0;
var d = [];

var totalDataSpread = 0;
$.each(data, function(index, value) {
  totalDataSpread += value.set.length;
});

console.log("totalDataSpread", totalDataSpread);

$.each(data, function(index, value) {

  var segmentTotal = value.set.length;
  $.each(value.set, function(i, v) {
    d.push({
      group: value.group,
      label: v,
      id: id++,
      value: 1 // ((segmentTotal/totalDataSpread)*10) 
    });
  });

  var gapSize = 10;
  if (segmentTotal > 10) {
    gapSize = 20;
  }

  //console.log("create GAP", value.set);
  d.push({
    group: "gap",
    label: "gap " + id,
    id: -1,
    value: gapSize
  });

});

console.log("d", d);

data = d;

var lineColors = ["e2d7c7",
  "d7b093",
  "c04830",
  "fffcef",
  "4aaba2",
  "c94f42",
  "52b0a2"
];

var lineData = [{
  group: 1,
  plotSets: [
    "skill1",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 1,
  plotSets: [
    "skill2",
    "<1min",
    "unsure, unanserablem impossible",
    "Facebook"
  ]
}, {
  group: 4,
  plotSets: [
    "skill3",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill4",
    "<5secs",
    "unsure, unanserablem impossible",
    "Email"
  ]
}, {
  group: 3,
  plotSets: [
    "skill5",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill6",
    "<5secs",
    "unsure, unanserablem impossible",
    "Email"
  ]
}, {
  group: 3,
  plotSets: [
    "skill7",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill8",
    "<5secs",
    "unsure, unanserablem impossible",
    "Twitter"
  ]
}, {
  group: 4,
  plotSets: [
    "skill9",
    "<1day",
    "clever, funny, sarcastic",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill10",
    "<5secs",
    "unsure, unanserablem impossible",
    "Twitter"
  ]
}, {
  group: 2,
  plotSets: [
    "skill11",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill12",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill13",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill14",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill15",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill16",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill17",
    "<1hour",
    "unsure, unanserablem impossible",
    "Email"
  ]
}, {
  group: 4,
  plotSets: [
    "skill18",
    "<1day",
    "unsure, unanserablem impossible",
    "Facebook"
  ]
}, {
  group: 4,
  plotSets: [
    "skill19",
    "<5secs",
    "clever, funny, sarcastic",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill20",
    "<5secs",
    "unsure, unanserablem impossible",
    "Linkedin"
  ]
}, {
  group: 4,
  plotSets: [
    "skill21",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill22",
    "<1hour",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill23",
    "<1hour",
    "unsure, unanserablem impossible",
    "Twitter"
  ]
}, {
  group: 3,
  plotSets: [
    "skill24",
    "<5secs",
    "unsure, unanserablem impossible",
    "Linkedin"
  ]
}, {
  group: 4,
  plotSets: [
    "skill25",
    "<1day",
    "unsure, unanserablem impossible",
    "Email"
  ]
}, {
  group: 4,
  plotSets: [
    "skill26",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill27",
    "<5secs",
    "unsure, unanserablem impossible",
    "Facebook"
  ]
}, {
  group: 4,
  plotSets: [
    "skill28",
    "<5secs",
    "unsure, unanserablem impossible",
    "Facebook"
  ]
}, {
  group: 3,
  plotSets: [
    "skill29",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill30",
    "<5secs",
    "unsure, unanserablem impossible",
    "Linkedin"
  ]
}, {
  group: 3,
  plotSets: [
    "skill31",
    "<1day",
    "clever, funny, sarcastic",
    "Telephone"
  ]
}, {
  group: 3,
  plotSets: [
    "skill32",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill33",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill34",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 2,
  plotSets: [
    "skill35",
    "<5secs",
    "unsure, unanserablem impossible",
    "Twitter"
  ]
}, {
  group: 1,
  plotSets: [
    "skill36",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill37",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill38",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill39",
    "<1day",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill40",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill41",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 2,
  plotSets: [
    "skill42",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 4,
  plotSets: [
    "skill43",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 2,
  plotSets: [
    "skill44",
    "<5secs",
    "unsure, unanserablem impossible",
    "Telephone"
  ]
}, {
  group: 2,
  plotSets: [
    "skill45",
    "<5secs",
    "clever, funny, sarcastic",
    "Twitter"
  ]
}];

//add gaps 

change(data);

function change(data) {

  var slice = svg.select(".slices").selectAll("path.slice")
    .data(pie(data));

  slice.enter()
    .insert("path")
    .attr('fill', function(d, i) {
      return colores_google(i);
    })
    .attr("class", "slice");

  slice
    .transition().duration(1000)
    .attrTween("d", function(d) {
      this._current = this._current || d;
      var interpolate = d3.interpolate(this._current, d);
      this._current = interpolate(0);
      return function(t) {
        return arc(interpolate(t));
      };
    })

  slice
    .exit()
    .remove();

  var placeholders = svg.select(".placeholders").selectAll("circle.placeholder")
    .data(pie(data));

  placeholders.enter()
    .insert("circle")
    .style("fill", function(d) {
      return "white";
    })
    .attr("transform", function(d) {
      return "translate(" + arc.centroid(d) + ")";
    })
    .attr("x", function(d) {
      return arc.centroid(d)[0];
    })
    .attr("y", function(d) {
      return arc.centroid(d)[1];
    })
    .attr("data-set", function(d) {
      return d.data.label;
    })
    .attr("r", "5")
    .attr("id", function(d) {
      return "p" + d.data.id;
    })
    .attr("class", function(d) {
      return "placeholder " + d.data.group;
    });

  placeholders
    .transition().duration(1000)

  placeholders.exit()
    .remove();


  /*removing mid arcs on gaps*/
  var gapplaceholders = svg.select(".placeholders").selectAll("circle.placeholder.gap");
  gapplaceholders.remove();
  /*removing mid arcs on gaps*/

  var labelholders = svg.select(".labelholders").selectAll("text.labelholder")
    .data(pie(data));

  labelholders.enter()
    .insert("text")
    .attr("transform", function(d) {
      return "translate(" + arc.centroid(d) + ")";
    })
    .attr("dy", -5)
    .text(function(d) {
      return d.data.label; //d.data.id;
    })
    .attr("class", function(d) {
      return "labelholder " + d.data.group;
    });

  labelholders
    .transition().duration(1000)

  labelholders.exit()
    .remove();

  //gap place holder circles
  var gapplaceholders = svg.select(".gapplaceholders");
  var arcradius = radius * 0.85;
  var circleradius = 1.5;

  var lineCount = lineData.length;

  // Approx number of circles we can fit around the circumference
  var n = (Math.PI * 2 * arcradius) / (2 * circleradius);
  var baseX2Angle = 0.5;
  var gapcoords = [];

  for (var i = 0; i < lineCount; i++) {
    var ang = ((Math.PI * 2 * i) / n) - baseX2Angle;
    var cx = arcradius * Math.sin(ang);
    var cy = arcradius * Math.cos(ang);

    gapplaceholders.append("circle")
      .attr('cx', cx)
      .attr('cy', cy)
      .attr('class', "gapcircles")
      .attr('r', circleradius);

    gapcoords.push({
      "x": cx,
      "y": cy
    });
  }
  //gap place holder circles


  $.each(lineData, function(index, value) {

    var coords = [];

    var group = value.group;

    $.each(value.plotSets, function(i, v) {

      $('[data-set="' + v + '"]').each(function() {
        var x = $(this).attr("x");
        var y = $(this).attr("y");

        coords.push({
          "x": x,
          "y": y
        });
      });
    });

    //console.log("coords", coords);

    var baseX = 60;

    coords.push({
      "x": gapcoords[index].x,
      "y": gapcoords[index].y
    });

    coords.push({
      "x": (3 * index) - baseX,
      "y": radius + 200
    });

    var maxLeng = coords.length - 2;

    var linebatch = svg.append("g")
      .attr("class", "linebatch")

    $.each(coords, function(i, v) {
      var line = linebatch.append("line")
        .style("stroke", function(d) {
          return lineColors[group];
        })
        .attr("x1", coords[i]["x"])
        .attr("y1", coords[i]["y"])
        .attr("x2", coords[i + 1]["x"])
        .attr("y2", coords[i + 1]["y"]);

      if (i == maxLeng) {
        return false;
      }
    });

  });
};