2015-11-21 2 views
1

Я хотел бы визуализировать круг со случайным цветом при случайной координате x и y, а затем добавить дополнительную красочную круг в случайном месте каждую секунду.Как связать изменяющийся источник данных с набором svg?

Я использую d3.timer для запуска функции, которая добавляет координаты x и y к моему объекту dataset, который привязан ко всем объектам circle. Когда я печатаю объект dataset, я вижу, что моя функция фактически добавляет новые координаты x и y к моему объекту dataset. Однако визуализация не обновляется новыми кругами. Как я могу добавить новый круг каждую секунду?

Соответствующие функции ниже:

var reshuffleData = function(){ 
    for (var i=0; i<5; i++){ 
    console.log('Reshuffling') 
    dataset.push({x: randomXPosition(), y: randomYPosition()}) 
    } 
    console.log(dataset) 
    return true 
    } 

    d3.timer(reshuffleData, 10); 

Полный jsfiddle здесь: http://jsfiddle.net/d74Le5xk/

ответ

3

Это не не работает, потому что d3.timer используется неправильно. Поскольку d3.timer просто берет функцию для рисования следующего кадра анимации. Мы не будем контролировать, когда будет вызываться эта функция, но она будет называться наиболее вероятной (1/кадров в секунду). Где FPS может меняться каждую секунду.

Если вы хотите что-то делать, используйте setInterval, также вам нужно перерисовать круги после изменения размера набора данных.

Ниже приведена ссылка jsfiddle для рабочего кода.

http://jsfiddle.net/d74Le5xk/3/

прикрепление Также код здесь для справки.

HTML

<svg class='canvas'></svg> 

Javascript

(function() { 

    var width = 420, height = 200; 

    var randomXPosition = function(d){ 
    return Math.random() * width; 
    } 
    var randomYPosition = function(d){ 
    return Math.random() * height; 
    } 

    var dataset = []; 
    var circleBatchSize = 5; 
    var maxCircleCount = 100; 

    for (var i=0; i < circleBatchSize; i++){ 
    dataset.push({x: randomXPosition(), y: randomYPosition()}) 
    } 

    var testInterval = null; 
    var reshuffleData = function(){ 
    for (var i=0; i<circleBatchSize; i++){ 

     dataset.push({x: randomXPosition(), y: randomYPosition()}) 
     //return true; 
    } 
    console.log('Reshuffled ' + dataset.length) 
    console.log(dataset) 

    if(dataset.length > maxCircleCount) { 
     clearInterval(testInterval); 
    } 
    } 

    console.log(dataset); 

    var colours = ['#FDBB30', '#EE3124', '#EC008C', '#F47521', '#7AC143', '#00B0DD']; 
    var randomColour = function() { 
    return colours[Math.floor(Math.random() * colours.length)]; 
    } 
    //d3.timer(reshuffleData, 0, 5000); 
    testInterval = window.setInterval(reshuffleData, 2000); 

    var canvas = d3.select('.canvas') 
     .attr('width', width) 
     .attr('height', height) 
     .style('background-color', 'black'); 

    var datasetOldLength = 0; 
    function drawCircles() { 
    if(datasetOldLength === dataset.length) { 
     return; 
    } 
    datasetOldLength = dataset.length; 
    var circles = canvas.selectAll('circle') 
     .data(dataset) 
     .enter() 
     .append('circle') 
     .style('r', 20) 
     .style('fill', randomColour) 
     .style('cx', function(d) { return d.x}) 
     .style('cy', function(d) { return d.y}); 

    if(dataset.length > maxCircleCount) { 
     return true; 
    } 
    } 

    d3.timer(drawCircles, 1000); 
})(); 

d3.timer использование объяснение

# d3.timer(function[, delay[, time]]) 

[function] аргумент вызывается при каждом рендеринге кадра с помощью d3. Он вызывается до тех пор, пока он не вернет true.

опционально [задержка] в миллисекундах для задержки первого вызова [функции]. Задержка берется, поскольку [время] передано третьим аргументом. Если время [time] не передается, начинается с новой Date(). GetTime().

опционально [время] - это эпоха, когда считается, что задержка считается.

Код ссылки https://github.com/mbostock/d3/wiki/Transitions#timers

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