如何使用 d3.js 基于 2 个直径点且没有长度或高度值绘制矩形?

Haf*_*ich 2 javascript charts data-visualization d3.js

我想在d3.js图表中添加一个矩形来突出显示特定的数据区域。问题是我不想指定起点,然后指定高度和长度

\n\n

相反,我想指定位于矩形左上角和右下角的直径 \xe2\x80\x93 的两个点。突出显示区域矩形需要从数据集中的最低 X 值到最高 X 值,以及从特定的较低 y 边界到特定的较高 y 边界。

\n\n

期望的结果

\n

Ger*_*ado 5

如果您只是传递两个点的x和值,为什么不使用元素本身呢?它比在你的答案中绘制路径更短、更容易:yrect

function drawRectanglePoints(x1,y1,x2,y2,container,thisClass){
    container.append("rect")
      .attr("x", x1).attr("y", y1)
      .attr("width", x2-x1).attr("height", y2-y1)
      .attr("class", thisClass).attr("id", thisId);
}
Run Code Online (Sandbox Code Playgroud)

这是您的演示:

function drawRectanglePoints(x1,y1,x2,y2,container,thisClass){
    container.append("rect")
      .attr("x", x1).attr("y", y1)
      .attr("width", x2-x1).attr("height", y2-y1)
      .attr("class", thisClass).attr("id", thisId);
}
Run Code Online (Sandbox Code Playgroud)
function drawRectanglePoints(x1,y1,x2,y2,container,thisClass, thisId){
  container.append("rect").attr("x", x1).attr("y", y1).attr("width", x2-x1).attr("height", y2-y1).attr("class", thisClass).attr("id", thisId);
}
    
    
function drawLine(x1,y1,x2,y2, svgContainer, thisClass, thisId){
    svgContainer.append("line")
    .attr("x1", x1)
    .attr("y1", y1)
    .attr("x2", x2)
    .attr("y2", y2)
    .attr("class", thisClass)
    .attr("id", thisId);
}
    
    
	// Set the dimensions of the canvas / graph
	var margin = {top: 30, right: 20, bottom: 30, left: 50},
	width = 600 - margin.left - margin.right,
	height = 270 - margin.top - margin.bottom;

    // Adds the svg canvas
	var svg = d3.select("#graph")
	.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 + ")");

	// Parse the date / time
	var parseDate = d3.time.format("%Y-%m-%d").parse;

	// Set the ranges
	var x = d3.time.scale().range([0, width]);
	var y = d3.scale.linear().range([height, 0]);

	// Define the axes
	var xAxis = d3.svg.axis().scale(x)
	.orient("bottom").ticks(5);

	var yAxis = d3.svg.axis().scale(y)
	.orient("left").ticks(5);

	// Define the line
	var valueline = d3.svg.line()
	.x(function(d) { return x(d.date); })
	.y(function(d) { return y(d.rate); })
	.interpolate("monotone");

	// Define the div for the tooltip
	var div = d3.select("body").append("div")
	.attr("class", "tooltip")
	.style("opacity", 0);


	// Get the data
    // this is where you would get your data via ajax / read a file / whatever
    var resData = JSON.parse('[{"date":"2016-09-23","rate":"11.0707","nbItems":"8"},{"date":"2016-09-24","rate":"12.0317","nbItems":"10"},{"date":"2016-09-25","rate":"14.6562","nbItems":"9"},{"date":"2016-09-26","rate":"12.9523","nbItems":"7"},{"date":"2016-09-27","rate":"11.8636","nbItems":"10"},{"date":"2016-09-28","rate":"14.1731","nbItems":"10"},{"date":"2016-09-30","rate":"14.3167","nbItems":"3"},{"date":"2016-10-01","rate":"14.8398","nbItems":"4"},{"date":"2016-10-02","rate":"10.2088","nbItems":"1"},{"date":"2016-10-03","rate":"12.1985","nbItems":"9"},{"date":"2016-10-04","rate":"16.0133","nbItems":"5"},{"date":"2016-10-05","rate":"15.4206","nbItems":"6"}]');
    var sigmaMin = 10; // our fictional lower bound of data highlighting
	var sigma = 12.5;
	var sigmaMax = 15; // our fictional upper bound of data highlighting


	var i = 0;
	var startDate = false;
	resData.forEach(function(d) {
		// console.log(d.date);
		d.date = parseDate(String(d.date));
		d.rate = +d.rate;
		d.nbItems = +d.nbItems;
		if(i === 0){
			startDate = d.date;
		}
		endDate = d.date;
		i++;
	});

    // Scale the range of the data
    x.domain(d3.extent(resData, function(d) { return d.date; }));
    y.domain([0, d3.max(resData, function(d) { return d.rate; })]);

    // Add the valueline path for the data
    svg.append("path")
    .attr("class", "line")
    .attr("d", valueline(resData));

    drawRectanglePoints(x(startDate), y(sigmaMax), x(endDate), y(sigmaMin), svg, 'sigmaRectangle','sigmaRectangle');
    drawLine(0, y(sigmaMin), 530, y(sigmaMin), svg, 'sigma_line', 'sigma_line_min');
    drawLine(0, y(sigma), 530, y(sigma), svg, 'sigma_line', 'sigma_line');
    drawLine(0, y(sigmaMax), 530, y(sigmaMax), svg, 'sigma_line', 'sigma_line_max');


    // Add the scatterplot
    svg.selectAll("dot")
    .data(resData)
    .enter().append("circle")
    .attr("r", function(d) { return d.nbItems+7; }) // make size of dots depending on nb items included in this day +7 for min value
    .attr("cx", function(d) { return x(d.date); })
    .attr("cy", function(d) { return y(d.rate); })
    .attr("data-date", function(d) { return d.date; });

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

    // Add the Y Axis
    svg.append("g")
    .attr("class", "y axis")
    .call(yAxis);

function drawRectangle(x1,y1,x2,y2,container,thisClass){
  var width = x2 - x1, height = y2 - y1;
  container.append("rect").attr("x", x1).attr("y", y1).attr("width", width).attr("height", height).attr("class", thisClass);
}
Run Code Online (Sandbox Code Playgroud)

这和你的代码之间的唯一区别是,这不会检查负宽度/高度值(但这并不重要,因为你说你将左上角作为第一对传递,右下角作为第一对传递)第二)。除此之外,值得一提的是,rect它与D3无关,它是一个SVG元素,其规范由W3C提供。