简体   繁体   中英

Width in d3 heatmap

This is my sample code. My intention is to generate a heatmap with rectangles like 这个

 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 / 22), legendElementWidth = gridSize*2, buckets = 9, colors = ["#ffffd9","#edf8b1","#c7e9b4","#7fcdbb","#41b6c4","#1d91c0","#225ea8","#253494","#081d58"], // alternatively colorbrewer.YlGnBu[9] days = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], times = ["1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a", "9a", "10a", "11a", "12a", "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p", "10p", "11p", "12p"]; datasets = ["data.tsv", "data2.tsv"]; 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 + ")"); var dayLabels = svg.selectAll(".dayLabel") .data(days) .enter().append("text") .text(function (d) { return d; }) .attr("x", 0) .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 >= 7 && i <= 16) ? "timeLabel mono axis axis-worktime" : "timeLabel mono axis"); }); var data= [ { "day": 1, "hour": 1, "value": 16 }, { "day": 1, "hour": 2, "value": 20 }, { "day": 1, "hour": 3, "value": 0 }, { "day": 1, "hour": 4, "value": 0 }, { "day": 1, "hour": 5, "value": 0 }, { "day": 1, "hour": 6, "value": 2 }, { "day": 1, "hour": 7, "value": 0 }, { "day": 1, "hour": 8, "value": 9 }, { "day": 1, "hour": 9, "value": 25 }, { "day": 1, "hour": 10, "value": 49 }, { "day": 1, "hour": 11, "value": 57 }, { "day": 1, "hour": 12, "value": 61 }, { "day": 1, "hour": 13, "value": 37 }, { "day": 1, "hour": 14, "value": 66 }, { "day": 1, "hour": 15, "value": 70 }, { "day": 1, "hour": 16, "value": 55 }, { "day": 1, "hour": 17, "value": 51 }, { "day": 1, "hour": 18, "value": 55 }, { "day": 1, "hour": 19, "value": 17 }, { "day": 1, "hour": 20, "value": 20 }, { "day": 1, "hour": 21, "value": 9 }, { "day": 1, "hour": 22, "value": 4 }, { "day": 1, "hour": 23, "value": 0 }, { "day": 1, "hour": 24, "value": 12 }, { "day": 2, "hour": 1, "value": 6 }, { "day": 2, "hour": 2, "value": 2 }, { "day": 2, "hour": 3, "value": 0 }, { "day": 2, "hour": 4, "value": 0 }, { "day": 2, "hour": 5, "value": 0 }, { "day": 2, "hour": 6, "value": 2 }, { "day": 2, "hour": 7, "value": 4 }, { "day": 2, "hour": 8, "value": 11 }, { "day": 2, "hour": 9, "value": 28 }, { "day": 2, "hour": 10, "value": 49 }, { "day": 2, "hour": 11, "value": 51 }, { "day": 2, "hour": 12, "value": 47 }, { "day": 2, "hour": 13, "value": 38 }, { "day": 2, "hour": 14, "value": 65 }, { "day": 2, "hour": 15, "value": 60 }, { "day": 2, "hour": 16, "value": 50 }, { "day": 2, "hour": 17, "value": 65 }, { "day": 2, "hour": 18, "value": 50 }, { "day": 2, "hour": 19, "value": 22 }, { "day": 2, "hour": 20, "value": 11 }, { "day": 2, "hour": 21, "value": 12 }, { "day": 2, "hour": 22, "value": 9 }, { "day": 2, "hour": 23, "value": 0 }, { "day": 2, "hour": 24, "value": 13 }, { "day": 3, "hour": 1, "value": 5 }, { "day": 3, "hour": 2, "value": 8 }, { "day": 3, "hour": 3, "value": 8 }, { "day": 3, "hour": 4, "value": 0 }, { "day": 3, "hour": 5, "value": 0 }, { "day": 3, "hour": 6, "value": 2 }, { "day": 3, "hour": 7, "value": 5 }, { "day": 3, "hour": 8, "value": 12 }, { "day": 3, "hour": 9, "value": 34 }, { "day": 3, "hour": 10, "value": 43 }, { "day": 3, "hour": 11, "value": 54 }, { "day": 3, "hour": 12, "value": 44 }, { "day": 3, "hour": 13, "value": 40 }, { "day": 3, "hour": 14, "value": 48 }, { "day": 3, "hour": 15, "value": 54 }, { "day": 3, "hour": 16, "value": 59 }, { "day": 3, "hour": 17, "value": 60 }, { "day": 3, "hour": 18, "value": 51 }, { "day": 3, "hour": 19, "value": 21 }, { "day": 3, "hour": 20, "value": 16 } ] var colorScale = d3.scale.quantile() .domain([0, buckets - 1, d3.max(data, function (d) { return d.value; })]) .range(colors); var cards = svg.selectAll(".hour") .data(data, function(d) {return d.day+':'+d.hour;}); cards.append("title"); cards.enter().append("rect") .attr("x", function(d) { return (d.hour - 1) * gridSize; }) .attr("y", function(d) { return (d.day - 1) * gridSize; }) .attr("rx", 4) .attr("ry", 4) .attr("class", "hour bordered") .attr("width", gridSize+10) .attr("height", gridSize) .style("fill", colors[0]); cards.transition().duration(1000) .style("fill", function(d) { return colorScale(d.value); }); cards.select("title").text(function(d) { return d.value; }); cards.exit().remove(); var legend = svg.selectAll(".legend") .data([0].concat(colorScale.quantiles()), function(d) { return d; }); legend.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 "≥ " + Math.round(d); }) .attr("x", function(d, i) { return legendElementWidth * i; }) .attr("y", height + gridSize); legend.exit().remove(); 
 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; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div id="chart"></div> <div id="dataset-picker"></div> 

I am using the code in published here . My intention is to increase the width. So I am adding a +10 to the grid size to my rects. But my heatmap still appears a collection of squares. My intention is to have a heatmap with rectangles rather than squares.

What am I doing wrong?

You are on the right path, your grid widths have increased. You can check this if you right click on any of the tile and inspect element. But what is happening is that your grids are still overlapping at the same distance, therefore appearing as squares. You need to add the 10px to the x as well so that they do not overlap.

cards.enter().append("rect")
              .attr("x", function(d) { return (d.hour - 1) * (gridSize+10); }) //10px added to the gridSize for the x displacement
              .attr("y", function(d) { return (d.day - 1) * gridSize; })
              .attr("rx", 4)
              .attr("ry", 4)
              .attr("class", "hour bordered")
              .attr("width", gridSize+10)
              .attr("height", gridSize)
              .style("fill", colors[0]);

Hope this helps.

A cautionary note for the future though, in the above code, the original gridSize is calculated based on the variable width . Since the rectangles are larger than the gridSize, your rectangles will most likely go out of your svg container and get cut. To fix this you will have to interchange the roles, ie set the gridSize and then calculate the width based on the gridSize+10 . Let me know if you need help with this as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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