te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How can I change the radius and opacity of a circle in d3? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How can I change the radius and opacity of a circle in d3? - Stack Overflow

programmeradmin3浏览0评论

I'm working on a visualization in d3. It involves drawing circles over countries a map and then scaling the sizes of the circles to correspond with data about those countries. I want to change the opacity as the radius of the circles gets larger, but the code I have isn't working, despite lots of experimentation and tweaking. Can someone point out what I'm missing here?

I'll post the entire code below, just in case. Scroll down to the showJan function to see what I've tried to do (which isn't working). Many thanks in advance.

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

  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>

I'm working on a visualization in d3. It involves drawing circles over countries a map and then scaling the sizes of the circles to correspond with data about those countries. I want to change the opacity as the radius of the circles gets larger, but the code I have isn't working, despite lots of experimentation and tweaking. Can someone point out what I'm missing here?

I'll post the entire code below, just in case. Scroll down to the showJan function to see what I've tried to do (which isn't working). Many thanks in advance.

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

Share Improve this question asked Apr 13, 2013 at 13:44 ACPriceACPrice 6772 gold badges11 silver badges25 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 11

After the transition and duration, you must update the attributes that will change. A code sample:

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

I wrote a minimal example that can help you. http://jsfiddle/pnavarrc/udMUx/.

发布评论

评论列表(0)

  1. 暂无评论