D3.js csv过滤互动

时间:2015-12-05 20:49:57

标签: javascript csv d3.js

我是d3.js&的新手。 HTML,我找不到我的问题的答案。

我有这个数组我想在时间图上绘制。 This is the CSV with marked countries i want to filter

This is an example of my plot right now

如您所见,您无法识别哪个圈子属于哪个国家/地区。我想整合一些鼠标等来区分圆圈。

  1. 但我不知道如何从.csv过滤原始国家我该怎么办?
  2. 我想从“Origin”中获取条目,以便我可以将圈子分组到国家/地区。如果我想归属不透明度/颜色,这会是正确的方法吗?)
  3. body,
    html {
      margin: 0;
      padding: 0;
      font-family: "Arial", sans-serif;
      font-size: 0.95em;
      text-align: center;
    }
    #chart {
      background-color: #F5F2EB;
      border: 1px solid #CCC;
    }
    .bar {
      fill: purple;
      shape-rendering: crispEdges;
    }
    .bar-label {
      fill: black;
      text-anchor: middle;
      font-size: 18px;
    }
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
    .gridline path,
    .gridline line {
      fill: none;
      stroke: #ccc;
      shape-rendering: crispEdges;
    }

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>Learning D3</title>
      <link rel="stylesheet" href="main.css">
      <script type="text/javascript" src="d3.min.js"></script>
    </head>
    
    <body>
      <!--Place all DOM elements here -->
      <script>
        d3.csv("refugee_data.csv", function(d) {
    
          return {
            date: d.Year + "/" + d.Month,
            origin: d.Origin,
            asylum: d.Asylum,
            value: +d.Value
          };
        }, function(error, rows) {
          console.log(rows);
          render(rows)
        });
    
    
    
        function render(data) {
          var w = 800;
          var h = 450;
          var margin = {
            top: 100,
            bottom: 0,
            left: 80,
            right: 40
          };
          var width = w - margin.left - margin.right;
          var height = h - margin.top - margin.bottom;
    
          var svg = d3.select("body").append("svg")
            .attr("id", "chart")
            .attr("width", w)
            .attr("height", h)
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
          var dateParser = d3.time.format("%Y/%B").parse;
          var x = d3.time.scale()
            .domain(d3.extent(data, function(d) {
              var date = dateParser(d.date);
              return date;
            }))
            .range([0 + margin.left, width]);
    
          var y = d3.scale.linear()
            .domain([0, d3.max(data, function(d) {
              return d.value;
            })])
            .range([height, 0 + margin.top]);
          //range([0, height]);
    
          //enter()
          svg.selectAll(".point")
            .data(data)
            .enter()
            .append("circle")
            .classed("point", true)
            .attr("r", 2);
          //Update
          svg.selectAll(".point")
            .attr("cx", function(d) {
              var date = dateParser(d.date);
              return x(date);
            })
            .attr("cy", function(d) {
              return y(d.value);
            })
    
          //Exit()
          svg.selectAll(".point")
            .data(data)
            .exit()
            .remove();
        }
      </script>
    </body>
    
    </html>

    基本上我想要实现这种情节

    var data = [{
      glazed: 3.14,
      jelly: 4.43,
      powdered: 2.43,
      sprinkles: 3.86,
      age: 18,
      responses: 7
    }, {
      glazed: 3.00,
      jelly: 3.67,
      powdered: 2.67,
      sprinkles: 4.00,
      age: 19,
      responses: 3
    }, {
      glazed: 2.00,
      jelly: 4.00,
      powdered: 2.33,
      sprinkles: 4.33,
      age: 20,
      responses: 3
    }, {
      glazed: 3.50,
      jelly: 4.50,
      powdered: 1.00,
      sprinkles: 3.50,
      age: 21,
      responses: 2
    }, {
      glazed: 2.83,
      jelly: 3.50,
      powdered: 1.83,
      sprinkles: 4.50,
      age: 22,
      responses: 6
    }, {
      glazed: 3.25,
      jelly: 4.75,
      powdered: 2.25,
      sprinkles: 3.50,
      age: 23,
      responses: 4
    }, {
      glazed: 1.50,
      jelly: 4.00,
      powdered: 2.50,
      sprinkles: 4.00,
      age: 25,
      responses: 2
    }, {
      glazed: 1.67,
      jelly: 3.00,
      powdered: 1.33,
      sprinkles: 4.00,
      age: 26,
      responses: 3
    }, {
      glazed: 2.50,
      jelly: 4.00,
      powdered: 1.00,
      sprinkles: 4.50,
      age: 27,
      responses: 2
    }, {
      glazed: 3.00,
      jelly: 4.33,
      powdered: 1.33,
      sprinkles: 4.33,
      age: 28,
      responses: 3
    }, {
      glazed: 5.00,
      jelly: 4.00,
      powdered: 1.00,
      sprinkles: 4.00,
      age: 29,
      responses: 1
    }, {
      glazed: 5.00,
      jelly: 5.00,
      powdered: 2.00,
      sprinkles: 5.00,
      age: 30,
      responses: 1
    }, {
      glazed: 1.50,
      jelly: 4.50,
      powdered: 3.00,
      sprinkles: 4.75,
      age: 31,
      responses: 4
    }, {
      glazed: 3.67,
      jelly: 3.33,
      powdered: 1.67,
      sprinkles: 4.67,
      age: 32,
      responses: 3
    }, {
      glazed: 2.00,
      jelly: 4.50,
      powdered: 1.00,
      sprinkles: 5.00,
      age: 33,
      responses: 2
    }, {
      glazed: 2.75,
      jelly: 3.75,
      powdered: 2.50,
      sprinkles: 4.50,
      age: 34,
      responses: 4
    }, {
      glazed: 4.00,
      jelly: 3.00,
      powdered: 2.75,
      sprinkles: 4.25,
      age: 35,
      responses: 4
    }, {
      glazed: 1.50,
      jelly: 3.00,
      powdered: 4.00,
      sprinkles: 4.00,
      age: 36,
      responses: 2
    }, {
      glazed: 3.00,
      jelly: 3.00,
      powdered: 3.50,
      sprinkles: 4.00,
      age: 37,
      responses: 2
    }, {
      glazed: 4.00,
      jelly: 2.00,
      powdered: 3.33,
      sprinkles: 4.67,
      age: 39,
      responses: 3
    }, {
      glazed: 3.50,
      jelly: 3.00,
      powdered: 4.00,
      sprinkles: 4.50,
      age: 40,
      responses: 2
    }, {
      glazed: 2.75,
      jelly: 2.75,
      powdered: 4.00,
      sprinkles: 4.25,
      age: 41,
      responses: 4
    }, {
      glazed: 2.25,
      jelly: 2.50,
      powdered: 1.75,
      sprinkles: 4.25,
      age: 42,
      responses: 4
    }, {
      glazed: 1.00,
      jelly: 2.00,
      powdered: 1.00,
      sprinkles: 5.00,
      age: 43,
      responses: 1
    }, {
      glazed: 2.00,
      jelly: 3.00,
      powdered: 3.67,
      sprinkles: 3.33,
      age: 44,
      responses: 3
    }, {
      glazed: 3.33,
      jelly: 2.33,
      powdered: 3.33,
      sprinkles: 3.33,
      age: 46,
      responses: 3
    }, {
      glazed: 2.25,
      jelly: 4.00,
      powdered: 2.75,
      sprinkles: 3.00,
      age: 47,
      responses: 4
    }, {
      glazed: 3.75,
      jelly: 2.00,
      powdered: 3.00,
      sprinkles: 2.75,
      age: 48,
      responses: 4
    }, {
      glazed: 2.75,
      jelly: 2.00,
      powdered: 3.75,
      sprinkles: 3.25,
      age: 49,
      responses: 4
    }, {
      glazed: 2.67,
      jelly: 2.67,
      powdered: 1.67,
      sprinkles: 3.67,
      age: 51,
      responses: 3
    }, {
      glazed: 2.50,
      jelly: 2.50,
      powdered: 4.00,
      sprinkles: 3.00,
      age: 52,
      responses: 2
    }, {
      glazed: 3.00,
      jelly: 3.67,
      powdered: 4.67,
      sprinkles: 2.67,
      age: 53,
      responses: 3
    }, {
      glazed: 5.00,
      jelly: 5.00,
      powdered: 5.00,
      sprinkles: 3.50,
      age: 54,
      responses: 2
    }, {
      glazed: 2.33,
      jelly: 1.67,
      powdered: 2.33,
      sprinkles: 3.33,
      age: 55,
      responses: 3
    }, {
      glazed: 3.00,
      jelly: 2.00,
      powdered: 3.00,
      sprinkles: 3.00,
      age: 56,
      responses: 1
    }, {
      glazed: 2.00,
      jelly: 2.00,
      powdered: 2.00,
      sprinkles: 4.00,
      age: 57,
      responses: 1
    }, {
      glazed: 1.25,
      jelly: 2.00,
      powdered: 3.00,
      sprinkles: 1.75,
      age: 59,
      responses: 4
    }, {
      glazed: 2.50,
      jelly: 2.50,
      powdered: 4.00,
      sprinkles: 2.50,
      age: 60,
      responses: 2
    }, {
      glazed: 2.33,
      jelly: 2.33,
      powdered: 2.67,
      sprinkles: 3.00,
      age: 61,
      responses: 3
    }, {
      glazed: 2.25,
      jelly: 2.50,
      powdered: 3.75,
      sprinkles: 3.00,
      age: 62,
      responses: 4
    }, {
      glazed: 1.50,
      jelly: 3.00,
      powdered: 3.00,
      sprinkles: 2.00,
      age: 63,
      responses: 2
    }, {
      glazed: 2.00,
      jelly: 3.00,
      powdered: 3.40,
      sprinkles: 2.40,
      age: 64,
      responses: 5
    }, {
      glazed: 2.00,
      jelly: 1.00,
      powdered: 4.50,
      sprinkles: 2.00,
      age: 65,
      responses: 2
    }, {
      glazed: 2.00,
      jelly: 1.67,
      powdered: 4.00,
      sprinkles: 1.67,
      age: 66,
      responses: 3
    }, {
      glazed: 1.50,
      jelly: 1.75,
      powdered: 3.75,
      sprinkles: 2.25,
      age: 67,
      responses: 4
    }, {
      glazed: 2.00,
      jelly: 2.50,
      powdered: 4.25,
      sprinkles: 2.00,
      age: 68,
      responses: 4
    }, {
      glazed: 3.00,
      jelly: 2.00,
      powdered: 3.00,
      sprinkles: 3.00,
      age: 70,
      responses: 1
    }, {
      glazed: 2.33,
      jelly: 2.67,
      powdered: 4.33,
      sprinkles: 2.33,
      age: 71,
      responses: 3
    }, {
      glazed: 3.00,
      jelly: 2.50,
      powdered: 3.75,
      sprinkles: 2.00,
      age: 72,
      responses: 4
    }, {
      glazed: 2.00,
      jelly: 2.50,
      powdered: 4.50,
      sprinkles: 2.50,
      age: 73,
      responses: 2
    }, {
      glazed: 3.00,
      jelly: 2.00,
      powdered: 4.00,
      sprinkles: 1.50,
      age: 74,
      responses: 2
    }];
    body,
    html {
      margin: 0;
      padding: 0;
      font-family: "Arial", sans-serif;
      font-size: 0.95em;
      text-align: center;
    }
    #chart {
      background-color: #F5F2EB;
      border: 1px solid #CCC;
    }
    .bar {
      fill: purple;
      shape-rendering: crispEdges;
    }
    .bar-label {
      fill: black;
      text-anchor: middle;
      font-size: 18px;
    }
    .axis path,
    .axis line {
      fill: none;
      stroke: #000;
      shape-rendering: crispEdges;
    }
    .gridline path,
    .gridline line {
      fill: none;
      stroke: #ccc;
      shape-rendering: crispEdges;
    }
    .trendline {
      fill: none;
      stroke: #ccc;
      stroke-width: 4px;
    }
    .area {
      opacity: 0.25;
      fill: #ccc;
      stroke: #ccc;
      stroke-width: 1px;
    }
    .donut {
      opacity: 0.1;
    }
    .highlight {
      opacity: 1;
      cursor: hand;
    }
    .axis-label {
      text-anchor: middle;
    }
    .chart-header {
      text-transform: capitalize;
      font-size: 125%;
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>Learning D3</title>
      <link rel="stylesheet" href="main.css">
      <script type="text/javascript" src="d3.min.js"></script>
    </head>
    
    <body>
      <!--Place all DOM elements here -->
      <script type="text/javascript" src="survey_data.js"></script>
      <script>
        var w = 800;
        var h = 450;
        var margin = {
          top: 60,
          bottom: 80,
          left: 100,
          right: 80
        };
        var width = w - margin.left - margin.right;
        var height = h - margin.top - margin.bottom;
        var svg = d3.select("body").append("svg")
          .attr("id", "chart")
          .attr("width", w)
          .attr("height", h);
        var chart = svg.append("g")
          .classed("display", true)
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        var tickValues = [18, 25, 32, 39, 46, 53, 60, 67, 74];
        var colorScale = d3.scale.category10();
        var x = d3.scale.linear()
          .domain(d3.extent(data, function(d) {
            return d.age;
          }))
          .range([0, width]);
        var y = d3.scale.linear()
          .domain([1, 5])
          .range([height, 0]);
        var xAxis = d3.svg.axis()
          .scale(x)
          .tickValues(tickValues)
          .orient("bottom");
        var yAxis = d3.svg.axis()
          .scale(y)
          .ticks(5)
          .tickSize(20)
          .tickFormat(function(d) {
            return d.toFixed(1);
          })
          .orient("left");
        var xGridlines = d3.svg.axis()
          .scale(x)
          .tickValues(tickValues)
          .tickSize(height, height)
          .tickFormat("")
          .orient("bottom");
        var yGridlines = d3.svg.axis()
          .scale(y)
          .tickSize(-width, 0, 0)
          .tickFormat("")
          .orient("left");
        var responseScale = d3.scale.linear()
          .domain(d3.extent(data, function(d) {
            return d.responses;
          }))
          .range([2, 15]);
        var initialize = 1;
    
        function drawAxis(params) {
          if (initialize) {
            this.append("g")
              .call(params.gridlines.x)
              .classed("gridline x", true)
              .attr("transform", "translate(" + 0 + "," + 0 + ")");
            this.append("g")
              .call(params.gridlines.y)
              .classed("gridline y", true)
              .attr("transform", "translate(" + 0 + "," + 0 + ")");
            this.append("g")
              .call(params.axis.x)
              .classed("axis x", true)
              .attr("transform", "translate(" + 0 + "," + height + ")");
            this.append("g")
              .call(params.axis.y)
              .classed("axis y", true)
              .attr("transform", "translate(" + 0 + "," + 0 + ")");
            this.select(".y.axis")
              .append("text")
              .classed("y axis-label", true)
              .attr("transform", "translate(" + -56 + "," + height / 2 + ") rotate(-90)")
              .text("Rating (1=Low, 5=High)");
            this.select(".x.axis")
              .append("text")
              .classed("x axis-label", true)
              .attr("transform", "translate(" + width / 2 + "," + 48 + ")")
              .text("Customer age");
            this.append("g")
              .append("text")
              .classed("chart-header", true)
              .text("")
              .attr("transform", "translate(0," + -24 + ")")
            initialize = 0;
          }
        }
    
        function plot(params) {
          var self = this;
          //Get each of the donut types
          var donuts = d3.keys(params.data[0]).filter(function(d) {
            return d !== "age" && d !== "responses";
          });
          drawAxis.call(this, params);
          //Create a group for each type of donut
          this.selectAll(".donut")
            .data(donuts)
            .enter()
            .append("g")
            .attr("class", function(d) {
              return d;
            })
            .classed("donut", true);
    
          this.selectAll(".donut")
            .style("fill", function(d, i) {
              return colorScale(i);
            })
            .on("mouseover", function(d, i) {
              d3.select(this)
                //.classed("highlight", true)
                .transition()
                .style("opacity", 1);
            })
            .on("mouseout", function(d, i) {
              d3.select(this)
                //.classed("highlight", false)
                .transition()
                .style("opacity", 0.1);
            });
    
          donuts.forEach(function(donut) {
            var g = self.selectAll("g." + donut);
            var arr = params.data.map(function(d) {
              return {
                key: donut,
                value: d[donut],
                age: d.age,
                responses: d.responses
              };
            });
            //Setup circles
            g.selectAll(".response")
              .data(arr)
              .enter()
              .append("circle")
              .classed("response", true);
            //Update circles
            g.selectAll(".response")
              .attr("r", function(d) {
                return responseScale(d.responses);
              })
              .attr("cx", function(d) {
                return x(d.age);
              })
              .attr("cy", function(d) {
                return y(d.value);
              })
              .on("mouseover", function(d, i) {
                var str = d.key + " Donut: ";
                str += "Age: " + d.age + ", ";
                str += "Responses: " + d.responses + ", ";
                str += "Average Rating: " + d.value;
                str += ""
                d3.select(".chart-header").text(str);
              })
              .on("mouseout", function(d, i) {
                d3.select(".chart-header").text("");
              });
            //Remove any unbound elements
            g.selectAll(".response").data(arr).exit().remove();
          });
        }
        plot.call(chart, {
          data: data,
          gridlines: {
            x: xGridlines,
            y: yGridlines
          },
          axis: {
            x: xAxis,
            y: yAxis
          }
        });
      </script>
    </body>
    
    </html>

1 个答案:

答案 0 :(得分:2)

要过滤数据以便只拥有特定来源的数据,您可以使用filter功能。此函数接受一个参数,这是另一个函数,对于要包含的所有数据点将返回true,对于要排除的所有数据点将返回false。例如,如果您想要以德国为原点的圈子,您可以这样做:

var germany = svg.selectAll(".point")
                 .filter(function(d) {return d.Origin == "Germany"});

至于设置颜色和不透明度,它看起来不像你在任何地方那样做(即使在你的样式表中,你没有“circle”元素或“.point”类的任何样式)。由于您只想更改圈子的颜色和不透明度,最好的办法是使用d3的style()函数,它可以让您更改数据点的样式。例如,如果你想让所有代表德国数据点的圆圈为红色并且完全不透明,你可以这样做:

germany.style("fill", "red").style("opacity", 1);

或者,如果您想根据原点为所有圆圈着色,可以跳过过滤步骤并使用色标一次为所有圆圈着色:

//creates a scale to assign colors
var colorScale = d3.scale.category10(); 

//Then apply it to all points by assigning
// fill based on a callback function
svg.selectAll(".point")
   .style("fill", function(d){return colorScale(d.Origin)});