【问题标题】:D3.js csv Filter for InteractivityD3.js 用于交互的 csv 过滤器
【发布时间】:2016-03-10 16:56:59
【问题描述】:

我是 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”获取条目,以便将圈子分组到国家/地区。如果我想归因不透明度​​/颜色,这会是正确的方法吗?)

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>

【问题讨论】:

  • 您能否阐明您希望最终结果的样子?您是否只想一次显示一个来源的国家/地区?或者您想显示来自多个国家/地区的数据,但基于该国家/地区的不透明度和颜色?此外,您问您是否正确归因颜色和不透明度,但您似乎没有任何代码甚至尝试这样做 - 您是否忘记了部分代码? (也许是样式表?)
  • 我想按原产地过滤,但所有圈子都应该透明地绘制,但我没有到达那里,因为我很难获得国家(阿富汗、叙利亚等)的条目。所以基本上是第二个。正如我提到的那样,我无法到那里尝试不透明度。我只需要先过滤国家/地区的帮助。但谢谢,我编辑了我的问题以澄清

标签: javascript csv d3.js


【解决方案1】:

要过滤您的数据,以便您只拥有来自特定来源的数据,您可以使用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)});

【讨论】:

  • 谢谢你,这对我帮助很大。我将在另一个问题中发布过滤分离的问题,以便我可以更详细地解释
猜你喜欢
  • 2021-09-15
  • 1970-01-01
  • 2020-03-02
  • 2019-08-23
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多