我使用D3.js创建了组条形图。每组有2个酒吧。单击任何栏时,必须使用自定义警告框显示一些数据。现在,栏可以单击并显示数据。
var state = svg.selectAll(".TestSuite")
.data(data)
.enter().append("g")
.attr("class", "TestSuite")
.on("click", function(d,i) {
if(i==0){
Alert.render(d3.select(this).data()[0].FalseStatements);
}else{
Alert.render(d3.select(this).data()[0].TrueStatements);
}
})
.attr("transform", function (d) {
return "translate(" + x0(d.TestSuite) + ",0)";
});
但数据根据点击的栏数而有所不同。那么如何唯一地识别单个组中的每个单个栏。
这里“如果条件”我使用的不做我想要的东西。我该怎么纠正呢?
谢谢。
(假设一组条形图包含两个条形图,一个显示真实计数,另一组显示特定方案的错误计数。当我们单击显示真实计数的条形图时,它应显示已存在于数据中的“TrueStatements”。使用d3.select(this).data()[0].TrueStatements
可以做到这一点。当有人点击显示错误计数的栏时,它应该出现在数据中已有的“FalseStatements”。使用d3.select(this).data()[0].FalseStatements
可以做到这一点。我的问题是如何做我们确定显示真实计数的栏和显示错误计数的栏,以执行此任务。)
编辑:
如何获取条形图的数据(这是在for循环中)
originalDataSetForBarChart.push({
TestSuite: "TS"+treeIndex,
Pass: trueAppear,
Fail: falseAppear,
FalseStatements : falseStatement,
TrueStatements : trueStatement
});
条形图代码
var margin = {
top: 20,
right: 10,
bottom: 30,
left: 40
},
width = 890 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], .5);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#4169E1", "#800080"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(""));
var w = width + margin.left + margin.right;
var h = height + margin.top + margin.bottom;
var svg = d3.select(".chart1").append("svg")
.attr("width", w)
.attr("height", h)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//svg.call(tip);
var xg = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")");
var yg = svg.append("g")
.attr("class", "y axis");
yg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Count");
我使用以下方法在setInterval函数中将条形附加到此图表。
function update() {
startTime_barChart = new Date().getTime();
for (var i = 0; i < data.length; i++) {
var testSuite = d3.keys(data[i]).filter(function (key) {
return key !== "TestSuite";
});
}
data.forEach(function (d) {
d.trueFalseCount = testSuite.map(function (name) {
return {
name: name,
value: +d[name]
};
});
});
x0.domain(data.map(function (d) {
return d.TestSuite;
}));
x1.domain(testSuite).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(data, function (d) {
return d3.max(d.trueFalseCount, function (d) {
return d.value;
});
})]);
//making the x axis/y axis
xg.call(xAxis);
yg.call(yAxis);
//removing all the rectangles
svg.selectAll(".TestSuite").remove();
var tip_word;
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
tip_word= "<strong style='color:white'>"+
"Pass count :"+
"</strong>"+
" <span style='color:white'>" + d.True +
"</span></br>"+
"<strong style='color:white'>"+
"Fail count :"+
"</strong>"+
" <span style='color:white'>" + d.False +
"</span>";
return word;
});
var state = svg.selectAll(".TestSuite")
.data(data)
.enter().append("g")
.attr("class", "TestSuite")
.on("click", function(d,i) {
if(i%2 == 0){//How to set this condition
Alert.render(d3.select(this).data()[0].FalseStatements);
}else{
Alert.render(d3.select(this).data()[0].TrueStatements);
}
})
.attr("transform", function (d) {
return "translate(" + x0(d.TestSuite) + ",0)";
});
svg.call(tip);
state.selectAll("rect")
.data(function (d) {
return d.trueFalseCount;})
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function (d) {
return x1(d.name);
})
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
})
.style("fill", function (d) {
return color(d.name);
});
if(barChartLegentController==1){
var legend = svg.selectAll(".legend")
.data(testSuite.slice().reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return d; });
barChartLegentController=2;
}
endTime_barChart = new Date().getTime();
var totalbar = (endTime_barChart-startTime_barChart)/1000;
//alert('Total bar time : '+ totalbar+' seconds');
}
答案 0 :(得分:0)
我不确定我是否完全理解你的要求,但识别任何元素/实体的最佳方法是使用id,如下所示:
d3.select(this).attr(id, function(d, i) {return 'bar_' + i});
在创建条形图的迭代函数中添加它。通过这种方式,您可以使用d3.select('#bar_1)
从代码中的任意位置选择它们。
如果您只想识别每个栏,它将是这样的:
var state = svg.selectAll(".TestSuite")
.data(data)
.enter().append("g")
.attr("id", function(d,i) {return 'bar_' + i})
.attr("class", "TestSuite")
.on("click", function(d,i) {
if(i==0){
Alert.render(d3.select(this).data()[0].FalseStatements);
}else{
Alert.render(d3.select(this).data()[0].TrueStatements);
}
})
.attr("transform", function (d) {
return "translate(" + x0(d.TestSuite) + ",0)";
});
如果您希望识别每个栏的ID与其内容相关(真或假陈述),我建议如下:
var state = svg.selectAll(".TestSuite")
.data(data)
.enter().append("g")
.attr("class", "TestSuite")
.on("click", function(d,i) {
var barId;
if(i==0){
barId = 'falseBar_' + i;
Alert.render(d3.select(this).data()[0].FalseStatements);
}else{
barId = 'trueBar_' + i;
Alert.render(d3.select(this).data()[0].TrueStatements);
}
d3.select(this).attr('id', barId);
})
.attr("transform", function (d) {
return "translate(" + x0(d.TestSuite) + ",0)";
});
在任何情况下,这都会为每个栏分配一个唯一的ID(即“bar_25”或“falseBar_14”),为您提供识别每个栏的理想方式。
编辑:在OP向我展示他们正在使用的实际代码之后,以下是我对解决方案的建议(实际上与上面的代码在同一行)。您实际应该修改的代码是您发布的代码下面的代码。它是渲染实际条形的地方:
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
我建议在每个栏中添加一个id属性如下:
state.selectAll("rect")
.data(function(d) { return d.ages; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("id", function(d, i) {return 'bar_' + i}) // <-- Edited line
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); });
您必须了解为什么这个,而不是您最初提供的代码块是相关的。如你所说,第一个块渲染每组条形(因此append("g")
代表svg组)。第二个块以append("rect")
开头,表示svg矩形。这个和其他行(即样式(“填充”)...,attr(“x”)...和attr(“y”)......)清楚地表明这个块是处理实际条形的块而不是团体。