I have plotted the X and Y axes. I have couple of points to show on the axis. My points vary for X axis from 4.5 to 8 and for Y axis from 2 to 4.
You can find the DEMO of what I have done.
function kmeans(){
x_means[0] = 5.9;
plotMeans();
}
The problem is this chart shows the points such as 0.59. However, I can't see when I give the value of 5.9 since it falls out of the chart.
Any ideas on how to solve this?
Thank you!
If you inspect your javascript console, you'll see this error:
Error: Invalid value for <circle> attribute cy="NaN"
This is because the data you feed d3 is:
> numeric.transpose([[0.59],[]])
Array[2]
0: 0.59
1: undefined
So that:
.attr("cy", function(d, i){return Y(d[1]);});
is an operation on undefined.
EDITS
Do'h, just re-read your question. Your scales need a domain, this is the user space span of your coordinate space. The range then is is the pixel span of your coordinate space. The scale maps the two together:
var X = d3.scale.linear()
.range([0, width]) //<-- 0 to 960 pixels
.domain([0,10]); //<-- maps to coordinates 0 to 10
See update here.
I also modified it to use proper axis so it's easier to visualize.
Related
I have a scatterplot that uses constraint relaxation to de-conflict the labels for the points that it graphs (Plunker here). The problem is that, when I relax the constraints, this causes collisions between the point labels and the x-axis labels. The axes are generated using d3.extent and d3.scale.linear.
I've tried to de-conflict the point labels and the x-axis by extending the length of the y-axis, but the closest I've come to achieving this is by changing the original value of 0 to 30 in the following stanza:
var yext = d3.extent(data, d => d[1]);
var sy = d3.scale.linear()
.domain(yext)
.range([height, 30]) // flip y-axis
.nice();
The result is less than ideal, leaving an awkward gap instead of an intersection between the x and y axes:
What I want to achieve is something like this:
(Except I want to achieve this through code, rather than Photoshop).
Can anyone demonstrate a solution? (Plunker here)
Why don't you add a padding in the domain? Like:
.domain([yext[0] * 0.95, yext[1] * 1.05])
//less here---------^-- more here----^
Here is the plunker with that solution: http://plnkr.co/edit/rKArjn7DwQa9g1X5CaNW?p=preview
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'm trying to make a d3 plot based on Focus+Context example.
It works fine, but I'm not able to set a minimal value for the y-axis.
I taught I understood the theory of input domain and output range (http://chimera.labs.oreilly.com/books/1230000000345/ch07.html), but it seems I'm missing something.
here is my code: http://jsfiddle.net/cecdsmnv/1/
I want the y axis to go from minAltitude to maxAltitude
any idea?
You have all the right ideas.
The settings you made for y.domain will be overwritten in line 72. Change around line to (switch min and max):
var z = 50;
x.domain(d3.extent(data.map(function(d) { return d.date; })));
y.domain([minAltitude, maxAltitude + z]);
x2.domain(x.domain());
y2.domain(y.domain());
I added a z padding variable there in case you want some heading space at the top.
I'm trying to do a chart based on http://mbostock.github.com/d3/talk/20111116/bar-hierarchy.html, the only difference being that I'd like to use a log scale for the x-axis.
Here's my fiddle: http://jsfiddle.net/JhDVC/5/
As you can see, the x-axis is defined at line 4:
x = d3.scale.linear().range([0, w]),
If I change it for
x = d3.scale.log().range([0, w]),
Then it doesn't work (nothing is rendered), throwing these error messages:
Error: Invalid value for <rect> attribute width="NaN"
Changing the domain setting from
x.domain([0, root.value]).nice();
to
x.domain([1, root.value]).nice();
shows me the z axis (names) but still no bars or values.
There are a few other places where the domain for the scale is set. You need to update those as well.
Working jsfiddle here.
And here's some code so that it allows me to post this:
x.domain([1, root.value]).nice();
Your range includes zero - log(0) is undefined.
I'm trying to create a grouped bar chart with 70 samples and 2 series. Similar to this example:
http://bl.ocks.org/882152
However one series is [0 ... 1] and the other series is [0 ... 1.000.000]. I can't recreate the example with my numbers.
I also don't really get the example. Shouldn't be the variables switched, i.e. x -> y, y0 -> x0 and y1 -> x0? Or don't they stand for the x and y axis?
Thank's!
Edit:
Here is an example that demonstrates my problem (look in the console).
http://jsfiddle.net/kQSGF/3/
The problem seems to come from the scale definition:
var x = d3.scale.linear().domain([0, 1]).range([h, 0]);
The domain is set to [0,1] but only your first data series actually falls in that range.
you could consider setting the domain to the extent of your data, and reversing the output range so that it shows the values in your data instead of the 'non' value amount as a bar:
var x = d3.scale.linear().domain(d3.extent(d3.merge(data))).range([0,h]);
Note that you will still be unlikely to see your smaller data series, as the ranges of your data are so significantly different