2013-04-13 55 views
9

Tôi đang làm việc trên trực quan hóa trong d3. Nó bao gồm việc vẽ vòng tròn trên các quốc gia một bản đồ và sau đó mở rộng quy mô của các vòng tròn để tương ứng với dữ liệu về các quốc gia đó. Tôi muốn thay đổi độ mờ khi bán kính của các vòng tròn lớn hơn, nhưng mã tôi không hoạt động, mặc dù có nhiều thử nghiệm và tinh chỉnh. Ai đó có thể chỉ ra những gì tôi đang thiếu ở đây?Làm cách nào để thay đổi bán kính và độ mờ của một vòng tròn trong d3?

Tôi sẽ đăng toàn bộ mã bên dưới, chỉ trong trường hợp. Cuộn xuống hàm showJan để xem những gì tôi đã cố gắng thực hiện (không hoạt động). Rất cám ơn trước.

<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> 

Trả lời

10

Sau transitionduration, bạn phải cập nhật các thuộc tính đó sẽ thay đổi. Mẫu mã:

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

Tôi đã viết một ví dụ tối thiểu có thể giúp bạn. http://jsfiddle.net/pnavarrc/udMUx/.

+0

Điều này đã cho tôi chỉ đúng hướng và tôi đã có nó hoạt động ngay bây giờ. Cảm ơn rất nhiều! – ACPrice

+0

Vui lòng đánh dấu câu hỏi là đã trả lời. Cảm ơn, –

Các vấn đề liên quan