D3 transition Circle Tooltip error - javascript

I have multiline chart, so I plot the chart with tooltip. The tips are circles. The function that plot is
function renderStates(localArr) {
x.domain([
d3.min(localArr, function (c) {
return d3.min(c.values, function (v) {
return v.date;
});
}),
d3.max(localArr, function (c) {
return d3.max(c.values, function (v) {
return v.date;
});
})
]);
y.domain([
d3.min(localArr, function (c) {
return d3.min(c.values, function (v) {
return v.cost;
});
}),
d3.max(localArr, function (c) {
return d3.max(c.values, function (v) {
return v.cost;
});
})
]);
var container = '#container-graph-state';
var svg = d3.select(container).append("svg")
.attr("width", width2 + margin.left + margin.right)
.attr("height", height2 + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.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("Total(R$)");
var city = svg.selectAll(".city")
.data(localArr)
.enter().append("g")
.attr("class", "city");
city.append("path")
.attr("class", "line")
.attr("d", function (d) {
return lineCost(d.values);
})
.style("stroke", function (d) {
return colorMultiline(d.group);
})
.transition()
.duration(2000)
;
city.append("text")
.datum(function (d) {
return {name: d.name, value: d.values[d.values.length - 1]};
})
.attr("transform", function (d) {
return "translate(" + x(d.value.date) + "," + y(d.value.cost) + ")";
})
.attr("class", 'textname')
.attr("x", 3)
.attr("dy", ".35em")
.text(function (d) {
return d.name;
});
city.selectAll("circle")
.data(function (d) {
return(d.values);
})
.enter()
.append("circle")
.attr("class", "tipcircle")
.attr("cx", function (d, i) {
return x(d.date);
})
.attr("cy", function (d, i) {
return y(d.cost);
})
.attr("r", 12)
.style('opacity', 1e-6)//1e-6
.attr("title", maketip);
$('circle').tipsy({opacity: .9, gravity: 'n', html: true});
}
But when I filter the chart my lines are updated and circle didn't.
function reRenderStates(localArr, container) {
var svg = d3.select(container)
.select("svg g");
svg.selectAll(".y.axis").transition().duration(300).ease("linear").call(yAxis);
svg.selectAll(".x.axis").transition().duration(300).ease("linear").call(xAxis);
var t01 = svg.selectAll(".city")
.data(localArr, function key(d) {
return d.name;
});
var t01Enter = t01.enter().append("g")
.attr("class", "city");
t01Enter.append("path")
.attr("class", "line")
.attr("d", function (d) {
return lineCost(d.values);
})
.style("stroke", function (d) {
return colorMultiline(d.group);
})
.transition().duration(750);
t01Enter.append("text")
.attr("class", "textEnd")
.datum(function (d) {
return {name: d.name, value: d.values[d.values.length - 1]};
})
.attr("transform", function (d) {
return "translate(" + x(d.value.date) + "," + y(d.value.cost) + ")";
})
.attr("x", 3)
.attr("dy", ".35em")
.text(function (d) {
return d.name;
})
.transition().duration(750);
t01Enter.selectAll("circle")
.data(function (d) {
return(d.values);
})
.enter()
.append("circle")
.attr("class", "tipcircle")
.attr("cx", function (d, i) {
return x(d.date);
})
.attr("cy", function (d, i) {
return y(d.cost);
})
.attr("r", 12)
.style('opacity', 1e-6)//1e-6
.attr("title", maketip)
.transition().duration(750);
t01.exit().transition().duration(750).remove();
// Then transition the y-axis.
var t1 = t01.transition();
svg.transition().duration(750).transition().selectAll(".y.axis").call(yAxis);
t1.select(".line").attr("d", function (d) {
return lineCost(d.values);
});
t1.select("text")
.attr("transform", function (d) {
return "translate(" + x(d.values[d.values.length - 1].date) + "," + y(d.values[d.values.length - 1].cost) + ")";
});
$('circle').tipsy({opacity: .9, gravity: 'n', html: true});
}
I have tried many different ways to update the circle. Someone can help me to solve?
EDIT
Checkout the fiddle https://jsfiddle.net/rafarorafaro/t22svjkm/

Finally I've done it!
在Update中操作circle的update才行;
here
//line 272 add code
t1.selectAll("circle").attr("cx", function (d, i) {
return x(d.date);
})
.attr("cy", function (d, i) {
return y(d.cost);
});

Related

Total height of Stacked Bar on tip of every rectangle in stacked Bar Chart using d3

I drawn a stackedbar Chart in which now I trying to place the Total value(I mean the yaxis value) on tip of the every rectangle. I have coded to fetch the details but here the problem is I am getting Every Layer value on tip of every layer but i need to show only the last layer value.
the problem is shown in below fig's.
My code is Shown below
var fData =
[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},{
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}]
var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];
var colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
var colorScale = d3.scale.ordinal()
.domain(headers)
.range(colors);
var layers = d3.layout.stack()(headers.map(function (count) {
return fData.map(function (d, i) {
// alert(d);
return { x: d.ORDER_TYPE, y: +d[count], color: colorScale(count) };
});
}));
//StackedBar Rectangle Max
var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
// Set x, y and colors
var xScale = d3.scale.ordinal()
.domain(layers[0].map(function (d) { return d.x; }))
.rangeRoundBands([25, width], .08);
var y = d3.scale.linear()
.domain([0, yStackMax])
.range([height, 0]);
// var color = d3.scale.ordinal()
//.domain(headers)
// .range(["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"]);
// Define and draw axes
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(1)
.tickPadding(6)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
var layer = svg.selectAll(".layer")
.data(layers)
.enter().append("g")
.attr("class", "layer")
.style("fill", function (d, i) { return colorScale(i); });
var rect = layer.selectAll("rect")
.data(function (d) { return d; })
.enter().append("rect")
.attr("x", function (d) { return xScale(d.x); })
.attr("y", height)
.attr("width", xScale.rangeBand())
.attr("height", 0)
.attr("class", function (d) {
return "rect bordered " + "color-" + d.color.substring(1);
});
layer.selectAll("text.rect")
.data(function (layer) { return layer; })
.enter().append("text")
.attr("text-anchor", "middle")
.attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
.attr("y", function (d) { return y(d.y + d.y0) - 3; })
.text(function (d) { return d.y + d.y0; })
.style("fill", "4682b4");
//********** AXES ************
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", ".15em")
.attr("transform", function (d) {
return "rotate(-45)"
});
svg.attr("class", "x axis")
.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")") // centre below axis
.text("Order Velocity Group");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr({ "x": -75, "y": -70 })
.attr("dy", ".75em")
.style("text-anchor", "end")
.text("No. Of Lines");
//********** LEGEND ************
var legend = svg.selectAll(".legend")
.data(headers.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d, i) { return "translate(" + i * (-100) + "," + (height + 50) + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
//.style("fill", color);
.style("fill", function (d, i) { return colors[i]; })
.on("mouseover", function (d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
})
.on("mouseout", function (d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
});
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function (d) { return d; });
transitionStacked();
function transitionStacked() {
y.domain([0, yStackMax]);
rect.transition()
.duration(500)
.delay(function (d, i) { return i * 10; })
.attr("y", function (d) { return y(d.y0 + d.y); })
.attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
.transition()
.attr("x", function (d) { return xScale(d.x); })
.attr("width", xScale.rangeBand());
rect.on('mouseover', tip.show)
.on('mouseout', tip.hide)
};
can anyone help me.
Here is what you need: First, we'll set fData as the data for the texts:
layer.selectAll("text.rect")
.data(fData)
.enter()
.append("text")
But, as this dataset doesn't have the correct yScale value, we'll have to extract it using a filter:
.attr("y", function (d) {
var filtered = fData.filter(function(e){
return e.Total_Units == d.Total_Units
});
return y(filtered[0].Total_Lines) - 3;
})
All together:
layer.selectAll("text.rect")
.data(fData)
.enter().append("text")
.attr("text-anchor", "middle")
.attr("x", function(d) {
return xScale(d.orders) + xScale.rangeBand() / 2;
})
.attr("y", function(d) {
var filtered = fData.filter(function(e) {
return e.Total_Units == d.Total_Units
});
return y(filtered[0].Total_Lines) - 3;
})
.text(function(d) {
return d.Total_Units
})
.style("fill", "4682b4");
Here is your fiddle: https://jsfiddle.net/wnwb6meh/

Hightlight the respective layer in stacked Bar chart when mouseover on legend in d3

I have Done a stacked Bar chart now I am extending the Chart feature as when mouseover on the legend the Respective Bars should highlight.
The Problem I am facing is the mouseover event is working on the Last legend only but but highlighting the every rect layer in chart.
The Problem shown in below fig. This image is when I mouseover on D_Lines Legend Rect
My Code part is
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 fData =
[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},{
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}]
var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];
var layers = d3.layout.stack()(headers.map(function (count) {
return fData.map(function (d) {
// alert(d);
return { x: d.ORDER_TYPE, y: +d[count] };
});
}));
//StackedBar Rectangle Max
var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
// Set x, y and colors
var xScale = d3.scale.ordinal()
.domain(layers[0].map(function (d) { return d.x; }))
.rangeRoundBands([25, width], .08);
colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
var y = d3.scale.linear()
.domain([0, yStackMax])
.range([height, 0]);
var colorScale = d3.scale.ordinal()
.domain(headers)
.range(colors);
// Define and draw axes
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(1)
.tickPadding(6)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"))
var layer = svg.selectAll(".layer")
.data(layers)
.enter().append("g")
.attr("class", "layer")
.style("fill", function (d, i) { return colorScale(i); });
var rect = layer.selectAll("rect")
.data(function (d) { return d; })
.enter().append("rect")
.attr("x", function (d) { return xScale(d.x); })
.attr("y", height)
.attr("width", xScale.rangeBand())
.attr("height", 0)
.attr("class", function (d) {
return "rect bordered " + "color-" + colorScale(d.value).substring(1);
});
debugger;
layer.selectAll("text.rect")
.data(function (layer) { return layer; })
.enter().append("text")
.attr("text-anchor", "middle")
.attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
.attr("y", function (d) { return y(d.y + d.y0) - 3; })
.text(function (d) { return d.y + d.y0; })
.style("fill", "4682b4");
//********** AXES ************
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", ".15em")
.attr("transform", function (d) {
return "rotate(-45)"
});
svg.attr("class", "x axis")
.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")") // centre below axis
.text("Order Velocity Group");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr({ "x": -75, "y": -70 })
.attr("dy", ".75em")
.style("text-anchor", "end")
.text("No. Of Lines");
//********** LEGEND ************
var legend = svg.selectAll(".legend")
.data(headers.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d, i) { return "translate(" + i * (-100) + "," + (height + 50) + ")"; });
debugger;
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function (d, i) { return colors[i]; })
.on("mouseover", function (d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
})
.on("mouseout", function (d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
});
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function (d) { return d; });
transitionStacked();
function transitionStacked() {
y.domain([0, yStackMax]);
rect.transition()
.duration(500)
.delay(function (d, i) { return i * 10; })
.attr("y", function (d) { return y(d.y0 + d.y); })
.attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
.transition()
.attr("x", function (d) { return xScale(d.x); })
.attr("width", xScale.rangeBand());
};
}
Can any one help me to overcome this problem.
You are appending the same class : color-9999CC to all your rect elements, so once you hover the last legend item having color : #9999CC all rect element will be selected.
To create the required class properly, you can add the corresponding color info to each element in your layers object while creating it.
I added a color property that has as value the color of the corresponding headers item:
var layers = d3.layout.stack()(
headers.map(function (count) {
return fData.map(function (d,i) {
return { x: d.orders, y: +d[count] , color: colorScale(count)};
/*color = current headers item color */
});
}));
Then while creating your rect items you can add to each element a class by accessing its color property like this:
var rect = layer.selectAll("rect")
.data(function (d) { return d; })
.....
.attr("class", function (d) {
return "rect bordered " + "color-" +d.color.substring(1);
});
complete code:
var margin = {top:10, right: 10, bottom: 80, left: 50},
width =960,
height=650;
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 fData =
[{"orders":"A","Total_Orders":76,"A_Lines":123,"B_Lines":0,"C_Lines":0,"D_Lines":0,"Total_Lines":123,"Total_Units":3267},
{"orders":"B","Total_Orders":68,"A_Lines":0,"B_Lines":107,"C_Lines":0,"D_Lines":0,"Total_Lines":107,"Total_Units":3115},
{"orders":"C","Total_Orders":81,"A_Lines":0,"B_Lines":0,"C_Lines":123,"D_Lines":0,"Total_Lines":123,"Total_Units":3690},
{"orders":"D","Total_Orders":113,"A_Lines":0,"B_Lines":0,"C_Lines":0,"D_Lines":203,"Total_Lines":203,"Total_Units":7863},
{"orders":"AB","Total_Orders":62,"A_Lines":70,"B_Lines":76,"C_Lines":0,"D_Lines":0,"Total_Lines":146,"Total_Units":1739},
{"orders":"AC","Total_Orders":64,"A_Lines":77,"B_Lines":0,"C_Lines":79,"D_Lines":0,"Total_Lines":156,"Total_Units":2027},
{"orders":"AD","Total_Orders":100,"A_Lines":127,"B_Lines":0,"C_Lines":0,"D_Lines":144,"Total_Lines":271,"Total_Units":6467},
{"orders":"BC","Total_Orders":64,"A_Lines":0,"B_Lines":80,"C_Lines":84,"D_Lines":0,"Total_Lines":164,"Total_Units":1845},
{"orders":"BD","Total_Orders":91,"A_Lines":0,"B_Lines":108,"C_Lines":0,"D_Lines":135,"Total_Lines":243,"Total_Units":4061},
{"orders":"CD","Total_Orders":111,"A_Lines":0,"B_Lines":0,"C_Lines":132,"D_Lines":147,"Total_Lines":279,"Total_Units":5011},
{"orders":"ABC","Total_Orders":45,"A_Lines":58,"B_Lines":63,"C_Lines":55,"D_Lines":0,"Total_Lines":176,"Total_Units":1245},
{"orders":"ABD","Total_Orders":69,"A_Lines":105,"B_Lines":87,"C_Lines":0,"D_Lines":116,"Total_Lines":308,"Total_Units":4538},
{"orders":"ACD","Total_Orders":66,"A_Lines":91,"B_Lines":0,"C_Lines":88,"D_Lines":132,"Total_Lines":311,"Total_Units":4446},
{"orders":"BCD","Total_Orders":68,"A_Lines":0,"B_Lines":84,"C_Lines":95,"D_Lines":111,"Total_Lines":290,"Total_Units":4187},
{"orders":"ABCD","Total_Orders":56,"A_Lines":96,"B_Lines":90,"C_Lines":93,"D_Lines":143,"Total_Lines":422,"Total_Units":6331}]
var headers = ["A_Lines", "B_Lines", "C_Lines", "D_Lines"];
var colors = ["#9999CC", "#F7A35C", "#99CC99", "#CCCC99"];
var colorScale = d3.scale.ordinal()
.domain(headers)
.range(colors);
var layers = d3.layout.stack()(
headers.map(function (count) {
return fData.map(function (d,i) {
return { x: d.orders, y: +d[count] , color: colorScale(count)};
});
}));
//StackedBar Rectangle Max
var yStackMax = d3.max(layers, function (layer) { return d3.max(layer, function (d) { return d.y0 + d.y; }); });
// Set x, y and colors
var xScale = d3.scale.ordinal()
.domain(layers[0].map(function (d) { return d.x; }))
.rangeRoundBands([25, width], .08);
var y = d3.scale.linear()
.domain([0, yStackMax])
.range([height, 0]);
// Define and draw axes
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(1)
.tickPadding(6)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"))
var layer = svg.selectAll(".layer")
.data(layers)
.enter().append("g")
.attr("class", "layer")
.style("fill", function (d, i) { return colorScale(i); });
var rect = layer.selectAll("rect")
.data(function (d) { return d; })
.enter().append("rect")
.attr("x", function (d) { return xScale(d.x); })
.attr("y", height)
.attr("width", xScale.rangeBand())
.attr("height", 0)
.attr("class", function (d,i) {
return "rect bordered " + "color-" +d.color.substring(1);
});
layer.selectAll("text.rect")
.data(function (layer) { return layer; })
.enter().append("text")
.attr("text-anchor", "middle")
.attr("x", function (d) { return xScale(d.x) + xScale.rangeBand() / 2; })
.attr("y", function (d) { return y(d.y + d.y0) - 3; })
.text(function (d) { return d.y + d.y0; })
.style("fill", "4682b4");
//********** AXES ************
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", ".15em")
.attr("transform", function (d) {
return "rotate(-45)"
});
svg.attr("class", "x axis")
.append("text")
.attr("text-anchor", "end") // this makes it easy to centre the text as the transform is applied to the anchor
.attr("transform", "translate(" + (width / 2) + "," + (height + 60) + ")") // centre below axis
.text("Order Velocity Group");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(20,0)")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr({ "x": -75, "y": -70 })
.attr("dy", ".75em")
.style("text-anchor", "end")
.text("No. Of Lines");
//********** LEGEND ************
var legend = svg.selectAll(".legend")
.data(headers)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function (d, i) { return "translate(" + (headers.length-(i+1))*-100 + "," + (height + 50) + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", function (d, i) { return colors[i]; })
.on("mouseover", function (d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "blue");
})
.on("mouseout", function (d, i) {
svg.selectAll("rect.color-" + colors[i].substring(1)).style("stroke", "white");
});
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function (d) { return d; });
transitionStacked();
function transitionStacked() {
y.domain([0, yStackMax]);
rect.transition()
.duration(500)
.delay(function (d, i) { return i * 10; })
.attr("y", function (d) { return y(d.y0 + d.y); })
.attr("height", function (d) { return y(d.y0) - y(d.y0 + d.y); })
.transition()
.attr("x", function (d) { return xScale(d.x); })
.attr("width", xScale.rangeBand());
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.0/d3.min.js"></script>
<body></body>

Data not being redrawn after being filtered on d3 bar chart

I've been trying to add a filter to a bar chart. The bar is removed when I click on the legend, but when I try to reactivate the bar is not being redrawn.
Here is a plnk;
http://plnkr.co/edit/GZtErHGdq8GbM2ZawQSD?p=preview
I can't seem to work out the issue - if anyone could lend a hand?
Thanks
JS code;
// load the data
d3.json("data.json", function(error, data) {
var group = [];
function updateData() {
group = [];
var organization = data.organizations.indexOf("Org1");
var dateS = $("#selectMonth").text()
for (var country = 0; country < data.countries.length; country++) {
var date = data.dates.indexOf(dateS);
group.push({
question: data.organizations[organization],
label: data.countries[country],
value: data.values[organization][country][date]
});
}
}
function draw(create) {
updateData();
x.domain(group.map(function(d) {
return d.label;
}));
y.domain([0, 100]);
// add axis
// Add bar chart
var bar = svg.selectAll("rect")
.data(group);
if (create) {
bar
.enter().append("rect")
.attr('x', function(d) {
return x(d.label);
})
.attr('y', function(d) {
return y(d.value);
})
.attr('width', x.rangeBand())
.attr('height', function(d) {
return height - y(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(-90)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 5)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Value");
}
bar
.transition()
.duration(750)
.attr("y", function(d) {
return y(d.value);
})
.attr("height", function(d) {
return height - y(d.value);
});
// Existing code to draw y-axis:
var legendGroups = d3.select("#legend")
.selectAll(".legendGroup")
.data(group, function(d) {
return d.label; // always try and use a key function to uniquely identify
});
var enterGroups = legendGroups
.enter()
.append("g")
.attr("class", "legendGroup");
legendGroups
.exit()
.remove();
legendGroups
.attr("transform", function(d, i) {
return "translate(10," + (10 + i * 15) + ")"; // position the whole group
});
enterGroups.append("text")
.text(function(d) {
return d.label;
})
.attr("x", 15)
.attr("y", 10);
enterGroups
.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("fill", function(d) {
return "#bfe9bc";
})
.attr("class", function(d, i) {
return "legendcheckbox " + d.label.replace(/\s|\(|\)|\'|\,|\.+/g, '')
})
.on("click", function(d) {
d.active = !d.active;
d3.select(this).attr("fill", function(d) {
if (d3.select(this).attr("fill") == "#cccccc") {
return "#bfe9bc";
} else {
return "#cccccc";
}
})
var result = group.filter(function(d) {
return $("." + d.label.replace(/\s|\(|\)|\'|\,+/g, '')).attr("fill") != "#cccccc"
})
x.domain(result.map(function(d) {
return d.label;
}));
bar
.select(".x.axis")
.transition()
.call(xAxis);
bar
.data(result, function(d) {
return d.label.replace(/\s|\(|\)|\'|\,|\.+/g, '')
})
.enter()
.append("rect")
.attr("class", "bar")
bar
.transition()
.attr("x", function(d) {
return x(d.label);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.value);
})
.attr("height", function(d) {
return height - y(d.value);
});
bar
.data(result, function(d) {
return d.label.replace(/\s|\(|\)|\'|\,|\.+/g, '')
})
.exit()
.remove()
});
}
The bar disappear because you totally remove it with
.remove()
What you can do is hide the element when not selected like that :
d3.selectAll('.graph').selectAll("rect").attr("visibility", function(e) {
return e.active ? "hidden" : "";
})
See http://plnkr.co/edit/2UWaZOsffkw1vkdIJuSA?p=preview

Uncaught TypeError: Cannot read property 'mydata' of undefined

Data being inputted correctly, but shown as undefined when logged:
d3.json('linedata.00.json', function(error, data){
console.log(data)
Error shows up on this line:
data.mydata.forEach(function (kv) {
var labelName = kv.label;
var colorName = kv.color
kv.values.forEach(function (d) {
d.id = d.id;
d.color = colorName;
d.val = +d.val;
d.label = labelName;
});
});
JSON Code as follows:
{
"mydata":[
{
"id":"line01",
"color":"#de6868",
"label":"internal",
"values":[
{"week":"Week 1","val":37},
{"week":"Week 2","val":38},
{"week":"Week 3","val":33},
{"week":"Week 4","val":32},
{"week":"Week 5","val":40},
{"week":"Week 6","val":27},
{"week":"Week 7","val":30},
{"week":"Week 8","val":37},
{"week":"Week 9","val":42},
{"week":"Week 10","val":36},
{"week":"Week 11","val":35},
{"week":"Week 12","val":37},
{"week":"Week 13","val":33}
]
},
The question is. Why am I getting the error when everything is (seemingly) in the right place and how do I fix it?
Callback in it's entirety:
d3.json('linedata.00.json', function(error, data){
console.log(data)
data.mydata.forEach(function (kv) {
var labelName = kv.label;
var colorName = kv.color
kv.values.forEach(function (d) {
d.id = d.id;
d.color = colorName;
d.val = +d.val;
d.label = labelName;
});
});
color.domain(data.mydata.map(function (d) { return d.label; }));
myColor = function(d){return d.color};
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<span style='color:red'>" + d3.format("$,")(d.val) + "</span>";
})
svg.call(tip);
var dataNest = d3.nest()
.key(function(d) {return d.label;})
.entries(data.mydata);
function make_y_axis() { // function for the y grid2 lines
return d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
}
console.log(yAxis.ticks());
var minY = d3.min(data.mydata, function (kv) { return d3.min(kv.values, function (d) { return d.val; }) });
var maxY = d3.max(data.mydata, function (kv) { return d3.max(kv.values, function (d) {return d.val; }) });
var maxX = d3.max(data.mydata, function (kv){return d3.max(kv.values, function(d){ return d.week + 1;});});
console.log(maxX);
var padding = width/(data.mydata[0].values.length + 1)/2;
x.domain(data.mydata[0].values.map(function (d) { return d.week; })).rangePoints([padding, width-padding]);
y.domain([0,(1.2 * maxY)]);
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");
svg.append("g") // Draw the y grid2 lines
.attr("class", "grid2")
.call(make_y_axis()
.tickSize(-width, 0, 0)
.tickFormat("")
);
svg.selectAll(".grid2")
.selectAll(".tick")
.append("rect")
.attr("width", width)
.attr("height", height / (yAxis.ticks()[0]-1) -3)
.attr("class", function(d, i) {
return ((i) % 2) == 1 ? "zebraGrey" : "zebraNone";
})
.attr("stroke", "none");
var city = svg.selectAll(".branch")
.data(data.mydata)
.enter().append("g")
.attr("class", "branch");
city.append("path")
.attr("class", "line")
.attr("id", function(d){return d.id})
.attr("data-legend",function(d){return d.label;})
.attr("d", function (d) {
return line(d.values);
})
.style("stroke", myColor)
.style("fill", "none")
.style("stroke-width", 3);
svg.selectAll("g.dot")
.data(data.mydata)
.enter().append("g")
.attr("class", "dot")
.selectAll("circle")
.data(function(d) {return d.values; })
.enter().append("circle")
// .style("stroke", function (d){return d.color;})
.attr("r", 2)
.attr("cx", function(d,i) { return x(d.week); })
.attr("cy", function(d,i) { return y(d.val); })
.style("stroke", myColor)
.style("fill", myColor)
.style("stroke-width", 3)
// Tooltip stuff after this
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
// add legend
var legend = svg.append("g")
.attr("class", "legend")
.attr("height", 100)
.attr("width", 100)
.attr('transform', 'translate('+ -1 * .37 * width + ',' + height +')');
legend.selectAll('rect')
.data(data.mydata)
.enter()
.append("rect")
.attr("x", function(d, i){return i * 150 + 480})
.attr("y", 40)
.attr("width", 10)
.attr("height", 10)
.style("fill", myColor)
.style("stroke", "none");
legend.selectAll('text')
.data(data.mydata)
.enter()
.append("text")
.attr("class", "legText")
.attr("x", function(d, i){ return i * 150 + 500;})
.attr("y", 50)
.style("fill", myColor)
.style("stroke", "none")
.text(function(d){return d.label});
});
Thanks everyone for looking into this. The code was right, I had two misplaced comas in the JSON itself that were causing the troubles. Thanks though for the concern.

Unable to get x,y position in d3

I am trying to add some text inside rectangles in d3.
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) {
return "translate(" + x(d[columns[0]]) + ",0)";
});
var count = 0;
state.selectAll("rect")
.data(function(d) {
return d.val;
})
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.y1); <<<===== Line 1
})
.attr("height", function(d) {
return y(d.y0) - y(d.y1);
})
.attr("x", function(d) {
return x(d.x); <<<===== Line 2
})
.style("fill", function(d,i) {
return colorSet(i);
})
.attr("id", function(d, i) {
return col[i];
})
.attr("onclick", fun)
.append("text")
.attr("transform",function(d) {
var xvalue =x(d.x); <<<===== Line 3
var yValue = y(d.y1); <<<===== Line 4
return "translate(" + xvalue + ", " + yValue + ")";
})
.text("AAA");
First when i am adding the rectangles I am able to get x and y positons x(d.x) and y(d.y1) as mentioned by 'line 1' and 'line 2' but when I am again trying to get x and y value in 'line 3' and 'line 4' I am getting wrong values.
Can anyone point out what is wrong with this code???
Thanks in advance.
As #Cool Blue mentioned you cannot append text element inside a rect element so try this code:
var state = svg.selectAll(".state")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) {
return "translate(" + x(d[columns[0]]) + ",0)";
});
var count = 0;
state.selectAll("rect")
.data(function(d) {
return d.val;
})
.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);
})
.attr("x", function(d) {
return x(d.x);
})
.style("fill", function(d,i) {
return colorSet(i);
})
.attr("id", function(d, i) {
return col[i];
})
.attr("onclick", fun);
state.selectAll("text")
.data(function(d) {
return d.val;
})
.enter().append("text")
.attr("transform",function(d) {
var xvalue =x(d.x);
var yValue = y(d.y1);
return "translate(" + xvalue + ", " + yValue + ")";
})
.text("AAA");

Categories