I have this graph : http://jsfiddle.net/thatOneGuy/Rt65L/94/
I can't seem to figure out how to get the same scale in both x and y. What I need is the same distance between the ticks on both but I need the x axis to be 600px long and y axis to be 300px high.
I have tried calling the same scale but obviously the x scale is too big for the y. Any ideas ?
<svg id='svgContainer' width="1000" height="700"> </svg>
var container = d3.select('#svgContainer')
.style('stroke', 'red')
var width = 600, height = 300;
var xScale = d3.scale.linear()
.range([0, width]);
var yScale = d3.scale.linear()
.range([0, height]);
var xTicks = width/50;
var yTicks = height/50;
var xAxis = d3.svg.axis()
.scale(xScale)
.innerTickSize(-(height)) // vertical grid lines
.outerTickSize(0)
.orient("bottom")
.ticks(xTicks);
var yAxis = d3.svg.axis()
.scale(yScale)
.innerTickSize(-(width)) // horizontal grid lines
.outerTickSize(0)
.orient("left")
.ticks(yTicks);
container.append("g")
.attr("class", "x axis")
.attr("transform", "translate(50," + (height+20) + ")")
.call(xAxis)
container.append("g")
.attr("class", "y axis")
.attr("transform", "translate(50,20)")
.call(yAxis)
If you don't set the domain, D3 will automatically set it as [0, 1]. So, I believe that, in your case, it's simply a matter of setting the domains:
var xScale = d3.scale.linear()
.range([0, width])
.domain([0,1]);
var yScale = d3.scale.linear()
.range([height, 0])
.domain([0,0.5]);
Here is the fiddle: http://jsfiddle.net/gerardofurtado/Rt65L/96/
Related
I am new to D3 and currently trying to create a line graph. The axis are created with the right dimensions, however the label for the axes are not showing up. They are there, as when I highlight where they are supposed to be, they show up. They must be hidden or being displaying with a white fill but I'm not sure as to why that is happening. Below is my code for adding axes to the chart.
var xScale = d3.scaleTime()
.domain(d3.extent(data[0].values, d => d.date))
.range([0, width1-margin1]);
var yScale = d3.scaleLinear()
.domain([0, 40])
.range([height1-margin1, 0]);
/* Add Axis into SVG */
var xAxis = d3.axisBottom(xScale).ticks(10);
var yAxis = d3.axisLeft(yScale).ticks(10);
svg1.append("g")
.attr("class", "x axis")
.attr("transform", `translate(0, ${height1-margin1})`)
.call(xAxis);
svg1.append("g")
.attr("class", "y axis")
.call(yAxis)
}
The values are there, they are just not displayed for some reason
I tried to create a bar chart showing days of each month in a year. I want to change the numbers in x-axis of bar chart, but it turns out that the number starts from 0 and ends with 11, instead of 1 to 12. How can I solve this problem?
//x
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, width - padding.left - padding.right]);
//y
var yScale = d3.scale.linear()
.domain([0,d3.max(dataset)])
.range([height - padding.top - padding.bottom, 0]);
//the define of x
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
//define of y
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
/add x
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis);
use tickformat() to format the axis labels as:
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(function(d) { return d + 1; }); //make changes here relevant to ur data
I'm trying to update the width of my axis like so:
Initial setup with zero width:
var x2 = d3.scale.linear()
.domain([0, 10])
.range([0, 0])
.clamp(true);
svg.append("g")
.attr("class", "x axis2")
.attr("transform", "translate(0," + height / 2 + ")")
.call(d3.svg.axis()
.scale(x2)
.orient("bottom")
.tickFormat(function(d) { return d; })
.tickSize(0)
.tickPadding(12))
.select(".domain")
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "bar-highlight");
Later I want to update the width of the path (with a nice transition would be great). I tried it like suggested in this answer, with no luck:
x2 = d3.scale.linear()
.domain([0, data.page_count])
.range([0, 15])
.clamp(true);
d3.selectAll("g.x.axis2")
.call(x2);
You need to call d3.svg.axis().scale(x2) on the axis, not just x2. The following update procedure works for me (albeit on an empty plot):
// Update the range of existing variable, x2
x2.range([0, 15]);
// Select and change the axis in D3
d3.selectAll("g.x.axis2")
.call(d3.svg.axis().scale(x2));
I'm plotting the graphs with "number of clicks" as Y axis and "date" as X axis. Because of the large amount of data, the X axis is jumbled and couldn't display all the dates. I tried to use ticks(d3.time.months, 1) and tickFormat('%b %Y') to cur off some of the ticks. When I run the code, I got "getMonth() is not defined" for my data.
.tsv file:
date count
2013-01-01 4
2013-03-02 5
sample code:
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1, 0);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months, 1)
.tickFormat(d3.time.format('%b %Y'))
d3.tsv("data_Bar_Chart_Paino_Kristen.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.hits; })]);
var temp = height + 30; //+15
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(-8," + temp + ")")
.call(xAxis);
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.date); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.hits); })
.attr("height", function(d) {return height - y(d.hits); });
}
Is there a way to solve my problem and show ticks properly?
You'll need to tell D3 that your axis is a date. Try this:
//assumes the data is sorted chronologically
var xMin = data[0].dateFieldName;
var xMax = data[data.length-1].dateFieldName;
//set the scale for the x axis
var x = d3.time.scale().domain([xMin, xMax]).range([0, width]);
//straight from your code
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months, 1)
.tickFormat(d3.time.format('%b %Y'))
The trick here is to use the d3.time.scale() method.
If you use the d3.time.scale() you have another problem, you can't use x.rangeBand() when you draw the rect.
Working with one bar chart with d3.js I am unable to align ticks in x axis with bars.
In left and right verges the ticks are ok, but not in the middle.
Here is the code:
var formatDate = d3.time.format("%e %b");
var height = 325;
var xTimeScale = d3.time.scale()
.domain([new Date(data[0].date), d3.time.day.offset(new Date(data[data.length - 2].date), 1)])
.range([30, width]);
var xAxis = d3.svg.axis()
.scale(xTimeScale)
.orient("bottom")
.ticks(d3.time.days, .1)
.tickFormat(formatDate);
chart.append("g")
.attr("class", "xaxis axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
chart.selectAll(".xaxis text")
.attr("transform", function(d) {return "translate(" + this.getBBox().height * -2 + "," + this.getBBox().height + ")rotate(-45)";});
What am I missing?
Thanks in advance.
Update: Here is the jsFiddle updated with chrtan suggestions.
My problem now is to align text with the center of bar and not in left.
From the looks of your graph, you lost a bar's worth of space. If all the bars are supposed to be left-aligned against a tick, that final bar you have should be to the right of the January 31st tick.
You might need to add the February 1st tick by perhaps changing the [data.length - 2] to [data.length - 1] in the domain() for your xTimeScale.
Then for display purposes, you could probably remove the last tick axis text with:
d3.select(chart.selectAll(".xaxis text")[0].pop()).remove();
The inner selectAll should get the array containing your xAxis tick texts and then pop the very last tick. This last tick should then be removed by the outer select.
An example with an auto time ticks with d3.js
// set domain for axis
var x_domain = d3.extent(data, function(d) { return new Date(d.date); });
//format date
var date_format = d3.time.format('%Y %B');
var vis = d3.select("#graph")
.append("svg:svg")
.attr('class', 'chart')
.attr("width", width)
.attr("height", height);
var yScale = d3.scale.linear()
.domain([0, d3.max(data, function(d) { return d.data; })]).nice()
.range([height - padding, padding]);
var xScale = d3.time.scale()
.domain(x_domain)
.range([padding, width - padding]);
// define the y axis
var yAxis = d3.svg.axis()
.orient("left")
.scale(yScale);
// define the x axis
var xAxis = d3.svg.axis()
.orient("bottom")
.scale(xScale)
.tickFormat(date_format);
// draw y axis with labels and move in from the size by the amount of padding
vis.append("g")
.attr("class", "axis")
.attr("transform", "translate("+padding+",0)")
.call(yAxis);
// draw x axis with labels and move to the bottom of the chart area
vis.append("g")
.attr("class", "xaxis axis")
.attr("transform", "translate(0," + (height - padding) + ")")
.call(xAxis);
// and set data in graph...
a great example : http://bl.ocks.org/phoebebright/3061203