2015-10-12 36 views
2

我想用d3.js生成一個平行座標我的問題是第一個比例尺應該顯示不同的字符串。d3.js用一個不同的比例平行座標

與原來的代碼看起來是這樣的:

,並與我的測試,它看起來像這樣(沒有臺詞): 錯誤代碼是:

Error: Invalid value for attribute d="M33,NaNL99,161.37817638266068L165,6.543121881682145L231,16.962488563586458L297,180"

這裏是我的代碼:

function parallelChart (id, size) { 

    if(size == 'small') { 
    var margin = {top: 20, right: 80, bottom: 30, left: 50}, 
     width = 460 - margin.left - margin.right, 
     height = 230 - margin.top - margin.bottom; 
    } else { 
    var margin = {top: 20, right: 80, bottom: 30, left: 50}, 
     width = 960 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom; 
    } 

    var x = d3.scale.ordinal().rangePoints([0, width], 1), 
     y = {}, 
     dragging = {}; 

    var line = d3.svg.line(), 
     axis = d3.svg.axis().orient("left"), 
     background, 
     foreground; 

    var svg = d3.select(id).append("svg") 
    .attr("class", 'center-block') 
    .attr("width", width + margin.left + margin.right) 
    .attr("height", height + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

    // Original 
    d3.csv("dataNew.csv", function(error, healthdata) { 
    x.domain(dimensions = d3.keys(healthdata[0]).filter(function(d) { 
     return d != "Datum" && (y[d] = d3.scale.linear() 
     .domain(d3.extent(healthdata, function(p) { return +p[d]; })) 
     .range([height, 0])); 
    })); 

    // this did not work 
    // d3.csv("dataNew.csv", function(error, healthdata) { 
    // x.domain(dimensions = d3.keys(healthdata[0]).filter(function(d) { 
    //  if(d == "Datum") { 
    //  return d == "Datum" && ((y[d] = d3.time.scale() 
    //   .domain(d3.extent(healthdata, function(p) { return +p[d]; })) 
    //   .range([height, 0]))); 
    //  } 
    //  return d != "Datum" && ((y[d] = d3.scale.linear() 
    //  .domain(d3.extent(healthdata, function(p) { return +p[d]; })) 
    //  .range([height, 0])));     
    // })); 

     // Add grey background lines for context. 
     background = svg.append("g") 
     .attr("class", "background") 
     .selectAll("path") 
     .data(healthdata) 
     .enter().append("path") 
     .attr("d", path); 

     // Add blue foreground lines for focus. 
     foreground = svg.append("g") 
     .attr("class", "foreground") 
     .selectAll("path") 
     .data(healthdata) 
     .enter().append("path") 
     .attr("d", path); 

     // Add a group element for each dimension. 
     var g = svg.selectAll(".dimension") 
     .data(dimensions) 
     .enter().append("g") 
     .attr("class", "dimension") 
     .attr("transform", function(d) { return "translate(" + x(d) + ")"; }) 
     .call(d3.behavior.drag() 
      .origin(function(d) { return {x: x(d)}; }) 
      .on("dragstart", function(d) { 
      dragging[d] = x(d); 
      background.attr("visibility", "hidden"); 
      }) 
      .on("drag", function(d) { 
      dragging[d] = Math.min(width, Math.max(0, d3.event.x)); 
      foreground.attr("d", path); 
      dimensions.sort(function(a, b) { return position(a) - position(b); }); 
      x.domain(dimensions); 
      g.attr("transform", function(d) { return "translate(" + position(d) + ")"; }) 
      }) 
      .on("dragend", function(d) { 
      delete dragging[d]; 
      transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")"); 
      transition(foreground).attr("d", path); 
      background 
       .attr("d", path) 
       .transition() 
       .delay(500) 
       .duration(0) 
       .attr("visibility", null); 
      })); 

    // Add an axis and title. 
    g.append("g") 
     .attr("class", "axis") 
     .each(function(d) { d3.select(this).call(axis.scale(y[d])); }) 
     .append("text") 
     .style("text-anchor", "middle") 
     .attr("y", -9) 
     .text(function(d) { return d; }); 

    // Add and store a brush for each axis. 
    g.append("g") 
     .attr("class", "brush") 
     .each(function(d) { 
     d3.select(this).call(y[d].brush = d3.svg.brush().y(y[d]).on("brushstart", brushstart).on("brush", brush)); 
     }) 
     .selectAll("rect") 
     .attr("x", -8) 
     .attr("width", 16); 
    }); 

    function position(d) { 
    var v = dragging[d]; 
    return v == null ? x(d) : v; 
    } 

    function transition(g) { 
    return g.transition().duration(500); 
    } 

    // Returns the path for a given data point. 
    function path(d) { 
    return line(dimensions.map(function(p) { return [position(p), y[p](d[p])]; })); 
    } 

    function brushstart() { 
    d3.event.sourceEvent.stopPropagation(); 
    } 

    // Handles a brush event, toggling the display of foreground lines. 
    function brush() { 
    var actives = dimensions.filter(function(p) { return !y[p].brush.empty(); }), 
     extents = actives.map(function(p) { return y[p].brush.extent(); }); 
    foreground.style("display", function(d) { 
     return actives.every(function(p, i) { 
     return extents[i][0] <= d[p] && d[p] <= extents[i][1]; 
     }) ? null : "none"; 
    }); 
    } 
} 

回答

1

這裏舉一個例子,其中作者mana GE字符串和數字中相同的平行座標:

http://bl.ocks.org/syntagmatic/4020926

創建將進一步使用的尺寸的陣列...

var dimensions = [ 
    { 
    name: "name", 
    scale: d3.scale.ordinal().rangePoints([0, height]), 
    type: "string" 
    }, 
    { 
    name: "economy (mpg)", 
    scale: d3.scale.linear().range([0, height]), 
    type: "number" 
    }, 
... 
] 

...之前加載數據,定義域通過映射你以前尺寸定義...

var x = d3.scale.ordinal() 
    .domain(dimensions.map(function(d) { return d.name; })) 
    .rangePoints([0, width]); 

...定義一個變量尺寸(注意,尺寸!=尺寸)與各軸的位置...

var dimension = svg.selectAll(".dimension") 
    .data(dimensions) 
    .enter().append("g") 
    .attr("class", "dimension") 
    .attr("transform", function(d) { return "translate(" + x(d.name) + ")"; }); 

...一旦數據被加載,執行爲每個以限定每個維度的域...

d3.csv("cars.small.csv", function(data) { 

    dimensions.forEach(function(dimension) { 
    dimension.scale.domain(dimension.type === "number" 
     ? d3.extent(data, function(d) { return +d[dimension.name]; }) 
     : data.map(function(d) { return d[dimension.name]; }).sort()); 
    }); 

... 
} 

...軸線和前景仍然加載以同樣的方式...

svg.append("g") 
     .attr("class", "background") 
     .selectAll("path") 
     .data(data) 
     .enter().append("path") 
     .attr("d", draw); 

    svg.append("g") 
     .attr("class", "foreground") 
     .selectAll("path") 
     .data(data) 
     .enter().append("path") 
     .attr("d", draw); 

...這種合作de將加載每個軸的文本,觀察它現在使用我們在開始定義的尺寸中的屬性。

dimension.append("g") 
      .attr("class", "axis") 
      .each(function(d) { d3.select(this).call(yAxis.scale(d.scale)); }) 
      .append("text") 
      .attr("class", "title") 
      .attr("text-anchor", "middle") 
      .attr("y", -9) 
      .text(function(d) { return d.name; }); 

that`s all =)。