how to create bar graph dynamically using d3 js in .net - asp.net-mvc-3

I am new in D3 js and working on it.i wanted to implement bar graph through it in my MVC3 web application.Could you please let me know how can i create bar graph with dynamically.below is sample code but i am not able to find the dynamic creation bar graph
<script>
var margin = { top: 20, right: 20, bottom: 30, left: 50 },
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y").parse;
var x = d3.time.scale()
.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");
var line = d3.svg.line()
.x(function (d) { return x(d.year); })
.y(function (d) { return y(d.oil); });
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 + ")");
d3.csv("YearlyOilProduction.csv", function (error, data)
{
data.forEach(function (d) {
d.year = parseDate(d.year);
d.oil = +d.oil;
});
x.domain(d3.extent(data, function (d) { return d.year; }));
y.domain(d3.extent(data, function (d) { return d.oil; }));
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("million Sm3");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
</script>

Related

Constraining axis labels in d3

I am following a tutorial so I can learn a bit of d3js.
Here is my code:
'use strict';
//Dashboard
//setup size of line chart
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
//parse data from file
var parseDate = d3.time.format("%b").parse;
//set scales
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
//create axes
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
//construct the line using points from data
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.users); });
var svg = d3.select(".linechart").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 + ")");
d3.tsv("data.tsv", function(error, data) {
if (error) throw error;
//traverse through the data
data.forEach(function(d) {
d.date = parseDate(d.date);
d.users = +d.users;
});
//establish the domain for x and y axes
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain(d3.extent(data, function(d) { return d.users; }));
//add "groups"
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("Users (unique)");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
The results look like this:
The data is:
date users
Jan 10
Feb 20
Mar 30
....
My question is about the axis, how can I force it to not insert labels on the x axis that are not in the data set?
Set ticks for x axis manually:
...
if (error) throw error;
var ticks = data.map(function(d) { return parseDate(d.date) };
...
x.domain(d3.extent(data, function(d) { return d.date; })).tickValues(ticks);
https://github.com/d3/d3-3.x-api-reference/blob/master/SVG-Axes.md#tickValues

Change chart colors

I have a bar chart/histogram, all working fine.
I need to change the text and lines on the chart is on a black background.I
Also, the bar colors need to be orange.
I have had a look around the web, and seen some references to .attr("style":...); and have tried this without success.
Any pointers gratefully received.
<script>
// set the dimensions of the canvas
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 1890 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// set the ranges
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
var y = d3.scale.linear().range([height, 0]);
// define the axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(10);
// add the SVG element
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 + ")");
// load the data
d3.json("/assets/js/risk_hist_values.json", function(error, data) {
// the number of columns in this chart
var numCols = data.length;
data.forEach(function(d) {
d.Letter = d.bin_no;
d.Freq = +d.count;
});
// scale the range of the data
x.domain(data.map(function(d) { return d.Letter; }));
y.domain([0, d3.max(data, function(d) { return d.Freq; })]);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Count:</strong> <span style='color:red'>" + d.count + "</span>";
})
// call the tips
svg.call(tip);
// add axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", "-.55em")
.attr("transform", "rotate(-90)" );
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Count");
// Add bar chart
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.Letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.Freq); })
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
.on('click', drill)
.attr("id", function(d, i){ return 'b_'+i+''; })
.attr("height", function(d) { return height - y(d.Freq); });
});
function drill(){
alert( 'drilling' );
}
</script>

transform linechart to 'squared' chart not being a barchart

I just created a linechart but what I would really like is that the line is not going from point to point, but that the line is more squared.
I don't know if this has a specific name, but these pictures should make it all a bit more clear:
This is what I have:
This is what I want:
Is there a way to do this in d3 without having to create a script which adds the 'extra' points?
This is the code I use for the line chart:
var maxDepth = graphObj[graphObj.length-1].maxDepth ;
$('#floodRiskChart').html('');
var margin = {top: 5, right: 5, bottom: 50, left: 65},
width = 410 - margin.left - margin.right,
height = 210 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.domain([0, maxDepth ])
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return x(d.exceedance); })
.y(function(d) { return y(d.depth); });
var svg = d3.select("#chart").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 + ")");
graphObj.forEach(function(d) {
//d.date = parseDate(d.date);
d.exceedance = parseFloat(+d.exceedance);
d.depth= parseFloat(+d.depth);
});
x.domain(d3.extent(graphObj, function(d) { return parseFloat(d.exceedance); }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", "25%")
.attr("dy", "3em")
.html("chance");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", -50)
.attr("dx", 0)
.style("text-anchor", "end")
.html("depth");
svg.append("path")
.datum(graphObj)
.attr("class", "line")
.attr("d", line);
you need to add .interpolate('step-after') on the line generator, like so:
var line = d3.svg.line()
.interpolate('step-after')
.x(function(d) { return x(d.exceedance); })
.y(function(d) { return y(d.depth); });
this will give you that result, more info can be found here: enter link description here towards the end of the page

TypeError: Cannot call method 'forEach' of undefined " in d3 js on MVC Razor

Why I am getting error on below code in place of data.forEach
I added D3 js as well but code is not able to identified the "data.forEach".please let me know how to resolve this issue on MVC razor.
my data2.csv is below
date,close
1971,0.357
1972,1.927
1973,1.870
1974,2.014
1975,10.995
1976,16.227
1977,16.643
1978,20.644
1979,22.478
my scripts is below
var margin = { top: 20, right: 20, bottom: 30, left: 50 },
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y").parse;
var x = d3.time.scale()
.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");
var line = d3.svg.line()
.x(function (d) { return x(d.date); })
.y(function (d) { return y(d.close); });
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 + ")");
d3.csv("data2.csv", function (error, data)
{
data.forEach(function (d)
{
d.date = parseDate(d.date);
d.close = +d.close;
});
x.domain(d3.extent(data, function (d) { return d.date; }));
y.domain(d3.extent(data, function (d) { return d.close; }));
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("million Sm3");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
</script>
According to the comments above, it has to do with the parsing of the date and perhaps with the loading of the csv, as Lars suspects. In any case, here is a working fiddle after changing the csv to a javascript variable.
data.forEach(function (d)
{
d.date = parseDate(d.date.toString());
d.close = +d.close;
});

D3.js, Sortable Barchart not displaying

I`m using d3.js, Sortable Barchart with the following code:
function countrydownloads(input) {
d3.select(".barchartCountryDownloads").select("svg").remove();
var data = [{"country":"Austria","downloads":"10000"},{"country":"Germany","downloads":"20000"},{"country":"Spain","downloads":"30000"}];
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var formatPercent = d3.format(".0%");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1, 1);
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")
.tickFormat(formatPercent);
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 + ")");
data.forEach(function(d) {
d.downloads = +d.downloads;
});
x.domain(data.map(function(d) { return d.country; }));
y.domain([0, d3.max(data, function(d) { return d.downloads; })]);
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("Frequency");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return x(d.country); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.downloads); })
.attr("height", function(d) { return height - y(d.downloads); });
d3.select("input").on("change", change);
var sortTimeout = setTimeout(function() {
d3.select("input").property("checked", true).each(change);
}, 2000);
function change() {
clearTimeout(sortTimeout);
// Copy-on-write since tweens are evaluated after a delay.
var x0 = x.domain(data.sort(this.checked
? function(a, b) { return b.downloads - a.downloads; }
: function(a, b) { return d3.ascending(a.country, b.country); })
.map(function(d) { return d.country; }))
.copy();
var transition = svg.transition().duration(750),
delay = function(d, i) { return i * 50; };
transition.selectAll(".bar")
.delay(delay)
.attr("x", function(d) { return x0(d.country); });
transition.select(".x.axis")
.call(xAxis)
.selectAll("g")
.delay(delay);
};
}
I don`t get anything displayed. I tried Barchart with the same kind of data, there it worked. Where is the mistake with Sortable Barchart?
.append("g:")
should be
.append("g")
If you haven't used them before, you might want to check out the chrome dev tools. Small typos like this are a lot easier to debugger when you can step through your code to see exactly what line is is causing the error to occur.

Resources