简体   繁体   English

如何使用D3更新热图中的文本?

[英]How to update text in heatmap using D3?

I've created a D3 heatmap based on this example , and have written an update function for it. 我已经基于此示例创建了一个D3热图,并为其编写了一个更新函数。 Here's the relevant code for the base heatmap: 这是基本热图的相关代码:

<!DOCTYPE html>
<html lange = "en">
<head>
    <meta charset="UTF-8">
    <title>Heatmap</title>
    <script type ="text/javascript" src="d3/d3.v3.js"></script>
    <script type ="text/javascript" src="updateHeatmap.js"> </script>
    <style type ="text/css">  

    .btn { 
        display: inline; 
    }


        rect.bordered {
        stroke: #E6E6E6;
        stroke-width:2px;   
      }

      text.mono {
        font-size: 9pt;
        font-family: Consolas, courier;
        fill: #aaa;
      }

      text.axis-workweek {
        fill: #000;
      }

      text.axis-worktime {
        fill: #000;
      }</style>
</head>


<body>

    <div id="n1" class="btn">
        <input name="updateButton" 
               type="button" 
               value="1" 
        />
    </div>
    <div id="n2" class="btn">
        <input name="updateButton" 
               type="button" 
               value="2" 
        />
    </div>



    <div id="chart"></div>
    <script type="text/javascript">
    var margin = {top:50, right:0, bottom:100, left:30},
        width=960-margin.left-margin.right,
        height=430-margin.top-margin.bottom,
        gridSize=Math.floor(width/24),
        legendElementWidth=gridSize*2.665,
        buckets = 10,
        colors = ["#f7fcf0","#e0f3db","#ccebc5","#a8ddb5","#7bccc4","#4eb3d3","#2b8cbe","#0868ac","#084081"],
        days = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
    times = ["12am", "1am", "2am", "3am", "4am", "5am", "6am", "7am", "8am", "9am", "10am", "11am", "12am", "1pm", "2pm", "3pm", "4pm", "5pm", "6pm", "7pm", "8pm", "9pm", "10pm", "11pm"];

    var heatmap;
    var legend;

    var svg = d3.select("#chart").append("svg")
        .attr("width",width + margin.left+margin.right)
        .attr("height", height+margin.top+margin.bottom)
        .append("g")
        .attr("transform", "translate("+ margin.left+","+margin.top+")");

    d3.csv("1.csv", function(d){
        return {
            day:+d.day2,
            hour:+d.hour,
            value:+d.per_day_per_hour
            };
        },
        function(error, data){

            console.log(data);

            var colorScale = d3.scale.quantile()
                .domain([0, (d3.max(data, function(d){return d.value;})/2), d3.max(data, function(d){return d.value;})])
                .range(colors);


            var dayLabels = svg.selectAll(".dayLabel")
                .data(days)
                .enter().append("text")
                .text(function (d) {return d; })
                .attr("y", function (d, i){ return i*gridSize;})
                .style("text-anchor", "end")
                .attr("transform", "translate(-6," + gridSize/1.5+")")
                .attr("class", function(d, i) { return ((i>=0 && i<=4) ? "dayLabel mono axis axis-workweek": "dayLabel mono axis"); });

            var timeLabels = svg.selectAll(".timeLabel")
                .data(times)
                .enter().append("text")
                .text(function(d){return d;})
                .attr("x", function(d,i) {return i * gridSize;})
                .attr("y",0)
                .style("text-anchor", "middle")
                .attr("transform", "translate(" + gridSize/2+", -6)")
                .attr("class", function(d, i) { return ((i>=9 && i<= 17) ? "timeLabel mono axis axis-worktime": "timeLabel mono axis"); });

            var heatMap = svg.selectAll(".hour")
                .data(data)
                .enter().append("rect")
                .attr("x", function(d) {return (d.hour) * gridSize;})
                .attr("y", function(d) {return (d.day) * gridSize;})
                .attr("rx", 4)
                .attr("ry", 4)
                .attr("class", "hour bordered")
                .attr("width", gridSize)
                .attr("height", gridSize)
                .style("fill", colors[0]);

            heatMap.transition().duration(1000)
                .style("fill", function(d){ return colorScale(d.value);});

            heatMap.append("title").text(function(d) {return d.value;});

            var legend = svg.selectAll(".legend")
                .data([0].concat(colorScale.quantiles()), function(d) {return d;})
                .enter().append("g")
                .attr("class", "legend");

            legend.append("rect")
                .attr("x", function(d, i){ return legendElementWidth * i;})
                .attr("y", height)
                .attr("width", legendElementWidth)
                .attr("height", gridSize/2)
                .style("fill", function(d, i) {return colors[i]; });

            legend.append("text")
                .attr("class", "mono")
                .text(function(d) {return "≥ "+d.toString().substr(0,4);})
                .attr("x", function(d, i){ return legendElementWidth *i;})
                .attr("y", height+ gridSize);



            d3.select("#n1")
                .on("click", function() {
                    updateHeatmap("1_1.csv");
                });


            d3.select("#n2")
                .on("click", function() {
                    updateHeatmap("1_2.csv");
                });     

        ;       
        }
);
</script>

<script>

</script>

</body>
</html>

The code above is essentially the same as that in the fiddle I've linked to up top, except that it includes 2 buttons, and has the legend, svg, and heatmap variables declared globally. 上面的代码与我链接到小提琴的小提琴基本上相同, 除了它包括2个按钮, 并且具有全局声明的图例,svg和heatmap变量。

Here's the meat of my question, which has to do with the update function I created to load in two new CSVs: 这是我的问题的关键,这与我创建的用于加载两个新CSV的更新功能有关:

function updateHeatmap(x){
    svg.selectAll(".legend").attr("opacity", 0);
    d3.csv(x, function(d){
        return {
            day:+d.day2,
            hour:+d.hour,
            value:+d.per_day_per_hour
            };
        },

        function(error, data){


        colorScale = d3.scale.quantile()
            .domain([0, (d3.max(data, function(d){return d.value;})/2), d3.max(data, function(d){return d.value;})])
            .range(colors);


        var heatMap = svg.selectAll(".hour")
            .data(data)
            .transition().duration(1000)
            .style("fill", function(d){ return colorScale(d.value);});

        heatMap.selectAll("title").text(function(d) {return d.value;});

        var legend = svg.selectAll(".legend")
            .data([0].concat(colorScale.quantiles()), function(d) {return d;})
            .enter().append("g")
            .attr("class", "legend");

        legend.append("rect")
            .attr("x", function(d, i){ return legendElementWidth * i;})
            .attr("y", height)
            .attr("width", legendElementWidth)
            .attr("height", gridSize/2)
            .style("fill", function(d, i) {return colors[i]; });

        legend.append("text")
            .attr("class", "mono")
            .text(function(d) {return "≥ "+d.toString().substr(0,4);})
            .attr("x", function(d, i){ return legendElementWidth *i;})
            .attr("y", height+ gridSize);



        }
    )
}

I've managed to update the color of the heatmap squares (huzzah), but can't get the legend that sits below the heatmap to cooperate, and can't get the values underlying each square to display on hover like I did on initial loading. 我设法更新了热图方块的颜色(烟丝),但无法获得热图下方的图例进行协作,也无法像在初始时那样在悬停时显示每个方块下面的值加载。 I get a feeling that it's because my JS is pretty flaky (as is, let's face it, my D3), but can't be sure — I think it may have to do with my screwing up the appropriate syntax for selecting the text element (ie, I'm unsure of how to do it the right way). 我感觉这是因为我的JS非常不整齐(按原样,我的D3面对它),但不能确定-我认为这可能与我为选择文本元素选择适当的语法有关(即,我不确定如何正确执行操作)。

To sum up : legend in this heatmap (here's the gist block) isn't updating properly, and the on-hover values for each of the squares don't appear on update. 综上所述此热图中的图例(此处为要点框)未正确更新,并且每个正方形的悬停值未在更新时显示。 Yikes. 让人惊讶。 Any suggestions? 有什么建议么?

I've updated my example to allow switching between datasets - this should help. 我已经更新了示例,以允许在数据集之间切换-这应该有所帮助。

http://bl.ocks.org/tjdecke/5558084 http://bl.ocks.org/tjdecke/5558084

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM