2013-04-13 6 views
9

Sto lavorando a una visualizzazione in d3. Si tratta di disegnare cerchi su paesi di una mappa e quindi ridimensionare le dimensioni dei cerchi in modo che corrispondano ai dati relativi a tali paesi. Voglio cambiare l'opacità mentre il raggio dei cerchi diventa più grande, ma il codice che ho non funziona, nonostante molti esperimenti e modifiche. Qualcuno può far notare cosa mi manca qui?Come posso modificare il raggio e l'opacità di un cerchio in d3?

Inserirò l'intero codice qui sotto, per ogni evenienza. Scorri verso il basso fino alla funzione showJan per vedere cosa ho provato a fare (che non funziona). Molte grazie in anticipo.

<div id="viz"> 
</div> 


<div id="cal"> 
</div> 
<a href='#' class='jan'>January</a> 
<a href='#' class='feb'>February</a> 
<a href='#' class='mar'>March</a> 
<a href='#' class='apr'>April</a> 
<a href='#' class='may'>May</a> 
<a href='#' class='june'>June</a> 
<a href='#' class='july'>July</a> 
<a href='#' class='aug'>August</a> 
<a href='#' class='sept'>September</a> 
<a href='#' class='oct'>October</a> 
<a href='#' class='nov'>November</a> 
<a href='#' class='dec'>December</a> 

<script> 
    var height = 530; 
    var width = 860; 
    var svg = d3.select('#viz').append('svg') 
           .attr('height', height) 
           .attr('width', width) 

    var countriesData = window.countriesData; 
    // This is a big list of all the countries in the world 
    // in a format that d3 likes 

    // The skyscanner flight data. 
    var sizeData = window.skyscanner; 

    // A scale to manage the size of the circles. 
    var rScale = d3.scale.log(); 
    rScale.domain([1, 50000]).range([1, 100]) 

    // A scale to manage the opacity of the circles. 
    var oScale = d3.scale.log(); 
    oScale.domain([1, 50000]).range([.6, 0]) 


</script> 


<script> 
    // Setup a mercator projection 
    // A projection is a bit like a scale except it maps 
    // latitudes and longitudes to pixels 
    // There are a lot of projections: 
    // https://github.com/mbostock/d3/wiki/Geo-Projections 

    var projection = d3.geo.mercator() 
          .scale(880) 
          .translate([410, 340]) 


    // Setup a geo path 
    // A path is a magical path drawer, that can take things 
    // listed in a geo format called geojson (lots of geo data 
    // is formatted like this) and draws those shapes onto your 
    // projection 

    var path = d3.geo.path().projection(projection) 


    // Take our loaded big list of countries and draw it 
    // using our path 
    // 
    // All countries are under a 'countries' group 
    // to make them easier to work with 
    // 
    // The 'path' element is just 
    // a freeform path that joins points to make a shape. 
    // 
    // The 'path' generator that we pass to .attr('d', path) takes 
    // the geo data and draws a path 

    var countries = svg.append('g') // make a group to hold them all 

    countries.selectAll('path') 
       .data(countriesData.features) 
       .enter() 
       .append('path') 
       .attr('d', path) // uses our path to draw the countries 


    function calculateCountryCenter(country) { 
    var coords; 

    //If the country has more than one bounding region (like the usa has 
    //the main usa, alaska and hawaii, use the first one) 
    //Otherwise just use the only list 
    if (country.geometry.coordinates.length > 1) { 

     console.log("length " + country.geometry.coordinates.length); 
     console.log("name " + country.name); 
     console.log("size of first region " + country.geometry.coordinates[0].area); 


     for (index = 0; index < country.geometry.coordinates.length; index++) { 
     console.log(country.geometry.coordinates[index].area) 
     } 

     coords = country.geometry.coordinates[0][0]; 

    } else { 
     coords = country.geometry.coordinates[0]; 
    } 

    var averageCoords = [0,0]; 
    coords.forEach(function(coord) { 
     averageCoords[0] += coord[0] 
     averageCoords[1] += coord[1] 
    }); 


    averageCoords[0] = averageCoords[0]/coords.length 
    averageCoords[1] = averageCoords[1]/coords.length 
    return averageCoords; 
    } 


    var countryCirclesGroup = svg.append('g') // a group to hold our circles 

    // Bind the data to the country circles group. Bind on country id (see json file) 
    var countryCircles = countryCirclesGroup.selectAll('circle') 
         .data(countriesData.features, function(country) 
         { return country.id }) 

    // Enter a circle for each data point, with pos. at x and y coords. 
    countryCircles.enter().append('circle') 
        .attr('r', 0) 
        .attr('cx', function(country) { 
        var center = calculateCountryCenter(country); 
        return projection(center)[0] // return x coord of mapped center 
        }) 
        .attr('cy', function(country) { 
        var center = calculateCountryCenter(country); 
        return projection(center)[1] // return y coord of mapped center 
        }) 
        .style('fill', 'black') 
        .style('opacity', .15) 
        .on('click', function(country) { alert(country.properties.name) }) 


    // Functions for the month buttons. 
    function showJan() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Jan + 1) }) 
       .style('opacity', function(dataPoint) { return oScale(dataPoint.Jan + 1) }) 
    } 

    function showFeb() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Feb + 1) })     
    } 

    function showMar() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Mar + 1) })  
    } 

    function showApr() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Apr + 1) }) 
    }  

    function showMay() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.May + 1) }) 
    } 

    function showJune() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Jun + 1) }) 
    } 

    function showJuly() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Jul + 1) }) 
    }     

    function showAug() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Aug + 1) }) 
    } 

    function showSept() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Sep + 1) }) 
    } 

    function showOct() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Oct + 1) }) 
    } 

    function showNov() { 

     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Nov + 1) }) 
    } 

    function showDec() { 

     // This sets the circles with size data as a certain size and as red. 
     countryCirclesGroup.selectAll('circle') 
      .data(sizeData, function(dataPoint) { return dataPoint.name }) 
       .transition().duration(1000) 
       .attr('r', function(dataPoint) { return rScale(dataPoint.Dec + 1) }) 
    }  

    // A reset function for debugging help. Rewrite to show Jan sizes. 
    function reset() { 
     countryCirclesGroup.selectAll('circle') 
      .data(sizeData) 
      .transition().duration(1000) 
      .attr('r', 0) 
    }      


    d3.select('a.jan').on('click', showJan) 
    d3.select('a.feb').on('click', showFeb) 
    d3.select('a.mar').on('click', showMar) 
    d3.select('a.apr').on('click', showApr) 
    d3.select('a.may').on('click', showMay) 
    d3.select('a.june').on('click', showJune) 
    d3.select('a.july').on('click', showJuly) 
    d3.select('a.aug').on('click', showAug) 
    d3.select('a.sept').on('click', showSept) 
    d3.select('a.oct').on('click', showOct) 
    d3.select('a.nov').on('click', showNov) 
    d3.select('a.dec').on('click', showDec) 

</script> 

<script> 
    //Don't delete this 
    reset(); 
</script> 

risposta

10

Dopo la transition e duration, è necessario aggiornare gli attributi che cambieranno. Esempio di codice:

var svg = d3.select("body").append("svg"); 

svg 
    .attr('id','mySVG') 
    .attr('width', '100%') 
    .attr('height', '100%'); 

// Set the initial properties of the circles 
var circle = svg.selectAll('circle') 
    .data([2, 5, 8]) 
    .enter() 
    .append('circle') 
     .attr('cx', function(item) { return item; }) 
     .attr('cy', function(item) { return item; }) 
     .attr('r', 0) 
     .attr('fill', '#babdb6'); 

// Update the attributes that will change 
circle 
    .transition() 
    .duration(2000) 
     .attr('fill-opacity', 0.2) 
     .attr('r', function(item) { return 100 * item; }); 

Ho scritto un esempio minimo che può aiutarti. http://jsfiddle.net/pnavarrc/udMUx/.

+0

Questo mi ha fatto puntare nella giusta direzione e ho funzionato ora. Grazie mille! – ACPrice

+0

Per favore, segna anche la domanda come risposta. Grazie, –