d3在热图框中添加文本

时间:2017-07-12 13:16:21

标签: javascript d3.js svg

我正在尝试绘制CSV文件的热图。

在热图的每个框中,我还想写出与该框相关联的数值。

此代码可以完成工作,但数字隐藏在方框后面。如何更改它以使数字显示在方框的上方?

const margin = { top: 50, right: 0, bottom: 100, left: 130 },
          xLocLabel = 10
          width = 700 - margin.left - margin.right,
          height = 3000 - margin.top - margin.bottom,
          gridSize = Math.floor(width / 24),
          legendElementWidth = gridSize*2,
          buckets = 9,
          colors = ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"], // alternatively colorbrewer.YlGnBu[9]
          datasets = ["num_machines_full.csv"];

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


      const type = (d) => {
        return {
          username: d.UserName,
          x: +d.Hour,
          y: +d.Y,
          value: +d.value
        };
      };

      const heatmapChart = function(csvFile) {
        d3.csv(csvFile, type, (error, data) => {
          const colorScale = d3.scaleQuantile()
            .domain([0, buckets - 1, d3.max(data, (d) => d.value)])
            .range(colors);

          console.log(data.length)


      const cards = svg.selectAll(".boxColors")
            .data(data, (d) => d.y+':'+d.x);

      var valuesText = svg.selectAll(".valuesText")
        .data(data)
        .enter()
        .append("text");

      valuesText.attr("text-anchor", "middle")
        .attr("dominant-baseline", "central")
        .attr("x", function(d){ return  35 +  d.x*gridSize})
        .attr("y", function(d){ return d.y*gridSize})
        .text(function(d){ return d.value})
        .attr("class", "parentText");




      var users = [...new Set(data.map(function(d) {return d.username}))];
      var firstOccurrence = users.map(function(d) {return data.find(function(e) {
                                                       return e.username === d})});
      const yLabels = svg.selectAll(".yLabel")
            .data(firstOccurrence)
            .enter().append("text")
            .text(function (d) { return d.username; })
            .attr("x", xLocLabel)
            .attr("y", (d, i) => (i+1) * gridSize)
            .style("text-anchor", "end")
            .attr("transform", "translate(-6," + gridSize / 1.5 + ")")
            .attr("class",  "dayLabel mono axis");

      var times = [...new Set(data.map(function(d) {return d.x}))];
      var firstOccurrence = times.map(function(d) {return data.find(function(e) {
                                                   return e.x === d})});
      const xLabels = svg.selectAll(".xLabel")
            .data(times)
            .enter().append("text")
            .text((d) => d)
            .attr("x", (d, i) => (i+1) * gridSize)
            .attr("y", 0)
            .style("text-anchor", "middle")
            .attr("transform", "translate(" + gridSize / 2 + ", -6)")
            .attr("class",   "timeLabel mono axis");


      cards.append("title");
      cards.enter().append("rect")
            .attr("x", (d) =>  (d.x + 1) * gridSize)
            .attr("y", (d) => (d.y + 1) * gridSize)
            .attr("rx", 4)
            .attr("ry", 4)
            .attr("class", "hour bordered")
            .attr("width", gridSize)
            .attr("height", gridSize)
            .style("fill", colors[0])
            .merge(cards)
            .transition()
            .duration(1000)
            .style("fill", (d) => colorScale(d.value));
      cards.select("title").text((d) => d.value);


      cards.exit().remove();

      const legend = svg.selectAll(".legend")
            .data([0].concat(colorScale.quantiles()), (d) => d);

      const legend_g = legend.enter().append("g")
            .attr("class", "legend");

      legend_g.append("rect")
            .attr("x", (d, i) => legendElementWidth * i)
            .attr("y", height)
            .attr("width", legendElementWidth)
            .attr("height", gridSize / 2)
            .style("fill", (d, i) => colors[i]);

      legend_g.append("text")
            .attr("class", "mono")
            .text((d) => "≥ " + Math.round(d))
            .attr("x", (d, i) => legendElementWidth * i)
            .attr("y", height + gridSize);

      legend.exit().remove();
        });
      };

      heatmapChart(datasets[0]);

      const datasetpicker = d3.select("#dataset-picker")
        .selectAll(".dataset-button")
        .data(datasets);

      datasetpicker.enter()
        .append("input")
        .attr("value", (d) => "Dataset " + d)
        .attr("type", "button")
        .attr("class", "dataset-button")
        .on("click", (d) => heatmapChart(d));

最终结果应类似于:https://i.stack.imgur.com/fUfuu.png

1 个答案:

答案 0 :(得分:1)

在SVG中,最后留在上面的任何东西,就像真正的画家在画布上使用墨水一样。

话虽如此,这......

var valuesText = svg.selectAll(".valuesText")
    .data(data)
    .enter()
    .append("text");

....必须 之后:

cards.enter().append("rect")