2017-01-03 16 views
5

Tôi đang cố gắng "dịch" parallel coordinates example sang phiên bản mới của d3 v4. Tôi có một ví dụ làm việc với javascript này (mà bổ sung là một ví dụ tốt nếu có ai đang cố gắng làm việc với v4 của d3 và có vấn đề với các chức năng mới):Văn bản được thêm vào không hiển thị trong d3 v4

var margin = {top: 30, right: 10, bottom: 10, left: 10}, 
    width = 600 - margin.left - margin.right, 
    height = 200 - margin.top - margin.bottom; 

var x = d3.scaleBand().rangeRound([0, width]).padding(1), 
    y = {}, 
    dragging = {}; 


var line = d3.line(), 
    //axis = d3.axisLeft(x), 
    background, 
    foreground, 
    extents; 

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("cars.csv", function(error, cars) { 
    // Extract the list of dimensions and create a scale for each. 
    //cars[0] contains the header elements, then for all elements in the header 
    //different than "name" it creates and y axis in a dictionary by variable name 
    x.domain(dimensions = d3.keys(cars[0]).filter(function(d) { 
    if(d == "name") { 
     return false; 
    } 
    return y[d] = d3.scaleLinear() 
     .domain(d3.extent(cars, function(p) { 
      return +p[d]; })) 
     .range([height, 0]); 
    })); 

    extents = dimensions.map(function(p) { return [0,0]; }); 

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

    // Add blue foreground lines for focus. 
    foreground = svg.append("g") 
     .attr("class", "foreground") 
    .selectAll("path") 
     .data(cars) 
    .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.drag() 
     .subject(function(d) { return {x: x(d)}; }) 
     .on("start", 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("end", 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(d3.axisLeft(y[d]));}) 
     //text does not show up because previous line breaks somehow 
    .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.brushY().extent([[-8, 0], [8,height]]).on("brush start", brushstart).on("brush", brush_parallel_chart)); 
     }) 
    .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_parallel_chart() {  
    for(var i=0;i<dimensions.length;++i){ 
     if(d3.event.target==y[dimensions[i]].brush) { 
      extents[i]=d3.event.selection.map(y[dimensions[i]].invert,y[dimensions[i]]); 

     } 
    } 

     foreground.style("display", function(d) { 
     return dimensions.every(function(p, i) { 
      if(extents[i][0]==0 && extents[i][0]==0) { 
       return true; 
      } 
      return extents[i][1] <= d[p] && d[p] <= extents[i][0]; 
     }) ? null : "none"; 
     }); 
} 

Tất cả mọi thứ hoạt động chính xác (đánh răng trên mỗi các trục, thay đổi thứ tự của các trục ...) ngoại trừ các nhãn trên đầu của mỗi trục không hiển thị, mặc dù thẻ văn bản được nối và văn bản được viết trong thẻ (có thể được kiểm tra bằng cách kiểm tra kết quả html bằng trình duyệt). Tôi tin rằng mã chịu trách nhiệm cho việc này là một phần này, nhưng tôi không có khả năng tìm ra lý do tại sao điều này xảy ra:

g.append("g") 
     .attr("class", "axis") 
     .each(function(d) { d3.select(this).call(d3.axisLeft(y[d]));}) 
     //text does not show up because previous line breaks somehow 
    .append("text") 
     .style("text-anchor", "middle") 
     .attr("y", -9) 
     .text(function(d) { return d; }); 

Tại sao các nhãn văn bản không hiển thị?

Trả lời

7

Trong D3 v4 thành phần trục sẽ đặt rõ ràng điền vào none trên vùng chọn được gọi. Từ source code:

selection.filter(entering) 
    .attr("fill", "none")  // <=== Fill set to none by D3 
    .attr("font-size", 10) 
    .attr("font-family", "sans-serif") 
    .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle"); 

này sẽ tạo ra đoạn mã sau:

enter image description here

trái ngược với các mã được tạo bởi v3:

enter image description here

Các <text> yếu tố sẽ kế thừa những đặc tính này, bởi vì chúng là con của những nhóm này, ereby ẩn các văn bản.

Để hiển thị các nhãn bạn cần để tạo kiểu cho họ một cách rõ ràng, có thể được thực hiện

  1. Via CSS:

    .axis text { 
        fill:black; /* <== Set the fill */ 
        text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; 
        cursor: move; 
    } 
    

    Làm việc demo.

  2. Bằng cách đặt thuộc tính fill trên <text> yếu tố chính:

    .append("text") 
        .attr("fill", "black")   // <=== Set the fill 
    // .style("fill", "black")  // Will also work when using .style() 
        .style("text-anchor", "middle") 
        .attr("y", -9) 
        .text(function(d) { return d; }); 
    

    Làm việc demo.

+0

Đây không phải là trình diễn thực sự hoạt động. Tôi biết đây không phải là một câu hỏi nhưng các cọ vẽ không hoạt động trong ví dụ được đăng. Họ không đặt lại bộ lọc khi xóa bàn chải. – konrad

+0

@konrad Các bản demo chỉ là bản sao của mã OP với một dòng được thêm vào để giải quyết vấn đề mà câu hỏi là tất cả về. Tôi không yêu cầu họ không có lỗi hoặc đầy đủ chức năng. – altocumulus

+0

Chắc chắn. Chỉ muốn chỉ ra rằng trong trường hợp những người khác nhận thấy là tốt. Bạn cũng có thể nhận xét về cách giải quyết vấn đề đó? – konrad

Các vấn đề liên quan