我不知道dc.js
和crossfilter.js
是否可以这样做,但我还是决定问。
我将a scatterplot中的a barChart和dc示例合并为一个交互式信息中心:
var chart1 = dc.scatterPlot("#test1");
var chart2 = dc.scatterPlot("#test2");
d3.csv("output.csv", function(error, data) {
data.forEach(function (x) {
x.x = +x.x;
x.y = +x.y;
x.z = +x.z;
});
var ndx = crossfilter(data),
dim1 = ndx.dimension(function (d) {
return [d.x, d.y];
}),
dim2 = ndx.dimension(function (d) {
return Math.floor(parseFloat(d.z) * 10) / 10;
}),
group1 = dim1.group(),
group2 = dim2.group(),
chart1.width(300)
.height(300)
.x(d3.scale.linear().domain([-2, 2]))
.y(d3.scale.linear().domain([-2, 2]))
.yAxisLabel("y")
.xAxisLabel("x")
.clipPadding(10)
.dimension(dim1)
//.excludedOpacity(0.5)
.excludedColor('#ddd')
.group(group1)
.symbolSize([2.5]);
chart2
.width(600)
.dimension(dim2)
.group(group2)
.x(d3.scale.linear().domain([0,3]))
.elasticY(true)
.controlsUseVisibility(false)
.barPadding([0.1])
.outerPadding([0.05]);
chart2.xAxis().tickFormat(function(d) {return d}); // convert back to base unit
chart2.yAxis().ticks(10);
dc.renderAll();
});
刷条形图时的结果:
我想更改过滤,以便在刷条形图时,散点图中的刷点将具有不透明度值,在画笔中间为1,并且朝向画笔范围的末尾减小。
其他点(画笔外部)应该是灰色的,而不是像当前脚本中那样不可见。插图:
是否可以使用dc.js
和crossfilter.js
?
PS:附加的散点图不是理想的结果。它不会根据不透明度进行过滤。我只是附上它来显示刷完条形图后其他点(灰色)的样子。
答案 0 :(得分:2)
我无法使用动画过渡效果,因为我缺少有关如何中断过渡的内容,原始dc.scatterPlot
已经应用了不透明度过渡。
因此,首先,让我们在原始散点图上转换过渡:
chart1
.transitionDuration(0)
我们还需要将Z添加到散点图的输入数据中。虽然将它添加到值更有意义,但将其添加到键中很容易(并且散点图将忽略键中的额外元素):
dim1 = ndx.dimension(function (d) {
return [d.x, d.y, d.z];
}),
然后我们可以在散点图中添加一个处理程序,根据条形图中过滤器的范围将不透明度应用于点:
chart1.on('pretransition', function(chart) {
var range = chart2.filter(); // 1
console.assert(!range || range.filterType==='RangedFilter'); // 2
var mid, div; // 3
if(range) {
mid = (range[0] + range[1])/2;
div = (range[1] - range[0])/2;
}
chart1.selectAll('path.symbol') // 4
.attr('opacity', function(d) {
if(range) { // 5
if(d.key[2] < range[0] || range[1] < d.key[2])
op = 0; // 6
else
op = 1 - Math.abs(d.key[2] - mid)/div; // 7
//console.log(mid, div, d.key[2], op);
return op;
}
else return 1;
})
});
null
或者应该是RangedFilter 您可以使用d3.ease使用曲线而不是线性地将距离[0,1]映射到不透明度[0,1]。这可能很好,因此它强调了更接近中点的点
这个演示并不是那么酷,因为数据纯粹是随机的,但它显示了这个想法: https://jsfiddle.net/gordonwoodhull/qq31xcoj/64/
编辑:好吧,它完全滥用了dc.js,但是如果你真的想在没有过滤的情况下使用它,并以灰色显示排除的点,你也可以这样做
这将禁用条形图上的过滤:
chart2.filterHandler(function(_, filters) { return filters; });
然后将不透明度和颜色应用于散点图,而不是:
chart1.selectAll('path.symbol')
.attr('opacity', function(d) {
if(range && range.isFiltered(d.key[2]))
return 1 - Math.abs(d.key[2] - mid)/div;
else return 1;
})
.attr('fill', function(d) {
if(!range || range.isFiltered(d.key[2]))
return chart1.getColor(d);
else return '#ccc';
})
有了这些数据,看到淡蓝色点和灰色点之间的差异是很棘手的。也许它可以更好地使用非随机数据,也许不是。也许另一种颜色会有所帮助。
同样,您也可以使用直接D3,因为这会禁用dc.js和crossfilter的大部分功能。但是你必须从头开始问这个问题。
编辑2:按照以下过滤方式对点进行排序:
.sort(function(d) {
return range && range.isFiltered(d.key[2]) ? 1 : 0;
})