1. 程式人生 > >JavaScript-D3入門四-事件繫結

JavaScript-D3入門四-事件繫結

直接給出可以在WebServer中執行的程式碼,通過這個示例,你可以知道如何進行事件繫結

表格資料官方建議用csv執行效率高

d3ia_2.html

<html>
<head>
    <title>D3 in Action Examples</title>
    <!-- 演示D3的事件繫結 -->
    <meta charset="utf-8" />
    <link type="text/css" rel="stylesheet" href="d3ia.css" />
</head>
<script src='/d3/d3.min.js'></script>
<!--http://d3js.org/colorbrewer.v1.min.js-->
<script src="colorbrewer.v1.min.js"></script>
<script src="soccerviz.js"></script>
<body onload="createSoccerViz()">
    <div id="viz">
        <svg style="width:500px;height:500px;border:1px lightgray solid;" />
    </div>
    <div id="controls" />
</body>
</html>

soccerviz.js

function createSoccerViz() {
    d3.csv("/data/worldcup.csv", data => {overallTeamViz(data)})

    function overallTeamViz(incomingData) {
        //根據incomingData的行數新增g.overallG
        d3.select("svg")
          .append("g")
          .attr("id", "teamsG")
          .attr("transform", "translate(50,300)")
          .selectAll("g")
          .data(incomingData)
          .enter()
          .append("g")
          .attr("class", "overallG")
          .attr("transform", (d, i) =>"translate(" + (i * 50) + ", 0)");

        //為新建的g.overallG新增circle和text.
        var teamG = d3.selectAll("g.overallG");

        //新建circle不帶動畫效果
        //teamG
        //  .append("circle")
        //  .attr("r", 20);

        //新建circle帶動畫效果
        teamG
         .append("circle")
         .attr("r", 0)
         .transition().delay((d, i) => i * 100).duration(500)//多個circle依次變大
         .attr("r", 40)
         .transition().duration(500)
         .attr("r", 20);

        teamG
         .append("text")
         .attr("y", 30)
         .text(d => d.team);

        //incomingData第一行資料除了team,region其它column都作為key
        //dataKeys=["win","loss","draw","points","gf","ga","cs","yc","rc"]
        const dataKeys = Object.keys(incomingData[0])
            .filter(d => d !== "team" && d !== "region");

        //在body下新增<div id='controls'>節點,在這個節點下再新增button節點
        //Hint: 由於button.teams是不存在的,所以會新增button節點.
        d3.select("#controls").selectAll("button.teams")
           .data(dataKeys).enter()
           .append("button")
           .on("click", buttonClick)//事件繫結
        .html(d => d);

        //點選某個button物件更新檢視
        function buttonClick(datapoint) {
            //datapoint的值為["win","loss","draw","points","gf","ga","cs","yc","rc"]陣列中的元素!
            var maxValue = d3.max(incomingData, d => parseFloat(d[datapoint]))

            //linear map
            var radiusScale = d3.scaleLinear()
              .domain([0, maxValue]).range([2, 20])

            //更新circle物件的屬性,不帶動畫效果
            //d3.selectAll("g.overallG").select("circle")
            //   .attr("r", d => {
            //       if (radiusScale(d[datapoint]) > 0)
            //           return radiusScale(d[datapoint]);
            //       else
            //           return 0;//r屬性不接受negative number.
            //   });

            //更新circle物件的屬性,帶動畫效果
            d3.selectAll("g.overallG").select("circle")
                .transition().duration(1000)//這行添加了動畫效果
                .attr("r", d => {
                    if (radiusScale(d[datapoint]) > 0)
                        return radiusScale(d[datapoint]);
                    else
                        return 0;//r屬性不接受negative number.
                })
        }//buttonClick

        //highlight同一個region的物件。
        teamG.on("mouseover", highlightRegion);
        function highlightRegion(d) {
            d3.selectAll("g.overallG").select("circle")
              .attr("class", p => {
                  return p.region === d.region ? "active" : "inactive"
              });
        }//highlightRegion

        //
        teamG.on("mouseout", function () {
            d3.selectAll("g.overallG")
            .select("circle").classed("inactive", false).classed("active", false)
        })

    }//overallTeamViz
}//createSoccerViz

worldcup.csv

"team","region","win","loss","draw","points","gf","ga","cs","yc","rc"
Germany,UEFA,7,6,0,1,19,18,4,14,4,6,0
Argentina,CONMEBOL,7,5,1,1,16,8,4,4,4,8,0
Netherlands,UEFA,7,5,0,2,17,15,4,11,4,11,0
Belgium,UEFA,5,4,1,0,12,6,3,3,2,7,1
Colombia,CONMEBOL,5,4,1,0,12,12,4,8,2,5,0
Brazil,CONMEBOL,7,3,2,2,11,11,14,-3,1,14,0
Japan,AFC,3,0,2,1,1,2,6,-4,1,4,0
United States,CONCACAF,4,1,2,1,4,5,6,-1,0,4,0