根据所选数据更新热图

时间:2018-06-09 10:26:34

标签: javascript d3.js heatmap

我在this example之后创建了一个热图和一些迷你图。 在示例中,用户可以单击行的标签和列的标签,在我的情况下,我只保留点击列标签的可能性。

该示例非常适合我的数据,只需要根据单选按钮选择更新热图。

第一个单选按钮允许您选择区域类型(A或B)。 第二组单选按钮允许您选择要显示的每日数据。 但是,数据“不完整”:并非所有月份都有每日数据,而只有4月和12月。 因此,如果您选择四月或十二月单选按钮,则会显示热图上的每日数据,否则会显示每月数据。

该示例有效,但它非常原始,因为每次都会删除并重新创建热图。

// Return to the initial order when the user clicks on the button
d3.select('#initialOrder').on('click', function() {
    var trans = heat.transition().duration(1000);
    var sortedYear = Array.from(Array(numYLabels).keys());
    trans.selectAll('.cell')
        .attr('y', function(d) { 
            var row = parseInt(d3.select(this).attr('data-r'));
            return sortedYear.indexOf(row)*cellSize;
        });
    trans.selectAll('.rowLabel')
        .attr('y', function(d, k) {
            return sortedYear.indexOf(k) * cellSize;
        });
    sortedYear.forEach(function(d) {
        d3.select('#data-svg-' + d).raise();
    });
});

// Area radio button change selection
d3.selectAll('input[name=area-rb]').on('change', function() {
    areaSelected = d3.select('input[name="area-rb"]:checked').property("value");
    console.log('areaSelected:', areaSelected);
    d3.select('#heatmapSvg').remove();
    d3.selectAll('.data-svg').remove();
    createHeatmap();
});

// Month radio button change selection
d3.selectAll('input[name=month-rb]').on('change', function() {
    monthSelected = d3.select('input[name="month-rb"]:checked').property("value");
    console.log('monthSelected:', monthSelected);
    if(avaibleDayData.includes(monthSelected)) {
        d3.select('#heatmapSvg').remove();
        d3.selectAll('.data-svg').remove();
        createHeatmap();
    }
    else {
        monthSelected = 'nothing';
        d3.select('#heatmapSvg').remove();
        d3.selectAll('.data-svg').remove();
        createHeatmap();
    }   
});

我发现this example允许更新热图,但我无法调整代码。 在该示例中,数据仅改变值而不是“形状”。也就是说,标签的数量保持不变。就我而言,情况有点复杂。

我使用代码创建Plunker

1 个答案:

答案 0 :(得分:2)

这是一个很好的例子,可以实现很多d3的进入/更新/退出选择。

是的,我同意:在每次更改时重新创建图表并不是一个好的解决方案。

好的,所以这是使用输入/更新/合并/退出方法的Plunkr的分支。

http://plnkr.co/edit/2v8YQoZSClhKpW2U1pwi?p=preview

预览我如何完成合并选择:让我们以rowLabels为例:

// make region labels
var rowLabels = rowLabelGroup
    .selectAll('text.rowLabel')
    .data(yLabelsNames);

// ENTER SELECTION FOR COL LABELS
// ENTER + UPDATE
// After merging the entered elements with the update selection,
// apply operations to both.

rowLabels
    .enter().append('text').attr('class', 'rowLabel mono')
    .attr('font-weight', 'normal')
    .style('text-anchor', 'end')
    .on('mouseover', function(d) {
        d3.select(this).attr('font-weight', 'bold').style('fill', 'red');
    })
    .on('mouseout', function(d) {
        d3.select(this).attr('font-weight', 'normal').style('fill', 'black');
    })
    .attr('x', 0)
    .attr('y', function(d, i) {
        return i * cellSize;
    })
    .attr('transform', function(d, i) {
        return 'translate(-3, 11)';
    })
    .merge(rowLabels)
    .attr('name', function(d) {
        return d;
    })
    .text(function(d) {
        return d;
    })
    .attr('id', function(d) {
        return 'rowLabel_' + yLabelsNames.indexOf(d);           
    })
    .attr('label-r', function(d) {
        return yLabelsNames.indexOf(d);
    });


// exit/remove elements which are no longer in use
rowLabels.exit().remove();

同样,正如您在代码中所注意到的,这些方法已应用于colLabelscellssparkLineSvgs

关于附加SVG,我已将该代码移至外部 updateHeatmap函数。是的,顺便说一句,我已将该功能的名称从createHeatmap更改为updateHeatmap

我在徘徊于工具提示时确实遇到了一个问题,即工具提示闪烁了很多。为了解决这个问题,我已将pointer-events:none添加到.d3-tip工具提示。

仔细检查代码,如果我错过了任何内容,或者您​​遇到任何问题,请告诉我。

希望它有所帮助。