Haf*_*ich 2 javascript charts data-visualization d3.js
我想在d3.js图表中添加一个矩形来突出显示特定的数据区域。问题是我不想指定起点,然后指定高度和长度。
\n\n相反,我想指定位于矩形左上角和右下角的直径 \xe2\x80\x93 的两个点。突出显示区域矩形需要从数据集中的最低 X 值到最高 X 值,以及从特定的较低 y 边界到特定的较高 y 边界。
\n\n\n如果您只是传递两个点的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提供。