根据所选数据更新热图

Update the heatmap based on the selected data

我在 之后创建了一个热图和一些迷你图。 在这个例子中,用户可以点击行标签和列标签,在我的例子中,我只保留了点击列标签的可能性。

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

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

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

// 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 允许更新热图,但我无法调整代码。 在示例中,数据仅更改值而不更改 "shape"。也就是说,标签的数量保持不变。就我而言,情况有点复杂。

我用代码创建了一个 Plunker

这是一个很好的例子,可以实现很多 d3 的 enter/update/exit 选择。

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

好的,这是使用 enter/update/merge/exit 方法的 Plunkr 分支。

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

我如何完成 merge 选择的预览:让我们以 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

我在将鼠标悬停在工具提示上时确实遇到了一个问题,即工具提示经常闪烁。为了解决这个问题,我在 .d3-tip 工具提示中添加了 pointer-events:none

仔细阅读代码,如果我遗漏了什么或者您在理解任何部分时遇到问题,请告诉我。

希望对您有所帮助。