I want to add a legend to my D3js donut chart, like this post, its supposed to be kind of simple but I can't get it and I don't know what I'm doing wrong, also the console is not throwing any errors, anyone can see the error?
my data comes from a csv and looks like this:
data = [{
value: 30,
key: "Alta"
}, {
value: 37,
key: "Media"
}, {
value: 15,
key: "Moderada"
}, {
value: 8,
key: "Baja"
},
{
value: 13,
key: "Muy baja"
},
]
and this is the part that adds the data to the chart:
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 500 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom,
radius = width/2;
var color = d3.scaleOrdinal()
.range(["#B4DC70", "#FEFE2B", "#FE8E2B", "#FE2B2B", "#2B5EFE"]);
// arc generator
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70);
// generate pie chart and donut chart
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.value; });
// define the svg for pie chart
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.csv("alertas.csv", function(error, data) {
if (error) throw error;
var amenazasCount = d3.nest()
.key(function(d) { return d.TEXTO_AMENAZA; })
.rollup(function(v) { return v.length; })
.entries(data);
amenazasCount.forEach(function(d) {
d.value = +d.value;
});
var g = svg.selectAll(".arc")
.data(pie(amenazasCount))
.enter().append("g")
.attr("class", "arc");
// append path
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.key); });
var legendG = svg.selectAll(".legend")
.data(pie(amenazasCount))
.enter().append("g")
.attr("transform", function(d,i){
return "translate(" + (width - 110) + "," + (i * 15 + 20) + ")";
})
.attr("class", "legend");
legendG.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("fill", function(d) { return color(d.data.key); });
legendG.append("text")
.text(function(d){
return d.value + " " + d.data.key;
})
.style("font-size", 12)
.attr("y", 10)
.attr("x", 11);
});
The SVG and G elements are not sized correctly or consistently with the margins you had defined, so that legend was positioned too far to the right, and outside of the SVG view.
If you set up your SVG and g elements like this then it will work:
// set a width and height inclusive of the margins
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
// create a parent g element for everything to be included within
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// position the pie half of the width and height
var pieG = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("transform", "translate(" + width/2 + "," + height/2 + ")")
.attr("class", "arc");
And then append the legendG to the "g" element:
var legendG = g.selectAll(".legend")
.data(legendData)
.enter()
.append("g")
.attr("transform", function(d,i){
return "translate(" + (width - 60) + "," + (i * 15 + 20) + ")";
})
.attr("class", "legend");
Related
I am creating an area chart with d3 (maybe v4). In the database, it has some data points doesn't have the key I want. I mean it has missing data, which cause I can't create an area chart with the all data.
I already tried to use following code to remove the data point with missing data, but it doesn't work:
drawAirVisualData(data) {
var divE = document.createElement("div");
var divId = document.createAttribute('id');
divId.value = 'AirVisualDiv';
divE.setAttributeNode(divId);
divE.style.textAlign = "center";
var title = document.createElement("text");
title.style.lineHeight = "40px";
title.style.fontSize = "20px";
title.textContent = "Air Visual";
document.getElementById('chartDiv').appendChild(divE);
document.getElementById('AirVisualDiv').appendChild(title);
// for each chart, the x and xAxis are same, the y and yAxis are always changed.
var width = w - margin.left - margin.right,
height = (h - margin.top) / 9;
var parseTime = d3.time.format.utc("%H:%M").parse,
midnight = parseTime("00:00");
var x = d3.time.scale.utc()
.domain([midnight, d3.time.day.utc.offset(midnight,1)])
.range([0, width]);
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(25).tickFormat(d3.time.format.utc("%I %p"));
//---------------------------- chart 1-------------------------------
var y = d3.scale.linear()
.range([height, 0])
.domain([0, 100]);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(10);
var areaInHumidity = d3.svg.area()
.defined(function (d) {
return d.y1 != null;
})
.x(function (d) {
var time = new Date(d.created_at);
return x(time);
})
.y0(height)
.y1(function (d, i) {
var humidity = d.data["current"].hm;
return y(humidity);
});
var areaOutHumidity = d3.svg.area()
.defined(function (d) {
return d.y1 != null;
})
.x(function (d) {
var time = new Date(d.created_at);
var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
return x(dayTime);
})
.y0(height)
.y1(function (d) {
var humidity = d.data.outdoor_weather.hu;
return y(humidity);
});
var chart1 = d3.select("#AirVisualDiv")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr('id', 'HumidityChart')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Add legend
chart1.append('text').text('Outdoor Humidity - Indoor Humidity').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");
chart1.append("circle").attr("cx", width * 7 / 10).attr("cy", 10).attr("r", 6)
.style({
'fill': "#0d7dfa",
'opacity': 0.2
});
chart1.append("circle").attr("cx", width * 8 / 10).attr("cy", 10).attr("r", 6)
.style({
'fill': "#0d7dfa",
'opacity': 0.6
});
chart1.append("text").attr("x", (width * 7 / 10) + 14).attr("y", 10).text("Indoor Humidity").style("font-size", "12px").attr("alignment-baseline", "middle");
chart1.append("text").attr("x", (width * 8 / 10) + 14).attr("y", 10).text("Outdoor Humidity").style("font-size", "12px").attr("alignment-baseline", "middle");
chart1.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the X Axis
chart1.append("g")
.style("font", "12px centralesanscndlight")
.style('stroke-width', 1)
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart1.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.call(yAxis);
// Add area for indoor humidity
chart1.append('path')
.attr({
'd': areaInHumidity(data),
'fill': '#0d7dfa',
'opacity': 0.2
});
// Add area for outdoor humidity
chart1.append('path')
.attr({
'd': areaOutHumidity(data),
'fill': '#0d7dfa',
'opacity': 0.6
});
//---------------------------- chart 2-------------------------------
var y2 = d3.scale.linear()
.range([height, 0])
.domain([0, 50]);
var yAxis2 = d3.svg.axis().scale(y2)
.orient("left").ticks(10);
var areaInTemp = d3.svg.area()
.defined(function (d) {
return d.y != null;
})
.x(function (d) {
var time = new Date(d.created_at);
var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
return x(dayTime);
})
.y0(height)
.y1(function (d) {
var temperature = d.data.current.tp;
return y2(temperature);
});
var areaOutTemp = d3.svg.area()
.defined(function (d) {
return d.y != null;
})
.x(function (d) {
var time = new Date(d.created_at);
var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
return x(dayTime);
})
.y0(height)
.y1(function (d) {
var temperature = d.data.outdoor_weather.tp;
return y2(temperature);
});
var chart2 = d3.select("#AirVisualDiv")
.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 + ")");
chart2.append('text').text('Outdoor Temperature - Indoor Temperature').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");
// Add legend
chart2.append("circle").attr("cx", width * 7 / 10).attr("cy", 10).attr("r", 6)
.style({
'fill': "#f26100"
});
chart2.append("circle").attr("cx", width * 8 / 10).attr("cy", 10).attr("r", 6)
.style({
'fill': "#ff9b00"
});
chart2.append("text").attr("x", (width * 7 / 10) + 14).attr("y", 10).text("Indoor Temperature").style("font-size", "12px").attr("alignment-baseline", "middle");
chart2.append("text").attr("x", (width * 8 / 10) + 14).attr("y", 10).text("Outdoor Temperature").style("font-size", "12px").attr("alignment-baseline", "middle");
// Add the X Axis
chart2.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart2.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.call(yAxis2);
// Add area for indoor humidity
chart2.append('path')
.attr({
'd': areaInTemp(data),
'fill': orange,
'opacity': 0.5
});
// Add area for outdoor humidity
chart2.append('path')
.attr({
'd': areaOutTemp(data),
'fill': lightorange,
'opacity': 0.5
});
//---------------------------- chart 3-------------------------------
var y3 = d3.scale.linear()
.range([height, 0])
.domain([0, 1000]);
var yAxis3 = d3.svg.axis().scale(y3)
.orient("left").ticks(10);
var coLine = d3.svg.line()
.defined(function (d) {
return d.y != null;
})
.x(function (d) {
var time = new Date(d.created_at);
var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
return x(dayTime);
})
.y(function (d) {
var co = d.data.current.co;
return y3(co);
});
var chart3 = d3.select("#AirVisualDiv")
.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 + ")");
chart3.append('text').text('CO2 Level').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");
// Add the X Axis
chart3.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart3.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.call(yAxis3);
// Add line for co2
chart3.append('path')
.attr({
'd': coLine(data),
'stroke': grey,
'stroke-width': '1.5px',
'fill': 'none'
});
//---------------------------- chart 4-------------------------------
var y4 = d3.scale.linear()
.range([height, 0])
.domain([0, 50]);
var yAxis4 = d3.svg.axis().scale(y4)
.orient("left").ticks(10);
var p2Line = d3.svg.line()
.defined(function (d) {
return d.y != null;
})
.x(function (d) {
var time = new Date(d.created_at);
var dayTime = time.getHours() + time.getMinutes() / 60 + time.getSeconds() / 3600;
return x(dayTime);
})
.y(function (d) {
var p2 = d.data.current.p2;
return y4(p2);
});
var chart4 = d3.select("#AirVisualDiv")
.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 + ")");
chart4.append('text').text('PM 2.5 Level').attr("x", width / 2).attr("y", 0).attr("text-anchor", "middle");
// Add the X Axis
chart4.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
chart4.append("g")
.attr("class", "axisLine")
.style("font", "12px centralesanscndlight")
.call(yAxis4);
// Add line for co2
chart4.append('path')
.attr({
'd': p2Line(data),
'stroke': grey,
'stroke-width': '1.5px',
'fill': 'none'
});
}
The normal data point looks like:
{clusterAliases: ["dlab"]
created_at: "2019-06-04T05:15:18.794Z"
data:{
current:{
co: 429,
hm: 62,
p01: 17,
p1: 25,
p2: 22,
tp: 22.7834,
ts: "2019-06-04T05:10:10.646Z",
__proto__: Object},
outdoor_station: {
p1: {…},
api_id: 1646,
ts: "2019-06-04T04:00:00.000Z",
p2: {…},
mainus: "p2"},
outdoor_weather: {
wd: 0,
hu: 40,
ic: "01d",
ts: "2019-06-04T05:00:00.000Z",
tp: 33,
__proto__: Object},
identifier: "54:C9:DF:E3:AE:19",
meta: {version: 0},
type: "AQI_STATUS",
updated_at: "2019-06-04T05:15:18.808Z",
__v: 1,
_id: "5cf5fe661d9b1900213c98ec",
__proto__: Object}
The missing data point looks like:
{clusterAliases: ["dlab"]
created_at: "2019-06-04T05:13:50.977Z"
data:{
message: "HTTPSConnectionPool(host='www.airvisual.com', port=443): Read timed out. (read timeout=10)"
status: "ERROR",
__proto__: Object
},
identifier: "54:C9:DF:E3:AE:19",
meta: {version: 0},
type: "ERROR",
updated_at: "2019-06-04T05:13:50.990Z",
__v: 1,
_id: "5cf5fe0e1d9b1900213c98e5",
__proto__: Object}
The big difference between normal data point and missing data point is in missing data point it does't have "current" key under data, and its type shows "ERROR". I already tried to remove this data point before it was used to create area chart, but it can't be removed. so I also tried to use defined() to overcome it, but it doesn't work. Does anyone know how to overcome or remove the missing data point from area chart by d3? Thank you.
"I checked the d3 API and noticed that '''defined()''' required to have at least the key of the value. for example,"
'''
data {
temperature: 65,
humidity: null
}
'''
"this kind of data missing can be solved by" ''' defined()'''
"However, when the key (in our case humidity) is missing, '''defined()''' can not overcome the missing data anymore. to solve this problem, my current solution is to check if it has a key, if not, then define a value for y/x to keep drawing the line or areas"
In Bellow code I am trying to use separate charts (i.e. Bar and line chart) and getting Error: attribute d: Expected number, "MNaN,116LNaN,117L…"
Tried with using different SVG elements for both charts. Give some suggestions if I am missing something.
If I commenting Bar chart code then Line chart works properly and same works with the Bar chart but both at a same time doesn't work.
<div>
<div>Simple Bar Chart</div>
<div class="simpleBar">
<svg width="960" height="500"></svg>
</div>
</div>
<div>
<div>Line Chart</div>
<div id="lineGraph"></div>
</div>
<script>
// --------------- Bar chart code starts -----------------------
var svg = d3.select(".simpleBar > svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;
var tooltip = d3.select("body").append("div").attr("class", "toolTip");
var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
y = d3.scaleLinear().rangeRound([height, 0]);
var colours = d3.scaleOrdinal()
.range(["#6F257F", "#CA0D59"]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.json("dataSample.json", function(error, data) {
if (error) throw error;
x.domain(data.map(function(d) { return d.Timestamp; }));
y.domain([0, d3.max(data, function(d) { return d.DayTotal; })]);
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y).ticks(5).tickFormat(function(d) { return parseInt(d) + "Rs"; }).tickSizeInner([-width]))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 1)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.attr("fill", "#5D6971")
.text("Average Expence(Rs)");
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("x", function(d) { return x(d.Timestamp); })
.attr("y", function(d) { return y(d.DayTotal); })
.attr("width", x.bandwidth())
.attr("height", function(d) { return height - y(d.DayTotal); })
.attr("fill", function(d) { return colours(d.Timestamp); })
.on("mousemove", function(d){
tooltip
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block")
.html((d.Timestamp) + "<br>" + "Rs" + (d.DayTotal));
})
.on("mouseout", function(d){ tooltip.style("display", "none");});
});
// --------------- Line chart code starts -----------------------
// parse the Timestamp / time
var parseTime = d3.timeParse("%d-%b-%y");
// set the ranges
var xLine = d3.scaleTime().range([0, width]);
var yLine = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) { return x(d.Timestamp); })
.y(function(d) { return y(d.DayTotal); });
var svgLine = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svgLine = d3.select("#lineGraph").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 + ")");
// Get the data
d3.json("dataSample.json", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.Timestamp = parseTime(d.Timestamp);
d.DayTotal = +d.DayTotal;
});
// Scale the range of the data
xLine.domain(d3.extent(data, function(d) { return d.Timestamp; }));
yLine.domain([0, d3.max(data, function(d) { return d.DayTotal; })]);
// Add the valueline path.
svgLine.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// Add the X Axis
svgLine.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xLine).ticks(5));
// Add the Y Axis
svgLine.append("g")
.call(d3.axisLeft(yLine));
});
</script>
and bellow is the Json data format:
[
{
"DayTotal": "418",
"Timestamp": "15-Mar-18"
},{...}
]
You are supposed to use xLine, yLine in your d3 line function whereas you used the ones(x, y) that you meant for bar charts.
var valueline = d3.line()
.x(function(d) { return xLine(d.Timestamp); })
.y(function(d) { return yLine(d.DayTotal); });
Solved JSFiddle
I got this piece of code in which the timeline updates his value by sliding(manually). Problem is That I got an error saying that projection is not a code. Can someone help me please.
Setting the size of the slider.
var margin = {
top: 50,
right: 90,
bottom: 50,
left: 50
},
width = 1000 - margin.left - margin.right,
height = 300 - margin.bottom - margin.top;
// scale function
var timeScale = d3.time.scale()
.domain([new Date('2016-01-01'), new Date('2016-12-31')])
.range([0, width])
.clamp(true);
// initial value
var startValue = timeScale(new Date('2012-03-20'));
startingValue = new Date('2016-08-12');
//////////
defines brush
var brush = d3.svg.brush()
.x(timeScale)
.extent([startingValue, startingValue])
.on("brush", brushed);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
// classic transform to position g
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
// put in middle of screen
.attr("transform", "translate(0," + height / 2 + ")")
// inroduce axis
.call(d3.svg.axis()
.scale(timeScale)
.orient("bottom")
.tickFormat(function(d) {
return formatDate(d);
})
.tickSize(0)
.tickPadding(12)
.tickValues([timeScale.domain()[0], timeScale.domain()[1]]))
.select(".domain")
.select(function() {
console.log(this);
return this.parentNode.appendChild(this.cloneNode(true));
})
.attr("class", "halo");
var slider = svg.append("g")
.attr("class", "slider")
.call(brush);
slider.selectAll(".extent,.resize")
.remove();
slider.select(".background")
.attr("height", height);
var handle = slider.append("g")
.attr("class", "handle")
handle.append("path")
.attr("transform", "translate(0," + height / 2 + ")")
.attr("d", "M 0 -20 V 20")
handle.append('text')
.text(startingValue)
.attr("transform", "translate(" + (-18) + " ," + (height / 2 - 25) + ")");
slider
.call(brush.event)
Sets the canvas with the projection.
var width = 1280;
var height = 900;
var projection = d3.geo.mercator()
.scale(200000)
.center([4.9, 52.36])
.translate([width / 2, height / 2]);
var canvas = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().on("zoom", function () {
canvas.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
}))
.append("g")
Logs the events of the day and the coordinates to the console.
function brushed() {
var value = brush.extent()[0];
console.log()
if (d3.event.sourceEvent) { // not a programmatic event
value = timeScale.invert(d3.mouse(this)[0]);
brush.extent([value, value]);
}
handle.attr("transform", "translate(" + timeScale(value) + ",0)");
handle.select('text').text(formatDate(value));
slidedate = (formatDate(value));
console.log(slidedate)
console.log("dit is datum" + slidedate)
dataCsv.forEach(function(d) {
//console.log("datum is" + slidedate)
if (slidedate == d.Datepattern_startdate) {
console.log(slidedate)
console.log(d.Title)
coords = projection([+d["Longitude"],+d["Latitude"]]);
console.log(coords);
var circle = canvas.append("circle")
.attr("cx", coords[0] )
.attr("cy", coords[1] )
.attr("r", "6px")
.attr("fill", "orange")
.style("opacity", .6)
.append("title")
.text(function(dataCsv) {return d.Title})
} else {
//console.log(" Werkt niet")
}
});
Error = mapm.html:272 Uncaught TypeError: projection is not a function.
I want to update data on a click but the bars that are changing are not the right ones. There is something I cant quite fix with the select. On click the grey bars, which should be bar2 are updating. It should be bar.
Example: https://jsfiddle.net/Monduiz/kaqv37gu/
D3 chart:
var values = feature.properties;
var data = [
{name:"Employment rate",value:values["ERate15P"]},
{name:"Participation rate",value:values["PR15P"]},
{name:"Unemployment rate",value:values["URate15P"]}
];
var margin = {top: 70, right: 50, bottom: 20, left: 50},
width = 400 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom,
barHeight = height / data.length;
// Scale for X axis
var x = d3.scale.linear()
.domain([0, 100]) //set input to a scale of 0 - 1. The index has a score scale of 0 to 1. makes the bars more accurate for comparison.
.range([0, width]);
var y = d3.scale.ordinal()
.domain(["Employment rate", "Participation rate", "Unemployment rate"])
.rangeRoundBands([0, height], 0.2);
var svg = d3.select(div).select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.classed("chartInd", true);
var bar2 = svg.selectAll("g.bar")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
var bar = svg.selectAll("g.bar")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
bar2.append("rect")
.attr("height", y.rangeBand()-15)
.attr("fill", "#EDEDED")
.attr("width", 300);
bar.append("rect")
.attr("height", y.rangeBand()-15)
.attr("fill", "#B44978")
.attr("width", function(d){return x(d.value);});
bar.append("text")
.attr("class", "text")
.attr("x", 298)
.attr("y", y.rangeBand() - 50)
.text(function(d) { return d.value + " %"; })
.attr("fill", "black")
.attr("text-anchor", "end");
bar.append("text")
.attr("class", "text")
.attr("x", function(d) { return x(d.name) -5 ; })
.attr("y", y.rangeBand()-50)
//.attr("dy", ".35em")
.text(function(d) { return d.name; });
d3.select("p")
.on("click", function() {
//New values for dataset
var values = feature.properties;
var dataset = [
{name:"Employment rate",value:values["ERate15_24"]},
{name:"Participation rate",value:values["PR15_24"]},
{name:"Unemployment rate",value:values["URate15_24"]}
];
//Update all rects
var bar = svg.selectAll("rect")
.data(dataset)
.attr("x", function(d){return x(d.value);})
.attr("width", function(d){return x(d.value);})
});
}
var bar2 = svg.selectAll("g.bar")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
var bar = svg.selectAll("g.bar")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i) { return "translate(0," + i * barHeight + ")"; });
'bar2' above generates 3 new g elements (one for each datum)
Since you don't set attr("class","bar") for these then 'bar' will also generate 3 new g elements - (if you had set the class attribute bar would return empty as no new elements would be generated and you'd see missing stuff)
Further on you add rects to all these g elements for six rectangles in total and in the click function you select all these rectangles and re-attach 3 fresh bits of data
Since bar2 was added first the rectangles in its g elements are hoovering up the new data
You need to select and set different classes on the g elements, .selectAll("g.bar") and .attr("class", "bar") for bar, and .selectAll("g.bar2") and .attr("class", "bar2") for bar2 (use the same name to keep it simple)
then in the new data you need select only the rects belonging to g elements of the bar class: svg.selectAll(".bar rect")
Another way would be to have only one set of g elements and add two types of rectangle (differentiated by class attribute)
Im new to d3.js im able to create donut chart and im able to rotate chart but i dont want labels on chart to rotate. Can anyone help how to proceed. how shall i make sure that labels on chart should not rotate
var dataset = [
{
count: 10
},
{
count: 20
},
{
label: 'Cantaloupe',
count: 30
}
];
var width = 360;
var height = 360;
var radius = 100;
var color = d3.scale.ordinal()
.range(["red", "blue", "green"]);
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + (width / 2) +
',' + (height / 2) + ')');
var arc = d3.svg.arc()
.innerRadius(radius - 60)
.outerRadius(radius);
var pie = d3.layout.pie()
.value(function (d) {
return d.count;
});
var arcs = svg.selectAll('.arc')
.data(pie(dataset))
.enter()
.append('g')
.attr("class", "arc");
arcs.append("path")
.attr("d", arc)
.attr("fill", function (d) {
return color(d.data.count);
})
.on("click", function (d) {
var curAngle = 180;
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ") rotate(" + curAngle + ")");
});
arcs.append("text")
.attr("transform", function (d) {
return "translate(" + arc.centroid(d) + ")";
}).attr("text-anchor", "middle")
.attr("font-size", "1.5em")
.text(function (d) {
return d.data.count
});