I need to create two bar rectangles one near another using data array [74, 26]. I have a container that is, for example, 100px height. So I need to make first bar 74px height and second bar 26px to fill in the container.
I suppose I can do this with d3.scale.linear, but having something like this:
y = d3.scale.linear()
.domain([d3.min(data), d3.max(data)])
.range([0, 100])
I get one bar as 0px height and another as 100px height which is incorrect. How can I do it properly?
In D3 scales, the first value of the domain is mapped to the first value in the range and similarly the second value of the domain is mapped to the second value in the range. For linear scales, the function connecting the two extremes is linear.
So for the example in your question, you would need a scale like this.
d3.scale.linear().domain([0,100]).range([0,100]);
Related
I am using d3.js library to construct a barchart with horizontal bars. When there are more than 50 bars in my chart then the spacing between the beginning of the axis and the first bar is strangely higher compared to when there are less than 50 total bars.
Spacing with less than 50 bars (desired behavior) -
Spacing with more than 50 bars (undesirable) -
I am wondering what could be the issue since in both the cases similar code flow is used. Is it even possible or is there any known attribute/property which is responsible for controlling this particular spacing ?
The trick was to replace
d3.scale.ordinal()
.rangeRoundBands([0, size], 0.5);
with
d3.scale.ordinal()
.rangeBands([0, size], 0.5);
because using rangeRoundBand rounding apparently introduces additional outer padding which is, on average, proportional to the length of the domain. This is the reason why in case of more than 50 bars I was able to see more space at the beginning and the end.
I've completed a bar graph codepen showing US GDP (the popular one from FCC).
https://codepen.io/le-hu/pen/Baoywgd
The problem i can't eradicate is such - the graph does not start at bottom padding 50units above svg bottom, but instead spans to the border and even goes below svg border i believe. I've tried changing every setting. My bet is something's wrong with the yScale domain, or range property.
const yScale = d3.scaleLinear()
.domain([0,
d3.max(data.data, d => d[1])])
.range([height - padding, padding]);
Code seams to be ignoring the height - padding part in range setting. (or my understanding of it)
I'd like the graph to start on the line the x axis we have, the one showing dates in years 1950+.
Just like in the original:
https://codepen.io/freeCodeCamp/pen/GrZVaM
thank you for any insight!
Mehdi's solution worked like a charm - thank you very much for your time!
In SVG, the vertical coordinates go from top to bottom(reference).
This makes the reasoning about the y coordinate and height of a vertical bar in a bar chart less straightforward.
The tutorial Let's make a bar chart, part 4 explains how to perform this.
the y position of the rectangle has correctly been set tothe one of the value d[1]:
.attr("y", (d, i) => yScale(d[1]))
The height of the rectangle is incorrect, though. It should be the distance between origin (value 0) and position of the value d[1]. As shown below:
.attr("height", (d, i) => yScale(0)- yScale(d[1]))
I am new to d3v4 and working on a chart where i need to show little rectangle on certain date matching to its title on yaxis. The problem i am facing is rectangles in the chart area not drawing equal to the yaxis point labels, i have tried changing the y value by hardcoding, it works fine but the point is the number of data object will change in real time like it could be any number of objects in an array. Here is the plunker
To draw the graph dynamically with limited data objects i've created few buttons on top of chart so that rectangles in the chart can draw equal to y-axis labels.
Any help is much appreciated.
You are using a band scale: that being the case, you should not change the y position, which should be just...
.attr('y', function(d) {
return yScale(d.title);
})
.. and you should not hardcode the height: use the bandwidth() instead:
.attr('height', yScale.bandwidth())
The issue now is setting the paddingInner and paddingOuter of the scale until you have the desired result. For instance:
var yScale = d3.scaleBand().domain(data.map(function(d) {
return d.title
}))
.range([height - 20, 0])
.paddingInner(0.75)
.paddingOuter(.2);
Here is the plunker with those changes: https://plnkr.co/edit/ZxGCeDGYwDGzUCYiSztQ?p=preview
However, if you still want (for whatever reason) hardcode the height or the width of the rectangles, use a point scale instead, and move the y position by half the height.
I have a line chart in D3 as seen here:
I am attempting to extend the x-axis to be the same size as the y-axis tick width. Currently I am setting the ranges as follows:
// set the ranges
var x = d3.scaleTime().range([20, width - 20]);
var y = d3.scaleLinear().range([height, 0]);
This achieves my desired effect of pushing the plot in from the left and right sides but does not extend the x-axis. I'm sure there has to be a way to add padding to the plot without changing the ranges but I can't seem to figure out how?
There's no easy way to add padding to a linear scale.
However, in your case, since your x axis is presenting categorical data (days of the week), you can use a d3.scalePoint and configure its outer padding with the padding function.
I'm trying to display axis for a grid based chart (heat map) to display correctly. I can get them into the right alignment (centered with each grid whether it be row or column), but they are on top of the grid where I want to have them displayed outside of the grids.
Here's what I have so far: http://jsbin.com/hihepo/8
Provide some margins around and translate your chart's g wrapper. You have margins defined, but they are never used, so you chart stretches until svg element borders and there's no more space around.
Use .orient('left') for y axis and .orient('bottom') for x axis orientation. See docs for orient method.
Adjust the transform and text-anchor of your x axis labels (or change the translation of their g wrapper).
Here's a demo for x axis labels.