AMCharts Maps v4 - 有没有办法在 heatLegend 中拥有两种以上的颜色?

Wes*_*oel 5 amcharts ammap

认为能够为热图设置一系列颜色而不是两个(最小和最大)会很好。就像我们为渐变列表所做的那样。

就像是...

function am4themes_myHeatmap(target) {
  if (target instanceof am4core.ColorSet) {
    target.list = [
      am4core.color("#F7E3D4"),
      am4core.color("#FFC480"),
      am4core.color("#DC60BF"),
      am4core.color("#A43B7D"),
      am4core.color("#5B0A25")
    ];
  }
}
Run Code Online (Sandbox Code Playgroud)

请参阅模型中的示例

如果这样的东西已经存在,我很乐意看到它。

not*_*uch 8

像这样的东西不存在。

不幸的是有没有一个简单的方法,只是使用heatRulesHeatLegend并让他们使用其他颜色。但是模拟起来heatRules并不太复杂,如果您只marker在您的HeatLegend(即一个长条而不是多个条)中使用 1,则可以使用自定义的来覆盖其渐变。

我从您提供的图像中抓取了 2 种颜色,并将它们和黑色放入一个数组中:

var heatColors = [
  am4core.color("rgb(248, 227, 211)"),
  am4core.color("rgb(237, 137, 166)"),
  am4core.color("rgb(0,0,0)")
];
Run Code Online (Sandbox Code Playgroud)

这不是必需的,但可能很有用。这些是三色渐变的颜色。我选择使用 3 种颜色,这样我们就可以在渐变的左/右半部分之间平均分配计算,它应该简化下面的演示。您分享的图片的左半部分可能需要额外的颜色,您必须相应地调整计算,但这同样可行。

为了模拟heatRules,我们将提供一个适配器mapPolygonsfill。在那里,我们将 a mapPolygon'svalue与值的最小值/最大值进行比较,后者可以通过 series'dataItem.values["value"].low和 找到.high。这将为我们提供一个小数百分比,以从一系列颜色中获取颜色。效用函数挑选从范围内的颜色是am4core.colors.interpolate,它的前两个参数是iRGB小号(用普通对象rgb,和a属性/值),第三个是在小数的百分比。如果百分比在前半部分,我们将让适配器返回上面前两个之间的颜色heatColors,如果它在后半部分,我们将返回后两者之间的颜色。

下面是代码的样子:

polygonSeries.mapPolygons.template.adapter.add("fill", function(
  fill,
  mapPolygon
) {
  var workingValue = mapPolygon.dataItem.values["value"].workingValue;
  var minValue = polygonSeries.dataItem.values["value"].low;
  var maxValue = polygonSeries.dataItem.values["value"].high;
  var percent = (workingValue - minValue) / (maxValue - minValue);
  if (am4core.type.isNumber(percent)) {
    if (percent > 0.5) {
      return new am4core.Color(
        am4core.colors.interpolate(
          heatColors[1].rgb,
          heatColors[2].rgb,
          (percent - 0.5) * 2
        )
      );
    } else {
      return new am4core.Color(
        am4core.colors.interpolate(
          heatColors[0].rgb,
          heatColors[1].rgb,
          percent * 2
        )
      );
    }
  }
  return fill;
});
Run Code Online (Sandbox Code Playgroud)

如果您有一个 1-marker heatLegend,即只是一个带有渐变的条形,您也可以制作自己的渐变并将其分配到适配器中:

var gradient = new am4core.LinearGradient();
heatColors.forEach(function(color) {
  gradient.addColor(color);
});
heatLegend.markers.template.adapter.add("fill", function() {
  return gradient;
});
Run Code Online (Sandbox Code Playgroud)

如果您在 a 中有多个标记heatLegend(根据您图片中的顶部热量图例),自定义着色将更像我们为 所做的heatRules,除了不是适配器,因为我们需要知道它们的位置并且没有dataItemindex可用,markers一旦它们准备好,我们将遍历它们,然后在那里覆盖它们的颜色:

var heatLegendTop = chart.createChild(am4maps.HeatLegend);
heatLegendTop.series = polygonSeries;
heatLegendTop.minColor = heatColors[0];
heatLegendTop.maxColor = heatColors[2];
heatLegendTop.marginBottom = 10;
heatLegendTop.markerCount = 10;
heatLegendTop.events.on("inited", function() {
  heatLegendTop.markers.each(function(marker, markerIndex) {

    // Gradient colors!
    if (markerIndex < heatLegendTop.markerCount / 2) {
      marker.fill = new am4core.Color(
        am4core.colors.interpolate(
          heatColors[0].rgb,
          heatColors[1].rgb,
          (markerIndex / heatLegendTop.markerCount) * 2
        )
      );
    } else {
      marker.fill = new am4core.Color(
        am4core.colors.interpolate(
          heatColors[1].rgb,
          heatColors[2].rgb,
          ((markerIndex - heatLegendTop.markerCount / 2) /
            heatLegendTop.markerCount) *
            2
        )
      );
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

我用上面的代码分叉了我们的美国热量(choropleth)地图演示,然后一些更接近您分享的图像的外观/感觉:

https://codepen.io/team/amcharts/pen/7fd84c880922a6fc50f80330d778654a

  • 这太棒了,正是我需要的。非常感谢你花时间在这上面。 (2认同)