Unable to get x,y position in d3 - javascript

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");

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/

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

D3 transition Circle Tooltip error

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);
});

Update Bar Chart in d3

I have a question about updating a bar chart in d3.js. I've played around with the transition function but can't seem to get it working.
Here is the code for the basic bar chart:
<script>
var width = 960,
height = 500;
var y = d3.scale.linear()
.range([height, 0]);
var chart = d3.select(".chart")
.attr("width", width)
.attr("height", height);
d3.tsv("data/data.tsv", type, function(error, data) {
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
var barWidth = width / data.length;
var bar = chart.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; });
bar.append("rect")
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.attr("width", barWidth - 1);
bar.append("text")
.attr("x", barWidth / 2)
.attr("y", function(d) { return y(d.frequency) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.frequency; });
});
function type(d) {
d.frequency = +d.frequency;
return d;
}
And so far, I have this for the update function:
function updateBarData(){
var width = 960,
height = 500;
var y = d3.scale.linear()
.range([height, 0])
d3.tsv("data/data3.tsv", type, function(error, data) {
y.domain([0, d3.max(data, function(d) { return d.frequency; })])
})
var barupdate = chart.selectAll("")
.data(data);
barupdate.enter()
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; })
barupdate.append("rect")
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.attr("width", barWidth - 1);
barupdate.append("text")
.attr("x", barWidth / 2)
.attr("y", function(d) { return y(d.frequency) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.frequency; });
barupdate.transition()
.duration(1000)
.attr("transform", function(d, i) { return "translate(" + i * barWidth + ",0)"; })
barupdate.append("rect")
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.attr("width", barWidth - 1);
barupdate.append("text")
.attr("x", barWidth / 2)
.attr("y", function(d) { return y(d.frequency) + 3; })
.attr("dy", ".75em")
.text(function(d) { return d.frequency; });
barupdate.exit().transition()
.duration(1000)
.remove();
}
I've been starting at this all day, so may be missing something blindingly obvious, but would appreciate any help.
Thanks.
Update 1:
function updateBarData(){
d3.tsv("data/data3.tsv", type, function(error, data) {
})
var updatechart = g.selectAll("body")
.data(data)
updatechart.enter().insert("rect")
.attr("y", function(d) { return y(d.frequency); })
.attr("height", function(d) { return height - y(d.frequency); })
.attr("width", barWidth - 1)
updatechart.transition()
.duration(1000)
.attr("y", function(d) { return y(d.frequency); })
updatechart.exit()
.remove();
}

Displaying tooltips permanently in d3.js line chart

I'm making a line chart using d3.js. A tooltip at a point is displayed on mouseover,and disappears on mouseout. I want to display all the tooltips together permanently when the chart is created. Is there a way to do it?
My javascript-
var x = d3.time.scale().range([0, w]);
var y = d3.scale.linear().range([h, 0]);
x.domain(d3.extent(data, function(d) { return d.x; }));
y.domain(d3.extent(data, function(d) { return d.y; }));
var line = d3.svg.line()
.x(function(d) {
return x(d.x);
})
.y(function(d) {
return y(d.y);
})
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var graph = d3.select("#graph").append("svg:svg")
.attr("width", 900)
.attr("height", 600)
.append("svg:g")
.attr("transform", "translate(" + 80 + "," + 80 + ")");
var xAxis = d3.svg.axis().scale(x).ticks(10).orient("bottom");
var yAxisLeft = d3.svg.axis().scale(y).ticks(10).orient("left");
var area = d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(h)
.y1(function(d) { return y(d.y); });
graph.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("class", "circle")
.attr("cx", function (d) { return x(d.x); })
.attr("cy", function (d) { return y(d.y); })
.attr("r", 4.5)
.style("fill", "black")
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div
.html(d.y) + "<br/>" + d.x)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 30) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
To label each data point, you can add text elements at the appropriate positions. The code would look something like this.
graph.selectAll("text").data(data).enter()
.append("text")
.attr("x", function (d) { return x(d.x); })
.attr("y", function (d) { return y(d.y) - 10; })
.text(function(d) { return d.value; });

Categories