为泰坦尼克号可视化加载数据的麻烦

时间:2016-05-13 04:59:35

标签: javascript d3.js

在运行D3散点图可视化时遇到了一些麻烦。不知道如何引用数据,因此可以从dropbox link here获得。

有一些问题。

  1. 我对加载数据感到有点困惑。

    • 我似乎无法加载数据。我之前已经成功,但我试图加载数据而不必引用一个函数(即全局)。但是,你会看到 - 我什么也没得到 - []。
    • 我是否需要在脚本底部加载它,然后引用d3.csv中的函数(function(d){...},FUNCTION);?为什么我不能简单地将它加载到我脚本顶部的变量(我正在尝试)。这样它的第一个对象可用吗?
  2. 我还觉得我对Mike Bostock教程有很好的处理方法,关于.enter(),update(),. exit()。但我知道我在“// ENTER + UPDATE”的评论部分有一个问题,我有circle.circle(function(d){return d;});.我不明白这一点。

  3. 总的来说,我希望创建一个散点图,其中票价为我的x轴,年龄为我的y轴,然后循环选择“仅限女性”,“仅限男性”,“仅限儿童”和“所有“(以All开头和结尾)。

    我计划增加更多内容,因为我可以更好地了解我目前的绊脚石。

    			d3.csv("titanic_full.csv", function(d) {
    			  return {
    			    fare: +d.fare,
    			    age: d.age == '' ? NaN : +d.age,
    			    sibsp: +d.sibsp,
    			    pclass: +d.pclass,
    			    sex: d.sex,
    			    name: d.name,
    			    survived: d.survived
    
    			  };
    			}, function(error, d) {
    			  //Filter out erroneous age values (263 rows are removed)
    			  var dataset = d.filter(function(d) {
    			    if (d['age'] >= 0) {
    			      return d;
    			    }
    			  });
    
    			  //*Main Elements Setup*
    
    			  //Width and height
    			  var w = 650;
    			  var h = 650;
    			  var padding = 20;
    
    			  //Create scale functions
    			  var xScale = d3.scale.linear()
    			    .domain([0, d3.max(dataset, function(d) {
    			      return d.fare;
    			    })])
    			    .range([padding, w - padding * 2]); // introduced this to make sure values are not cut off
    
    			  var yScale = d3.scale.linear()
    			    .domain([0, d3.max(dataset, function(d) {
    			      return d.age;
    			    })])
    			    .range([h - padding, padding]);
    
    			  var xAxis = d3.svg.axis()
    			    .scale(xScale)
    			    .orient("bottom");
    
    			  var yAxis = d3.svg.axis()
    			    .scale(yScale)
    			    .orient("left");
    
    			  //Create SVG element
    			  var svg = d3.select("body")
    			    .append("svg")
    			    .attr("width", w)
    			    .attr("height", h);
    
    			  //Show Axes
    			  svg.append('g')
    			    .attr('class', 'x axis')
    			    .attr('transform', 'translate(0,' + (h - padding) + ')')
    			    .call(xAxis);
    
    			  svg.append('g')
    			    .attr('class', 'y axis')
    			    .attr('transform', 'translate(' + padding + ',0)')
    			    .call(yAxis);
    
    			  function update(dataset) {
    			    //DATA JOIN
    			    //Join new data with old elements, if any.
    			    var circle = svg.selectAll('circle')
    			      .data(dataset);
    
    			    //UPDATE
    			    //Update old elements as needed.
    			    circle.attr('class', 'update');
    
    			    //ENTER
    			    //Create new elements as needed.
    			    circle.enter().append('circle')
    			      .attr('class', 'enter')
    			      .transition()
    			      .duration(1000)
    			      .attr("cx", function(d) {
    			        return xScale(d.fare);
    			      })
    			      .attr("cy", function(d) {
    			        return yScale(d.age);
    			      })
    			      .attr("r", 6)
    			      .attr('fill', function(d) {
    			        if (d.survived === '0') {
    			          return 'green';
    			        } else {
    			          return 'red';
    			        }
    			      })
    
    			    //ENTER + UPDATE
    			    //Appending to the enter selection expands the update selection to include
    			    //entering elements; so, operations on the update selection after appending to
    			    //the enter selection will apply to both entering and updating nodes.
    			    circle.circle(function(d) {
    			      return d;
    			    });
    
    			    //EXIT
    			    //Remove old elements as needed.
    			    circle.exit().remove();
    			  };
    
    			  //The initial display.
    			  update(dataset);
    
    			  //Work through each selection
    			  var options = ['Female Only', 'Male Only', 'Children Only', 'All']
    			  var option_idx = 0;
    			  console.log('next')
    			  var option_interval = setInterval(function(options) {
    			    if (options == 'Female Only') {
    			      var filteredData = dataset.filter(function(d) {
    			        if (d['sex'] == 'female') {
    			          return d;
    			        }
    			      })
    			    } else if (options == 'Male Only') {
    			      var filteredData = dataset.filter(function(d) {
    			        if (d['sex'] == 'male') {
    			          return d;
    			        }
    			      })
    			    } else if (options == 'Children Only') {
    			      var filteredData = dataset.filter(function(d) {
    			        if (d['age'] <= 13) {
    			          return d;
    			        }
    			      })
    			    } else if (options == 'All') {
    			      var filteredData = dataset.filter(function(d) {
    			        return d;
    			      })
    			    };
    			    console.log('interval')
    			    option_idx++; // increment by one
    			    update(filteredData);
    			    if (option_idx >= options.length) {
    			      clearInterval(option_interval);
    			    };
    			  }, 1500);
    			});
    		.axis path,
    		.axis line {
    		  fill: none;
    		  stroke: black;
    		  shape-rendering: crispEdges;
    		}
    		.axis text {
    		  font-family: sans-serif;
    		  font-size: 8px;
    		}
    		
    <title>Titanic Visualization - Fare and Age Survival</title>

2 个答案:

答案 0 :(得分:1)

您应该在d3.csv回调函数中编写整个代码。试试这种方式。

d3.csv("titanic_full.csv", function(d) {
  return {
    fare: +d[fare],
    age: d.age == '' ? NaN : +d.age,
    sibsp: +d.sibsp,
    pclass: +d.pclass
  };
}, function(error, dataset) {
  //Filter out erroneous age values (263 rows are removed)
  var dataset = dataset.filter(function(d) {
    if (d['age'] >= 0) {
      return d;
    }
  });
  //Remaining code
});

有关详细信息,请参阅here

答案 1 :(得分:0)

好的,所以我有一个答案,但我可能也不会解释这个。

<强> 1。我对加载数据感到有点困惑。

在@Gilsha的帮助下,我能够重新配置我的脚本以首先加载数据,其余的脚本是d3.csv函数的“回调”部分。这很顺利。我还能够过滤我的数据以立即删除空白。这是第一部分:

d3.csv("titanic_full.csv", function(d) {
          return {
            fare: +d.fare,
            age: d.age == '' ? NaN : +d.age,
            sibsp: +d.sibsp,
            pclass: +d.pclass,
            sex: d.sex,
            name: d.name,
            survived: d.survived

          };
        }, function(error, d) {
          //Filter out erroneous age values (263 rows are removed)
          var dataset = d.filter(function(d) {
            if (d['age'] >= 0) {
              return d;
            }
          });

            //Rest of script here.

** 2。我也觉得我对Mike Bostock教程有一个很好的处理.enter(),update(),. exit()。 Link to Bostock Tutorial I was following **

我在这里做错了一些让我失望的事情。我坚持的主要项目是这部分:

//ENTER + UPDATE
                //Appending to the enter selection expands the update selection to include
                //entering elements; so, operations on the update selection after appending to
                //the enter selection will apply to both entering and updating nodes.
                circle.circle(function(d) {return d;});

基本上,我过于密切地关注本教程,并没有意识到当他使用“text.text(function(d){return d;});”时,他正在设置文本属性(?)某事。这是我认为我应该对我的ENTER和UPDATE选择进行任何更改的地方(我期望在DOM中的所有项目)。所以,当Mike正在做text.text并且我用circle.circle复制时,我应该有circle.text(.....)。或者我想要的任何东西。有人关心评论或解释更好吗?

PS - 我还有很多其他错误......特别是在建立我的间隔期间!