如何从d3.js中的嵌套结构中的数据追加路径?

时间:2015-12-29 11:18:19

标签: javascript d3.js

我是新用d3.js.我喜欢代表多线图。在x轴上,年份,y轴是每个国家拥有的专利数量。每一行都应该是一个不同的国家。

我有一个包含以下信息的csv文件:

PATENT,GYEAR,GDATE,APPYEAR,COUNTRY
3070801,1963,1096,,"BE"
3070802,1963,1096,,"US"
3070802,1963,1096,,"US"
3070802,1963,1096,,"US"
3070802,1963,1096,,"US"
3070803,1964,1096,,"US"
3070804,1964,1096,,"US"
3070801,1964,1096,,"BE"
3070801,1964,1096,,"BE"
3070801,1964,1096,,"BE"
3070801,1964,1096,,"BE"
3070801,1964,1096,,"BE"
3070801,1964,1096,,"BE"
...

我使用如下嵌套结构:

 var countries = d3.nest()
                .key(function(d) { return d.COUNTRY; })
                .key(function(d) { return d.GYEAR; })
                .rollup(function(v) {  return { "total": v.length} })
                .map(data);

此结构以下列方式提供信息:

BE: Object
    1963: Object
        total: 1
    1964: Object
        total: 6
US: Object
    1963: Object
        total: 4
    1964: Object
        total: 2

我的剧本:

<script>
    var margin = {top: 20, right: 80, bottom: 30, left: 50},
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;

    var parseDate = d3.time.format("%Y").parse;

    var x = d3.time.scale()
            .range([0, width]);

    var y = d3.scale.linear()
            .range([height, 0]);

    var color = d3.scale.category10();

    var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");

    var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");

    var line = d3.svg.line()
            .interpolate("basis")
            .x(function(d) {...}) //not so sure how to obtain the x and y
            .y(function(d) {... });

    var svg = d3.select("body").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    d3.csv("data3", function(error, data) {
        if (error) throw error;

        color.domain(d3.keys(data[0]).filter(function (key) {
            return key !== "GYEAR";
        }));

        data.forEach(function(d) {
            d.GYEAR = parseDate(String(d.GYEAR));
        });


        var countries = d3.nest()
                .key(function(d) { return d.COUNTRY; })
                .key(function(d) { return d.GYEAR; })
                .rollup(function(v) {  return { "total": v.length} })
                .map(data);



        x.domain(d3.extent(data, function (d) {                
            return d.GYEAR;
        }));

        y.domain([0,10]);

        svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .style({'stroke': 'Black', 'fill': 'none', 'stroke-width': '1.5px'})
                .call(xAxis);

        svg.append("g")
                .attr("class", "y axis")
                .style({'stroke': 'Black', 'fill': 'none', 'stroke-width': '1.5px'})
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Cantidad");

        var city = svg.selectAll(".country")
                .data(countries)
                .enter().append("g")
                .attr("class", "country");      

        //How to append path?
        city.append("path")
                .attr("class", "line")
                .attr("d", function(d) {...})
                .style("stroke", function(d) {...});


    });
</script>

如何构建我的var线?我该如何追加这条路?

提前致谢。

1 个答案:

答案 0 :(得分:2)

对于生成线功能,您可以执行以下操作:

var countries = d3.nest()
        .key(function(d) { return d.COUNTRY; })
        .key(function(d) { return d.GYEAR.getFullYear(); })
        .rollup(function(v){ 
          var pat = 0;
          var yr = 0;
          var country = ""
          v.forEach(function(r){
            pat += parseInt(r.PATENT);
            yr = r.GYEAR;
            country = r.COUNTRY
          });
          //store all the info like patent year country 
          return { "total": v.length, patent:pat, year:yr, country: country} 

        })
        .map(data);

对于汇总功能,获取所有数据:

var city = svg.selectAll(".country")
                .data([countries.BE, countries.US])//this will genrate 2 lines for the two datset.
                .enter().append("g")
                .attr("class", "country");      

        //How to append path?
        city.append("path")
                .attr("class", "line")
                .attr("d", function(d) {
                  var d_array = []
                  //for all the years make it an array
                  for (key in d) {
                      d_array.push(d[key])
                  }  
                   return line(d_array);

                })
                .style("stroke", function(d) { 
                  var country = "";
                  //the first object will tell the country
                  for (key in d) {
                      country = d[key].country;
                      break;
                  }  
                  return color(country)

                });

用于设置Line的值:

    var country_data = [];
    for (key in countries) {
          country_data.push(countries[key])
    }  

修改

将国家置于一般形式: 而不是这样做:

.data([countries.BE,countries.US]),

执行此操作以获取阵列:

   .data(country_data), 

以后再做

for t in result:
    for fn in t:
        with open (fn) as f:
            for line in f:
                print (line) # or whatever

工作代码here

清洁代码here

希望这有帮助!