I am trying to graph a vertical line on a time axis using the d3js library. The x-axis is the year 2015. I'd like the vertical line to represent today (where today is always the current day). The problem I'm having is figuring out how exactly to feed the date as a coordinate in order to be graphed properly. Here is the jsfiddle for the code.
var margin = {top: 10, right: 10, bottom: 30, left: 10},
width = 1200 - margin.left - margin.right,
height = 800 - margin.top - margin.bottom;
var x = d3.time.scale()
.domain([new Date(2015, 0, 1), new Date(2015, 11, 31)])
.range([0, width]);
var y = d3.scale.linear()
.domain([0,1000])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months)
.tickSize(30, 0)
.tickFormat(d3.time.format("%B"));
var xAxisMinor = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months)
.tickSize(-height)
.tickFormat(d3.time.format("%B"));
var xAxisMinorTicks = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.weeks)
.tickSize(-height)
.tickFormat(d3.time.format("%U"));
var svg = d3.select("body").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 + ")");
svg.append("rect")
.attr("class", "grid-background-light")
.attr("width", width)
.attr("height", height + margin.bottom)
.attr("rx", 5)
.attr("ry", 5);
svg.append("rect")
.attr("class", "grid-background")
.attr("width", width)
.attr("height", 30)
.attr("transform", "translate(0," + (height) + ")");
svg.append("g")
.attr("class", "minorTicks")
.attr("transform", "translate(0," + height + ")")
.call(xAxisMinorTicks)
.selectAll(".tick")
.data(x.ticks(52), function(d) { return d; })
.exit()
.classed("minorTicks", true);
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(xAxisMinor)
.selectAll(".tick")
.data(x.ticks(12), function(d) { return d; })
.exit()
.classed("minor", true);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll(".tick text")
.style("text-anchor", "start")
.attr("x", 12)
.attr("y", 12);
// Vertical line for today
var theDate = new Date();
var today = theDate.getMonth()+1 + "/" + theDate.getDate() + "/" + theDate.getFullYear();
svg.append("svg:line")
.attr("class", "today")
.attr("x1", x(d3.time.format("%x").parseDate(today)))
.attr("y1", height)
.attr("x2", x(d3.time.format("%x").parseDate(today)))
.attr("y2", 0);
In your code you just need to change the code like below,
svg.append("svg:line")
.attr("class", "today")
.attr("x1", x(d3.time.format("%x").parseDate(today)))
.attr("y1", height)
.attr("x2", x(d3.time.format("%x").parseDate(today)))
.attr("y2", 0);
to
svg.append("svg:line")
.attr("class", "today")
.attr("x1", x(theDate))
.attr("y1", height)
.attr("x2", x(theDate))
.attr("y2", 0);
d3.time.format("%x") this will return a function which takes date object as argument and it returns date string in %x format.
But you are calling parseDate function which is not available/defined.
Refer this
Hope you got it, if not ask me for more.
Related
I am working with a scatterplot in d3. The x axis represents the YEAR. I get information from the database and plot it as circles on the graph. My problem is how do I parse the x value so it is formatted as a year? ie. currently it displays like 1,999 but it should look like 1999. Can someone show me how I should parse this correctly to get the right format! Here is the relevant code:
var margin = {top: 20, right: 20, bottom: 30, left: 60},
width = 1800 - margin.left - margin.right,
height = 600- margin.top - margin.bottom;
var YearFn = function(d) {return d.YEAR ;};
var Num_citationsFn = function(d) {return d.counter;};
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left");
d3.json("connection4.php", function(error,data) {
dataJson.forEach(function(d) {
d.YEAR = +d.YEAR;
d.counter = d.counter;
x.domain([d3.min(data, YearFn)-1, d3.max(data, YearFn)+1]);
y.domain([d3.min(data, Num_citationsFn)-1, d3.max(data, Num_citationsFn)+1]);
var svg = d3.select("body")
.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 + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("YEAR");
// y-axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Number of citations");
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 8.5)
.attr("cx", function(d) {return x(YearFn(d))})
.attr("cy", function(d) {return y(Num_citationsFn(d))})
.style("fill","blue")
});
I appreciate any feedback I am new to d3! Thanks in advance!
xAxis.tickFormat(d3.format('0f'));
I am using this http://bl.ocks.org/mbostock/3885304 reference for drawing Bar Char using Meteor and D3
This code returns y Axis is 0 and height always same.....
CODE PART
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var xScale = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var yScale = d3.scale.linear()
.range([height, 0]);
var xAxis =d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var svg = d3.select('#Rectangle')
.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 + ")");
var drawCircles = function(error,update) {
if (error) throw error;
var data = Extra.find().fetch();
xScale.domain(data.map(function(d) { return d.inst; }));
yScale.domain([0, d3.max(data, function(d) { return d.percent; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Percentaz");
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr("x", function(d) { return xScale(d.inst); })
.attr("y", function(d) { return yScale(d.percent); })
.attr("width", xScale.rangeBand())
.attr("height", function(d) { return height-yScale(d.percent); });
};
Extra.find().observe({
added: function () {
x =[];
var f = Extra.find().fetch() ;
for(var i=0;i<f.length;i++){
x.push(parseInt(f[i].percent))
}
drawCircles(false);
},
changed: _.partial(drawCircles, true)
});
};
Please provide me solution regarding this so i can implement it
I'm trying to adapt this code:
http://bl.ocks.org/anupsavvy/9513382
To plot a stacked-bar chart using custom data. I don't need any transitions, just a simple plot.
I end up with this code:
data = jsonArr;
var margin = {
top: 40,
right: 40,
bottom: 40,
left: 40
},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var color = d3.scale.ordinal()
.range(colorrange);
var stack = d3.layout.stack();
stack(data);
var xScale = d3.time.scale()
.domain([new Date(0, 0, 0, data[0][0].label, 0, 0, 0), new Date(0, 0, 0, data[0][data[0].length - 1].label, 0, 0, 0)])
.rangeRound([0, width - margin.left - margin.right]);
var yScale = d3.scale.linear()
.domain([0,
d3.max(data, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.value;
});
})
])
.range([height - margin.bottom - margin.top, 0]);
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(d3.time.hour, 1)
.tickFormat(d3.time.format("%H"));
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(10);
var svg = d3.select("#info")
.append("svg")
.attr("width", width)
.attr("height", height);
var groups = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("class", "rgroups")
.attr("transform", "translate(" + margin.left + "," + (height - margin.bottom) + ")")
.style("fill", function(d, i) {
return colorrange[i];
});
var rects = groups.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("width", 6)
.attr("height", function(d) {
return -yScale(d.value) + (height - margin.top - margin.bottom);
})
.attr("x", function(d) {
return xScale(new Date(0, 0, 0, d.label, 0, 0, 0));;
})
.attr("y", function(d) {
return -(-yScale(d.y0) - yScale(d.value) + (height - margin.top - margin.bottom) * 2);
});
console.log(rects);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(40," + (height - margin.bottom) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(yAxis);
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - 5)
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.text("Number of complaints");
svg.append("text")
.attr("class", "xtext")
.attr("x", width / 2 - margin.left)
.attr("y", height - 5)
.attr("text-anchor", "middle")
.text("Hour of day");
More specifically:
yScale(d.y0) is returning NaN.
If I comment this piece of code, I can see the axes:
After a while, I managed to see the and some data (among errors):
I guess I'm not understanding the properly way to plot the data itself.
Any help would be appreciated.
My json label attribute is related to the y coordinate, while value is related to the x coordinate.
EDIT:
It seems that the problem begins when I call stack. The first array has y0 values as 0, but the second and third ones have y0 = NaN. I don't know how to fix this.
This is the relative jsfiddle:
https://jsfiddle.net/rhzkz9gb/13/
You need to provide the accessor functions for the data (because it is not keyed with 'x' and 'y').
var stack = d3.layout.stack().x(function(d,i){return i;}).y(function(d){return d.value;});
https://jsfiddle.net/ermineia/rhzkz9gb/14/
I've an horizontal bar chart in d3.js and I would like to add the name like "y-label" for every bar of the chart.
The original example of my bar chart is http://bl.ocks.org/mbostock/2368837
without negative values.
So I modified it for my purpose
var margin = {top: 40, right: 20, bottom: 100, left: 60},
width = 720 - margin.left - margin.right,
height = 480 - margin.top - margin.bottom;
var x_4 = d3.scale.linear()
.range([0, width])
var y_4 = d3.scale.ordinal()
.rangeRoundBands([0, height], .2);
var xAxis_4 = d3.svg.axis()
.scale(x_4)
.orient("top");
var tip_4 = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Value:</strong> <span style='color:red'>" + d.ln_numfollowers + "</span>";
})
var sampleSVG_4 = d3.select("#LinkedIn").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 + ")")
.call(tip_4);
d3.csv("#routes.Assets.at("d3/linkedin_competitor_prova.csv")", type, function(error, data) {
x_4.domain(d3.extent(data, function(d) { return d.ln_numfollowers; })).nice();
y_4.domain(data.map(function(d) { return d.organization_name; }));
sampleSVG_4.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", function(d) { return d.ln_numfollowers < 0 ? "bar negative" : "bar positive"; })
.attr("x", function(d) { return x_4(Math.min(0, d.ln_numfollowers)); })
.attr("y", function(d) { return y_4(d.organization_name); })
.attr("width", function(d) { return Math.abs(x_4(d.ln_numfollowers) - x_4(0)); })
.attr("height", y_4.rangeBand())
.on('mouseover', tip_4.show)
.on('mouseout', tip_4.hide);;
sampleSVG_4.append("g")
.attr("class", "x axis")
.call(xAxis_4);
sampleSVG_4.append("g")
.attr("class", "y axis")
.append("line")
.attr("x1", x_4(0))
.attr("x2", x_4(0))
.attr("y2", height)
});
function type(d) {
d.ln_numfollowers = +d.ln_numfollowers;
return d;
}
The csv data file is:
organization_name,ln_numfollowers
Carrot.mx,100
CarJump,45
I don't know why the organization_name is not showing.
As you can see, not even in the original example the label on the y axis are showing.
Couple of problems:
1.) You probably don't want to create your x-axis using extent. With your sample data this would create a chart from 45 to 100. You probably want to start it at zero.
x_4.domain([0,d3.max(data, function(d) { return d.ln_numfollowers; })]);
2.) You don't actually create a conventional y-axis. This code:
sampleSVG_4.append("g")
.attr("class", "y axis")
.append("line")
.attr("x1", x_4(0))
.attr("x2", x_4(0))
.attr("y2", height)
Is creating a y-axis that's just a line. It's not using the built-in d3axis creation. What you need is:
var yAxis_4 = d3.svg.axis()
.scale(y_4)
.orient("left");
....
sampleSVG_4.append("g")
.attr("class", "y axis")
.call(yAxis_4);
Example here.
I have built a barchart with D3 but I'm running into these 2 minor issues which I am not be able to fix.
1) The first bar of the barchart overlaps the y axis
2) The labels of the y axis ticks are disappearing on the left side when the number(Volume) exceeds 1 million.
Here is a snapshot of what is happening:
Here's my D3 code:
function drawGraph(dataGraph){
if (dataGraph.length == 0){
$('#graph-container').append('<h3>No Data Match</h3>');
return;
}
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 900 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom,
padding = 15;
var max = d3.max(dataGraph, function(d) { return +d.VOLUME;} );
var maxDate = d3.max(dataGraph, function(d) { return +d.AS_OF_DATE;} );
var x = d3.scale.ordinal()
.domain(dataGraph.map(function(d) {return d.AS_OF_DATE;}))
.rangeRoundBands([0, (width- padding )], .1);
var y = d3.scale.linear()
.domain([0,max])
.range([height,0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
var yAxis = d3.svg.axis()
.scale(y)
.orient('left')
.ticks(10);
var svg = d3.select("#graph-container")
.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 + ")");
svg.append('g')
.attr('class', 'x axis')
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.style("color", "#333")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style("color", "#333")
.text("Volume");
svg.selectAll('.bar')
.data(dataGraph)
.enter().append('rect')
.attr('class', 'bar')
.attr("x", function(d) { return x(d.AS_OF_DATE); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.VOLUME); })
.attr("height", function(d) { return height - y(d.VOLUME); });
}