简体   繁体   中英

d3 transition: update axis and data just once

I would like to update my scatterplot and its axis via radio button as shown in this example: https://bl.ocks.org/mbostock/3903818

my problem: the scatterplot is updating just once, the second call of the function has no effect on markers or axis.

in addition, the axis got updatet after the first call, but there are still markers out of the visible window which is not intendet. I dont know why the axis is not scaling "completely".

Some definitions for the axis:

var xValue_tsne = function(d) { return d.X_tsne;};
var xMap_tsne = function(d) { return xScale(xValue_tsne(d));};
var xValue_pca = function(d) { return d.X_pca;};
var xMap_pca = function(d) { return xScale(xValue_pca(d));};
var xScale = d3.scale.linear().range([0, width]);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom");

var yValue_tsne = function(d) { return d.Y_tsne};
var yMap_tsne = function(d) { return yScale(yValue_tsne(d));};
var yValue_pca = function(d) { return d.Y_pca};
var yMap_pca = function(d) { return yScale(yValue_pca(d));};
var yScale = d3.scale.linear().range([height, 0]);
var yAxis = d3.svg.axis().scale(yScale).orient("left");

My render function:

function render (data) {

function transition(dimension)  {
    if (dimension == "pca") {
        var x = xMap_pca;
        var y = yMap_pca;
    }
    else if (dimension == "tsne") {
        var x = xMap_tsne;
        var y = yMap_tsne;
    }

    console.log(x);
    console.log(y);

    // Update old
    circles.attr("class", "update")
        .transition()
            .duration(0)
            .attr("cx", x)
            .attr("cy", y);

    // Create new
    circles.enter().append("circle")
        .transition()
            .duration(0)
            .attr("cx", x)
            .attr("cy", y);

    //Rescale Domains
    xScale.domain([d3.min(data, xValue_pca)-1, d3.max(data, xValue_pca)+1]);
    yScale.domain([d3.min(data, yValue_pca)-1, d3.max(data, yValue_pca)+1]);

    //Update Axis
    holder.select(".xaxis")
        .transition()
            .duration(0)
        .call(xAxis);  
    holder.select(".yaxis")
        .transition()
            .duration(0)
        .call(yAxis);

}


//Initial scale of ranges
xScale.domain([d3.min(data, xValue_tsne)-1, d3.max(data, xValue_tsne)+1]);
yScale.domain([d3.min(data, yValue_tsne)-1, d3.max(data, yValue_tsne)+1]);



//X Axis
holder.append("g")
  .attr("class", "xaxis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis)
.append("text")
  .attr("x", width)
  .attr("y", -achse_beschriftung)
  .style("text-anchor", "end")
  .text("X");



//Y Axis
holder.append("g")
  .attr("class", "yaxis")
  .call(yAxis)
.append("text")
  .attr("transform", "rotate(-90)")
  .attr("y", achse_beschriftung)
  .attr("dy", 8)
  .style("text-anchor", "end")
  .text("Y");



//draw dots
var circles = holder.selectAll("dot")
  .data(data);



// Create initial elements
circles.enter().append("circle")
  .attr("class", "dot")
  .attr("r", rMin)
  .attr("cx", xMap_tsne)
  .attr("cy", yMap_tsne)
  .style("fill", "#660066");


// EXIT
circles.exit()
    .attr("class", "exit")
    .transition()
        .duration(0)
            .remove();


//Event Handler für Radiobox
d3.select("#pca").on("change", function() {
    transition(document.getElementById("pca").value);
});



//Event Handler für Radiobox
d3.select("#tsne").on("change", function() {
    transition(document.getElementById("tsne").value);
});

}

I could solve the two problems:

Just deleted the "Create new" part of my transition-function and split the rescaling of the domain inside the the two if-statements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM