【问题标题】:How to make legend color show up in Highcharts for a line graph under certain conditions?在某些条件下,如何在折线图的 Highcharts 中显示图例颜色?
【发布时间】:2022-02-04 00:23:32
【问题描述】:

我正在探索 Highcharts,它似乎是一个非常全面的软件包!我有一个关于图例颜色的问题。

我注意到,当我对线条使用线性颜色渐变时,图例旁边的颜色(我相信它称为 symbolColor)可能会显示也可能不会显示,具体取决于我使用的格式:

1) symbolColor works fine: linearGradient: [ 00, 00, 00, 350 ]
2) symbolColor doesn't show up: linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }

我宁愿使用第二种格式;它更容易,第一个没有响应。

symbolColor 是否应该始终显示,这是一个晦涩难懂的问题/错误?还是我做错了什么?我还刚刚注意到,如果在系列的 plotOptions 中启用了标记,则 symbolColor 可以在第二种格式下正常工作。但我有很多数据点,不想使用标记。

小提琴图有两条线——紫色和绿色——虽然使用方法 (1) 的紫色 symbolColor 看起来不错,但您会注意到使用方法 (2) 的绿色 symbolColor 没有出现。

https://jsfiddle.net/jwinkle/s6d9ah17/6/

【问题讨论】:

  • 我找到了一个可以正常工作的例子:jsfiddle.net/q9ac21m7 但我还没有弄清楚让它工作的特殊酱汁是什么。
  • 看起来问题出在标记上。你的和我上面给出的例子之间的区别是你的标记被禁用了。默认情况下,图例中显示了一个标记,其中有一条线,在我给出的示例中,该线丢失但标记在那里。可能表示有问题,而不是错过了选项或其他东西。
  • 我有一个解决方案,但有点晦涩难懂,等等……

标签: highcharts


【解决方案1】:

在您的 HTML 文件中,添加:

<script src="https://code.highcharts.com/maps/modules/map.src.js"></script>

在您的图表代码上方添加:

Highcharts.addEvent(Highcharts.Chart.prototype, 'render', function() {
    this.series.forEach(function(series) {
      if (series.legendLine) {
        var pathDef = series.legendLine.attr('d').split(' ');
        pathDef[5] = parseFloat(pathDef[2]) + 0.0001;
        series.legendLine.attr({
          d: pathDef
        });
      }
    })
  });

解决方法是在您的路径定义中添加一点点(您可以通过进入开发工具中的 svg 路径元素并将“d”属性中的最后一个数字更改为浮点数来测试:

<path fill="none" d="M 0 11 L 16 11" ... ></path>

变成:

<path fill="none" d="M 0 11 L 16 11.1" ... ></path>

上面的函数遍历每个系列,并在正确的位置添加小数值来按摩行数据。完全破解。但是,如果它确实有这个小数值,为什么这条线不会出现,我不知道。我还会在浏览器中测试它,看看它是否能始终如一地工作(我在 Chrome 中测试过)。

这是一个有点相关的问题,我在其中抄袭了修复:https://www.highcharts.com/forum/viewtopic.php?t=38588 (其中大部分是在解决一个完全不同的问题,但图例行确实出现了,所以我调查了原因)。

如果您不想使用额外的库,您可以编写一个原生 js 函数来查找图例行并以相同的方式操作它们。

【讨论】:

  • 谢谢@Katharine,这行得通(!),但晦涩难懂!我以为我开始了解 Highcharts。我不知道这是在做什么,但没关系......请继续关注我想出的解决方案/hack。
  • 你可以用这样的函数做很多事情,比如动态重新渲染东西,但在这里应用它只是修复 svg 行。所以你遇到的问题可能是 Highcharts 的 bug,也可能是 svg 渲染的 bug。可能值得向 Highcharts 报告,因为您尝试做的事情应该按照您的预期方式工作。
【解决方案2】:

Here,你可以找到一个很好的问题解释。


差异是由于 Highcharts 使用 'userSpaceOnUse' 作为 gradientUnits 的默认值(如果梯度被定义为数组)。

Highcharts source code:

// Keep < 2.2 kompatibility
if (isArray(gradAttr)) {
  (colorOptions as any)[gradName] = gradAttr = {
    x1: gradAttr[0] as number,
    y1: gradAttr[1] as number,
    x2: gradAttr[2] as number,
    y2: gradAttr[3] as number,
    gradientUnits: 'userSpaceOnUse'
  };
}

作为一种可能的解决方案,您也可以将gradientUnits 设置为定义为对象的linearGradient

color: {
  linearGradient: {
    ...,
    gradientUnits: 'userSpaceOnUse'
  },
  ...
}

现场演示: http://jsfiddle.net/BlackLabel/yz6sagxj/


或者稍微修改路径,使它们不是完全水平的

chart: {
  events: {
    render: function() {
      this.series.forEach(function(series) {
        if (series.legendLine) {
          var pathDef = series.legendLine.attr('d').split(' ');
          pathDef[5] = parseFloat(pathDef[2]) + 0.0001;
          series.legendLine.attr({
            d: pathDef
          });
        }
      })
    }
  }
}

现场演示: http://jsfiddle.net/BlackLabel/L1kzg0cn/

Github 线程: https://github.com/highcharts/highcharts/issues/1936

【讨论】:

  • 感谢@ppotaczek 的回复,但不幸的是,不能像在您的演示中使用“userSpaceOnUse”那样使用“1”。您引用的帖子的其他答案之一解释说“但有时 userSpaceOnUse 很痛苦,因为它将插值分布在整个画布上,而不仅仅是线条。”这是一个使用 1 和 400 表示 x2 的小提琴;您可以看到它在使用 400 时只是一个渐变。也感谢您简化了我的示例(尽管我重新禁用了标记,因为正如我最初提到的,如果启用它一切正常,但我不想要它)。 jsfiddle.net/jwinkle/a279j1cf/17
  • 嗨@Jim,我很高兴能提供帮助。我不确定您到底想达到什么目标。使用x2: 400,您的图表上有一个渐变,并显示了图例符号。你想在图例符号上也有渐变吗?
  • 我宁愿使用第二种格式;它更容易,第一个(数组格式)没有响应。此外,不再记录数组格式;看起来 HC 人更喜欢我们使用对象格式。我在这里将其报告为潜在问题:github.com/highcharts/highcharts/issues/16947
  • 是的,你是对的。数组格式之所以有效,只是因为向后兼容。请指定您的图表应该是什么样子,我相信我们会想出办法的:)
  • 谢谢,@ppotaczek...我通过链接到一个虚拟系列找到了一个很好的解决方法,我在这里发布了另一个解决方案。 stackoverflow.com/a/70935607/18084691
【解决方案3】:

除了@Katharine 的解决方案,这是我发现的另一个解决方案。

如果我在一个系列中启用标记(将半径设置为 0),然后将数据放入与前一个链接的第二个系列中,它就可以工作。 (如果我在一个系列中全部完成,就再也没有图例颜色了。)

series: [{
    name: 'purple', lineWidth: 3, color: {
        linearGradient: [ 00, 00, 00, 350 ],
        //linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1, },
        stops: [
            [0, 'purple'], // start 
            [1, 'black'] // end
        ], 
    }, 
    data: [ 100, 95, 80, 60, 35, 50, 20, 10, 3, 2, 30, 40, ],
},{
    marker: {
        enabled: true,
        radius: 0,
    },
    name: 'green', color: 'green', lineWidth: 3, 
},{
    linkedTo: ':previous',
    lineWidth: 3, color: {
        //linearGradient: [ 00, 00, 00, 350 ], 
        linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1, },
        stops: [
            [0, 'green'], // start 
            [1, 'black'] // end
        ], 
    }, 
    data: [ 100, 100, 95, 80, 60, 35, 50, 20, 10, 3, 2, 30, ],
}],

这是“固定”的小提琴:https://jsfiddle.net/jwinkle/wztq78n1/6/

我将原始问题作为可能的错误报告给了 Highcharts,他们确认这是他们无法控制的 SVG 渲染问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 2020-12-23
    • 2017-01-30
    相关资源
    最近更新 更多