WedX - журнал о программировании и компьютерных науках

Очистите диаграммы d3.js перед загрузкой новой диаграммы

Я использую d3.js для отображения диаграмм с некоторыми данными датчиков. Когда я выбираю новый датчик и нажимаю «Отправить», я хочу очистить уже существующие графики и отобразить только что выбранный.

Я пробовал варианты d3.select("#vis").selectAll("svg").remove();, и проблема, с которой я столкнулся, заключается в том, что когда я нажимаю «Отправить», он сразу очищает диаграммы и ничего не отображает.

У меня есть файл d3helper, который выполняет все функции d3:

function initD3Chart( chartName, chartId, xAxisType, interpolate, width, height, yLabel ) {

// Size and margins
var m = [30, 60, 40, 20],// Margins
    w = width - m[1] - m[3],
    h = height - m[0] - m[2];
x = d3.time.scale().range([0, w]);
x2 = d3.time.scale().range([0, w]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickSize(-h, 0).tickPadding(6).tickFormat(d3.time.format("%H: &M"));
var xAxis2 = d3.svg.axis().scale(x).orient("bottom").tickSize(-15, 1).tickPadding(-12).ticks(d3.time.day, 1).tickFormat(d3.time.format("%B %d, %Y"));

// An area generator.
var area = d3.svg.area()
    .interpolate(interpolate)
    .defined(function(d) { return (!isNaN(d.v0) && !isNaN(d.v1)); })
    .x(function(d) { return x(d.p); })
    //.x2(function(d) { return x(d.r);})
    .y0(function(d) { return y(d.u1); })
    .y1(function(d) { return y(d.v1); });

// A line generator.
var line = d3.svg.line()
    .interpolate(interpolate)
    .defined(function(d) { return (!isNaN(d.v1)); })
    .x(function(d) { return x(d.p); })
    .y(function(d) { return y(d.v1); });

// Attach root visualization node to div.#vis
var svg = d3.select("#vis")
    .append("svg:svg")
        .attr("class", chartId)
        .attr("width", w + m[1] + m[3])
        .attr("height", h + m[0] + m[2])
    .append("svg:g")
        .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

// Clip overflow
    svg.append("svg:clipPath")
            .attr("id", "clip")
        .append("svg:rect")
            .attr("x", x(0))
            .attr("x2", x2(0))
            .attr("y", y(1))
            .attr("width", x(1) - x(0))
            .attr("height", y(0) - y(1));

// Y Axis
svg.append("svg:g")
    .attr("class", "y axis")
    .attr("transform", "translate(" + w + ",0)");

// X Axis
svg.append("svg:g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + h + ")");

svg.append("svg:g")
    .attr("class", "x axis2")
    .attr("transform", "translate(0," + (h + 30) + ")");

// Chartarea. Where plots will be appended
chart = svg.append("svg:g")
    .attr("class", "chartarea");

// Interaction area
var rect = svg.append("svg:rect")
    .attr("class", "pane")
    .attr("width", w)
    .attr("height", h);

return {
            "id": chartId,
            "svg": svg,
            "chart": chart,
            "rect": rect,
            "x": x,
            "x2": x2,
            "y": y,
            "xAxis": xAxis,
            "xAxis2": xAxis2,
            "yAxis": yAxis,
            "line": line,
            "area": area,
            "w": w,
            "h": h,
            "m": m
        };
    }

У меня есть кнопка отправки, которая при нажатии берет все данные из формы и инициализирует заголовок диаграммы и т. д., а также выполняет соответствующие вызовы AJAX. В моем файле инициализации я вызываю функции d3:

$(document).ready(function(){
    $("#submit").click(function() {
        for(var j = 0, n = sensor.length; j < n; j++)
        {
            var callback = {
                "id": "idGoesHere"
            };

            var chart = drawDataView ( callback );

            callback.dataLoaded = function(chart) {
                return function( total, remaining ) {
                    chart.redraw();
                };  
            }(chart);
        }
        //When selecting a new sensor remove the previous sensor from the array or it draws an additional graph
        sensor.length = 0;

        d3.select("#vis").selectAll("svg").remove();
    });         
}); 


function drawDataView(callback){    
    var vis = initD3Chart( demo['name'], demo['id'], demo['xAxis'], demo['interpolate'], width, height, yLabel );
    vis['x'].domain([timeToDate(displayRange.lower), timeToDate(displayRange.upper)]);
    vis['x2'].domain([timeToDate(displayRange.lower), timeToDate(displayRange.upper)]);
    vis['y'].domain( demo['yDomain'] ); // Default, will be set when first data loaded
    vis['rect'].call(d3.behavior.zoom().x(vis['x']).on("zoom", update));
    vis['rect'].call(d3.behavior.zoom().x(vis['x2']).on("zoom", update));
}
function redraw() {    
    // Update Axes
    vis['svg'].select("g.x.axis").call(vis['xAxis']);
    vis['svg'].select("g.x.axis2").call(vis['xAxis2']).selectAll("text").attr("x", 48);
    vis['svg'].select("g.y.axis").call(vis['yAxis']);
}

Есть ли способ сделать оба?

20.04.2015

  • Покажите нам больше кода. Как выглядит ваш код перерисовки? Он воссоздает элемент svg (который вы удаляете) или пытается добавить элемент, которого не существует? 21.04.2015
  • @TysonAnderson: отредактировано с кодом. Извините, я не был уверен, что включить в начале 21.04.2015

Ответы:


1

Вы призываете к удалению после того, как нарисовали новый график. Так что просто переместите некоторые вещи:

$(document).ready(function(){
    $("#submit").click(function() {

        //When selecting a new sensor remove the previous sensor from the array or it draws an additional graph
        sensor.length = 0;

        d3.select("#vis").selectAll("svg").remove();

        for(var j = 0, n = sensor.length; j < n; j++)
        {
            var callback = {
                "id": "idGoesHere"
            };

            var chart = drawDataView ( callback );

            callback.dataLoaded = function(chart) {
                return function( total, remaining ) {
                    chart.redraw();
                };  
            }(chart);
        }

    });         
}); 
21.04.2015
  • Омг я идиот, спасибо! Мне нужно только переместить d3.select("#vis").selectAll("svg").remove(); над циклом for. Перемещение sensor.length=0 очищает массив, прежде чем я могу что-либо нарисовать 21.04.2015
  • Вам, вероятно, следует использовать exit() remove(), если вы все равно повторно используете один и тот же тип диаграммы. 21.04.2015
  • Я просто думал о предотвращении возможных утечек памяти, но когда я попробовал d3.select("#vis").selectAll("svg").exit().remove();, он сказал, что выход не является функцией. Любые идеи, что я делаю неправильно? 22.04.2015
  • Чтобы использовать выход, вам нужен более широкий шаблон. Введите, выйдите, обновите. 22.04.2015
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]