【问题标题】:D3 donut chart function only works the first time it's calledD3 圆环图函数仅在第一次调用时有效
【发布时间】:2018-05-24 20:04:00
【问题描述】:

我创建了一个用 D3 制作圆环图的函数,它在第一次调用时效果很好。但是,随后它被称为 SVG 元素,它附加是空的,并且路径被附加到第一个图表。我是 D3 的新手,所以我很有可能在我的职能中做坏事。控制台中没有错误消息。如果您看到奇怪的东西,请告诉我。谢谢!!

函数如下:

function donutChart (id, data, color) {

var donut = (function(one){ 
    console.log("Hello");
    var width = 400;
    var height = 400;
    var radius = 200;
    var greyColor = '#e8e8e8';
    var dataColor = '#1dafd3';
    var red
    var colors = d3.scaleOrdinal([color, greyColor]);
    var piedata = [{
            name: "one", value: data
        }, {
            name: "two", value: (1 - data)
        }];

    var arc = d3.arc().innerRadius(radius - 50).outerRadius(radius);

    var donutChart = d3.select(id).append('svg')
      .attr('width', width)
      .attr('height', height)
      .append('g')
      .attr('transform', 'translate(' + (width - radius) + ',' + (height - radius) + ')');

    var pie = d3.pie()
      .sort(null)
      .value(function(piedata) { return piedata.value; });

    var arc_g = d3.select('svg g').selectAll('arc').data(pie(piedata)).enter()
        .append('g')
        .attr('class', 'slice');
    console.log()

    arc_g.append('path').attr("d",arc)
    .attr('fill', function(d, range) {
       return colors(range);
  })
  })();
};  

这是函数调用,第一次效果很好,第二次就不行了。

donutChart (songData.audio_features[0].danceability, "#1dafd3"); 
donutChart (songData.audio_features[0].acousticness, "#1dafd3");

【问题讨论】:

    标签: javascript function d3.js charts


    【解决方案1】:

    问题在于,每次调用该函数时,您都会在这一行附加一个新的 SVG 元素:

    var donutChart = d3.select(id).append('svg')
    

    因为这会选择它找到的第一个带有 ID 的元素,并附加一个新的 SVG 元素。

    第二个问题出现在你尝试用这条线追加弧线时

    var arc_g = d3.select('svg g').selectAll('arc')
    

    同样,'select' 只会在 DOM 中找到第一个匹配项,即您的原始 SVG > G 元素,然后选择它可以在那里找到的弧

    第三,.selectAll('arc') 找不到任何东西,因为现有元素要么是“路径”,要么具有类“切片”,因此您需要 selectAll 来匹配其中任何一个。

    解决问题:

    //append the SVG on the first call, with a dummy data, and each subsequent call will use the existing element in the DOM
    var donutChart = d3.select(id).selectAll('svg')
          .data([null])
    
    donutChart = donutChart.enter().append('svg')
          .merge(donutChart)
          .attr('width', width)
          .attr('height', height)
    
    var g = donutChart.append('g')
          .attr('transform', 'translate(' + (width - radius) + ',' + (height - radius) + ')');
    
        var pie = d3.pie()
          .sort(null)
          .value(function(piedata) { return piedata.value; });
    
    //selectAll on class '.slice'
        var arc_g = g.selectAll('.slice')
            .data(pie(piedata))
    
    //create new g and path elements on enter (ie if new), and then update d and color after a merge()
        arc_g = arc_g.enter()
            .append('g')
            .attr('class', 'slice')
            .append('path')
            .merge(arc_g)
            .attr("d",arc)
            .attr('fill', function(d, range) {
               return colors(range);
            })
    

    有关合并的更多信息,请参阅:https://github.com/d3/d3-selection#selection_merge

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多