【问题标题】:How to make D3.js path generator append two points?如何使 D3.js 路径生成器附加两个点?
【发布时间】:2015-06-04 21:38:23
【问题描述】:

使用 D3.js 我想创建一个具有水平线的图形,这些水平线由一条线连接。看这个例子:http://s15.postimg.org/7ffms1f7f/tmp.png

在一些教程的帮助下,我设法使用 line 显示水平条。 jsfiddle.net /m2p1xky9/4/

为了显示连接的条形,使用 path 对我来说很有意义。 https://jsfiddle.net/jaa07n6m/2/

// Append Path:
   var lineFunction = d3.svg.line()
          .x(function(d) { return x(d.letter); })
          .y(function(d) { return y(d.frequency); })
          .interpolate("linear")

   var lineGraph = svg.append("path")
          .attr("d", lineFunction(data))
          .attr("stroke", "blue")
          .attr("stroke-width", 2)
          .attr("fill", "none");

但我没有以正确的方式实现它。

我想我需要让 lineFunction 附加两个点。我的方法不起作用:

   var lineFunction = d3.svg.line()
          .x(function(d) { return x(d.letter); })
          .y(function(d) { return y(d.frequency); })
          .interpolate("linear")
          .x(function(d) { return x(d.letter)+x.rangeBand(); })
          .y(function(d) { return y(d.frequency); })
          .interpolate("linear");

实现它的正确方法是什么?

【问题讨论】:

  • 我回答你的问题了吗?
  • @cool-blue 你做到了。其实我的问题是如何画一条连续的线。但是您的解决方案甚至更好,使我能够为水平段使用不同的厚度。猜猜我的问题不够明确。但是,我希望有一个比直接访问数据数组更优雅的解决方案。类似于 data() 函数。

标签: javascript d3.js path


【解决方案1】:

策略

line 函数不关心有多少点,它需要一个点数组,然后将它们全部连接起来。访问器函数应用于您提供给它的每个点。
您需要一组比数据少一个成员的线条,因此您需要绑定一些虚拟数据,然后您需要构造具有两个点的成员并将它们提供给线条函数。

代码

	data = [

			{
			letter: "A",
			frequency: .08167
			}, {
			letter: "B",
			frequency: .01492
			}, {
			letter: "C",
			frequency: .02782
			}, {
			letter: "D",
			frequency: .04253
			}, {
			letter: "E",
			frequency: .12702
			}
	];

	var margin = { top: 20, right: 20, bottom: 30, left: 40 },
		width = 960 - margin.left - margin.right,
		height = 500 - margin.top - margin.bottom;

	var x = d3.scale.ordinal()
		.rangeRoundBands([0, width], .1);

	var y = d3.scale.linear()
		.rangeRound([height, 0]);

	//Define X axis:
	var xAxis = d3.svg.axis()
		.scale(x)
		.orient("bottom");

	//Define y axis:
	var yAxis = d3.svg.axis()
		.scale(y)
		.orient("left")
		.ticks(10, "%");

	var svg = d3.select("body").append("svg")
		.attr("width", width + margin.left + margin.right)
		.attr("height", height + margin.top + margin.bottom)
		.append("g")
			.attr("transform", "translate(" + margin.left + "," + margin.top + ")");


	x.domain(data.map(function (d) { return d.letter; }));
	y.domain([0, d3.max(data, function (d) { return d.frequency; })]);


	// Append X-Axis:
	svg.append("g")
		.attr("class", "x axis")
		.attr("transform", "translate(0," + height + ")")
		.call(xAxis);


	// Append Y-Axis:
	svg.append("g")
		.attr("class", "y axis")
		.call(yAxis)

	// Append Lines:
	svg.selectAll(".line")
		.data(data)
		.enter()
		.append("line")
		.attr("class", "line")
		.attr("x1", function (d) { return x(d.letter); })
		.attr("y1", function (d) { return y(d.frequency); })
		.attr("x2", function (d) { return x(d.letter) + x.rangeBand(); })
		.attr("y2", function (d) { return y(d.frequency); })

	var lineFunction2 = d3.svg.line()
		.x(function (d) { return d.x; })
		.y(function (d) { return d.y; })
		.interpolate("linear")

	var lineGraph = svg.selectAll(".connect")
		.data(d3.range(data.length-1))
		.enter().append("path")
		.attr("class", "connect")
		.attr("d", function(d, i) {
			var p1 = data[i], p2 = data[i+1];
			return lineFunction2([
			{x: x(p1.letter) + x.rangeBand(), y:y(p1.frequency)}, 
			{x: x(p2.letter), y:y(p2.frequency)}
			])
		})
		.attr("stroke", "blue")
		.attr("stroke-width", 2)
		.attr("fill", "none");
.line {
		
		stroke: gray;
		stroke-width: 1;
}

.axis {
			font: 10px sans-serif;
		}

		.axis path,
		.axis line {
			fill: none;
			stroke: #000;
			shape-rendering: crispEdges;
		}

		.x.axis path {
			display: none;
		}  </style>
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 2014-05-02
    • 2021-02-08
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多