D3.js數據可視化(一)——繪制熱圖(heat map)


二維標量可視化

1. 實驗名稱

  二維標量的可視化。

2. 實驗目的

  使用d3以及提供的NBA籃球上個賽季的數據(basketball statics.xlsx),繪制一個熱圖(heat map)。

3. 技術基礎

  Web, HTML, DOM, CSS, JavaScript, SVG。

  核心技術為D3 —— Data-Driven Documents(數據驅動的文檔)。數據來源於你,而文檔就是基於Web的文檔(或者網頁),代表可以在瀏覽器中展現的一切,比如HTML,SVG。D3扮演的是一個驅動程序的角色,因為它聯系着數據和文檔。

4. 步驟

4.1 配置web服務器

  使用windows集成軟件包xxamp,下載后安裝即可。XAMPP(Apache+MySQL+PHP+PERL,主要使用Apache)安裝后,其安裝目錄中htdocs文件夾即為自己的項目文件存放地址。為使目錄更清晰,再在htdocs文件夾中新建一個projects文件夾,把所有項目都放進projects文件夾。

4.2 下載安裝D3

  從http://d3js.org/ 下載d3源碼,在projects文件夾中新建一個文件夾,叫做lab_1,在lab_1中新建一個文件夾,叫做d3,另外在lab_1中新建一個文本文檔,命名為index.html。下載的d3源碼d3.v3.js放入d3文件夾。

4.3 編寫代碼

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<html>
  <head>
  
    <style>
      rect.bordered {
        stroke: #A1A1A1;
        stroke-width:1px;  
      }

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

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

      text.axis-worktime {
        fill: #000;
      }
    </style>
    
    <script type="text/javascript" src="d3/d3.v3.js"></script>
  </head>
  
  
  <body>
    <div id="chart"></div>        <!-- div定義一個大塊 -->
    <div id="newdiv"></div>        <!-- div定義一個大塊 -->
    
    <script type="text/javascript">
    var array_data = [];
      // 一句話定義了眾多變量, 定義了塊兒的位置、寬高、小格子的邊長等等與布局有關的變量
      var margin = { top: 50, right: 0, bottom: 100, left: 150 },
          width = 960 - margin.left - margin.right,        // 所有格子區域的寬度,即Heatmap的寬度
          height = 1830 - margin.top - margin.bottom,
          gridSize = Math.floor(width / 24),    // 求地板,即去掉小數部分,width分成24份
          legendElementWidth = gridSize * 2,    // 底下長條的長度,是格子邊長的兩倍
          buckets = 9,        // 一共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"];
          tests = ["G","MIN","PTS","FGM","FGA","FGP","FTM","FTA","FTP","3PM","3PA","3PP","ORB","DRB","TRB","AST","STL","BLK","TO","PF"];
          // 函數,讀取 CSV 文件
          d3.csv("ball_data.csv", //function(d) {}, function(error, data) {} );
          
            // 每一行的數據
            /*function(d) {
              return {
                day: +d.day,
                hour: +d.hour,
                value: +d.value
              };
            },*/
            
            function(error, data) {
                /*if(error){  
                    console.log(error);  
                }  
                console.log(csvdata);*/
              // colorScale:顏色級別
              var colorScale = d3.scale.quantile()        // 按分位數取值,可使每個區域內元素個數相等
                  .domain([0, buckets - 1, d3.max(data, function (d) { return d.G; })])  // 定義域
                  // domain([0, n, 數據的最大值]);
                  .range(colors);    // 值域:是顏色數組,函數的返回值是代表某種顏色的字符串
              
              // 設置chart,svg
              var svg = d3.select("#chart").append("svg") // 選擇“chart”(就是div),加入一個svg,設置屬性跟div一樣大
                  .attr("width", width + margin.left + margin.right)
                  .attr("height", height + margin.top + margin.bottom)
                  .append("g")    // 在svg內加入一個g(group組),並設置元素g的顯示位置
                  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
                
              // 編輯姓名行
              var dayLabels = svg.selectAll(".nameLabel")
                  .data(data)
                  .enter()    // 為data中每一項創建一個".dayLabel"
                  .append("text")    // 為days中每一項創建一的".dayLabel"添加文本,下面全是設置文本的屬性
                    .text(function (d, i) { return data[i].name; })
                    .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) ? "nameLabel mono axis axis-workweek" : "nameLabel mono axis"); }
                        );
     
              // 編輯測試項行
              var timeLabels = svg.selectAll(".testLabel")
                  .data(tests)
                  .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) ? "testLabel mono axis axis-worktime" : "testLabel mono axis"); }
                         );
              
                // 畫出格子,暫不塗色,color[0]
                for (var i = 0; i < 50; i++){
                    array_data[i*20] = data[i].G;
                    array_data[i*20+1] = data[i].MIN;
                    array_data[i*20+2] = data[i].PTS;
                    array_data[i*20+3] = data[i].FGM;
                    array_data[i*20+4] = data[i].FGA;
                    array_data[i*20+5] = data[i].FGP;
                    array_data[i*20+6] = data[i].FTM;
                    array_data[i*20+7] = data[i].FTA;
                    array_data[i*20+8] = data[i].FTP;
                    array_data[i*20+9] = data[i].P3PM;
                    array_data[i*20+10] = data[i].P3PA;
                    array_data[i*20+11] = data[i].P3PP;
                    array_data[i*20+12] = data[i].ORB;
                    array_data[i*20+13] = data[i].DRB;
                    array_data[i*20+14] = data[i].TRB;
                    array_data[i*20+15] = data[i].AST;
                    array_data[i*20+16] = data[i].STL;
                    array_data[i*20+17] = data[i].BLK;
                    array_data[i*20+18] = data[i].TO;
                    array_data[i*20+19] = data[i].PF;
              }

              
              var heatMap = svg.selectAll(".score")
                  .data(array_data)
                  .enter()        // 為data中每一項創建一個".hour"
                  .append("rect")
                  .attr("x", function(d, i){ return (i % 20)*gridSize;})
                  .attr("y", function(d, i){ return parseInt(i / 20)*gridSize;})
                  .attr("rx", 6)
                  .attr("ry", 6)
                  .attr("class", "hour bordered")
                  .attr("width", gridSize)
                  .attr("height", gridSize)
                  .style("fill", "#FFFFFF");
                
              // duration(1000) 在1000ns也就是1s內將格子圖上色
              heatMap.transition().duration(1000)
                  .style("fill", function(d) { return colorScale(d); });
                
              // 鼠標停留顯示value
              heatMap.append("title").text(function(d) { return d.G; });
                  
              // legend 是一個有7個組的什么東西,,,
              var legend = svg.selectAll(".legend")
                  .data([0].concat(colorScale.quantiles()), function(d) { return d; })    // 由data獲得的元素個數為7
                  .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);
          });
    </script>
  
  </body>
</html>

數據:ball_data.csv

name,G,MIN,PTS,FGM,FGA,FGP,FTM,FTA,FTP,P3PM,P3PA,P3PP,ORB,DRB,TRB,AST,STL,BLK,TO,PF
Dwyane Wade ,79,38.6,30.2,10.8,22,0.491,7.5,9.8,0.765,1.1,3.5,0.317,1.1,3.9,5,7.5,2.2,1.3,3.4,2.3
LeBron James ,81,37.7,28.4,9.7,19.9,0.489,7.3,9.4,0.78,1.6,4.7,0.344,1.3,6.3,7.6,7.2,1.7,1.1,3,1.7
Kobe Bryant ,82,36.2,26.8,9.8,20.9,0.467,5.9,6.9,0.856,1.4,4.1,0.351,1.1,4.1,5.2,4.9,1.5,0.5,2.6,2.3
Dirk Nowitzki ,81,37.7,25.9,9.6,20,0.479,6,6.7,0.89,0.8,2.1,0.359,1.1,7.3,8.4,2.4,0.8,0.8,1.9,2.2
Danny Granger ,67,36.2,25.8,8.5,19.1,0.447,6,6.9,0.878,2.7,6.7,0.404,0.7,4.4,5.1,2.7,1,1.4,2.5,3.1
Kevin Durant ,74,39,25.3,8.9,18.8,0.476,6.1,7.1,0.863,1.3,3.1,0.422,1,5.5,6.5,2.8,1.3,0.7,3,1.8
Kevin Martin ,51,38.2,24.6,6.7,15.9,0.42,9,10.3,0.867,2.3,5.4,0.415,0.6,3,3.6,2.7,1.2,0.2,2.9,2.3
Al Jefferson ,50,36.6,23.1,9.7,19.5,0.497,3.7,5,0.738,0,0.1,0,3.4,7.5,11,1.6,0.8,1.7,1.8,2.8
Chris Paul ,78,38.5,22.8,8.1,16.1,0.503,5.8,6.7,0.868,0.8,2.3,0.364,0.9,4.7,5.5,11,2.8,0.1,3,2.7
Carmelo Anthony ,66,34.5,22.8,8.1,18.3,0.443,5.6,7.1,0.793,1,2.6,0.371,1.6,5.2,6.8,3.4,1.1,0.4,3,3
Chris Bosh ,77,38.1,22.7,8,16.4,0.487,6.5,8,0.817,0.2,0.6,0.245,2.8,7.2,10,2.5,0.9,1,2.3,2.5
Brandon Roy ,78,37.2,22.6,8.1,16.9,0.48,5.3,6.5,0.824,1.1,2.8,0.377,1.3,3.4,4.7,5.1,1.1,0.3,1.9,1.6
Antawn Jamison ,81,38.2,22.2,8.3,17.8,0.468,4.2,5.6,0.754,1.4,3.9,0.351,2.4,6.5,8.9,1.9,1.2,0.3,1.5,2.7
Tony Parker ,72,34.1,22,8.9,17.5,0.506,3.9,5,0.782,0.3,0.9,0.292,0.4,2.7,3.1,6.9,0.9,0.1,2.6,1.5
Amare Stoudemire ,53,36.8,21.4,7.6,14.1,0.539,6.1,7.3,0.835,0.1,0.1,0.429,2.2,5.9,8.1,2,0.9,1.1,2.8,3.1
Joe Johnson ,79,39.5,21.4,7.8,18,0.437,3.8,4.6,0.826,1.9,5.2,0.36,0.8,3.6,4.4,5.8,1.1,0.2,2.5,2.2
Devin Harris ,69,36.1,21.3,6.6,15.1,0.438,7.2,8.8,0.82,0.9,3.2,0.291,0.4,2.9,3.3,6.9,1.7,0.2,3.1,2.4
Michael Redd ,33,36.4,21.2,7.5,16.6,0.455,4,4.9,0.814,2.1,5.8,0.366,0.7,2.5,3.2,2.7,1.1,0.1,1.6,1.4
David West ,76,39.3,21,8,17,0.472,4.8,5.5,0.884,0.1,0.3,0.24,2.1,6.4,8.5,2.3,0.6,0.9,2.1,2.7
Zachary Randolph ,50,35.1,20.8,8.3,17.5,0.475,3.6,4.9,0.734,0.6,1.9,0.33,3.1,6.9,10.1,2.1,0.9,0.3,2.3,2.7
Caron Butler ,67,38.6,20.8,7.3,16.2,0.453,5.1,6,0.858,1,3.1,0.31,1.8,4.4,6.2,4.3,1.6,0.3,3.1,2.5
Vince Carter ,80,36.8,20.8,7.4,16.8,0.437,4.2,5.1,0.817,1.9,4.9,0.385,0.9,4.2,5.1,4.7,1,0.5,2.1,2.9
Stephen Jackson ,59,39.7,20.7,7,16.9,0.414,5,6,0.826,1.7,5.2,0.338,1.2,3.9,5.1,6.5,1.5,0.5,3.9,2.6
Ben Gordon ,82,36.6,20.7,7.3,16,0.455,4,4.7,0.864,2.1,5.1,0.41,0.6,2.8,3.5,3.4,0.9,0.3,2.4,2.2
Dwight Howard ,79,35.7,20.6,7.1,12.4,0.572,6.4,10.7,0.594,0,0,0,4.3,9.6,13.8,1.4,1,2.9,3,3.4
Paul Pierce ,81,37.4,20.5,6.7,14.6,0.457,5.7,6.8,0.83,1.5,3.8,0.391,0.7,5,5.6,3.6,1,0.3,2.8,2.7
Al Harrington ,73,34.9,20.1,7.3,16.6,0.439,3.2,4,0.793,2.3,6.4,0.364,1.4,4.9,6.2,1.4,1.2,0.3,2.2,3.1
Jamal Crawford ,65,38.1,19.7,6.4,15.7,0.41,4.6,5.3,0.872,2.2,6.1,0.36,0.4,2.6,3,4.4,0.9,0.2,2.3,1.4
Yao Ming ,77,33.6,19.7,7.4,13.4,0.548,4.9,5.7,0.866,0,0,1,2.6,7.2,9.9,1.8,0.4,1.9,3,3.3
Richard Jefferson ,82,35.9,19.6,6.5,14.9,0.439,5.1,6.3,0.805,1.4,3.6,0.397,0.7,3.9,4.6,2.4,0.8,0.2,2,3.1
Jason Terry ,74,33.6,19.6,7.3,15.8,0.463,2.7,3,0.88,2.3,6.2,0.366,0.5,1.9,2.4,3.4,1.3,0.3,1.6,1.9
Deron Williams ,68,36.9,19.4,6.8,14.5,0.471,4.8,5.6,0.849,1,3.3,0.31,0.4,2.5,2.9,10.7,1.1,0.3,3.4,2
Tim Duncan ,75,33.7,19.3,7.4,14.8,0.504,4.5,6.4,0.692,0,0,0,2.7,8,10.7,3.5,0.5,1.7,2.2,2.3
Monta Ellis ,25,35.6,19,7.8,17.2,0.451,3.1,3.8,0.83,0.3,1,0.308,0.6,3.8,4.3,3.7,1.6,0.3,2.7,2.7
Rudy Gay ,79,37.3,18.9,7.2,16,0.453,3.3,4.4,0.767,1.1,3.1,0.351,1.4,4.2,5.5,1.7,1.2,0.7,2.6,2.8
Pau Gasol ,81,37.1,18.9,7.3,12.9,0.567,4.2,5.4,0.781,0,0,0.5,3.2,6.4,9.6,3.5,0.6,1,1.9,2.1
Andre Iguodala ,82,39.8,18.8,6.6,14,0.473,4.6,6.4,0.724,1,3.2,0.307,1.1,4.6,5.7,5.3,1.6,0.4,2.7,1.9
Corey Maggette ,51,31.1,18.6,5.7,12.4,0.461,6.7,8.1,0.824,0.5,1.9,0.253,1,4.6,5.5,1.8,0.9,0.2,2.4,3.8
O.J. Mayo ,82,38,18.5,6.9,15.6,0.438,3,3.4,0.879,1.8,4.6,0.384,0.7,3.1,3.8,3.2,1.1,0.2,2.8,2.5
John Salmons ,79,37.5,18.3,6.5,13.8,0.472,3.6,4.4,0.83,1.6,3.8,0.417,0.7,3.5,4.2,3.2,1.1,0.3,2.1,2.3
Richard Hamilton ,67,34,18.3,7,15.6,0.447,3.3,3.9,0.848,1,2.8,0.368,0.7,2.4,3.1,4.4,0.6,0.1,2,2.6
Ray Allen ,79,36.3,18.2,6.3,13.2,0.48,3,3.2,0.952,2.5,6.2,0.409,0.8,2.7,3.5,2.8,0.9,0.2,1.7,2
LaMarcus Aldridge ,81,37.1,18.1,7.4,15.3,0.484,3.2,4.1,0.781,0.1,0.3,0.25,2.9,4.6,7.5,1.9,1,1,1.5,2.6
Josh Howard ,52,31.9,18,6.8,15.1,0.451,3.3,4.2,0.782,1.1,3.2,0.345,1.1,3.9,5.1,1.6,1.1,0.6,1.7,2.6
Maurice Williams ,81,35,17.8,6.5,13.9,0.467,2.6,2.8,0.912,2.3,5.2,0.436,0.6,2.9,3.4,4.1,0.9,0.1,2.2,2.7
Shaquille O'neal ,75,30.1,17.8,6.8,11.2,0.609,4.1,6.9,0.595,0,0,0,2.5,5.9,8.4,1.7,0.7,1.4,2.2,3.4
Rashard Lewis ,79,36.2,17.7,6.1,13.8,0.439,2.8,3.4,0.836,2.8,7,0.397,1.2,4.6,5.7,2.6,1,0.6,2,2.5
Chauncey Billups ,79,35.3,17.7,5.2,12.4,0.418,5.3,5.8,0.913,2.1,5,0.408,0.4,2.6,3,6.4,1.2,0.2,2.2,2
Allen Iverson ,57,36.7,17.5,6.1,14.6,0.417,4.8,6.1,0.781,0.5,1.7,0.283,0.5,2.5,3,5,1.5,0.1,2.6,1.5
Nate Robinson ,74,29.9,17.2,6.1,13.9,0.437,3.4,4,0.841,1.7,5.2,0.325,1.3,2.6,3.9,4.1,1.3,0.1,1.9,2.8

 

5. 可視化效果(部分截圖,原圖太大)

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM