web-dev-qa-db-fra.com

Comment mettre à jour l'axe à l'aide de d3.js

J'essaie d'afficher différentes données sur un graphique. L'utilisateur peut modifier les données affichées en cliquant sur un bouton radio. J'utilise un "graphique à bulles" pour rendre les données.

Pour chaque type de données, je dois mettre à jour le Yaxis (le domaine est différent). Voici ce que j'ai fait pour l'instant:

Initialisation du graphique

var svg = d3.select("body .main-content").append("svg")
    .attr("class", "chart")
    .attr("width", width)
    .attr("height", height);

Initialiser l'axe

initAxis();
function initAxis()
{
    var y = d3.scale.linear().domain([0,1000]).range([height-margin, margin]).Nice(),
        x = d3.scale.linear().domain([0,23]).range([margin,width-margin]),
        yAxis = d3.svg.axis().scale(y).orient("left"),
        xAxis = d3.svg.axis().scale(x).orient("bottom");

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

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + (height - margin) + ")")
        .call(xAxis);
}

Mettre à jour le graphique

    function update(type)
    {
        // Get the data
        type = type || 'default';
        var m = max[type],
            mi = min[type]+0.1,
            data = dataset[type],
            step = stp[type];

        // Set the functions
        var y = d3.scale.linear().domain([mi,m]).range([height-margin, margin]).Nice();
        var o = d3.scale.linear().domain([0,m]).range([.5,1]);
        var r = d3.scale.linear().domain([0,Math.sqrt(m)]).range([0,30]);
        var x = d3.scale.linear().domain([0,23]).range([margin,width-margin]);
        var color = function (a, b) {
            for (var c = (a - 0) / (m - 0), d = [], e = 0; 3 > e; e++) d.Push(Math.round(K[0][e] +
                    c * (K[1][e] - K[0][e])));
            d.Push(b || 0.7);
            return "rgba(" + d.join(",") + ")"
        }

        //Attach the data to the graph
        var circle = svg.selectAll("circle").data(data);

        // Update existing element
        circle.attr("class", "update");

        // Add new element
        circle.enter()
            .append("circle")
            .attr("class", "enter")
            .attr("stroke-width", 0)
            .attr("stroke", "black")
                .transition()
                .duration(750)
                .attr("y", 0)
                .style("fill-opacity", 1);

        // Apply attribute to new and updated element
        circle.attr("cx", function(d,i) {return x(d.h);})
            .attr("cy", function(d,i) {return y(d.v);})
            .attr("r", function(d,i) {return r(Math.sqrt(d.v));})
            .style("fill", function(d,i) {return color(d.v);})
            .style("opacity", function(d,i) {return o(d.v);})
            .on("click", function(d,i){window.open(d.name,'_blank');})
            .on("mouseover", function(d,i){d3.select(this).style("fill", "red").attr("stroke-width", 1);})
            .on("mouseout", function(d,i){d3.select(this).style("fill", function(d,i) {return color(d.v);}).attr("stroke-width", 0);})
            .append("title")
            .text(function(d) { return d.v+' '+ d.t+' (adjusted) - '+ d.d })
                .transition()
                .duration(750)
                .attr("y", 0)
                .style("fill-opacity", 1);

        // Remove old elements
        circle.exit()
            .attr("class", "exit")
            .transition(750)
            .ease("linear")
            .attr("cy", 0)
            .style("opacity", 0.2)
            .remove();

        // Update the Axis
        var xAxis = d3.svg.axis().scale(x).orient("bottom");
        var yAxis = d3.svg.axis().scale(y).orient("left");

        svg.selectAll("g .y.axis")
            .call(yAxis)

        svg.selectAll("g .x.axis")
            .call(xAxis);
    }

Les cercles sont mis à jour correctement (les transitions ne fonctionnent pas) mais les axes ne changent pas et je ne vois pas pourquoi. Je suis un peu perdu, j'ai regardé beaucoup d'exemples mais je ne vois pas ce que je fais mal.

J'utilise la version d3.js: v3.1.10

Maxime

47
maxwell2022

Il semble que vous utilisez le mauvais sélecteur lors de la mise à jour des axes:

   svg.selectAll("g .y.axis")
        .call(yAxis);

   svg.selectAll("g .x.axis")
        .call(xAxis);

devrait peut-être lire:

   svg.selectAll("g.y.axis")
        .call(yAxis);

   svg.selectAll("g.x.axis")
        .call(xAxis);
49
musically_ut

Pourquoi utilisez-vous "g .y.axis"?

Essayer:

svg.select(".y.axis")
    .call(yAxis);

Et similaire pour l'axe x.

12
Anto Jurković