如何使用JSON响应来更新d3.js甜甜圈值

我只是从javascript和d3.js v3开始。我制作了一个甜甜圈图,希望它使用来自Google API的JSON数据。 应该使用JSON响应中的“得分”数据更新HTML中的data-value属性。

我知道可以使用d3.json(url,callback);提取JSON数据,但是我不确定如何正确设置它。

以及如何更改代码,以便在初始化图表之前更新data-value

HTML:

<div class="ui">
      <ul class="ui__downloadList">
        <li class="ui__downloadList__item red" id="red" data-value=25 data-type=performance>
          <div class="ui__downloadList__graphic" width=154 height=160></div>
          <h2 class="ui__downloadList__headline">Performance</h2>
          <h3 class="ui__downloadList__subHeadline">120 Files</h3>
        <li class="ui__downloadList__item purple" id="purple" data-value=50 data-type=accessibility>
          <div class="ui__downloadList__graphic" width=154 height=160></div>
          <h2 class="ui__downloadList__headline">accessibility</h2>
          <h3 class="ui__downloadList__subHeadline">65 Files</h3>
        <li class="ui__downloadList__item cyan" id="cyan" data-value=75 data-type=best-practices>
          <div class="ui__downloadList__graphic" width=154 height=160></div>
          <h2 class="ui__downloadList__headline">Best-Practices</h2>
          <h3 class="ui__downloadList__subHeadline">98 Files</h3>
      </ul>
</div>

API的JSON示例:

{"lighthouseResult":{"categories":{"performance":{"score":1.0},"accessibility":{"score":0.9},"best-practices":{"score":0.92}}}}

Javascript:

;( function( d3 ) {
  /**
   * Function to kick of all fancy download circles
   */
  function visualizeDownloadCircles ( selector ) {

    var d3items    = d3.selectAll( selector ),d3graphics = d3items.select( '.ui__downloadList__graphic' ),svgElements;

    // remove old svg for the case there was one
    d3graphics.select( 'svg' ).remove();

    d3items.each( function( svg,index ) { 
      var d3item = d3.select( this );

      index++;

      drawDownloadCircle( d3item,index );
    } );
  }

  /**
   * Function to draw one particular 
   * download circle
   */
  function drawDownloadCircle( d3item,index ) {
    var d3container = d3item.select( '.ui__downloadList__graphic' ),value       = d3item.attr( 'data-value' ),type        = d3item.attr( 'data-type' ),width       = d3container.attr( 'width' ),height      = d3container.attr( 'height' ),// circle stuff
        twoPi  = 2 * Math.PI,radius = Math.min( width,height ) / 2 - 5,arcBackground = d3.svg.arc()
                          .startAngle( 0 )
                          .endAngle( function( d ) { return d.value * twoPi; } )
                          .outerRadius( radius - 10 )
                          .innerRadius( radius - 35 ),arcForeground = d3.svg.arc()
                          .startAngle( 0 )
                          .endAngle( function( d ) { return d.value * twoPi; } )
                          .outerRadius( radius )
                          .innerRadius( radius - 27 ),// value stuff
        currentvalue = 0,progress     = 0,// animation stuff,duration = 3000;

    // string to number
    value = +value;

    // append new svg
    var svg = d3container.append( 'svg' )
                          .attr( 'width',width )
                          .attr( 'height',height )
                          .append( 'g' )
                          .attr(
                            'transform','translate(' + width / 2 + ',' + height / 2 + ')'
                          );

    // filter stuff
    /* For the drop shadow filter... */
    var defs = svg.append( 'defs' );

    var filter = defs.append( 'filter' )
                      .attr( 'id','dropshadow' )

    filter.append( 'feGaussianBlur' )
          .attr( 'in','SourceAlpha' )
          .attr( 'stdDeviation',2 )
          .attr( 'result','blur' );
    filter.append( 'feOffset' )
          .attr( 'in','blur' )
          .attr( 'dx',2 )
          .attr( 'dy',3 )
          .attr( 'result','offsetBlur' );

    var feMerge = filter.append( 'feMerge' );

    feMerge.append( 'feMergeNode' )
            .attr( 'in","offsetBlur' )
    feMerge.append( 'feMergeNode' )
            .attr( 'in','SourceGraphic' );
    // end filter stuff

    // gradient stuff    
    var gradientBackgroundRed = defs.append( 'linearGradient' )
                                    .attr( 'id','gradientBackgroundRed' )
                                    .attr( 'x1','0' )
                                    .attr( 'x2','0' )
                                    .attr( 'y1','0' )
                                    .attr( 'y2','1' );
    gradientBackgroundRed.append( 'stop' )
                        .attr( 'class','redBackgroundStop1' )
                        .attr( 'offset','0%' );

    gradientBackgroundRed.append( 'stop' )
                        .attr( 'class','redBackgroundStop2' )
                        .attr( 'offset','100%' ); 

    var gradientBackgroundPurple = defs.append( 'linearGradient' )
                                      .attr( 'id','gradientBackgroundPurple' )
                                      .attr( 'x1','0' )
                                      .attr( 'x2','0' )
                                      .attr( 'y1','0' )
                                      .attr( 'y2','1' );

    gradientBackgroundPurple.append( 'stop' )
                            .attr( 'class','purpleBackgroundStop1' )
                            .attr( 'offset','0%' );

    gradientBackgroundPurple.append( 'stop' )
                            .attr( 'class','purpleBackgroundStop2' )
                            .attr( 'offset','100%' ); 

    var gradientBackgroundCyan = defs.append( 'linearGradient' )
                                    .attr( 'id','gradientBackgroundCyan' )
                                    .attr( 'x1','1' );

    gradientBackgroundCyan.append( 'stop' )
                          .attr( 'class','cyanBackgroundStop1' )
                          .attr( 'offset','0%' );

    gradientBackgroundCyan.append( 'stop' )
                          .attr( 'class','cyanBackgroundStop2' )
                          .attr( 'offset','100%' );     

    var gradientForegroundRed = defs.append( 'linearGradient' )
                                    .attr( 'id','gradientForegroundRed' )
                                    .attr( 'x1','1' );
    gradientForegroundRed.append( 'stop' )
                        .attr( 'class','redForegroundStop1' )
                        .attr( 'offset','0%' );

    gradientForegroundRed.append( 'stop' )
                        .attr( 'class','redForegroundStop2' )
                        .attr( 'offset','100%' ); 

    var gradientForegroundPurple = defs.append( 'linearGradient' )
                                        .attr( 'id','gradientForegroundPurple' )
                                        .attr( 'x1','0' )
                                        .attr( 'x2','0' )
                                        .attr( 'y1','0' )
                                        .attr( 'y2','1' );

    gradientForegroundPurple.append( 'stop' )
                .attr( 'class','purpleForegroundStop1' )
                .attr( 'offset','0%' );

    gradientForegroundPurple.append( 'stop' )
                .attr( 'class','purpleForegroundStop2' )
                .attr( 'offset','100%' ); 

    var gradientForegroundCyan = defs.append( 'linearGradient' )
                            .attr( 'id','gradientForegroundCyan' )
                            .attr( 'x1','0' )
                            .attr( 'x2','0' )
                            .attr( 'y1','0' )
                            .attr( 'y2','1' );

    gradientForegroundCyan.append( 'stop' )
                .attr( 'class','cyanForegroundStop1' )
                .attr( 'offset','0%' );

    gradientForegroundCyan.append( 'stop' )
                .attr( 'class','cyanForegroundStop2' )
                .attr( 'offset','100%' );     
    // end gradient stuff



    var meter = svg.append( 'g' )
                    .attr( 'class','progress-meter' );

    meter.append( 'title' )
          .text( 'Progress meter showing amount of space used for ' + type );

    meter.data(
            [
              { value : .0,index : .5 }
            ]
          )
          .append( 'path' )
          .attr( 'class','ui__downloadList__backgroundCircle' )
          .attr( 'd',arcBackground )
          .attr( 'filter','url(#dropshadow)' )
          .transition()
          .duration( duration )
          .attrTween( 'd',tweenArcBackground( { value : 1 } ) );


    var foreground = meter.data(
                            [
                              { value : .0,index: .5 }
                            ]
                          )
                          .append( 'path' )
                          .attr( 'stroke','#fff' )
                          .attr( 'class','ui__downloadList__foregroundCircle' )
                          .attr( 'd',arcForeground )
                          .attr( 'filter','url(#dropshadow)' )
                          .transition()
                          .attr( 'stroke','#aaa' )
                          .delay( 100 * index )   
                          .duration( duration )
                          .attrTween( 'd',tweenArcForeground({ value : value / 100 } ) );


    meter.data( [ 0 ] )
          .append( 'text' )
          .text ( 0 )
          .attr( 'font-size','25px' )
          .attr( 'x',0 )
          .attr( 'y',0 )
          .attr( 'fill','#fff' )
          .attr( 'text-anchor','middle' )
          .attr( 'filter','url(#dropshadow)' )
          .transition()
          .delay( 100 * index )
          .duration( duration )
          .tween( 'text',tweenText( value ) );

    meter.append( 'text' )
          .attr( 'fill','#fff' )
          .attr( 'x',20 ) 
          .attr( 'text-anchor','url(#dropshadow)' )
          .text( '%' );


    // Helper functions!!!
    function tweenArcForeground( b ) {
      return function( a ) {
        var i = d3.interpolate( a,b );

        return function( t ) {
          return arcForeground( i ( t ) );
        };
      };
    }

    function tweenArcBackground( b ) {
      return function( a ) {
        var i = d3.interpolate( a,b );

        return function( t ) {
          return arcBackground( i ( t ) );
        };
      };
    }

    function tweenText( b ) {
      return function( a ) {
        var i = d3.interpolateRound( a,b );

        return function(t) {
          this.textContent = i(t);
        };
      }
    }
  }

  function kickoff() {
    visualizeDownloadCircles( '.ui__downloadList__item' );
  }

  // yeah,let's kick things off!!!
  kickoff();
} )( d3 );
henghbing 回答:如何使用JSON响应来更新d3.js甜甜圈值

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3159328.html

大家都在问