I am trying to add text on each bar in grouped bar chart. but it is not showing & no error is there on console.
I am using the sample code from https://bl.ocks.org/bricedev/0d95074b6d83a77dc3ad
I tried below code:
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
//display: none; //to show x axis
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 40, right: 60, bottom: 40, left: 40},
width = 560 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x0)
.tickSize(0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var color = d3.scale.ordinal()
.range(["#ca0020","#f4a582","#d5d5d5","#92c5de","#0571b0"]);
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) {
var categoriesNames = data.map(function(d) { return d.categorie; });
var rateNames = data[0].values.map(function(d) { return d.rate; });
x0.domain(categoriesNames);
x1.domain(rateNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(categorie) { return d3.max(categorie.values, function(d) { return d.value; }); })]);
//Graph Title
svg.append("text")
.attr("transform", "translate(100,0)")
.attr("x", 100)
.attr("y", -20)
.attr("font-size", "24px")
.text("Grouped Bar Chart");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style('font-weight','bold')
.attr("transform", "translate(" + width + ",10)")
.text("Months");
svg.append("g")
.attr("class", "y axis")
.style('opacity','0')
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.style('font-weight','bold')
.text("Incidents");
svg.select('.y').transition().duration(500).delay(1300).style('opacity','1');
var slice = svg.selectAll(".slice")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform",function(d) { return "translate(" + x0(d.categorie) + ",0)"; });
//draw bars
slice.selectAll("rect")
.data(function(d) { return d.values; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.rate); })
.style("fill", function(d) { return color(d.rate) })
.attr("y", function(d) { return y(0); })
.attr("height", function(d) { return height - y(0); })
.on("mouseover", function(d) {
d3.select(this).style("fill", d3.rgb(color(d.rate)).darker(2));
})
.on("mouseout", function(d) {
d3.select(this).style("fill", color(d.rate));
});
slice.selectAll("text")
.data(function(d) {return d.values ;})
.enter()
.append("text")
.attr("x", function(d) { return x1(d.rate); })
.attr("y", function(d) { return ( y(0) ) ; })
.text(function(d) {
return (d.value); // Value of the text
});
slice.selectAll("rect")
.transition()
.delay(function (d) {return Math.random()*1000;})
.duration(1000)
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
//Legend
var legend = svg.selectAll(".legend")
.data(data[0].values.map(function(d) { return d.rate; }).reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d,i) { return "translate(60," + i * 20 + ")"; })
.style("opacity","0");
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d) { return color(d); });
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) {return d; });
legend.transition().duration(500).delay(function(d,i){ return 1300 + 100 * i; }).style("opacity","1");
});
</script>
</body>
</html>
But the output is output after adding block
It is showing object object in output.
Please help.
output of code is here
You're appending to slice, which is a selection of all the bar groups, not the bars themselves. Try something like this to get started:
slice.selectAll("text")
.data(function(d) { return d.values; })
.enter().append("text")
.attr("x", function(d) { return x1(d.rate); })
.attr("y", function(d) { return y(d.value); })
.text(function(d) { return d.value })
Related
This question already has answers here:
D3 Appending Text to a SVG Rectangle
(2 answers)
SVG: text inside rect
(5 answers)
Closed 1 year ago.
After study this excelent d3.js tutorial, I like to add the bar value on top of each bar! below example code the text not show up!
XYZ.csv
year,value
2011,45
2012,47
2013,52
2014,70
2015,75
2016,78
html file:
<!doctype html>
<html>
<head>
<style>
.bar {
fill: steelblue;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<svg width="600" height="500"></svg>
<script>
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin
var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
d3.csv("XYZ.csv", function(error, data) {
if (error) {
throw error;
}
xScale.domain(data.map(function(d) { return d.year; }));
yScale.domain([0, d3.max(data, function(d) { return d.value; })]);
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
g.append("g")
.call(d3.axisLeft(yScale).tickFormat(function(d){
return "$" + d;
}).ticks(10));
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d.year); })
.attr("y", function(d) { return yScale(d.value); })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - yScale(d.value); })
.append("text")
.attr("x", function(d) { return xScale(d.year); })
.attr("y", function(d) { return yScale(d.value); })
.attr("text", function(d) { return d.value; })
});
</script>
</body>
</html>
Below code is added for text on top of each bar:
.append("text")
.attr("x", function(d) { return xScale(d.year); })
.attr("y", function(d) { return yScale(d.value); })
.attr("text", function(d) { return d.value; })
It's impossible to append a <text> to a <rect>. Just add the texts separately:
g.selectAll(".bar-title")
.data(data)
.enter()
.append("text")
.classed('bar-title', true)
.attr('text-anchor', 'middle')
.attr("x", d => xScale(d.year) + xScale.bandwidth()/2)
.attr("y", d => yScale(d.value))
.text(d => `$${d.value}`);
... or, you can append a <g> element on enter() and then append <text> and <rect> under <g>.
const data = [
{year: 2011, value: 45},
{year: 2012, value: 47},
{year: 2013, value: 52},
{year: 2014, value: 70},
{year: 2015, value: 75},
{year: 2016, value: 78}
];
var svg = d3.select("svg"),
margin = 200,
width = svg.attr("width") - margin,
height = svg.attr("height") - margin
var xScale = d3.scaleBand().range([0, width]).padding(0.4),
yScale = d3.scaleLinear().range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")");
xScale.domain(data.map(function(d) { return d.year; }));
yScale.domain([0, d3.max(data, function(d) { return d.value; })]);
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScale));
g.append("g")
.call(d3.axisLeft(yScale).tickFormat(function(d){
return "$" + d;
}).ticks(10));
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return xScale(d.year); })
.attr("y", function(d) { return yScale(d.value); })
.attr("width", xScale.bandwidth())
.attr("height", function(d) { return height - yScale(d.value); })
g.selectAll(".bar-title")
.data(data)
.enter()
.append("text")
.classed('bar-title', true)
.attr('text-anchor', 'middle')
.attr("x", d => xScale(d.year) + xScale.bandwidth()/2)
.attr("y", d => yScale(d.value) - 5)
.text(d => `$${d.value}`);
.bar {
fill: steelblue;
}
.bar-title {
font-family: 'Ubuntu';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg width="600" height="500"></svg>
I've tried to build d3 graph where line and columns are combined, but all of my attempts were unsuccessful.
Styles:
svg {
margin-left: auto;
margin-right: auto;
display: block;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis text{
font: Times;
font-size: 12px;
font-weight: bold;
}
JavaScript:
var margin = {top: 20, right: 10, bottom: 100, left:50},
width = 700 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var svg = d3.select("body")
.append("svg")
.attr ({
"width": width + margin.right + margin.left,
"height": height + margin.top + margin.bottom
})
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.right + ")");
// define x and y scales
var xScale = d3.scale.ordinal()
.rangeRoundBands([0,width], 0.93, 0.93);
var yScale = d3.scale.linear()
.range([height, 0]);
var formater = d3.format("");
// define x axis and y axis
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.tickFormat(formater);
d3.csv("result.csv", function(error,data) {
if(error) console.log("Error: data not loaded!");
data.forEach(function(d) {
d.day = d.day;
d.dayStr = d.dayStr;
d.Ratio = +d.Ratio;
console.log(d.dayStr);
});
// Specify the domains of the x and y scales
xScale.domain(data.map(function(d) { return d.dayStr; }) );
yScale.domain([0, 6]);
// Draw xAxis and position the label
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("dx", "-.8em")
.attr("dy", ".25em")
.attr("transform", "rotate(-60)" )
.style("text-anchor", "end")
.attr("font-size", "10px");
// Draw yAxis and postion the label
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height/8)
.attr("dy", "-3em")
.style("text-anchor", "middle")
.text("Risk Value (in %)");
});
Data:
Day,DayStr,Ratio,Note
2016-06-29T00:00:00+03:00,06-29-2016,1.3,
2016-06-30T00:00:00+03:00,06-30-2016,1.4,
2016-07-01T00:00:00+03:00,07-01-2016,1.2,
2016-07-02T00:00:00+03:00,07-02-2016,1.7,
2016-07-03T00:00:00+03:00,07-03-2016,1.9,
2016-07-04T00:00:00+03:00,07-04-2016,2.2,
2016-07-05T00:00:00+03:00,07-05-2016,2.5,
2016-07-06T00:00:00+03:00,07-06-2016,2.5,
2016-07-07T00:00:00+03:00,07-07-2016,2.4,
2016-07-08T00:00:00+03:00,07-08-2016,2.7,
2016-07-09T00:00:00+03:00,07-09-2016,3.1,
2016-07-10T00:00:00+03:00,07-10-2016,3.5,
2016-07-11T00:00:00+03:00,07-11-2016,3.7,
2016-07-12T00:00:00+03:00,07-12-2016,4.5,
2016-07-13T00:00:00+03:00,07-13-2016,4.4,
2016-07-14T00:00:00+03:00,07-14-2016,5,Alert!
Link to full code.
The final result should be something like this:
Your code is a good starting point, but you haven't drawn any of the columns, points or text. Here's one way to do it:
var colAndPointAndText =
svg.selectAll(".cPT")
.data(data)
.enter().append("g")
.attr("class", "cPT");
colAndPointAndText.append("rect")
.attr("x", function(d) {
return xScale(d.dayStr);
})
.attr("width", xScale.rangeBand())
.attr("y", function(d) {
return yScale(d.Ratio);
})
.attr("height", function(d) {
return height - yScale(d.Ratio);
})
.style("fill", "black");
colAndPointAndText.append("circle")
.attr("cx", function(d) {
return xScale(d.dayStr);
})
.attr("cy", function(d) {
return yScale(d.Ratio);
})
.attr("r", 5)
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "2px")
colAndPointAndText.append("text")
.attr("x", function(d) {
return xScale(d.dayStr);
})
.attr("y", function(d) {
return yScale(d.Ratio);
})
.text(function(d) {
return d.Note;
})
.style("fill", "#d62728")
var line = d3.svg.line()
.x(function(d) {
return xScale(d.dayStr);
})
.y(function(d) {
return yScale(d.Ratio);
});
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line)
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "2px");
Full code running here.
I am creating a D3 bar chart using below code .
<head>
<style>
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 70, left: 40},
width = 600 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([0, width], .05);
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 = [{"text":"A","value":50,"linkurl":"http://google.com"}, {"text":"B","value":100,"linkurl":"http://php.net"},{"text":"C","value":150,"linkurl":"http://drupal.org"}]
data.forEach(function(d) {
d.text = d.text;
d.value = +d.value;
d.linkurl = d.linkurl;
});
x.domain(data.map(function(d) { return d.text; }));
y.domain([0, d3.max(data, function(d) { return d.value; })]);
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(-45)" );
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("");
svg.selectAll("bar")
.data(data)
.enter().append("rect")
.style("fill", "steelblue")
.attr("x", function(d) { return x(d.text); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); });
svg.on("click", function (d) { //<-D
//var position = d3.mouse(svg.node());
window.location.href='http://google.com';
//window.location.href=d.linkurl;
});
</script>
</body>
And want to create a link on each bar.. for that I am using the code . It is working fine when I am using same URL for each bar but doesn't
for different URl for each bar...
var data = [{"text":"A","value":50,"linkurl":"http://google.com"},{"text":"B","value":100,"linkurl":"http://php.net"},{"text":"C","value":150,"linkurl":"http://drupal.org"}]
data.forEach(function(d) {
d.text = d.text;
d.value = +d.value;
d.linkurl = d.linkurl;
});
svg.on("click", function (d) { //<-D
//var position = d3.mouse(svg.node());
window.location.href='http://google.com';
//window.location.href=d.linkurl;
});
You have to bind the click listener to the bars (rectangles) instead of svg.
var bars = svg.selectAll("bar")
.data(data)
.enter()
.append("rect")
.style("fill", "steelblue")
.attr("x", function(d) {
return x(d.text);
}).attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.value);
}).attr("height", function(d) {
return height - y(d.value);
});
bars.on("click", function(d) {
window.location.href = d.linkurl;
});
var margin = {
top: 20,
right: 20,
bottom: 70,
left: 40
}, width = 600 - margin.left - margin.right, height = 300 - margin.top - margin.bottom;
var x = d3.scale.ordinal().rangeRoundBands([ 0, width ], .05);
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 = [ {
text: "A",
value: 50,
linkurl: "http://google.com"
}, {
text: "B",
value: 100,
linkurl: "http://php.net"
}, {
text: "C",
value: 150,
linkurl: "http://drupal.org"
} ];
data.forEach(function(a) {
a.text = a.text;
a.value = +a.value;
a.linkurl = a.linkurl;
});
x.domain(data.map(function(a) {
return a.text;
}));
y.domain([ 0, d3.max(data, function(a) {
return a.value;
}) ]);
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(-45)");
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("");
var bars = svg.selectAll("bar")
.data(data)
.enter()
.append("rect")
.style("fill", "steelblue")
.attr("x", function(a) {
return x(a.text);
}).attr("width", x.rangeBand())
.attr("y", function(a) {
return y(a.value);
}).attr("height", function(a) {
return height - y(a.value);
});
bars.on("click", function(a) {
window.location.href = a.linkurl;
});
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I'm trying to create a grouped bar chart that can include transitions. I referenced Mike Bostock's grouped bar chart example and have the bar chart transition working but can't get the axis to transition as well. What I'm referring to in this example is the state labels.
I tried following another example posted but I'm baffled as to why I can get it to work. For my example code the transition occurs on click of the SVG
Grouped Bar Chart Reference Example
Axis Reference Example
<!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="http://d3js.org/d3.v3.min.js"></script>
<script>
//Update the flips bars but not the axis
function update() {
var data_update = data.reverse()
x0.domain[data_update]
svg.selectAll(".state")
.data(data_update)
.transition()
.attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; });
svg.select(".x_axis")
.transition()
.call(xAxis);
}
d3.select("svg")
.on("click", update)
//The rest of the code
var data
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("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 + ")");
d3.csv("data.csv", function(error, csv) {
data = csv
var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; });
data.forEach(function(d) {
d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
});
x0.domain(data.map(function(d) { return d.State; }));
x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })]);
svg.append("g")
.attr("class", "x_axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "state")
.attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
});
</script>
I'm a dummy and figured it out.
Calling the .domain method on an array of objects is useless. I forgot to map the object array to get the value of the states
x0.domain(data_update.map(function(d) { return d.State; }))
Full Code below for those curious
<!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="http://d3js.org/d3.v3.min.js"></script>
<script>
var data
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var xAxis = d3.svg.axis()
.scale(x0)
.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.csv("data.csv", function(error, csv) {
data = csv
var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; });
data.forEach(function(d) {
d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
});
x0.domain(data.map(function(d) { return d.State; }));
x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })]);
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, function(d) {return d.State})
.enter().append("g")
.attr("class", "state")
.attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(ageNames.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; });
});
//Update the flips bars
function update() {
data.reverse()
x0.domain(data.map(function(d) { return d.State; }))
svg.selectAll(".state")
.data(data, function(d) {return d.State})
.transition()
.attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; });
svg.select(".x_axis")
.transition()
.call(xAxis);
}
d3.select("svg")
.on("click", update)
</script>
I have a problem... I am not able to include tooltips.. i've tried to do it with d3noobs tutorial and with much other.. But it doesn't work..
I hope anyone can help me or fullfill the code!
Thanks a lot!
<pre>
<!-- /.row -->
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body" id="gr1">
<svg id="graph" viewBox="0 0 100% 100%" preserveAspectRatio="xMidYMid" width="1500" height="600" ></svg>
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="tooltip" class="hidden" style="left: 429px, top: 489.6px">
<p><strong><span id="city">Dar es Salaam</span></strong></p>
<p id="population">Population: 4 million</p>
</div>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 1300 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#FF4000", "#D7DF01", "#DF013A", "#fbf10d"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
var svg = d3.select("#graph")
.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 + ")");
function make_x_axis() {
return d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(5)
}
function make_y_axis() {
return d3.svg.axis()
.scale(y)
.orient("left")
.ticks(20)
}
function mouseover(d) {
d3.select(this).style("fill", "orange");
var mousecoord = [0,0];
mousecoord = d3.mouse(this);
d3.select("#tooltip")
.style("left", mousecoord[0] + "px")
.style("top", mousecoord[1]-75 + "px");
d3.select("#city")
.text(d.city);
d3.select("#population")
.text(function () { return year + " population: " + comma(d["y"+year]); });
d3.select("#tooltip").classed("hidden", false);
};
d3.csv("groupeddatafordefaultdashboard.asp?3", function(error, data) {
var ageNames = d3.keys(data[0]).filter(function(key) { return key !== "State"; });
data.forEach(function(d) {
d.ages = ageNames.map(function(name) { return {name: name, value: +d[name]}; });
});
x0.domain(data.map(function(d) { return d.State; }));
x1.domain(ageNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.ages, function(d) { return d.value; }); })]);
svg.append("g")
.attr("class", "grid")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
)
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("Anzahl");
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
(blah blah)
.on("mouseover", mouseover)
.on("mouseout", mouseout);
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x0(d.State) + ",0)"; });
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
var legend = svg.selectAll(".legend")
.data(ageNames.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(20," + i * 50 + ")"; });
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>
</pre>