2015-05-02 2 views
2

Я работаю над веб-инструментом, который должен создать диаграмму рассеяния с заданными данными. Поскольку я новичок в том, что визуализирует (а не эксперт по JavaScript), я решил пойти с D3.D3 увеличить размер кисти

Следуя инструкциям, наблюдая за примерами и испытанными вещами, я получил диаграмму рассеянности с выбором кисти (которая еще ничего не делает). Теперь, когда thegoal рисует гены, многие из них будут очень близки друг к другу с точки зрения координат x и y. Поэтому я хотел бы реализовать что-то like this, но в обоих направлениях x и y. В основном увеличьте размер на щеткой секции.

Пока я не могу создать это поведение, на данный момент мои оси меняются, но больше не отображаются значения, и ни одно из них не происходит. Вы можете видеть это в прямом эфире на my toy subdomain. Я не уверен, где это происходит, поэтому любая помощь ценится.

Javascript используется в области игрушек:

// General variables 

var svg, width, height; 
var padding = 30; 

var dataset = [ 
       [ 5,  20 ], 
       [ 480, 90 ], 
       [ 250, 50 ], 
       [ 100, 33 ], 
       [ 330, 95 ], 
       [ 410, 12 ], 
       [ 475, 44 ], 
       [ 25, 67 ], 
       [ 85, 21 ], 
       [ 220, 88 ] 
      ]; 

function drawGraph(){ 
    scatterplot_area_size = $("#scatterplot").width(); 
    width = scatterplot_area_size; 
    height = scatterplot_area_size * 0.75; 

    console.log(width); 

    // Retrieve the interval of the x and y data 
    var maxX = d3.max(dataset, function(d) { 
     return d[0]; //References first value in each sub-array 
    }); 

    var minX = d3.min(dataset, function(d) { 
     return d[0]; //References first value in each sub-array 
    }); 

    var maxY = d3.max(dataset, function(d) { 
     return d[1]; //References second value in each sub-array 
    }); 

    var minY = d3.min(dataset, function(d) { 
     return d[1]; //References second value in each sub-array 
    }); 

    // Create a (square) scatterplot area in the div with id scatterplot 
    // which spans the entire div in width 
    svg = d3.select("#scatterplot") 
      .append("svg") 
      .attr("width", width) 
      .attr("height", height); 

    // plot all points 
    var points = svg.append("g") 
     .attr("class", "point") 
     .selectAll("point") 
     .data(dataset) 
     .enter() 
     .append("circle"); 


    console.log(minX + " " + minY); 

    // Create x and y scales 
    var x = d3.scale.linear() 
        .domain([minX, maxX]) 
        .range([padding, (width-padding)]); 

    var y = d3.scale.linear() 
        .domain([minY, maxY]) 
        .range([(height-padding), padding]); // Reverse the scale to let high values show at the top and low values at the bottom 

    // Set the x and y positions as well as the radius (hard coded 5) 
    points.attr("cx", function(d) { 
     return x(d[0]); 
    }) 
    .attr("cy", function(d) { 
     return y(d[1]); 
    }) 
    .attr("r", 5); 

    // Create the x and y axes 
    var xAxis = d3.svg.axis() 
        .scale(x) 
        .ticks(10) 
        .orient("bottom"); 

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

    // Add the axes to the scatterplot 
    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + (height-padding) + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .attr("transform", "translate(" + padding + ",0)") 
     .call(yAxis); 

    // Allow for brushing (selection of points) 
    var brush = d3.svg.brush() 
     .x(x) 
     .y(y) 
     .on("brush", brushmove) 
     .on("brushend", brushend); 

    svg.append("g") 
     .attr("class", "brush") 
     .call(brush) 
     .selectAll('rect') 
     .attr('height', height); 

    function brushmove() { 
     var extent = brush.extent(); 
     points.classed("selected", function(d) { 
     return extent[0][0] <= d[0] && d[0] <= extent[1][0] 
       && extent[0][1] <= d[1] && d[1] <= extent[1][1]; 
     }); 
    } 

    function brushend() { 
     x.domain(brush.extent()); 
     y.domain(brush.extent()); 

     transition_data(); 
     reset_axis(); 

     points.classed("selected", false); 
     d3.select(".brush").call(brush.clear()); 
    } 

    function transition_data() { 
     console.log("transistion data called"); 
     d3.selectAll("point") 
     .transition() 
     .duration(500) 
     .attr("cx", function(d) { console.log(d[0]); return x(d[0]); }) 
     .attr("cy", function(d) { return y(d[1]); }); 
    } 

    function reset_axis() { 
     svg.transition().duration(500) 
     .select(".x.axis") 
     .call(xAxis); 

     svg.transition().duration(500) 
     .select(".y.axis") 
     .call(yAxis); 
    } 
} 

// Wait until the document is loaded, then draw the graph. 
$(document).ready(function() { 
    drawGraph(); 
}); 

// If the window is resized, redraw graph to make it fit again. 
$(window).resize(function() { 
    if(typeof svg != 'undefined'){ 
     $("#scatterplot").empty(); 
    } 
    drawGraph(); 
}); 
+0

Вы принимаете сообщения об ошибке? –

+0

Нет, моя консоль не показывает никаких ошибок или предупреждений – Gooey

ответ

4

Есть две ошибки в коде:

  1. В функции brushend() вы настраиваете домены ваших чешуек с помощью возвращаемого значения brush.extent() в обоих случаях. Обратите внимание, однако, что объем, возвращаемый вашей кистью, представляет собой двумерный массив, такой как [[xMin,yMin],[xMax,yMax]]. Вы должны установить свои домены, используя

    var extent = brush.extent(); 
    x.domain([extent[0][0],extent[1][0]]); // x.domain([xMin,xMax]) 
    y.domain([extent[0][1],extent[1][1]]); // y.domain([yMin,yMax]) 
    

    Эти регулировки будут иметь правильную шкалу, если точки все еще фиксированы.

  2. Вы вводите и обрабатываете свои точки данных с помощью d3.selectAll("point"), который относится к ним как типа svg:point. Однако такого типа элемента svg нет. Хотя ваш вызов d3.selectAll("point") по-прежнему действителен, он всегда будет давать пустой выбор, потому что нет элемента для выбора. По этой причине ваш первый вызов функции при настройке svg действительно работает, поскольку он поместит все данные, связанные с выбором ввода, дающим желаемый результат. Ради справедливости вы должны исправить это

    // plot all points 
    var points = svg.append("g") 
        .attr("class", "point") 
        // .selectAll("point") 
        .selectAll("circle") // <-- This will work 
        .data(dataset) 
        .enter() 
        .append("circle"); 
    

    При попытке обновить точки после того, как установить домены Шкалы неисправный код не будет работать, потому что в этом случае пустой выбор не имеет смысла и не будет иметь никакого эффекта на любой элемент. Поскольку в приведенной выше цитате вы уже сохранили ссылку на ваш выбор в var points, нет необходимости выбирать их снова. Вы можете просто переписать обновление следующим образом:

    function transition_data() { 
        // d3.selectAll("point") // Instead of this... 
        points      // <-- ...use the reference to your selection 
         .transition() 
         .duration(500) 
         .attr("cx", function(d) { return x(d[0]); }) 
         .attr("cy", function(d) { return y(d[1]); }); 
    } 
    

я собрал рабочий JSFiddle, чтобы продемонстрировать решение.

+0

Ого, я не знал, что степень 2d-массива. Большое спасибо за ваше объяснение, это стало ясно. – Gooey

Смежные вопросы