【问题标题】:d3 curved legend with rectanglesd3 带矩形的曲线图例
【发布时间】:2017-08-29 01:25:54
【问题描述】:

我正在尝试使用 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;
  });

【问题讨论】:

标签: javascript d3.js


【解决方案1】:

/最新的 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]);

}
body {
  background: #412011;
}

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

【讨论】:

【解决方案2】:

不是完美的sn-p。但是,希望这会有所帮助。自己改进。

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;
  });
body {
  background: #412011;
}

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

text {
  fill: #ffffff;
}
<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>

【讨论】:

  • 我尝试增加半径——但标签和矩形没有相应调整
  • 如果你想增加半径,要么你应该相应地增加矩形的大小或矩形的数量。
  • jsfiddle.net/NYEaX/1773 -- 所以我添加了更多数据 -- 并增加了 svg 的大小 -- 和 arcradius 到 300 -- 但 rects/labels 不再同步
  • --我试图将这两个部分链接在一起-但需要将文本/矩形隔开更多 --- jsfiddle.net/NYEaX/1776
  • Hello @Gilsha 对此有更多的改进。我试图在此更多地连接矩形/标签——jsfiddle.net/NYEaX/1776
【解决方案3】:

我将矩形和标签更紧密地组合在一起 - 但这仍然缺乏控制标签/矩形的间距 - 并控制圆弧的半径。

//最新的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;
  });

【讨论】:

    猜你喜欢
    • 2019-10-26
    • 2017-11-25
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多