score:5
If you are just passing the x
and y
values of the two points, why not using a rect
element itself? It's way shorter and easier than drawing a path as in your answer:
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);
}
Here is your demo:
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);
}
<script src="http://d3js.org/d3.v3.min.js"></script>
<!-- dont do this inside an external css script -->
<style type="text/css">
#graph{
color: red;
width: 100%;
}
#graph path {
stroke: blue;
stroke-width: 4;
fill: none;
}
#graph .axis path,
#graph .axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
#graph circle{
fill: rgba(200, 200, 200,0.7);
cursor: pointer;
}
#graph #sigmaRectangle {
stroke: transparent;
stroke-width: 0;
fill: rgba(200, 200, 200,0.3);
}
#graph .sigma_line{
stroke: rgba(200, 200, 200,0.5);
stroke-width: 1;
fill: none;
}
</style>
<h2>D3.js Highlight area with</h2>
<p>rect with two diametral points from your dataset</p>
<div id="graph"></div>
The only difference between this and your code is that this doesn't check for negative width/height values (but it doesn't matter, because you said that you're passing the top left as the first pair and the bottom right as the second). Besides that, it's worth mentioning that rect
has nothing to do with D3, it's an SVG element and its specifications are provided by W3C.
score:1
Update: Just use a plain svg rect
object.
The trick is to build the rectangle yourself out of lines rather than to use the rect element provided by d3.js.
I use this function:
function drawRectanglePoints(x1, y1, x3, y3, svgContainer, thisClass, thisId){
// The data for the rectangle
var lineData = [
{ "x": x1, "y": y1}, // start at upper-left
{ "x": x3, "y": y1}, // goto upper-right
{ "x": x3, "y": y3}, // goto lower-right
{ "x": x1, "y": y3}, // goto lower-left
{ "x": x1, "y": y1}, // go back to upper-left
];
// accessor function
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear"); // draw straight lines, not curved
// draw the lines
var lineGraph = svgContainer.append("path") // svgContainer is the svg element initialised already
.attr("d", lineFunction(lineData)) // here we add our lines
.attr("class", thisClass) // give the element a class (performant for css)
.attr("id", thisId); // give the element an id (performant for js)
}
Usage:
drawRectanglePoints(
x(startDate),
y(sigmaMax),
x(endDate),
y(sigmaMin),
svgContainer, // this is the d3.js object of the initialized svg
'sigmaRectangle',
'sigmaRectangle'
);
Complete example:
function drawRectanglePoints(x1, y1, x3, y3, svgContainer, thisClass, thisId){
// this uses two diametral points to draw the rectange instead of a point and width and height
// The data for the rectangle
var lineData = [
{ "x": x1, "y": y1},
{ "x": x3, "y": y1},
{ "x": x3, "y": y3},
{ "x": x1, "y": y3},
{ "x": x1, "y": y1},
];
// accessor function
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
// draw the lines
var lineGraph = svgContainer.append("path")
.attr("d", lineFunction(lineData))
.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);
<script src="http://d3js.org/d3.v3.min.js"></script>
<!-- dont do this inside an external css script -->
<style type="text/css">
#graph{
color: red;
width: 100%;
}
#graph path {
stroke: blue;
stroke-width: 4;
fill: none;
}
#graph .axis path,
#graph .axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
#graph circle{
fill: rgba(200, 200, 200,0.7);
cursor: pointer;
}
#graph #sigmaRectangle {
stroke: transparent;
stroke-width: 0;
fill: rgba(200, 200, 200,0.3);
}
#graph .sigma_line{
stroke: rgba(200, 200, 200,0.5);
stroke-width: 1;
fill: none;
}
</style>
<h2>D3.js Highlight area with</h2>
<p>rect with two diametral points from your dataset</p>
<div id="graph"></div>
Source: stackoverflow.com
Related Query
- How to draw a rectangle with d3.js based on 2 diametrical points and no length or height values?
- How can you draw a collection of lines and points based on categorical data in D3?
- How to draw a line / link between two points on a D3 map based on latitude / longitude?
- Draw a map with D3.js: How to get the right scale() and translate()?
- how to draw nvd3 simple barchart with x and y axis in angularjs
- How to draw D3 Map with United States, Canada, Mexico and Puerto Rico
- How to draw a rectangle in D3.js with only 2 coordinates
- How can I draw an arc with array of points in d3 v4
- d3.js How to draw a directed graph with one node start and one node end
- Draw curve between draggable points with control points to adjust curve SVG and d3.js
- how to append a circle with a label to indicate information to rectangle node and remove the circle before download
- How can is draw rectangle based on two date?
- How to toggle data points on and off along with lines in multi-line chart
- How to draw a stack of rectangles with a predefined start position and margin level in d3
- How do I draw gridlines in d3.js with zoom and pan
- how to draw left and right rectangle sliders over x-axis of d3 graph chart
- How to draw a Bar Chart with time on xAxis and one or more numeric data for yAxis in d3js?
- How do I remove all children elements from a node and then apply them again with different color and size?
- How do I save/export an SVG file after creating an SVG with D3.js (IE, safari and chrome)?
- How to draw straight line in d3.js (horizontally and vertically)
- How to handle layers with missing data points in d3.layout.stack()
- How to draw line with arrow using d3.js
- D3 how to change the width and length of SVG
- How to create floor plans that work nice with mobile and desktop browsers?
- Draw imbricated blocks that are rotated and fliped with d3.js
- How can I show a graph using d3 force layout with initial positions set and no movement at all?
- How to pull data from mysql database and visualize with D3.JS?
- How to draw a *simple* line segment with d3.js?
- How to draw logarithmic line charts with nvd3
- d3.js visibility-zone calculations or how to draw geo rectangle
More Query from same tag
- d3plus.Geomap is not a constructor
- How to group HTML table entries with summary row above detail rows with D3
- Calculate how many std deviations the values of certain keys are from the mean
- d3 counting variable of JSON
- d3js link arc filled useless part
- wildcard selection using D3
- Creating scrollbars with SVG and d3.js
- D3.js Collapsible tree: Adding a label for each level
- array1.splice(1,1) is removing data from array2 which I have created using array1.slice(0)
- D3 remove 'zoom' completely
- How can I display a placeholder image in my SVG until the real image is loaded?
- Is there a drop event for d3.js?
- Linked hover between elements
- d3.js sankey diagram - using multi dime array as nodes
- Rearranging an array with key value
- Adding image to svg container using d3 not working on FF and Safari
- Sorting Through Multidimensional Dataset Bar Graph
- Calculate Width of a DIV based on sibling count (not-fixed) using CSS or LESS
- Two affectations and a test in if condition
- Loading csv data and save results to a variable
- Typescript d3 - Property 'pie' does not exist on type 'typeof d3'
- How does d3 select array for iteration?
- d3.js binary tree with HTML as the nodes
- D3 treemap for very large dataset
- Draw a vertical line representing the current date in d3 gantt chart
- D3 dashboard chart data bind from json or csv
- Error loading d3-geo-projection
- Dynamic path variable to play audio .mp3 file How to ? d3 javascript coffe script
- Sales pipeline chart
- Concentric arcs using D3.js