Amchart v4 嵌套饼图中的框是否可以有不同的颜色?

Is it possible to have different color for box in nested pie with Amchart v4?

我使用嵌套饼图来显示分层数据,我希望能够按框显示特定颜色

例如这里: 假设我只想将此框的颜色从黄色更改为灰色。

你可以在这里测试它:https://jsfiddle.net/aliz/gwz7om9e/

javascript代码:

(function(){
    /*
    Define all colors used.
  */
    var colorSet = new am4core.ColorSet();
    colorSet.list = ["#18dc08", "#e2ed0c", "#3be791", "#0eade6", "#8f55e9", "#dd0a4b"].map(function(color) {
        return new am4core.color(color);
  });

  var size = 16.6;

  /*
    Creates a pie slice
  */
  function createPie(chart, targetAttribute, positionRadiusInPie){
    var pieSeries = chart.series.push(new am4charts.PieSeries());
    pieSeries.dataFields.value = "size"; // the percentage size so all slice are equals
    pieSeries.dataFields.category = "name";
    pieSeries.slices.template.strokeWidth = 1;
    pieSeries.slices.template.strokeOpacity = 1;
    pieSeries.alignLabels = false;
    pieSeries.ticks.template.disabled = true;
    // Enable label
    pieSeries.labels.template.text = "{"+ targetAttribute +".length}";
    pieSeries.labels.template.radius = am4core.percent(positionRadiusInPie); // magic number
    // color
    pieSeries.colors = colorSet;
    pieSeries.labels.template.fill = am4core.color("white");
    pieSeries.slices.template.stroke = am4core.color("#fff");
    // Disable sliding out of slices
    //pieSeries.slices.template.states.getKey("hover").properties.shiftRadius = 0;
    //pieSeries.slices.template.states.getKey("hover").properties.scale = 1.1;
    // Tooltip conf
    // https://www.amcharts.com/docs/v4/reference/pieseries/#Events
    pieSeries.slices.template.events.on("over", function(ev){
        // https://www.amcharts.com/docs/v4/tutorials/tooltips-with-rich-html-content/
        var modalContent = [
        '<center><strong>'+ev.target.dataItem.dataContext.name+'</strong></center>',
        '<center><i>'+targetAttribute+'</i></center>',
                '<hr />',
      ].join("");

        if(!ev.target.dataItem.dataContext[targetAttribute] || 
            ev.target.dataItem.dataContext[targetAttribute].length == 0){
        modalContent += [
            '<span>No information</span>'
        ].join("");
      }else{
        modalContent += [
            '<table>',
            '<tbody>'
        ].join("");

        for(var i = 0; i < ev.target.dataItem.dataContext[targetAttribute].length; i++){
            var item = ev.target.dataItem.dataContext[targetAttribute][i];
          modalContent += [
                '<tr>',
                '<th align="left">Name</th>',
                '<td align="right">'+item.name+'</td>',
              '</tr>',
          ].join("");
        }

        modalContent += [
              '</tbody>',
            '</table>',
          '<hr />'
        ].join("");
      }
        pieSeries.slices.template.tooltipHTML = modalContent;
    }, this);

    // https://www.amcharts.com/docs/v4/reference/columnseries/#Events
    pieSeries.slices.template.events.on("inited", function(ev) {
      if(!ev.target.dataItem.dataContext[targetAttribute] || ev.target.dataItem.dataContext[targetAttribute].length == 0){
        ev.target.fillOpacity = 0.5;
      }
    }, this);
  }

  // Themes begin
  am4core.useTheme(am4themes_animated);
  // Themes end

  // Create chart instance
  var chart = am4core.create("chartdiv", am4charts.PieChart);

  // Let's cut a hole in our Pie chart the size of 20% the radius
  chart.innerRadius = am4core.percent(20);
  chart.pullOutRadius = 0;

  // Add data: can be fetched from a webservice
  chart.data = [
  {
    "name": "Sector1",
    "color": colorSet.list[0].hex,
    "size": size,
    "category1": [
      {
        name: "test 1"
      },
      {
        name: "titi"
      }
    ],
    "category2": [
      //{
  //        name: "test 1"
  //    }
    ],
    "category3" : [
      //{
      //    name: "test 1"
      //}
    ],
    "category4" : [
      {
        name: "test 1"
      }
    ]
  }, 
  {
    "name": "Sector2",
    "color": colorSet.list[1].hex,
    "size": size,
    "category1":  [
      {
        name: "test 1"
      }
    ],
    "category2": [
      {
        name: "test 1"
      }
    ],
    "category3" : [
      {
        name: "test 1"
      }
    ],
    "category4" : [
      {
        name: "test 1"
      }
    ]
  },
  {
    "name": "Sector3",
    "color": colorSet.list[2].hex,
    "size": size,
   "category1":  [
      {
        name: "test 1"
      }
    ],
    "category2": [
      //{
      //    name: "test 1"
      //}
    ],
    "category3" : [
      {
        name: "test 1"
      }
    ],
    "category4" : [
      {
        name: "test 1"
      }
    ]
  }, 
  {
    "name": "Sector4",
    "color": colorSet.list[3].hex,
    "size": size,
    "category1":  [
      {
        name: "test 1"
      }
    ],
    "category2": [
      {
        name: "test 1"
      }
    ],
    "category3" : [
      {
        name: "test 1"
      }
    ],
    "category4" : [
      {
        name: "test 1"
      }
    ]
  }, 
  {
    "name": "Sector5",
    "color": colorSet.list[4].hex,
    "size": size,
     "category1":  [
      {
        name: "test 1"
      }
    ],
    "category2": [
      {
        name: "test 1"
      }
    ],
    "category3" : [
      {
        name: "test 1"
      }
    ],
    "category4" : [
      {
        name: "test 1"
      }
    ]
  }, 
  {
    "name": "Sector6",
    "color": colorSet.list[5].hex,
    "size": size,
    "category2": [
      {
        name: "test 1"
      }
    ],
    "category1": [
      {
        name: "test 1"
      }
    ],

    "category3" : [
      {
        name: "test 1"
      }
    ],
    "category4" : [
      {
        name: "test 1"
      }
    ]
  }
  ];

  /*
    category1
  */
  createPie(chart, "category1", -28);

  /*
    category2
  */
  createPie(chart, "category2", -20);

  /*
    category3
  */
  createPie(chart, "category3", -10);

  /*
    Business ops
  */
 createPie(chart, "category4", -8);

  /*
    Legend builder
    // https://www.amcharts.com/docs/v4/reference/ipiechartevents/
  */
  chart.events.on('inited', function(event) {
  // populate our custom legend when chart renders
    chart.customLegend = document.getElementById('legend');
    // https://www.amcharts.com/docs/v4/tutorials/truncating-legend-labels/
    //chart.customLegend.labels.template.truncate = true;
    for (var i in chart.data) {
      var row = chart.data[i];
      var color = chart.data[i].color;
      var name = row.name;
      chart.customLegend.innerHTML += 
      [
        '<div class="legend-item" id="legend-item-' + i + '" style="color: ' + color + ';">',
          '<div class="legend-marker" style="background: ' + color + '"></div>',
          name,
        '</div>'
      ].join("");
    }
  });

})()

我找到了这个例子:https://codepen.io/team/amcharts/pen/PQrvJr 你可以看到 "netherland" 在两个级别之间有不同的颜色,但是 javascript 代码中没有任何具体...

你知道这是否可能吗?

I found this example: https://codepen.io/team/amcharts/pen/PQrvJr where you can see that the "netherland" has a different color between the 2 levels, but there is nothing specific in the javascript code...

发生这种情况的原因是:

pieSeries.colors.step = 2;

step property of a ColorSet 使其跳过其列表中的颜色(在本例中为自动生成)。如果您将外部系列的每第二种颜色与内部系列进行比较,您会发现它们是一致的。

至于为特定切片着色,有不同的方法。

现在这就是 Pie 系列获得颜色的方式:

// Earlier in code
var colorSet = new am4core.ColorSet();
colorSet.list = ["#18dc08", "#e2ed0c", "#3be791", "#0eade6", "#8f55e9", "#dd0a4b"].map(function(color) {
    return new am4core.color(color);
});

// createPie() ...
pieSeries.colors = colorSet;

如果您确切知道要更改哪个系列中的哪个片段,您可以提供一个新的 ColorSet,其列表相似但针对该片段进行了调整,例如:

if (chart.series.length === 3) {
    var distinctColors = new am4core.ColorSet();
  distinctColors.list = colorSet.list.map(function(color, index) {
    if (index === 1) {
      return am4core.color("gray");
    }
    return color;
  });
  pieSeries.colors = distinctColors;
} else {
  pieSeries.colors = colorSet;
}

不过,理想情况下,您会使用 an adapter,因此每当要应用 fill 时,您都可以提供逻辑来确定要提供的颜色,例如将 Sector1 着色:将 categor3 着色为黑色(不过,由于代码中的其他内容,它是半不透明的):

pieSeries.slices.template.adapter.add("fill", function(fill, target) {
  if (target.dataItem.dataContext && target.dataItem.dataContext.name === "Sector1" &&  targetAttribute === "category3") {
    return am4core.color("black");
  }
  return fill;
});

这是一个演示(我还用 tooltipHTML 的适配器替换了您的 "over" 事件代码):

https://jsfiddle.net/notacouch/v26zdncy/