我有一张可以重复使用的图表。我将以下简单代码添加到可重用图表中,期望它会将click监听器添加到由它创建的所有图表中。
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); });
});
}
但是click函数仅适用于可重用图表呈现的最后一个图形实例。如何将点击侦听器添加到可重用图表呈现的每个图表中?
这里有一个更简单的版本fiddle。我想在点击小条形图时添加缩放的弹出式条形图svg
。我认为问题在于动态创建div
,因为当我尝试在预定义div
中创建图表时,点击功能正常工作。
任何帮助将不胜感激!
答案 0 :(得分:0)
svg
变量的范围导致了问题。在您的代码中,svg
变量值通过可重用函数的所有实例共享。您可能希望使用enter()
来创建SVG元素和内部组件,并将click
侦听器添加到组件中。 svg
变量应在exports
函数内定义。
// 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.
});
});
}