【问题标题】:add circle in a spiral chart with d3js with line connecting to center使用 d3js 在螺旋图中添加圆圈,线连接到中心
【发布时间】:2015-05-28 10:01:04
【问题描述】:

hi 我在 d3.js 中创建了一个螺旋图,我想在螺旋线的不同位置添加圆圈。根据那里的值。 靠近中心的圆圈将具有最高优先级。 任何想法如何做到这一点。

这是我写的代码

var width = 400,
height = 430
num_axes = 8,
tick_axis = 1,
start = 0
end = 4;

var theta = function(r) {
  return -2*Math.PI*r;
};

var arc = d3.svg.arc()
  .startAngle(0)
  .endAngle(2*Math.PI);

var radius = d3.scale.linear()
  .domain([start, end])
  .range([0, d3.min([width,height])/2-20]);

var angle = d3.scale.linear()
  .domain([0,num_axes])
  .range([0,360])

var svg = d3.select("#chart").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width/2 + "," + (height/2+8) +")");

var pieces = d3.range(start, end+0.001, (end-start)/1000);

var spiral = d3.svg.line.radial()
  .interpolate("cardinal")
  .angle(theta)
  .radius(radius);

//svg.append("text")
//  .text("And there was much rejoicing!")
//  .attr("class", "title")
//  .attr("x", 0)
//  .attr("y", -height/2+16)
//  .attr("text-anchor", "middle")

//svg.selectAll("circle.tick")
//    .data(d3.range(end,start,(start-end)/4))
//  .enter().append("circle")
//    .attr("class", "tick")
//    .attr("cx", 0)
//    .attr("cy", 0)
//    .attr("r", function(d) { return radius(d); })

svg.selectAll(".axis")
    .data(d3.range(num_axes))
  .enter().append("g")
    .attr("class", "axis")
    .attr("transform", function(d) { return "rotate(" + -angle(d) + ")"; })
  .call(radial_tick)
  .append("text")
    .attr("y", radius(end)+13)
    .text(function(d) { return angle(d) + "°"; })
    .attr("text-anchor", "middle")
    .attr("transform", function(d) { return "rotate(" + -90 + ")" })

svg.selectAll(".spiral")
    .data([pieces])
  .enter().append("path")
    .attr("class", "spiral")
    .attr("d", spiral)
    .attr("transform", function(d) { return "rotate(" + 90 + ")" });

function radial_tick(selection) {
  selection.each(function(axis_num) {
    d3.svg.axis()
      .scale(radius)
      .ticks(5)
      .tickValues( axis_num == tick_axis ? null : [])
      .orient("bottom")(d3.select(this))

    d3.select(this)
      .selectAll("text")
      .attr("text-anchor", "bottom")
      .attr("transform", "rotate(" + angle(axis_num) + ")")
  });
}

请参阅我的实施的第二个解决方案。帮助我将圆与中心连接起来

【问题讨论】:

  • 如果我的答案不是您想要的,请发表评论。在我看来,它虽然得到了回答......

标签: javascript jquery d3.js data-visualization


【解决方案1】:

这是您似乎正在寻找的技术的模型......

var width = 400,
		height = 430,
		num_axes = 8,
		tick_axis = 1,
		start = 0,
		end = 4,
		testValue = 2;

		var theta = function (r) {
			return -2 * Math.PI * r;
		};

		var arc = d3.svg.arc()
			.startAngle(0)
			.endAngle(2 * Math.PI);

		var radius = d3.scale.linear()
			.domain([start, end])
			.range([0, (d3.min([width, height]) / 2 - 20)]);

		var angle = d3.scale.linear()
			.domain([0, num_axes])
			.range([0, 360]);

		var chart = d3.select("#chart")
			.style("width", width + "px");

		var svg = d3.select("#chart").append("svg")
				.attr("width", width)
				.attr("height", height)
			.append("g")
				.attr("transform", "translate(" + width / 2 + "," + (height / 2 + 8) + ")");

		var pieces = d3.range(start, end + 0.001, (end - start) / 500);

		var spiral = d3.svg.line.radial()
			.interpolate("linear")
			.angle(theta)
			.radius(radius);
		
		svg.append("text")
			.text("Title")
			.attr("class", "title")
			.attr("x", 0)
			.attr("y", -height/2+16)
			.attr("text-anchor", "middle")

		svg.selectAll("circle.tick")
				.data(d3.range(end,start,(start-end)/4))
			.enter().append("circle")
				.attr("class", "tick")
				.style({fill: "black", opacity: 0.1})
				.attr("cx", 0)
				.attr("cy", 0)
				.attr("r", function(d) { return radius(d); })

		svg.selectAll(".axis")
				.data(d3.range(num_axes))
			.enter().append("g")
				.attr("class", "axis")
				.attr("transform", function (d) { return "rotate(" + -angle(d) + ")"; })
			.call(radial_tick)
			.append("text")
				.attr("y", radius(end) + 13)
				.text(function (d) { return angle(d) + "°"; })
				.attr("text-anchor", "middle")
				.attr("transform", function (d) { return "rotate(" + -90 + ")" })

		svg.selectAll(".axis path")
			.style({fill: "none", stroke: "black"})
			.attr("stroke-dasharray", "5 5")

		svg.selectAll(".spiral")
				.data([pieces])
			.enter().append("path")
				.attr("class", "spiral")
				.attr("fill", "none")
				.attr("stroke", "black")
				.attr("d", spiral)
				.attr("transform", function (d) { return "rotate(" + 90 + ")" });

		function radial_tick(selection) {
			selection.each(function (axis_num) {
				d3.svg.axis()
					.scale(radius)
					.ticks(5)
					.tickValues(axis_num == tick_axis ? null : [])
					.tickSize(1)
					.orient("bottom")(d3.select(this))

				d3.select(this)
					.selectAll("text")
					.attr("text-anchor", "bottom")
					.attr("transform", "rotate(" + angle(axis_num) + ")")
			});
		}
		function radialScale(x) {
			var t = theta(x), r = radius(x);
			d3.select(this)
			.attr("cx", r * Math.cos(t))
			.attr("cy", r * Math.sin(t))
		}

		slider = SliderControl("#circleSlider", "data", update, [start, end], ",.3f");

		function update(x) {

		  if (typeof x != "undefined") testValue = x;
			
			var circles = svg.selectAll(".dataPoints")
				.data([testValue]);
			circles.enter().append("circle");

		  circles.attr("class", "dataPoints")
					.style({ fill: "black", opacity: 0.6 })
					.attr("r", 10)
					.each(radialScale)
			circles.exit().remove();
			return testValue
		}

		function SliderControl(selector, title, value, domain, format) {
			var accessor = d3.functor(value), rangeMax = 1000,
					_scale = d3.scale.linear().domain(domain).range([0, rangeMax]),
					_$outputDiv = $("<div />", { class: "slider-value" }),
					_update = function (value) {
						_$outputDiv.css("left", 'calc( '
							+ (_$slider.position().left + _$slider.outerWidth()) + 'px + 1em )')
						_$outputDiv.text(d3.format(format)(value));
						$(".input").width(_$outputDiv.position().left + _$outputDiv.outerWidth() - _innerLeft)

					},

					_$slider = $(selector).slider({
						value: _scale(accessor()),
						max: rangeMax,
						slide: function (e, ui) {
							_update(_scale.invert(ui.value));
							accessor(_scale.invert(ui.value));
						}
					}),
					_$wrapper = _$slider.wrap("<div class='input'></div>")
					.before($("<div />").text(title + ":"))
					.after(_$outputDiv).parent(),
					_innerLeft = _$wrapper.children().first().position().left;

			_update(_scale.invert($(selector).slider("value")))

			return d3.select(selector)
		};
.domain {
			stroke-width: 1px;
		}
<link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
	<div id="chart">
		<div id="circleSlider"></div>
	</div>

【讨论】:

  • 你的答案是正确的,但我以某种不同的方式实现了它,无论如何我会把它打勾为正确的答案:)。我在下面发布我的解决方案。如果可以的话,我还需要你的帮助。我想将下一张图片中的所有圆圈添加到中心。请看下面我的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多