dc.js - 将过滤器值显示为画笔上的标签
dc.js - display filter values as labels on brush
谁能告诉我如何自定义画笔以将过滤器值显示为标签?
我想得到和下面截图中箭头标记的一样的样式,但是我不知道怎么得到,也没看到例子。
这是一个很好的问题,我很惊讶以前没有人问过这个问题。很明显,dc.js可以在图表上方的文字中显示过滤值,但是放在笔刷上真的很酷!
任何 dc.js 图表都允许您收听 pretransition
event 并使用 D3 绘制您自己的注释。
让我们这样做:
chart.on('pretransition', function(chart) {
let brushBegin = [], brushEnd = []; // 1
if(chart.filter()) {
brushBegin = [chart.filter()[0]]; // 2
brushEnd = [chart.filter()[1]];
}
let beginLabel = chart.select('g.brush') // 3
.selectAll('text.brush-begin')
.data(brushBegin); // 4
beginLabel.exit().remove(); // 5
beginLabel = beginLabel.enter()
.append('text') // 6
.attr('class', 'brush-begin') // 7
.attr('text-anchor', 'end')
.attr('dominant-baseline', 'text-top')
.attr('fill', 'black')
.attr('y', chart.margins().top)
.attr('dy', 4)
.merge(beginLabel); // 8
beginLabel
.attr('x', d => chart.x()(d))
.text(d => d.toFixed(2)); // 9
let endLabel = chart.select('g.brush')
.selectAll('text.brush-end')
.data(brushEnd);
endLabel.exit().remove();
endLabel = endLabel.enter()
.append('text')
.attr('class', 'brush-end')
.attr('text-anchor', 'begin')
.attr('dominant-baseline', 'text-top')
.attr('fill', 'black')
.attr('y', chart.margins().top)
.attr('dy', 4)
.merge(endLabel);
endLabel
.attr('x', d => chart.x()(d))
.text(d => d.toFixed(2));
})
这看起来像很多代码;它实际上是在做同样的事情两次,每个标签一次。让我们看看第一个标签是如何显示的。
- D3 将数组数据绑定到元素。我们将把画笔开头和结尾的标签分别绑定到一个由零(画笔隐藏)或一个元素(画笔显示)组成的数组。此行将数组默认为空。
- 如果过滤器处于活动状态,我们会将数组设置为包含画笔开始值和结束值的单元素数组。
- 标准 D3 样板:select 父元素 (
d.brush
),然后 select 我们要创建、更新或销毁的元素,然后
- 将零元素或一元素数组绑定到 selections
- 如果画笔刚刚被隐藏,删除标签
- 如果刚刚显示画笔,请添加标签
- 并使用所需的 SVG 属性和我们刚刚在绑定中使用的 class
brush-begin
对其进行初始化。这些属性大部分是为了让标签位置正确。
- 合并 selection 在一起,所以现在我们有一个插入+修改 selection
- 应用 X 位置属性并在画笔更改时更改文本。
https://jsfiddle.net/gordonwoodhull/w4xhv8na/33/
获得黑底白字标签是 actually not trivial,但我希望稍后 return。
谁能告诉我如何自定义画笔以将过滤器值显示为标签?
我想得到和下面截图中箭头标记的一样的样式,但是我不知道怎么得到,也没看到例子。
这是一个很好的问题,我很惊讶以前没有人问过这个问题。很明显,dc.js可以在图表上方的文字中显示过滤值,但是放在笔刷上真的很酷!
任何 dc.js 图表都允许您收听 pretransition
event 并使用 D3 绘制您自己的注释。
让我们这样做:
chart.on('pretransition', function(chart) {
let brushBegin = [], brushEnd = []; // 1
if(chart.filter()) {
brushBegin = [chart.filter()[0]]; // 2
brushEnd = [chart.filter()[1]];
}
let beginLabel = chart.select('g.brush') // 3
.selectAll('text.brush-begin')
.data(brushBegin); // 4
beginLabel.exit().remove(); // 5
beginLabel = beginLabel.enter()
.append('text') // 6
.attr('class', 'brush-begin') // 7
.attr('text-anchor', 'end')
.attr('dominant-baseline', 'text-top')
.attr('fill', 'black')
.attr('y', chart.margins().top)
.attr('dy', 4)
.merge(beginLabel); // 8
beginLabel
.attr('x', d => chart.x()(d))
.text(d => d.toFixed(2)); // 9
let endLabel = chart.select('g.brush')
.selectAll('text.brush-end')
.data(brushEnd);
endLabel.exit().remove();
endLabel = endLabel.enter()
.append('text')
.attr('class', 'brush-end')
.attr('text-anchor', 'begin')
.attr('dominant-baseline', 'text-top')
.attr('fill', 'black')
.attr('y', chart.margins().top)
.attr('dy', 4)
.merge(endLabel);
endLabel
.attr('x', d => chart.x()(d))
.text(d => d.toFixed(2));
})
这看起来像很多代码;它实际上是在做同样的事情两次,每个标签一次。让我们看看第一个标签是如何显示的。
- D3 将数组数据绑定到元素。我们将把画笔开头和结尾的标签分别绑定到一个由零(画笔隐藏)或一个元素(画笔显示)组成的数组。此行将数组默认为空。
- 如果过滤器处于活动状态,我们会将数组设置为包含画笔开始值和结束值的单元素数组。
- 标准 D3 样板:select 父元素 (
d.brush
),然后 select 我们要创建、更新或销毁的元素,然后 - 将零元素或一元素数组绑定到 selections
- 如果画笔刚刚被隐藏,删除标签
- 如果刚刚显示画笔,请添加标签
- 并使用所需的 SVG 属性和我们刚刚在绑定中使用的 class
brush-begin
对其进行初始化。这些属性大部分是为了让标签位置正确。 - 合并 selection 在一起,所以现在我们有一个插入+修改 selection
- 应用 X 位置属性并在画笔更改时更改文本。
https://jsfiddle.net/gordonwoodhull/w4xhv8na/33/
获得黑底白字标签是 actually not trivial,但我希望稍后 return。