I have a reusable chart that works fine. I added the following simple code to the reusable chart expecting that it would add click listener to all the charts created by it.
d3.cloudshapes.barChart = function module() {
var margin = {top: 10, right: 10, bottom: 20, left: 20},
width = 500,
height = 500,
gap = 0,
ease = "bounce";
var svg;
// Define the 'inner' function: which, through the surreal nature of JavaScript scoping, can access
// the above variables.
function exports(_selection) {
_selection.each(function(_data) {
var chartW = 60,
chartH = 60;
var test_data = _data.value;
var x1 = d3.scale.ordinal()
.domain(test_data.map(function(d) { return d.x; }))
.rangeRoundBands([0, chartW], 0.1);
var y1 = d3.scale.linear()
.domain([0, 36])
.range([chartH, 0]);
var color = d3.scale.category10();
// If no SVG exists, create one - and add key groups:
if (!svg) {
svg = d3.select(this)
.append("svg")
.attr("width", width)
.attr("height", height)
.classed("chart", true);
var container = svg.append("g").classed("container-group", true);
container.append("g").classed("chart-group", true);
container.attr({transform: "translate(" + 60*_data.row + "," + 60*_data.col + ")"});
container.on("click", click);
}
// Transition the width and height of the main SVG and the key 'g' group:
svg.classed("chart", true).transition().attr({width: width, height: height});
var container = svg.append("g").classed("container-group", true);
container.append("g").classed("chart-group", true);
container.attr({transform: "translate(" + 60*_data.row + "," + 60*_data.col + ")"});
container.on("click", click);
function click() {
console.log("I got clicked");
}
// Define gap between bars:
var gapSize = x1.rangeBand() / 100 * gap;
// Define width of each bar:
var barW = x1.rangeBand() - gapSize;
// Select all bars and bind data:
var bars = svg.selectAll(".chart-group")
.selectAll(".bar")
.data(test_data);
bars.enter().append("rect")
.classed("bar", "true")
.attr({
width: barW,
x: function (d) {
return x1(d.x) + gapSize / 2; },
y: function(d) { return y1(d.y); },
height: function(d) { return chartH - y1(d.y); }
})
.attr("fill", function(d) { return color(d.x); });
});
}
But the click function works just for the last instance of graph rendered by the reusable chart. How can a click listener added to each graph rendered by the reusable chart ??
A simpler version is here fiddle . I want to add a zoomed popover bar chart svg
on clicking on little bar charts. I think the problem is with dynamically created div
because when I tried creating charts in predefined div
than the click function works fine.
Any help would be much appreciated !
The scope of the svg
variable is causing the problem. In your code, the svg
variable value is shared throug all the instances of your reusable function. You probably want to use enter()
to create the SVG element and the inner components, and add the click
listener to the component. The svg
variable should be defined inside the exports
function.
// rest of the code...
function exports(selection) {
selection.each(function(data) {
// Select the SVG element
var svg = d3.select(this).selectAll('svg').data([data]);
// Create the SVG element on enter, set it's size
svg.enter().append('svg')
.attr('width', width)
.attr('height', height);
var component = svg.selectAll('g.component').data([data]);
// Create the component group on enter and set its attributes
component.enter().append('g');
// Add other elements...
// click listener
component.on('click', function(d) {
// click callback.
});
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.