Plot bar chart using D3 JS - javascript

I am plotting a bar chart in D3.js (Version 3). Which has two axis, one is receive_data and another one is responses. I have a JSON file where I stored the data. JSON format looks like,
[{"receive_date":"2013-11-04","responses":"2"}]
In my JSON, I have two responses values for the same date 2013-11-04 .
Like,
[{"receive_date":"2013-11-04","responses":"2"},{"receive_date":"2013-11-04","responses":"8668"}
This is the JSON Source :- https://api.myjson.com/bins/gdpu7
So, when I am plotting the graph, it is not taking the sum of the values for the same receive_date instead it is showing two times. I want it to show the sum of responses. responses should be (8668+2) for the receive_date 2013-11-04
I also found it that by using reduce we can do this. I tried to use d3.json.reduce . But it is showing error d3.json.reduce is not a function.
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
//scale to numerical value by height
var y = d3.scale.linear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
d3.json("https://api.myjson.com/bins/gdpu7", function(error, data) {
x.domain(data.map(function(d) {
return d.receive_date
}));
y.domain([0, d3.max(data, function(d) {
return d.responses
})]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(" + x(d.receive_date) + ", 0)";
});
bar.append("rect")
.attr("y", function(d) {
return y(d.responses);
})
.attr("x", function(d, i) {
return x.rangeBand() + (margin.left / 2);
})
.attr("height", function(d) {
return height - y(d.responses);
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", x.rangeBand() + margin.left)
.attr("y", function(d) {
return y(d.responses) - 10;
})
.attr("dy", ".75em")
.text(function(d) {
return d.responses;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("responses");
});
function type(d) {
d.receive_date = +d.receive_date; // coerce to number
return d;
}
#chart rect {
fill: #4aaeea;
}
#chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #fff;
shape-rendering: crispEdges;
}
body {
background: #1a1a1a;
color: #eaeaea;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chart"></div>
JSfiddle :- https://jsfiddle.net/bL9940at/

The relevant part:
var array1 = data; //input
var array2 = [];
var last_d;
array1.reduce(function (accumulator, currentValue, i) {
var r = Number(currentValue.responses),
d = currentValue.receive_date;
if (d == last_d) r += accumulator;
array2[i] = {
receive_date: d,
responses: r
};
last_d = d;
return accumulator + Number(currentValue.responses);
}, 0);
data = array2; //output
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
//scale to numerical value by height
var y = d3.scale.linear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + (2 * margin.left) + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
d3.json("https://api.myjson.com/bins/gdpu7", function(error, data) {
//create new arrays
var array1 = data; //input
var array2 = [];
var last_d;
array1.reduce(function (accumulator, currentValue, i) {
var r = Number(currentValue.responses),
d = currentValue.receive_date;
if (d == last_d) r += accumulator;
array2[i] = {
receive_date: d,
responses: r
};
last_d = d;
return accumulator + Number(currentValue.responses);
}, 0);
data = array2; //output
x.domain(data.map(function(d) {
return d.receive_date;
}));
y.domain([0, d3.max(data, function(d) {
return d.responses;
})*1.1]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(" + x(d.receive_date) + ", 0)";
});
bar.append("rect")
.attr("y", function(d) {
return y(d.responses);
})
.attr("x", function(d, i) {
return x.rangeBand() + (margin.left / 2);
})
.attr("height", function(d) {
return height - y(d.responses);
})
.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", x.rangeBand() + margin.left)
.attr("y", function(d) {
return y(d.responses) - 10;
})
.attr("dy", ".75em")
.text(function(d) {
return d.responses;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("responses");
});
function type(d) {
d.receive_date = +d.receive_date; // coerce to number
return d;
}
#chart rect {
fill: #4aaeea;
}
#chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #fff;
shape-rendering: crispEdges;
}
body {
background: #1a1a1a;
color: #eaeaea;
padding: 10px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://code.jquery.com/jquery-git.js"></script>
<div id="chart"></div>
</body>
</html>

Related

d3.js bar chart not updating with new information from csv

I am trying to get my d3 bar graph to update with a csv and for some reason I keep getting the error that data is undefined when I run it with the live server extension, however I am not sure why because it works totally fine with a different csv. Earlier I was having a different error with this code where it would show up but only one bar would be filled in all the way to the top no matter what was selected from the dropdown. Any help would be greatly appreciated!! Here is my code:
d3 Updating Bar Chart With Dropdown
<style>
input {
position: relative;
font-size: large;
z-index: +1;
padding: .5em;
margin-bottom: .5em;
}
body {
font: 14px sans-serif;
background-color: lightgray;
}
select {
display: block;
}
.bar {
fill: rgb(209, 20, 184);
fill-opacity: 0.7;
stroke:rgb(0, 0, 0);
stroke-width:2.5; /* this changes the stroke width*/
stroke-linecap:butt;
stroke-opacity: 1.0;
}
.axis path,
.axis line {
fill: none;
stroke: rgb(0, 0, 0);
stroke-width:3; /*again stroke width*/
shape-rendering: crispEdges;
}
</style>
<h1>Bar Graph of Crashes by Light Condition</h1>
</head>
<body>
<div id='vis-container'></div>
<script type="text/javascript">
var fileName = "CSVs\TownTotalcrashesFatalsInjuryNoinjury.csv"; //Pulling Data
var conditionFields = ["Crashes", "Fatals", "Injury", "No Injury"];
d3.csv(fileName, function(error, data) { //Error CheckingS
var townMap = {};
data.forEach(function(d) {
var town = d.Town;
townMap[town] = [];
conditionFields.forEach(function(field) {
townMap[town].push( +d[field] );
});
});
makeVis(townMap);
});
var makeVis = function(townMap) {
var margin = { top: 30, right: 50, bottom: 30, left: 50 }, //Dimensions of the Visual
width = 800 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var xScale = d3.scale.ordinal() //Getting Scale for Axis
.domain(conditionFields)
.rangeRoundBands([0, width], 0.1);
var yScale = d3.scale.linear()
.range([height, 0]);
var canvas = d3.select("#vis-container") //Creating Canvas
.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 xAxis = d3.svg.axis() //Creation of X-Axis
.scale(xScale)
.orient("bottom");
canvas.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var yAxis = d3.svg.axis() //Creation of Y-axis
.scale(yScale)
.orient("left");
var yAxisHandleForUpdate = canvas.append("g")
.attr("class", "y axis")
.call(yAxis);
canvas.append("text") //Addition of Axis Labels And Title
.attr("transform",
"translate(" + (width/2) + " ," +
(height + margin.top + 20) + ")")
.style("text-anchor", "middle")
.text("Light Condition");
canvas.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margin.left)
.attr("x",0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.text("Crashes");
canvas.append("text")
.attr("x", (width / 2))
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "18px")
var updateBars = function(data) { //updating for new data
yScale.domain( d3.extent(data) );
yAxisHandleForUpdate.call(yAxis);
var bars = canvas.selectAll(".bar").data(data);
bars.enter() // Add bars for new data
.append("rect")
.attr("class", "bar")
.attr("x", function(d,i) { return xScale( conditionFields[i] ); })
.attr("width", xScale.rangeBand())
.attr("y", function(d,i) { return yScale(d); })
.attr("height", function(d,i) { return height - yScale(d); });
bars //updating new bars, removing old ones
.transition().duration(250)
.attr("y", function(d,i) { return yScale(d); })
.attr("height", function(d,i) { return height - yScale(d); });
bars.exit().remove();
};
var dropdownChange = function() { //dropdown menu handler
var newTown = d3.select(this).property('value'),
newData = townMap[newTown];
updateBars(newData);
};
var towns = Object.keys(townMap).sort(); //Creating Drop Down Menu
var dropdown = d3.select("#vis-container")
.insert("select", "svg")
.on("change", dropdownChange);
dropdown.selectAll("option")
.data(towns)
.enter().append("option")
.attr("value", function (d) { return d; })
.text(function (d) {
return d[0].toUpperCase() + d.slice(1,d.length); // capitalize 1st letter
});
var initialData = townMap[ towns[0] ];
updateBars(initialData);
};
</script>
</body>
</html>

D3.JS bar graph column offset while adding new data

I'm currently working with D3.JS attempting to add to an existing graph every 24 hours. Using JSON data like this:
[{"name": "bill", "val": 28}, {"name": "kevin", "val": 46}, {"name": "ryan", "val": 23},{"name": "ville", "val": 56}]
I have a frequency value on my Y axis, and a username on my xaxis. I think I have my placement function correct, but when adding a new column (although the offset should stay the same) all columns are shifted out of place. The goal is to be able to add columns (new data) and keep the columns (rects) above the proper username.
Here is my current working code:
<html>
<head>
<script type="text/javascript" src="d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script type="data/json" src="data.json"></script>
<style>
#chart rect{
fill: #4aaeea;
}
#chart text{
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.axis text{
font: 10px sans-serif;
}
.axis path, .axis line{
fill: none;
stroke : #fff;
shape-rendering: crispEdges;
}
body{
background: #1a1a1a;
color : #eaeaea;
padding : 5px;
}
</style>
</head>
<body>
<div id="chart"</div>
<script>
var margin ={top:20, right:30, bottom:30, left:40},
width=960-margin.left - margin.right,
height=500-margin.top-margin.bottom;
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
//scale to numerical value by height
var y = d3.scale.linear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width+(2*margin.left)+margin.right) //set width
.attr("height", height+margin.top+margin.bottom); //set height
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var data;
d3.json("http://localhost:8000/data.json", function(error, data){
if (error) return console.warn(error);
x.domain(data.map(function(d){ return d.name}));
y.domain([0, d3.max(data, function(d){return d.val})]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i){
return "translate("+x(d.name)+", 0)";
});
console.log(margin.left);
bar.append("rect")
.attr("y", function(d) {
return y(d.val);
})
.attr("x", function(d,i){
return x(margin.left + 2);
})
.attr("height", function(d) {
return height - y(d.val);
})
.attr("width", Math.min.apply(null, [x.rangeBand()-2, 100]));
//.attr("width", x.rangeBand()); //set width base on range on ordinal data
bar.append("text")
.attr("x", (margin.left * 2.2))
.attr("y", function(d) { return y(d.val) })
.attr("dy", ".75em")
.text(function(d) { return d.val; });
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate("+margin.left+","+ height+")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate("+margin.left+",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
});
function type(d) {
d.name = +d.name; // coerce to number
return d;
}
</script>
I have done a few adjustments to the positional attributes of g elements containing bar rect elements and dx and dy attributes of text elements.
Hope this working code snippet helps.
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// scale to ordinal because x axis is not numerical
var x = d3.scale.ordinal().rangeRoundBands([0, width], .1);
//scale to numerical value by height
var y = d3.scale.linear().range([height, 0]);
var chart = d3.select("#chart")
.append("svg") //append svg element inside #chart
.attr("width", width + margin.left + margin.right) //set width
.attr("height", height + margin.top + margin.bottom); //set height
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom"); //orient bottom because x-axis will appear below the bars
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var data = [{
"name": "bill",
"val": 28
}, {
"name": "kevin",
"val": 46
}, {
"name": "ryan",
"val": 23
}, {
"name": "ville",
"val": 56
}];
x.domain(data.map(function(d) {
return d.name
}));
y.domain([0, d3.max(data, function(d) {
return d.val
})]);
var barWidth = Math.min.apply(null, [x.rangeBand() - 2, 100]);
var bar = chart.selectAll("g")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) {
return "translate(" + x(d.name) + ", " + y(d.val) + ")";
});
bar.append("rect")
.attr("y", 0)
.attr("x", barWidth - 10)
.attr("height", function(d) {
return height - y(d.val);
})
.attr("width", barWidth);
bar.append("text")
.attr("x", barWidth - 10)
.attr("y", 0)
.attr("dx", barWidth / 2)
.attr("dy", ".75em")
.text(function(d) {
return d.val;
});
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + margin.left + "," + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + margin.left + ",0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Frequency");
function type(d) {
d.name = +d.name; // coerce to number
return d;
}
#chart rect {
fill: #4aaeea;
}
#chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #fff;
shape-rendering: crispEdges;
}
body {
background: #1a1a1a;
color: #eaeaea;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart" </div>

d3 - multiple overlaying charts with custom DOM element

I'm new to d3, but pretty familiar with the HighCharts api.
I've seen lots of examples of multiple d3 charts on the same page; but can't seem to find examples of one chart overlaying/sitting directly on top of another chart. Is this possible?
With HighCharts, you can define multiple chart types in the plotOptions config object. Is there something similar with d3? Or, how could you do this with d3?
I would effectively like to have a line graph on top of a bar chart. There will be different 'stages' according to the data, so some of the bar's could be inactive/empty.
Additionally, I need to display an indicator to show where the 'stage' is currently; and ensure that this is all responsive.
Example (rough mockup):
After researching d3 and looking for similar examples, I am thinking that maybe d3 isn't the best choice for this; maybe a custom CSS/JS/HTML solution (inside an angular app) would be better.
Any recommendations or pointers would be very appreciated.
Here's a quick mock-up started from this excellent bar chart example:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.point rect {
fill: steelblue;
}
.point circle {
fill: orange;
}
.point rect:hover {
fill: brown;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: orange
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 75, right: 20, bottom: 30, left: 40},
width = 600 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .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");
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 + ")");
var data = "abcdefghijklmnopqrstuvwxyz".split("").map(function(d){
return {
letter: d,
bar: Math.random() * 10,
line: Math.random() * 10
};
})
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d3.max([d.bar, d.line]); })]);
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");
var points = svg.selectAll(".point")
.data(data)
.enter().append("g")
.attr("class", "point");
points.append('rect')
.attr("x", function(d) { return x(d.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.bar); })
.attr("height", function(d) { return height - y(d.bar); });
points.append('circle')
.attr("r", 5)
.attr("cx", function(d){ return x(d.letter) + x.rangeBand() / 2; })
.attr("cy", function(d){ return y(d.line)});
var line = d3.svg.line()
.x(function(d) { return x(d.letter) + x.rangeBand() / 2; })
.y(function(d) { return y(d.line); });
svg.append("path")
.attr("class", "line")
.datum(data)
.attr("d", line);
var indicator = svg.append("g")
.attr("r", 5)
.attr("transform", "translate(" + (x("q") + x.rangeBand() / 2) + "," + -20 + ")");
indicator.append("circle")
.attr("r", 40)
.style("fill", "red");
indicator.append("text")
.text("!")
.style("fill", "white")
.style("text-anchor", "middle")
.style("alignment-baseline", "middle")
.style("font-size", 70);
indicator.append("line")
.attr("y1", 20)
.attr("y2", height + 20)
.attr("x1", 0)
.attr("x2", 0)
.style("stroke", "red")
.style("stroke-width", "4px");
</script>
New Solution Based on Comments
Given your input data, here's a new example. I went a bit overboard here, so please ask question on any confusing bits. I tried to comment it out:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
rect {
fill: steelblue;
}
circle {
fill: orange;
}
rect:hover {
fill: brown;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: orange
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var margin = {
top: 75,
right: 20,
bottom: 30,
left: 40
},
width = 600 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .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");
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 + ")");
// here's your data
var data =
{
'point1': [{
'value': 50
}, {
'value': 100
}, {
'value': 100
}, {
'value': 150
}],
'point2': [{
'value': 25
}, {
'value': 40
}, {
'value': 60
}],
'point3': [{
'value': 25
}]
};
// d3ify your data
// d3 likes arrays of objects, you have an object of objects
// so first make it an array
var barData = d3.entries(data);
// set x domain
x.domain(barData.map(function(d){ return d.key }));
// create lineData
var lineData = [];
barData.forEach(function(d0, i){
d0.mean = d3.mean(d0.value, function(d1){ return d1.value });
d0.max = d3.max(d0.value, function(d1){ return d1.value});
var N = d0.value.length,
// this is an inner scale
// that represents each bar
s = d3.scale.linear().range([
x(d0.key) + (x.rangeBand() / N) / 2,
x(d0.key) + x.rangeBand()
]).domain([
0, N
])
d0.value.forEach(function(d1, j){
lineData.push({
x: s(j), // this is the pixel position of x, it's jittered on the bar
y: d1.value // this is the user position of y
})
});
});
// set y domain
y.domain([0, d3.max(barData, function(d) {
return d.max;
})]);
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");
// draw bars
var bars = svg.selectAll(".bar")
.data(barData)
.enter()
.append('rect')
.attr('class', 'bar')
.attr("x", function(d) {
return x(d.key);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.mean);
})
.attr("height", function(d) {
return height - y(d.mean);
});
// add points
var points = svg.selectAll('point')
.data(lineData)
.enter()
.append('circle')
.attr('class', 'point')
.attr("r", 5)
.attr("cx", function(d) {
return d.x; // already pixel position
})
.attr("cy", function(d) {
return y(d.y)
});
var line = d3.svg.line()
.x(function(d) {
return d.x; // already pixel position
})
.y(function(d) {
return y(d.y);
});
svg.append("path")
.attr("class", "line")
.datum(lineData)
.attr("d", line);
var indicator = svg.append("g")
.attr("transform", "translate(" + (x("point2") + x.rangeBand() / 2) + "," + -20 + ")");
indicator.append("circle")
.attr("r", 40)
.style("fill", "red");
indicator.append("text")
.text("!")
.style("fill", "white")
.style("text-anchor", "middle")
.style("alignment-baseline", "middle")
.style("font-size", 70);
indicator.append("line")
.attr("y1", 20)
.attr("y2", height + 20)
.attr("x1", 0)
.attr("x2", 0)
.style("stroke", "red")
.style("stroke-width", "4px");
</script>
Happy d3ing!

How can I create hierarchical bar chart in d3.js

I wanted to use the Sortable Bar Chart of Mike Bostock without it's transition property and sort the bars according to their lenght but I couldn't. I want the bars just like this. without interactivity.
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
body {
font: 10px sans-serif;
}
.bar rect {
fill: steelblue;
}
.bar text {
fill: white;
}
.axis path, .axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
</style>
<script src="http://mbostock.github.com/d3/d3.js"></script>
<script>
var margin = {top: 0, right: 10, bottom: 20, left: 10},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var index = d3.range(24),
data = index.map(d3.random.normal(100, 10));
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, width]);
var y = d3.scale.ordinal()
.domain(index)
.rangeRoundBands([0, height], .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 + ")");
var bar = svg.selectAll(".bar")
.data(data)
.enter().append("g")
.attr("class", "bar")
.attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; });
bar.append("rect")
.attr("height", y.rangeBand())
.attr("width", x);
bar.append("text")
.attr("text-anchor", "end")
.attr("x", function(d) { return x(d) - 6; })
.attr("y", y.rangeBand() / 2)
.attr("dy", ".35em")
.text(function(d, i) { return i; });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.svg.axis()
.scale(x)
.orient("bottom"));
//var sort = false;
//setInterval(function() {
// if (sort = !sort) {
// index.sort(function(a, b) { return data[a] - data[b]; });
// } else {
// index = d3.range(24);
// }
// y.domain(index);
// bar.transition()
// .duration(750)
// .delay(function(d, i) { return i * 50; })
// .attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; });
//}, 5000);
var hierarchy = d3.layout.partition()
.data(function(d) { return d.data; });
</script>
I removed the the code from var sort = false; part and added
var hierarchy =.. part but It's still not working. How can I make it?
Any help will be appreciated.
Thanks.
You should add the following line to sort the values:
index.sort(function(a, b) { return data[b] - data[a]; });
Check out the jsfiddle: http://jsfiddle.net/k9rcyeyo/

d3 dynamic data in bar graph

i am using the d3 for making the bar graph . From example i see that they use the tsv file for the data . In my case i have the dynamic data . Here is the code and i want to use the var data1 to make the graph
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<div id="bar"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
var $window = $(window);
var wWidth = $window.width();
var wHeight = $window.height();
var margin = {top: 10, right: 0, bottom: 30, left: 40},
width = 300 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var formatPercent = d3.format(".0%");
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .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 data = [[1,1],[2,3],[3,2],[4,5],[5,4]];
var svg = d3.select("#bar").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 data1 = [
{letter:"A",frequency:"58.13"},
{letter:"B",frequency:"53.98"},
{letter:"C",frequency:"67.00"},
{letter:"D",frequency:"89.70"},
{letter:"E",frequency:"99.00"}
];
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
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.letter); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); });
});
function type(d) {
d.frequency = +d.frequency;
return d;
}
</script>
data.tsv
letter frequency
A .08167
B .01492
C .02780
D .04253
E .12702
F .02288
G .02022
H .06094
I .06973
J .00153
Change the variable name,
data1 To data
And remove these line
1. d3.tsv("data.tsv", type, function(error, data) {
2. });
See DEMO Here

Categories

Resources