d3带有矩形的弯曲图例

时间:2017-04-04 02:10:21

标签: javascript d3.js

enter image description here

我试图使用d3创建一个弯曲的图例。我创建了一条曲线路径 - 但我不确定如何在相应旋转标签/矩形的情况下将图例绘制在路径上。

//最新的jsfiddle http://jsfiddle.net/NYEaX/1768/

labels.selectAll('text')
  .data(data)
  .enter()
  .append('text')
  .style('text-anchor', 'middle')
  .append('textPath')
  .attr('xlink:href', '#label-path')
  .attr('startOffset', function(d, i) {
    return i * 100 / numBars + 50 / numBars + '%';
  })
  .text(function(d) {
    return d;
  });

3 个答案:

答案 0 :(得分:2)

/ 最新的Jsfiddle /

http://jsfiddle.net/NYEaX/1779/

我可以找到实现此功能的另一种方法。希望这会有所帮助。



var pi = Math.PI;
var outerRadius = 300;
var w = 1200,
  h = 900;
var vis = d3.select("body").append("svg").attr("width", 1200).attr("height", 900).append("g")
  .attr("transform", "translate(200," + (h / 2) + ")");

var arc = d3.svg.arc()
  .innerRadius(outerRadius)
  .outerRadius(outerRadius)
  .startAngle(0)
  .endAngle(Math.PI);

var path = vis
  .append("path")
  .attr("d", arc)
  .attr("fill", "red");

var data = [
  "a blink of an eye",
  "it is all the same",
  "something memorable",
  "when you figure out your birthday is in a month",
  "an event",
  "something special or unique that stands out in your mind",
  "something that happens",
  "a space in time",
  "a minute, a second or a tenth of a second",
  "inevitable",
  "a piece of time",
  "everything all at one time",
  "umm. uh",
  "a rush of warm tingle in my chest followed my a slight dizziness",
  "an indefinitely short period of time: instant",
  "something or anything that can be defined that capture",
  "a minute portion or point of time",
  "anything from the wind blowing a leaf, to your child",
  "something that takes less than a second to witness, but you can remember for a lifetime",
  "a very brief period of time comes to an almost complete stop",
  "a small piece of a bigger collection",
  "a small period of time",
  "the period of time when I'm eating my bagel",
  "an infinite period of time",
  "a blip of space where 1,000,00-million microcosms are coliding into each other",
  "special",
  "hazy and uncoordinated",
  "a given instance",
  "an indefintely short time",
  "enough time to think about something or do something",
  "enlightening",
  "something that sticks with you through your busy life",
  "something I don't have very much of",
  "a memory in time",
  "the first time she lays her hand on yours",
  "here and now: at this time",
  "something or anything that can be defined, that captures your attention in a instance",
  "a turning force produced by an object acting at a distance",
  "the lowest increment of a length of time",
  "a medieval unit of time equal to 1.5 minutes of 1/40 of an hour",
  "when time slows and you to come to realization about something important",
  "in modern english it usually refers to a short period of time",
  "when you look away and your child destroys something expensive",
  "a cluster of data in the program of life",
  "something between two people that is so special that is pondered after the momentum",
  "mmaraow...prrrrot",
  "the present time or any other particular time",
  "a piece of time independent from normal time",
  "90 seconds",
  "a span of time describing a specific instance or event",
  "a period of time where something significant begins",
  "right now"
];

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 totalLength = path.node().getTotalLength();

var noOfRects = data.length;
var rectSize = totalLength / (noOfRects * 3);
var len = 0;
var margin = 5;
var centroid = arc.centroid();;
for (var i = 0; i < data.length; i++) {
  var pt1 = path.node().getPointAtLength(len);

  len += rectSize;

  var pt2 = path.node().getPointAtLength(len);
  vis.append('path')
    .attr('stroke', function() {
      return colores_google(i);
    })
    .attr("stroke-width", 10)
    .attr("d", "M" + pt1.x + "," + pt1.y + "L" + pt2.x + "," + pt2.y + "Z");

  len += margin;


  var v1 = {
      x: pt2.x,
      y: pt2.y
    },
    v2 = {
      x: centroid[0],
      y: centroid[1]
    };

  var angleRad = Math.acos(v1.x / Math.sqrt(v1.x * v1.x + v1.y * v1.y))

  angleDeg = angleRad * 180 / Math.PI;
  angleDeg = i <= data.length / 2 ? angleDeg * -1 : angleDeg;
  vis.append('text')
    .attr("dx", "1.1em")
    .style("text-anchor", "start")
    .attr("transform", "translate(" + pt2.x + "," + pt2.y + ")  rotate(" + angleDeg + ")")
    .text(data[i]);

}
&#13;
body {
  background: #412011;
}

text {
  fill: #ffffff;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

不是一个完美的片段。但是,希望这会有所帮助。自己提高。

&#13;
&#13;
var $this = $("#progress");


var data = [
  "a blink of an eye",
  "it is all the same",
  "something memorable",
  "when you figure out your birthday is in a month",
  "an event",
  "something special or unique that stands out in your mind",
  "something that happens",
  "a space in time",
  "a minute, a second or a tenth of a second",
  "inevitable",
  "a piece of time",
  "everything all at one time",
  "umm. uh",
  "a rush of warm tingle in my chest followed my a slight dizziness",
  "an indefinitely short period of time: instant",
  "something or anything that can be defined that capture",
  "a minute portion or point of time"
];


var w = 600;
var h = 600;

var radius = Math.min(w, h) / 2;

var svg = d3.select($this[0])
  .append("svg")
  .attr("width", w)
  .attr("height", h)
  .append("g")

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

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

svg.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

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 numBars = data.length;


var arcradius = 150;
var rectWidth = 15;
// Approx number of rects we can fit around the circumference
var n = (Math.PI * 2 * arcradius) / (2 * rectWidth);

labelsrects.selectAll('rect')
  .data(data)
  .enter()
  .append('rect')
  .attr('width', 15)
  .attr('height', 15)
.attr("transform", function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return "rotate(" + (ang * 180 / Math.PI - 90) + ")" + "translate(" + (90 + rectWidth + 5) + ")";
  })
  .attr('x', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.sin(ang);
  })
  .attr('y', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.cos(ang);
  })
  .attr('fill', function(d, i) {
    return colores_google(i);
  });

var x = d3.scale.linear()
  .range([0, 2 * Math.PI]);

labels.selectAll('text')
  .data(data)
  .enter()
  .append('text')
  .attr("transform", function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return "rotate(" + (ang * 180 / Math.PI - 90) + ")" + "translate(" + (90 + rectWidth + 5) + ")";
  })
   .attr('x', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.sin(ang);
  })
  .attr('y', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.cos(ang);
  })
  .attr("dx", rectWidth*2+"px")
  .attr("dy", (rectWidth-5)+"px")
  .style('text-anchor', 'start')
  .text(function(d) {
    return d;
  });
&#13;
body {
  background: #412011;
}

path {
  stroke-width: 1px;
  stroke: #eeeeee;
}

text {
  fill: #ffffff;
}
&#13;
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>

<div id="progress"></div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

enter image description here

我已经将矩形和标签更紧密地结合在一起了 - 但是这仍然缺乏控制空间来标记/反射 - 并控制弧的半径。

//最新的jsfiddle http://jsfiddle.net/NYEaX/1776/

var arcradius =350;
var rectWidth = 10;
// Approx number of circles we can fit around the circumference
var n = (Math.PI * 2 * arcradius) / (2 * rectWidth);

labelsrects.selectAll('rect')
  .data(data)
  .enter()
  .append('rect')
  .attr('width', 10)
  .attr('height', 10)
  .attr("transform", function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return "rotate(" + (ang * 180 / Math.PI - 90) + ")" + "translate(" + (90 + rectWidth + 5) + ")";
  })
  .attr('x', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.sin(ang);
  })
  .attr('y', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.cos(ang);
  })
  .attr('fill', function(d, i) {
    return colores_google(i);
  });

//var x = d3.scale.linear().range([0, 2 * Math.PI]);

labels.selectAll('text')
  .data(data)
  .enter()
  .append('text')
  .attr("transform", function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return "rotate(" + (ang * 180 / Math.PI - 90) + ")" + "translate(" + (90 + rectWidth + 5) + ")";
  })
  .attr('x', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.sin(ang);
  })
  .attr('y', function(d, i) {
    var ang = (Math.PI * 2 * i) / n;
    return arcradius * Math.cos(ang);
  })
  .attr("dx", "1.1em")
  .style('text-anchor', 'start')
  .text(function(d) {
    return d;
  });