Grouped Bar Chart Selecions duplicate problem.

28 views
Skip to first unread message

Marvalo

unread,
Nov 4, 2011, 10:26:30 AM11/4/11
to protovis
Hi

I am trying out a grouped bar chart with selections. In the example
code I have data that will produce
two bar charts each with three bars. The problem is when I select a
bar on one chart the bar in the same position on the other chart gets
selected too! It seems like the local variable def("sel", []) is being
shared some how but I can't figure it out.

Can anyone help me out?

thanks

M


<head>
<html>
<head>
<title>Grouped Chart Test</title>
<script src="protovis.js" type="text/javascript"></script>
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {

var data = [
[
{"label":"Data 1","value":165,"color":"#1f77b4"},
{"label":"Data 2","value":200.0,"color":"#aec7e8"},
{"label":"Data 3","value":60.5,"color":"#ff7f0e"}
],
[
{"label":"Data 1","value":100.999,"color":"#1f77b4"},
{"label":"Data 2","value":250.0,"color":"#aec7e8"},
{"label":"Data 3","value":50.5,"color":"#ff7f0e"}
]
];


var yAxisMax = 275;
var multi = false;

var dim = {
h:400,
w:400
};

var scales = {
px : pv.Scale.ordinal(pv.range(2)).split(0, dim.w),
x : pv.Scale.ordinal(data).split(0, dim.w),
y : pv.Scale.linear(0, yAxisMax).range(0, dim.h)
}

var color = {
"border":"#000000",
"highlight":"#ffd700",
"highlightBorder":"#ffd700",
"select":"#ffd700",
"selectBorder":"#ff0000",
"background":"#ffffff",
"rule":"#eeeeee",
"tick":"#000000",
"font":"#000000"
};


/* The root panel. */
var vis = new pv.Panel()
.canvas('chart')
.overflow(false)
.width(dim.w)
.height(dim.h);

var panel = vis.add(pv.Panel)
.data(data)
.def("sel", [])
.strokeStyle("red")
.bottom(0)
.height(function(d) {return dim.h})
.left(function(d) {
var w = dim.w / 2;
var i = scales.px(this.index) - (w / 2);
return i;
})
.width(function() { return dim.w / 2});


var bar = panel.add(pv.Bar)
.data(function(d){return d;})
.title(function(d) {return d.value.toFixed(0)})
.bottom(0)
.height(function(d) scales.y(d.value))
.left(function(d) {
var w = (dim.w / 2) / 3;
return this.index * w;
})
.width(function() { return (dim.w / 2) / 3;})
.fillStyle(function(d){
if($.inArray(this.index, this.parent.sel()) !== -1){
return color.highlight;
}else{
return d.color;
}
})
.event("click", function() {
var arr = this.parent.sel();
var idx = $.inArray(this.index, arr);
if(idx === -1){
if(multi){
arr.push(this.index);
}else{
this.parent.sel([this.index]);
}
}else{
if(multi){
arr.splice(idx,1);
}else{
this.parent.sel([]);
}
}
vis.render();
});

vis.render();

});
</script>
</head>
<body>

<div id="fig"></div>
<div id="chart"></div>
</body>
</html>

Mike Bostock

unread,
Nov 4, 2011, 12:28:37 PM11/4/11
to prot...@googlegroups.com
Correct; this is a bit tricky to do with Protovis, because normally defs and other property definitions are shared by all instances of a mark. There's a special case that allows you to override a def for a mark that is the target of a user event, but I'm not sure that applies to its parent.

You'll have an easier time doing this in D3, if you can switch.

Mike

Marvalo

unread,
Nov 4, 2011, 2:07:02 PM11/4/11
to protovis
Hi

thanks for you reply you helped find the solution. Instead of storing
the index in the def("sel", []) I store
the index of the parent and the child as a string seems to work well!.

var id = this.parent.index+":"+this.index;

Marvalo
Reply all
Reply to author
Forward
0 new messages