如何在 x 轴上镜像此线性渐变并在缩放时对其进行调整

BuZ*_*uZz 2 css d3.js

我一直在研究时间序列的面积图,该时间序列在零上下紧密悬停。我需要我已经实现的缩放和焦点/工具提示功能。您可以拖动选择图表的一个区域,它会放大。双击缩小。

我想使用浅蓝色到深蓝色的线性渐变来强调离零最远的值。我设法将它添加到零以上的值(0 到 yMax)。

我怎么能对称地“镜像”负值的这种渐变效果?渐变在语义上应该是合乎逻辑的,例如这里描绘的 -0.5 的 yMin 应该具有大约 +0.5 的颜色级别,而不是 yMax。

我怎样才能将渐变应用于线条笔划?

如何避免缩放时渐变扭曲?

https://stackblitz.com/edit/angular-deviation-chart-gradient 在此处输入图片说明

wik*_*239 6

为此,我改变了两件事。首先是使渐变跨越图表线“下方”的整个区域。它跨越 的最低值和最高值y

.attr("gradientUnits", "userSpaceOnUse")    
.attr("x1", 0).attr("y1", y(d3.min(data, (d) => d[1])))
.attr("x2", 0).attr("y2", y(d3.max(data, (d) => d[1])))
Run Code Online (Sandbox Code Playgroud)

接下来要做的是修改渐变的停靠点。它是一个从最低y值到最高y值的梯度。停靠点设置为:

  1. “最小颜色”在 x 轴上,
  2. y 的绝对最高值获得“最大颜色”
  3. x 轴另一侧的最大值比 2. 获得成比例的颜色

因此我在另一种方法中设置停止

.selectAll("stop")                      
.data(this.getGradientData())   
Run Code Online (Sandbox Code Playgroud)

...并且该方法是这样编写的

getGradientData(): Array<T> {
const dataMaxValue = Math.max(...this.data.map(element => element[1]));
const dataMinValue = Math.min(...this.data.map(element => element[1]));
const valuesSpan = dataMaxValue - dataMinValue;  

if (Math.abs(dataMaxValue) > Math.abs(dataMinValue)) {
  const shorterPartToLongerPartRatio = Math.abs(dataMinValue) / Math.abs(dataMaxValue);
  const shorterPartToWholeRatio = Math.abs(dataMinValue) / valuesSpan;

  return [
    {offset: "0%", color: `rgba(0, 0, 0, ${shorterPartToLongerPartRatio})`},
    {offset: `${shorterPartToWholeRatio * 100}%`, color: 'lightblue'},
    {offset: "100%", color: "black"}
  ];
}

const shorterPartToLongerPartRatio = Math.abs(dataMaxValue) / Math.abs(dataMinValue);
const shorterPartToWholeRatio = Math.abs(dataMaxValue) / valuesSpan;
return [
  {offset: "0%", color: 'black'},
    {offset: `${100 - (shorterPartToWholeRatio * 100)}%`, color: 'lightblue'},
    {offset: "100%", color: `rgba(0, 0, 0, ${shorterPartToLongerPartRatio})`}
];
Run Code Online (Sandbox Code Playgroud)

}

请注意我是如何更改darkblueblack. 当背景为白色时,这是一种找到成比例颜色值(具有不透明度)的简单方法。这可以通过计算所需的颜色来改进。

即使负值大于正值,该解决方案也应该有效。这是修改后的示例:https : //stackblitz.com/edit/angular-deviation-chart-gradient-zrghr2

@Edit:至于在缩放时避免梯度失真的问题。不幸的是,您无法阻止这种情况。这是一个像计算机图形一样古老的问题,原因是没有足够的颜色可用:)

@Edit2:寻找中间色的方法相当简单:

getIntermediateColor(colorOneRGB, colorTwoRGB, ratio) {
    const newR = colorOneRGB[0] + (colorTwoRGB[0] - colorOneRGB[0]) * ratio;
    const newG = colorOneRGB[1] + (colorTwoRGB[1] - colorOneRGB[1]) * ratio;
    const newB = colorOneRGB[2] + (colorTwoRGB[2] - colorOneRGB[2]) * ratio;
    return `rgb(${newR}, ${newG}, ${newB})`;
  }
Run Code Online (Sandbox Code Playgroud)