在加载新图表之前清除d3.js图表

时间:2015-04-20 21:05:37

标签: svg d3.js charts

我正在使用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调用。 在我的init文件中,我调用了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']);
}

有两种方法可以做到吗?

1 个答案:

答案 0 :(得分:2)

您在绘制新图表后要求删除。所以只需移动一些东西:

$(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);
        }

    });         
});