将数据(条形图和天气信息)插入SVG圆圈中



我试图创建一个视觉效果(使用D3.js和json),其中4个小圆圈将弹出一旦我点击大黄圈。我想确保所有的圆圈将呈现我试图分配给每一个的信息片段。我计划有:第一个大黄圈表示天气(晴天,多云等)-2小圆圈按单词显示天气信息2个小圆圈表示我制作的D3条形图,以及一些文字天气信息(我用空格和注释分隔了所有的信息)

然而,我的问题是(因为缺乏更好的解释)我只是被难住了!我不知道该怎么做。如果你们能帮我,我会很感激的。这是我的代码(HTML和JS):Var h = 2000;Var w = 2000;var xGrid = 300;var yGrid = 300;Var半径= 300;

    var svg = d3.select("body")
         .append("svg")
         .attr("width", w)
         .attr("height", h);
    var shape = svg.append("circle")
         .attr("cx", xGrid)
         .attr("cy", yGrid)
         .attr("r", radius)
         .style("fill", "yellow");
         shape.on("click", function(){
       var circle1 = svg.append("circle")
           //.attr("cx", (xGrid-radius/2)+0)
           //.attr("cy", (yGrid-radius/2)+0)
          .attr("cx", xGrid - radius/2)
          .attr("cy", yGrid - radius/2)
           .attr("r", radius/2)
           .style("fill", "red");
       var circle2 = svg.append("circle")
           //.attr("cx", (xGrid-radius/2)+10)
           //.attr("cy", (yGrid-radius/2)+10)
          .attr("cx", xGrid + radius/2)
          .attr("cy", yGrid - radius/2)
           .attr("r", radius/2)
           .style("fill", "blue");
       var circle3 = svg.append("circle")
          // .attr("cx", (xGrid-radius/2)+20)
          // .attr("cy", (yGrid-radius/2)+20)
          .attr("cx", xGrid - radius/2)
          .attr("cy", yGrid + radius/2)
           .attr("r", radius/2)
           .style("fill", "green");
       var circle4 = svg.append("circle")
          // .attr("cx", (xGrid-radius/2)+30)
        //.attr("cy", (yGrid-radius/2)+30)
           .attr("cx", xGrid + radius/2)
           .attr("cy", yGrid + radius/2)
           .attr("r", radius/2)
           .style("fill", "purple");
   });
   <!-- ///////////////////////////////////////////////////////////////////////////// /////////////////
///////////////////////////////(END)  Circle Pop-up  (END)/////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////-->
  </script>
   <!--///////////////////////////////////////////////////////////////////////////// ////////////////////////
///////////////////////////(START) Info for circles to present   (START)////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////-->

   <!--/////Main Circle display/////////-->
   <p id="w"></p><p id="main"></p>
   <!--//////Circle 1 (upper left corner) display///////////-->
   <p id="rh"></p><p id="c1a"></p>
   <!--///////Circle 2 (upper right corner) display//////////-->
   <p id="ws"></p><p id="c2a"></p>
   <p id="wd"></p><p id="c2b"></p>
   <p id="we"></p><p id="c2c"></p>
   <p id="wm"></p><p id="c2d"></p>
   <!--////////Circle 3 (lower left corner) display/////////-->
   <p id="pti"></p><p id="c3a"></p>
   <p id="ptc"></p><p id="c3b"></p>
   <p id="df"></p><p id="c3c"></p>
   <p id="dc"></p><p id="c3d"></p>
   <!--///////Circle 4 (lower right corner) display//////////-->
   <p id="hif"></p><p id="c4a"></p>
   <p id="hic"></p><p id="c4b"></p>
   <p id="sr"></p><p id="c4c"></p>
   <p id="uv"></p><p id="c4d"></p>
   <script type = "text/javascript">
    var dataForMainCircle = '{"weather": "Mostly Cloudy"}';
    var mcDis= JSON.parse(dataForMainCircle);
    var weather = "weather: ";
    document.getElementById("w").innerHTML = weather;
    document.getElementById("main").innerHTML = mcDis.weather;
  /////////////////////////////////////////////////////////////////////////////////
  ////////////Setup for display of 1st circle info///////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////
     var dataForCircle1b = '{"relative_humidity": "92%"}';
     var relativeHum = "Relative Humidity: ";
      var c1Dis = JSON.parse(dataForCircle1b);
     d3.json("js/tempGraph.json", function (data) {
          var canvas = d3.select("body").append("svg")
                      .attr("width", 500)
                      .attr("height", 500)
              canvas.selectAll("rect")
                    .data(data)
                    .enter()
                           .append("rect")
                           .attr("width", function (d) {return d.temp * 10; })
                           .attr("height", 48)
                           .attr("y", function (d,i) {return i * 50; })
                           .attr("fill", "red");
               canvas.selectAll("text")
                    .data(data)
                    .enter()
                           .append("text")
                           .attr("fill", "white")
                           .attr("y", function (d,i) {return i * 50 + 24;   })
                           .text(function (d) {return d.temp; })
     })
     document.getElementById("rh").innerHTML = relativeHum;
     document.getElementById("c1a").innerHTML = c1Dis.relative_humidity;
  /////////////////////////////////////////////////////////////////////////////////////////
  / ////////////////////Setup for display of 2nd circle info////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////
    var dataForCircle2 = '{"wind_string": "Calm", "wind_dir": "SW",   "wind_degrees": 229, "wind_mph": 2}';
    var c2Dis = JSON.parse(dataForCircle2);
    var windCon = "Wind Condition: ";
    var windDir = "Wind Direction: ";
    var windDeg = "Wind Degree: ";
    var windMph = "Wind (Miles Per Hour): "
    document.getElementById("ws").innerHTML = windCon;
    document.getElementById("c2a").innerHTML = c2Dis.wind_string;
    document.getElementById("wd").innerHTML = windDir;
    document.getElementById("c2b").innerHTML = c2Dis.wind_dir;
    document.getElementById("we").innerHTML = windDeg;
    document.getElementById("c2c").innerHTML = c2Dis.wind_degrees;
    document.getElementById("wm").innerHTML = windMph;
    document.getElementById("c2d").innerHTML = c2Dis.wind_mph;
   ///////////////////////////////////////////////////////////////////////////// //////////////////////////////////
     //Setup for display of 3rd circle  info/////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////
   var dataForCircle3 = '{"precip_today_in": "0.00",    "precip_today_metric": "0"}';
   var c3Dis = JSON.parse(dataForCircle3);
   var predate = "Today's Precipitation: ";
   var prem = "Precipitation Metric: ";
   //var dewF = "Dewpoint-F: ";
   //var dewC = "Dewpoint-C: ";
   document.getElementById("pti").innerHTML = predate;
   document.getElementById("c3a").innerHTML = c3Dis.precip_today_in;
    document.getElementById("ptc").innerHTML = prem;
    document.getElementById("c3b").innerHTML = c3Dis.precip_today_metric;
    //document.getElementById("df").innerHTML = dewF;
    //document.getElementById("c3c").innerHTML = c3Dis.dewpoint_f;
    d3.json("js/dewGraph.json", function (data) {
       var canvas = d3.select("body").append("svg")
                     .attr("width", 500)
                     .attr("height", 500)
              canvas.selectAll("rect")
                    .data(data)
                    .enter()
                           .append("rect")
                           .attr("width", function (d) {return d.dewpoint  * 10; })
                           .attr("height", 48)
                           .attr("y", function (d,i) {return i * 50; })
                           .attr("fill", "white");
              canvas.selectAll("text")
                    .data(data)
                    .enter()
                           .append("text")
                           .attr("fill", "white")
                           .attr("y", function (d,i) {return i * 50 + 24;   })
                           .text(function (d) {return d.dewpoint; })
     })
      //document.getElementById("dc").innerHTML = dewC;
      //document.getElementById("c3d").innerHTML = c3Dis.dewpoint_c;
  <!--//////////////Setup for display of 4th circle    display////////////////////-->
    var dataForCircle4 = '{"heat_index_f": "NA", "heat_index_c": "NA", "solarradiation": "--", "UV": "0"}';
   var c4Dis = JSON.parse(dataForCircle4);
   var heatF = "Heat Index-F: ";
   var heatC = "Heat Index-C: ";
   var sunR = "Solar Radiation: ";
   var ultraV = "UV: ";
    document.getElementById("hif").innerHTML = heatF;
    document.getElementById("c4a").innerHTML = c4Dis.heat_index_f;
     document.getElementById("hic").innerHTML = heatC;
     document.getElementById("c4b").innerHTML = c4Dis.heat_index_c;
      document.getElementById("sr").innerHTML = sunR;
      document.getElementById("c4c").innerHTML = c4Dis.solarradiation;
      document.getElementById("uv").innerHTML = ultraV;
      document.getElementById("c4d").innerHTML = c4Dis.UV;
        d3.json("js/tempGraph.json", function (data) {
            var canvas1 = d3.select("body").append("svg")
                           .attr("width", 500)
                           .attr("height", 500)
              canvas1.selectAll("rect")
                    .data(data)
                    .enter()
                           .append("rect")
                           .attr("width", function (d) {return d.temp *     10; })
                           .attr("height", 48)
                           .attr("y", function (d,i) {return i * 50; })
                           .attr("fill", "red");
                canvas1.selectAll("text")
                         .data(data)
                         .enter()
                           .append("text")
                           .attr("fill", "white")
                           .attr("y", function (d,i) {return i * 50 + 24;    })
                           .text(function (d) {return d.temp; })
      })
          d3.json("js/dewGraph.json", function (data) {
             var canvas2 = d3.select("body").append("svg")
                      .attr("width", 500)
                      .attr("height", 500)
               canvas2.selectAll("rect")
                    .data(data)
                    .enter()
                           .append("rect")
                           .attr("width", function (d) {return d.dewpoint    * 10; })
                           .attr("height", 48)
                           .attr("y", function (d,i) {return i * 50; })
                           .attr("fill", "blue");
               canvas2.selectAll("text")
                    .data(data)
                    .enter()
                           .append("text")
                           .attr("fill", "white")
                           .attr("y", function (d,i) {return i * 50 + 24;         })
                           .text(function (d) {return d.dewpoint; })
   })
   </script>        
   </body>
   </html>

请记住,这个程序是一种原型。我主要关心的是为他们内部的圈子分配信息。如果你们在代码中发现任何错误/混淆,请随时通知我。谢谢你! !

好了,如我所承诺的,这是一个示例。它看起来不是很酷,但至少你会得到图片。如果您有更多的问题,请拍摄!下面是:

<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script src="donut.js" type="text/javascript"></script>
    <style>
        body{
            background-color:black;
        }
        #container {
            position:relative;
            display:inline-block;
            width:100%;
        }
        .row{
            position:relative;
            display:inline-block;
            width:100%;
            text-align:center;
        }
        #chart{
            width:60%;
            position:relative;
            display:inline-block;
        }
        text{
            font-size:1.4em;
        }
    </style>
</head>
<body>
    <div id="container">
        <div class="row">
            <div id="chart">
            </div>
        </div>
    </div>
    <script>
        var data = [
            {"type":"weather", "status":"sunny"},
            {"type":"humidity", "status":"high"},
            {"type":"temperature", "status":"23°"},
            {"type":"pressure", "status":"1040 hpa"},
            {"type":"wind", "status":"East"},
        ];
        var chartWidth = 500;
        var chartHeight = 500;
        /* Adding the svg drawing canvas by selecting the element that will contain the svg. put it in a var,
            as it is a d3 selection. We can reuse this selection. Remember, when chaining, you will get returned the
            element you last appended, in this case the svg.
        */
        var svg = d3.select("#chart")
                        .append("svg")
                            .attr({   // you can put attributes in a javascript object, i like this notation better.
                                width:chartWidth,
                                height:chartHeight
                            });

        /*  Here I am going to add the circles. With SVG elements, you cannot draw inside other elements. There are only 2 elements
            which can contain other elements (as far as I know) and that is the SVG element itself and the g element. So if you want 
            to give the impression that the elements are inside one another, you need to make them overlap. So if I add a circle and then
            add text with coordinates that match the circle, the text will overlap the circle, giving the impression it is inside it.
        */
        var circles = svg.selectAll("circle")
                            .data(data) //binding the data. I want 5 circles for my 5 pieces of data
                            .enter()
                            .append("circle")
                                .attr({
                                    cx:function(d,i){ //when doing the append on a d3 selection, you are iteration over each element!
                                        /* I will use the index (i) to 'identify' the pieces of data and to hardcode their x central point positions */
                                        if(i == 0) {
                                            return chartWidth/2;
                                        }
                                        if(i == 1) {
                                            return chartWidth/5;
                                        }
                                        if(i == 2) {
                                            return chartWidth *(2/7);
                                        }
                                        if(i == 3) {
                                            return chartWidth *(5/7);
                                        }
                                        if(i == 4) {
                                            return chartWidth * (4/5);
                                        }
                                    },
                                    cy:function(d,i){ //when doing the append on a d3 selection, you are iteration over each element!
                                        /* I will use the index (i) to 'identify' the pieces of data and to hardcode their y central point positions */
                                        if(i == 0) {
                                            return chartHeight/2;
                                        }
                                        if(i == 1) {
                                            return chartHeight *(3/5);
                                        }
                                        if(i == 2) {
                                            return chartHeight *(4/5);
                                        }
                                        if(i == 3) {
                                            return chartHeight *(4/5);
                                        }
                                        if(i == 4) {
                                            return chartHeight * (3/5);
                                        }
                                    },
                                    r:function(d,i) { /* the radius is in function of the type. The first one (weather) should be the biggest one */
                                        if(d.type === "weather") {
                                            return 200;
                                        }
                                        else{
                                            return 75;
                                        }
                                    },
                                    fill:"yellow",
                                    stroke:"black"
                                });
            /* Now i'll append the text as last, so it overlaps nicely with the circles. For positioning, i ll have to reuse the x and y functions
                from the circles. I want the text to be positioned at the center of the cirkels.
            */          
            var texts = svg.selectAll("text")
                                    .data(data)
                                    .enter()
                                    .append("text")
                                        .text(function(d){ return d.status})
                                        .attr({
                                            x:function(d,i){ 
                                                /* So I used the same positioning for the text as for the center points of the circles.
                                                    you should realize that the text really starts at the middle of the circles. So you
                                                    should substract a bit from the x position to get them nicely in the middle. I aint going
                                                    for that trouble, its just an example.
                                                */
                                                if(i == 0) {
                                                    return chartWidth/2;
                                                }
                                                if(i == 1) {
                                                    return chartWidth/5;
                                                }
                                                if(i == 2) {
                                                    return chartWidth *(2/7);
                                                }
                                                if(i == 3) {
                                                    return chartWidth *(5/7);
                                                }
                                                if(i == 4) {
                                                    return chartWidth * (4/5);
                                                }
                                            },
                                            y:function(d,i){ //when doing the append on a d3 selection, you are iteration over each element!
                                                /* I will use the index (i) to 'identify' the pieces of data and to hardcode their y central point positions */
                                                if(i == 0) {
                                                    return chartHeight/2;
                                                }
                                                if(i == 1) {
                                                    return chartHeight *(3/5);
                                                }
                                                if(i == 2) {
                                                    return chartHeight *(4/5);
                                                }
                                                if(i == 3) {
                                                    return chartHeight *(4/5);
                                                }
                                                if(i == 4) {
                                                    return chartHeight * (3/5);
                                                }
                                            }
                                        });

    </script>
</body>
</html>

我没有添加点击第一个圆圈来显示其他圆圈的功能。如果你想的话,我可以这么做,但是我觉得这个例子已经有足够的东西可以学习了。

最新更新