I'm trying to understand d3.js and experienced an issure related to drawing chart using d3.js. some of the data comes fine within the grid, but for some data it goes out of bound.Below is how my graph looks:
below is the js:
var svg = self.graph.selectAll(".series").data([data]);
svg.enter().append("svg:path");
//hardcoded values just for this example.
self.x = d3.time.scale()
.range([0, 881]);
self.y = d3.scale.linear()
.domain([0, 2), d3.round(36,2)])
.range([210, 15]);
How can I set a height width to the chart in order to avoid it going from out of bound?any ideas ? Thanks!!
Related
I am trying to plot stock data with a d3 line Chart. It has ugly spaces for weekends because there is no data available for weekends. What is the best way to make the X axis chart only the dates that I have data for?
const x = d3
.scaleTime()
.domain(d3.extent(data, (d) => d.datetime))
.range([0, width]);
d3 newbie experiencing a heavy learning curve at the moment.
For anyone who may have the same question:
const x = d3
.scaleBand()
.domain(data.map((d) => d.datetime))
.range([0, width]);
Band scale graphs only the dates you have data for.
I'm working on a heatmap which basically plots the graph between taxIDs and KeywordNames from an external JSON. While I'm able to plot the values I see many blank spaces on the graph and clueless how I can plot them with the available data.
Here's the link to codesandbox: https://codesandbox.io/s/40mnzk9xv4
On the X-Axis I'm plotting the TaxIDs which are being calculated within the given range. I did try using the function rangeBands() but I get an error everytime.
Its the similar case with Y-Axis where I'am plotting the keywordIDs which are also being calculated within a range. I'm trying to print all the KeywordNames on Y axis and all taxIDs on the X-Axis and plot their corresponding spectracount on graph.
Please help me where have I gone wrong.
The output I'm looking for is something similar to this: https://bl.ocks.org/Bl3f/cdb5ad854b376765fa99
Thank you.
Some things to help you get you one your way:
First, your scales should use scaleBand(), not scaleLinear(), as they have discrete domains (i.e. categories of something, rather than continuous)
Second, your scale domains is taking every value of taxId and keywordName in your data as a possible value. But some values are repeated more than once. You need to be filtering them so you only have unique values. So your scale code should be:
const xValues = d3.set(data.map(d => d.taxId)).values();
const yValues = d3.set(data.map(d => d.keywordName)).values();
const xScale = d3.scaleBand()
.range([0, width])
.domain(xValues); //X-Axis
const yScale = d3.scaleBand()
.range([0, height])
.domain(yValues); //Y-Axis
Finally, your code that places the heatmap tiles needs to be calling the scale functions so it works out the position of each rect correctly:
chart.selectAll('g')
.data(data).enter().append('g')
.append('rect')
.attr('x', d => { return xScale(d.taxId) })
.attr('y', d => { return yScale(d.keywordName) })
That should get you most of the way there. You'll want to also reduce cellSize and remove the tickFormat calls on the axes as they are trying to convert your text labels to numbers.
I created a clock with d3 by making a bar chart updates as each second passes.
Typically I would set my yScale like so:
var yScale = d3.scale.linear()
.domain(maximumTime)
.range([svgHeight, 0]);
but this will leave an a blank bar at each new minute, hour, and day. To solve for this I've set the to go to -1 so something is always displayed, even when the value is zero.
var yScale = d3.scale.linear()
.domain(maximumTime)
.range([svgHeight, -1]);
Is there a more graceful way that I can display zero values?
Full example in a CodePen: http://codepen.io/agconti/pen/vEWZXb
I'm trying to display a histogram using D3.
I started with the official example here and tried to change the scale of the x domain.
However, if I change the scale of the x domain, I get errors on the width of the individual histogram buckets.
The code in the example works (jsfiddle):
var x = d3.scale.linear()
.domain([0, 1])
.range([0, width]);
But this does not (jsfiddle):
var x = d3.scale.linear()
.domain([0.2, 1])
.range([0, width]);
Others have mentioned that, in order to zoom the x axis, you should use this:
var x = d3.scale.linear()
.domain(d3.extent(data))
.range([0, width]);
However, that's not possible since data has not been created yet, because data requires x:
var x = d3.scale.linear()
.domain([60, 95])
.range([0, width]);
// Generate a histogram using twenty uniformly-spaced bins.
var data = d3.layout.histogram()
.bins(x.ticks(7))
(values);
So how can I use data to create x if x is needed to create data?
Note that scaling the large side of the histogram does work:
var x = d3.scale.linear()
.domain([0, Number(d3.max(values))])
.range([0, width]);
However, if the small side is anything but zero, things break:
var x = d3.scale.linear()
.domain([Number(d3.min(values)), Number(d3.max(values))])
.range([0, width]);
The way you're computing the width of the bars is incorrect for your particular use case; in particular it results in negative widths (as the error message indicates). You need to take the width of the range and divide it by the number of items (minus a small number if you want gaps):
.attr("width", (x.range()[1] - x.range()[0]) / data.length - 2)
Complete demo here.
I am having a bit of a trouble scaling my graph, according to the length on the bars. For example, in the jsfiddle, I can't draw a bar beyond the data point of size 25. I know one way to fix this would be to make the width and height of the body larger. But I was thinking scaling the entire graph would be much more efficient, so that one bar doesn't end up looking abnormally large.
http://jsfiddle.net/NkkDC/
I was thinking, I would have to scale the "y" function here, but I wasn't sure how.
bars.on("click", clickEvent)
.transition().duration(2000).delay(200)
.attr("y", function(d, i) { return i * 20; })
.attr("width", x)
.attr("height", 20);
Thanks in advance :)
The input domain of your xScale can change every time you add a new value (since you could add a new maximum), so we need to recalculate the xScale when we re-render the chart. Moving the declaration of the x-scale inside your render function should do the trick :
var xScale = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, 420]);
http://jsfiddle.net/NkkDC/1/