2017-07-12 1 views
1

Ich versuche eine Heatmap meiner CSV-Datei zu zeichnen.d3 Text in Heatmap-Boxen hinzufügen

In jeder Box der Heatmap möchte ich auch den numerischen Wert für diese Box schreiben.

Dieser Code erledigt den Job, aber die Zahlen sind hinter den Boxen versteckt. Wie kann ich es ändern, so dass die Zahlen über den Feldern erscheinen?

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)); 

Das endgültige Ergebnis sollte ähnlich sein: In einer SVG https://i.stack.imgur.com/fUfuu.png

Antwort

1

was letzten Aufenthalte auf gemalt, wie ein echter Maler in einer Leinwand mit Tinte.

aber sagen, dass dies ...

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

.... muss kommen nach dieser:

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