I want to create a Stacked bar chart like http://bl.ocks.org/mbostock/3886208 . But I don't want to use CSV file.
How can I create Stacked chart using array or JSON data?
In csv we are using like this :
State,Post,Comment
AL,310504,552339
AK,52083,85640
How can I define data in array or json like
var data = []
do it like this
<!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>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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 = [
{
"State": "AL",
"Under 5 Years": 10,
"5 to 13 Years": 20,
"14 to 17 Years": 30,
"18 to 24 Years": 40,
"25 to 44 Years": 50,
"45 to 64 Years": 60,
"65 Years and Over": 70
},{
"State": "AK",
"Under 5 Years": 15,
"5 to 13 Years": 25,
"14 to 17 Years": 35,
"18 to 24 Years": 45,
"25 to 44 Years": 55,
"45 to 64 Years": 65,
"65 Years and Over": 75
}];
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; }));
data.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d) { return d.State; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
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("Population");
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.State) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
</script>
I know late for replying to this one. I modified #heshjse's code for D3 version 4. When I tried the above code with d3 v3, it's working fine. But we had limitation to use version 4, I was getting problem bcoz of some changes in d3 v4. So adding the code which worked for me. I hope it helps.
This should work fine for Json format in d3 v4.
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<div id="Dash"></div>
</body>
</html>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
drawStackChart();
});
//Draw Stack Chart
var marginStackChart = { top: 20, right: 20, bottom: 30, left: 40 },
widthStackChart = 500 - marginStackChart.left - marginStackChart.right,
heightStackChart = 300 - marginStackChart.top - marginStackChart.bottom;
var xStackChart = d3.scaleBand()
.range([0, widthStackChart])
.padding(0.1);
var yStackChart = d3.scaleLinear()
.range([heightStackChart, 0]);
var colorStackChart = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
var canvasStackChart = d3.select("#Dash").append("svg")
.attr("width", widthStackChart + marginStackChart.left + marginStackChart.right)
.attr("height", heightStackChart + marginStackChart.top + marginStackChart.bottom)
.append("g")
.attr("transform", "translate(" + marginStackChart.left + "," + marginStackChart.top + ")");
function drawStackChart() {
var data = [
{
"Year": "2012",
"Category1": "20",
"Category2": "5",
"Category3": "5",
"Category4": "5",
"Category5": "5",
"Category6": "5",
"Category7": "5",
"Category8": "5",
"Category9": "5"
},
{
"Year": "2013",
"Category1": "30",
"Category2": "10",
"Category3": "10",
"Category4": "10",
"Category5": "10",
"Category6": "10",
"Category7": "10",
"Category8": "10",
"Category9": "10"
},
{
"Year": "2014",
"Category1": "35",
"Category2": "15",
"Category3": "15",
"Category4": "15",
"Category5": "15",
"Category6": "15",
"Category7": "15",
"Category8": "15",
"Category9": "15"
},
{
"Year": "2015",
"Category1": "60",
"Category2": "20",
"Category3": "20",
"Category4": "20",
"Category5": "20",
"Category6": "20",
"Category7": "20",
"Category8": "20",
"Category9": "20"
},
{
"Year": "2016",
"Category1": "70",
"Category2": "40",
"Category3": "40",
"Category4": "40",
"Category5": "40",
"Category6": "40",
"Category7": "40",
"Category8": "40",
"Category9": "40"
}
];
colorStackChart.domain(d3.keys(data[0]).filter(function (key) { return key !== "Year"; }));
data.forEach(function (d) {
var y0 = 0;
d.ages = colorStackChart.domain().map(function (name) { return { name: name, y0: y0, y1: y0 += +d[name] }; });
d.total = d.ages[d.ages.length - 1].y1;
});
data.sort(function (a, b) { return b.total - a.total; });
xStackChart.domain(data.map(function (d) { return d.Year; }));
yStackChart.domain([0, d3.max(data, function (d) { return d.total; })]);
canvasStackChart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + heightStackChart + ")")
.call(d3.axisBottom(xStackChart));
canvasStackChart.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(yStackChart))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("No Of Buildings");
var state = canvasStackChart.selectAll(".Year")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function (d) { return "translate(" + xStackChart(d.Year) + ",0)"; });
state.selectAll("rect")
.data(function (d) { return d.ages; })
.enter().append("rect")
.attr("width", xStackChart.bandwidth())
.attr("y", function (d) { return yStackChart(d.y1); })
.attr("height", function (d) { return yStackChart(d.y0) - yStackChart(d.y1); })
.style("fill", function (d) { return colorStackChart(d.name); });
var legend = canvasStackChart.selectAll(".legend")
.data(colorStackChart.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", widthStackChart - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", colorStackChart);
legend.append("text")
.attr("x", widthStackChart - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function (d) { return d; });
}
</script>
If you have an array, data, you can use that just like the parameter data in the csv function in the example you linked. The code within that function will work as expected, provided that your data is in the same format.
If you can set breakpoints with your browser, you can have a look at what that format is fairly easily, set one just inside the csv function call in the js and look at the data variable.
Related
I have a problem with a bar chart and its line average.
The average line doesn't cover all the bars. The last bar is without average line.
I used d3js code.
var data = [{
"session": "1",
"score": 70
},
{
"session": "2",
"score": 30
},
{
"session": "3",
"score": 50
},
{
"session": "4",
"score": 60
},
{
"session": "5",
"score": 40
}
];
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 480 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x2 = d3.scale.ordinal()
.rangeBands([0, width], 0);
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 + ")");
data.forEach(function(d) {
d.score = +d.score;
});
x.domain(data.map(function(d) {
return d.session;
}));
x2.domain(data.map(function(d) {
return d.session;
}));
y.domain([0, d3.max(data, function(d) {
return d.score;
})]);
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("score");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.session);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.score);
})
.attr("height", function(d) {
return height - y(d.score);
});
var dataSum = d3.sum(data, function(d) {
return d.score;
});
var line = d3.svg.line()
.x(function(d, i) {
return x2(d.session) + i;
})
.y(function(d, i) {
return y(dataSum / data.length);
});
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("stroke-width", "2")
.attr("d", line);
<!DOCTYPE html>
<meta name="robots" content="noindex">
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
rect.bar {
fill: cyan;
}
path.line {
stroke: black;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</body>
</html>
The existing code was appending a multi-segment path that stopped short because it was going from the start point of each entry in data to the next start point. This example replaces it with a single line that goes from the left most element's start position to the far right side of the graph.
var data = [{
"session": "1",
"score": 70
},
{
"session": "2",
"score": 30
},
{
"session": "3",
"score": 50
},
{
"session": "4",
"score": 60
},
{
"session": "5",
"score": 40
}
];
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 480 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x2 = d3.scale.ordinal()
.rangeBands([0, width], 0);
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 + ")");
data.forEach(function(d) {
d.score = +d.score;
});
x.domain(data.map(function(d) {
return d.session;
}));
x2.domain(data.map(function(d) {
return d.session;
}));
y.domain([0, d3.max(data, function(d) {
return d.score;
})]);
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("score");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.session);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.score);
})
.attr("height", function(d) {
return height - y(d.score);
});
var dataSum = d3.sum(data, function(d) {
return d.score;
});
svg.append("line")
.attr("x1", x2(1))
.attr("x2", width)
.attr("y1", y(dataSum / data.length))
.attr("y2", y(dataSum / data.length));
<!DOCTYPE html>
<meta name="robots" content="noindex">
<html>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
rect.bar {
fill: cyan;
}
line {
stroke: black;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</body>
</html>
Assuming I have data like this:
const data = [
{
month: 1
apples: ...,
bananas: ...,
cherries: ...,
dates: ...,
},
{
month: 2
apples: ...,
bananas: ...,
cherries: ...,
dates: ...,
},
{
month: 3
apples: ...,
bananas: ...,
cherries: ...,
dates: ...,
}
]
Going for 12 months, using keys of ['apples','bananas','cherries','dates']. The d3.stack() will produce an array for 4 bars with 12 sets of values. This makes sense. However, what if I wanted to create 12 bars with the keys broken up so it's sets of 4 values.
Is it possible to flip things on their heads in this fashion?
You just need to convert the data into the required format and flip the axis and data configurations in the chart as shown below.
Existing :
var margin = {
top: 20,
right: 160,
bottom: 35,
left: 30
};
var width = 500 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
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 in strings like it would be if imported from a csv */
var data = [{
year: "2006",
redDelicious: "10",
mcintosh: "15",
oranges: "9",
pears: "6"
},
{
year: "2007",
redDelicious: "12",
mcintosh: "18",
oranges: "9",
pears: "4"
},
{
year: "2008",
redDelicious: "05",
mcintosh: "20",
oranges: "8",
pears: "2"
},
{
year: "2009",
redDelicious: "01",
mcintosh: "15",
oranges: "5",
pears: "4"
}
];
var parse = d3.time.format("%Y").parse;
// Transpose the data into layers
var dataset = d3.layout.stack()(["redDelicious", "mcintosh", "oranges", "pears"].map(function(fruit) {
return data.map(function(d) {
return {
x: parse(d.year),
y: +d[fruit]
};
});
}));
// Set x, y and colors
var x = d3.scale.ordinal()
.domain(dataset[0].map(function(d) {
return d.x;
}))
.rangeRoundBands([10, width - 10], 0.02);
var y = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})])
.range([height, 0]);
var colors = ["b33040", "#d25c4d", "#f2b447", "#d9d574"];
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(-width, 0, 0)
.tickFormat(function(d) {
return d
});
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(d3.time.format("%Y"));
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Create groups for each series, rects for each segment
var groups = svg.selectAll("g.cost")
.data(dataset)
.enter().append("g")
.attr("class", "cost")
.style("fill", function(d, i) {
return colors[i];
});
var rect = groups.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("x", function(d) {
return x(d.x);
})
.attr("y", function(d) {
return y(d.y0 + d.y);
})
.attr("height", function(d) {
return y(d.y0) - y(d.y0 + d.y);
})
.attr("width", x.rangeBand())
.on("mouseover", function() {
tooltip.style("display", null);
})
.on("mouseout", function() {
tooltip.style("display", "none");
})
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
// Draw legend
var legend = svg.selectAll(".legend")
.data(colors)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) {
return "translate(30," + i * 19 + ")";
});
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) {
return colors.slice().reverse()[i];
});
legend.append("text")
.attr("x", width + 5)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d, i) {
switch (i) {
case 0:
return "Anjou pears";
case 1:
return "Naval oranges";
case 2:
return "McIntosh apples";
case 3:
return "Red Delicious apples";
}
});
// Prep the tooltip bits, initial display is hidden
var tooltip = svg.append("g")
.attr("class", "tooltip")
.style("display", "none");
tooltip.append("rect")
.attr("width", 30)
.attr("height", 20)
.attr("fill", "white")
.style("opacity", 0.5);
tooltip.append("text")
.attr("x", 15)
.attr("dy", "1.2em")
.style("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-weight", "bold");
svg {
font: 10px sans-serif;
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
}
path.domain {
stroke: none;
}
.y .tick line {
stroke: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
New :
var margin = {
top: 20,
right: 160,
bottom: 35,
left: 30
};
var width = 500 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
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 in strings like it would be if imported from a csv */
var data = [{
fruit: "redDelicious",
2006: "10",
2007: "12",
2008: "05",
2009: "01",
2010: "02"
},
{
fruit: "mcintosh",
2006: "15",
2007: "18",
2008: "20",
2009: "15",
2010: "10"
},
{
fruit: "oranges",
2006: "9",
2007: "9",
2008: "8",
2009: "5",
2010: "4"
},
{
fruit: "pears",
2006: "6",
2007: "4",
2008: "2",
2009: "4",
2010: "2"
}
];
var legends = Object.keys(data[0]);
legends.splice(legends.indexOf('fruit'), 1);
// Transpose the data into layers
var dataset = d3.layout.stack()(legends.map(function(year) {
return data.map(function(d) {
return {
x: d.fruit,
y: +d[year]
};
});
}));
// Set x, y and colors
var x = d3.scale.ordinal()
.domain(dataset[0].map(function(d) {
return d.x;
}))
.rangeRoundBands([10, width - 10], 0.02);
var y = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})])
.range([height, 0]);
var colors = ["b33040", "#d25c4d", "#f2b447", "#d9d574","#6aa8e0"];
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(-width, 0, 0)
.tickFormat(function(d) {
return d
});
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
//.tickFormat(d3.time.format("%Y"));
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Create groups for each series, rects for each segment
var groups = svg.selectAll("g.cost")
.data(dataset)
.enter().append("g")
.attr("class", "cost")
.style("fill", function(d, i) {
return colors[i];
});
var rect = groups.selectAll("rect")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("x", function(d) {
return x(d.x);
})
.attr("y", function(d) {
return y(d.y0 + d.y);
})
.attr("height", function(d) {
return y(d.y0) - y(d.y0 + d.y);
})
.attr("width", x.rangeBand())
.on("mouseover", function() {
tooltip.style("display", null);
})
.on("mouseout", function() {
tooltip.style("display", "none");
})
.on("mousemove", function(d) {
var xPosition = d3.mouse(this)[0] - 15;
var yPosition = d3.mouse(this)[1] - 25;
tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");
tooltip.select("text").text(d.y);
});
// Draw legend
var legend = svg.selectAll(".legend")
.data(colors)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) {
return "translate(30," + i * 19 + ")";
});
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) {
return colors.slice().reverse()[i];
});
legend.append("text")
.attr("x", width + 5)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "start")
.text(function(d, i) {
return legends.reverse()[i];
});
// Prep the tooltip bits, initial display is hidden
var tooltip = svg.append("g")
.attr("class", "tooltip")
.style("display", "none");
tooltip.append("rect")
.attr("width", 30)
.attr("height", 20)
.attr("fill", "white")
.style("opacity", 0.5);
tooltip.append("text")
.attr("x", 15)
.attr("dy", "1.2em")
.style("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-weight", "bold");
svg {
font: 10px sans-serif;
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
}
path.domain {
stroke: none;
}
.y .tick line {
stroke: #ddd;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I am using the example chart from http://bl.ocks.org/mbostock/3885304 and rather than use the tsv example, I wish to use json from api call.
The chart does display, in the sense that it gives a large blob of what looks like a single bar.
The JSON returned from the api.php call looks like this
[{"id":"2","name":"wombat","total":"98000","record_date":"2016-01-21 00:00:00"},{"id":"5","name":"wombat","total":"96000","record_date":"2016-02-21 00:00:00"},{"id":"8","name":"wombat","total":"93000","record_date":"2016-03-21 00:00:00"},{"id":"11","name":"wombat","total":"91000","record_date":"2016-04-21 00:00:00"},{"id":"14","name":"wombat","total":"92000","record_date":"2016-05-21 00:00:00"},{"id":"17","name":"wombat","total":"83000","record_date":"2016-06-21 00:00:00"},{"id":"20","name":"wombat","total":"81000","record_date":"2016-07-21 00:00:00"}]
Plunker
Thanks
Kevin
Your json data array has the record_date property instead of event_time. But your code refers to event_time property. Try replacing them with the record_date.
I could not find no other errors in your code.
Here is the working Code Snippet:
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 960 - 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")
.ticks(10, "");
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 = [{
"id": "2",
"name": "wombat",
"total": "98000",
"record_date": "2016-01-21 00:00:00"
}, {
"id": "5",
"name": "wombat",
"total": "96000",
"record_date": "2016-02-21 00:00:00"
}, {
"id": "8",
"name": "wombat",
"total": "93000",
"record_date": "2016-03-21 00:00:00"
}, {
"id": "11",
"name": "wombat",
"total": "91000",
"record_date": "2016-04-21 00:00:00"
}, {
"id": "14",
"name": "wombat",
"total": "92000",
"record_date": "2016-05-21 00:00:00"
}, {
"id": "17",
"name": "wombat",
"total": "83000",
"record_date": "2016-06-21 00:00:00"
}, {
"id": "20",
"name": "wombat",
"total": "81000",
"record_date": "2016-07-21 00:00:00"
}];
var k = [];
data.forEach(function(d) {
d.record_date = d.record_date;
d.total = +d.total;
k.push(d.record_date)
});
x.domain(data.map(function(d) {
return d.record_date;
}));
y.domain([0, d3.max(data, function(d) {
return d.total;
})]);
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("Count");
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) {
return x(d.record_date);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.total);
})
.attr("height", function(d) {
return height - y(d.total);
});
function type(d) {
d.total = +d.total;
return d;
}
.bar {
fill: steelblue;
}
.bar:hover {
fill: brown;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I wanted to add data labels on each boxes in bars but couldn't figure out how to do it.
All examples I found on the net was getting data from simple arrays, not an external JSON file like I did.
Here is my code:
<!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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.rangeRound([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
//.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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.json("data.json", function(error, data) {
if (error) throw error;
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Brand"; }));
data.forEach(function(d) {
var y0 = 0;
d.stores = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.stores[d.stores.length - 1].y1;
});
data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d) { return d.Brand; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var brand = svg.selectAll(".brand")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.Brand) + ",0)"; });
brand.selectAll("rect")
.data(function(d) { return d.stores; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
});
</script>
data.json
[
{
"Brand": "A",
"LAST 3 MONTHS": "22",
"LAST MONTH": "15",
"THIS YEAR": "36",
"ALL STORES": "72"
},
{
"Brand": "B",
"LAST 3 MONTHS": "10",
"LAST MONTH": "24",
"THIS YEAR": "15",
"ALL STORES": "61"
},
{
"Brand": "C",
"LAST 3 MONTHS": "10",
"LAST MONTH": "11",
"THIS YEAR": "23",
"ALL STORES": "67"
},
{
"Brand": "D",
"LAST 3 MONTHS": "10",
"LAST MONTH": "17",
"THIS YEAR": "21",
"ALL STORES": "81"
},
{
"Brand": "E",
"LAST 3 MONTHS": "10",
"LAST MONTH": "31",
"THIS YEAR": "51",
"ALL STORES": "92"
},
{
"Brand": "F",
"LAST 3 MONTHS": "10",
"LAST MONTH": "27",
"THIS YEAR": "35",
"ALL STORES": "76"
},
{
"Brand": "G",
"LAST 3 MONTHS": "10",
"LAST MONTH": "23",
"THIS YEAR": "19",
"ALL STORES": "59"
},
{
"Brand": "H",
"LAST 3 MONTHS": "32",
"LAST MONTH": "27",
"THIS YEAR": "15",
"ALL STORES": "45"
}
]
How can I show data labels on each boxes in the bars? (like: 22, 15, 36, 72 on the first bar etc.)
I want a final view on all bars like the first bar on this picture:
https://dl.dropboxusercontent.com/u/58490833/Yollanan%20Dosyalar/stackedbar.jpg
Do the same code as you did for all rectangle .. but you have to either pass original object with it to read value or you can get it from parent node like this
brand.selectAll("text")
.data(function(d) { return d.stores; })
.enter().append("text")
.attr("y", function(d) { return y(d.y1)+10; })
.attr("x", x.rangeBand()/2)
.attr("text-anchor","middle")
.style("fill",'#fff')
.text(function(d) { return d3.select(this)[0][0].parentNode.__data__[d.name]; });
here is fiddle with solution hope this is what you needed ..
I am new in D3 js.most of the examples in gallery load data from TSV files.
but I wanted to render line graph using json in mvc3 razor. below is code where i hard code my data.please let me know how to retrive dynamic data using json.
var data = [
{ "date": 0, "close": 0.3372 },
{ "date": 1, "close": 1.7 },
{ "date": 2, "close": 1.8 },
{ "date": 3, "close": 2.014 },
{ "date": 4, "close": 10.995 },
{ "date": 5, "close": 16.227 },
{ "date": 6, "close": 16.643 },
{ "date": 7, "close": 20.644 },
{ "date": 8, "close": 22.478 }
];
var margin = { top: 20, right: 20, bottom: 30, left: 50 },
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
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 + ")");
console.log("here");
data.forEach(function (d) {
d.date = parseInt(d.date);
d.close = +d.close;
});
console.log("here2");
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 + ")")
.text("Request")
.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("Probability");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);