Css 如何在x轴上镜像此线性渐变并在缩放时进行调整
我一直在为接近零上下的时间序列绘制面积图。我需要缩放和聚焦/工具提示功能,我已经实现了。您可以拖动并选择图表的一个区域,它将放大。双击可缩小 我想使用浅蓝色到深蓝色的线性渐变来强调距离零最远的值。我设法将其添加到零以上的值(0到yMax) 如何对称地“镜像”负值的渐变效果?渐变在语义上应该是合乎逻辑的,例如在-0.5处描述的yMin应该具有+0.5的颜色级别,而不是yMax的颜色级别 如何将渐变也应用于线条笔划 如何避免缩放时的渐变失真Css 如何在x轴上镜像此线性渐变并在缩放时进行调整,css,d3.js,Css,D3.js,我一直在为接近零上下的时间序列绘制面积图。我需要缩放和聚焦/工具提示功能,我已经实现了。您可以拖动并选择图表的一个区域,它将放大。双击可缩小 我想使用浅蓝色到深蓝色的线性渐变来强调距离零最远的值。我设法将其添加到零以上的值(0到yMax) 如何对称地“镜像”负值的渐变效果?渐变在语义上应该是合乎逻辑的,例如在-0.5处描述的yMin应该具有+0.5的颜色级别,而不是yMax的颜色级别 如何将渐变也应用于线条笔划 如何避免缩放时的渐变失真 对于第一个问题,这里有一个注意事项,梯度要起作用,您必须
对于第一个问题,这里有一个注意事项,梯度要起作用,您必须将
y1
与梯度偏移量一起乘以2:
svg.append("linearGradient")
.attr("id", "area-gradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", y(0) * 2)
.attr("x2", 0).attr("y2", y(yExtent[1]))
.selectAll("stop")
.data([
{offset: "0%", color: "darkblue"},
{offset: "50%", color: "lightblue"},
{offset: "100%", color: "darkblue"},
])
问题2,如果你添加渐变,这将使它不可见,并删除它的整个目的,因为它有相同的颜色作为填充区域
问题3,“如何避免缩放时的渐变扭曲?”我没有面临缩放问题,您使用的是哪种浏览器?为了使这项功能发挥作用,我改变了两个方面。首先是使渐变跨越图表线“下方”的整个区域。它介于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])))
接下来要做的是修改渐变的停止点。它是一个从最低y
值到最高y
值的梯度。挡块的设置方式应确保:
“最小颜色”位于x轴上
y的绝对最高值为“最大颜色”
x轴另一侧的最大值不是2。获取比例颜色
因此,我用另一种方法设置停止
.selectAll("stop")
.data(this.getGradientData())
。。。方法就是这样写的
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})`}
];
我不精通d3,所以在代码方面我帮不了你多少忙
不过,让我给你解释一下解决问题的方法
计算数据中y的最小值和最大值
这行代码取自wiktus239响应,似乎就是这样做的
const dataMaxValue = Math.max(...this.data.map(element => element[1]));
const dataMinValue = Math.min(...this.data.map(element => element[1]));
现在取其中最大的绝对值
const dataLimit = Math.max (Math.abs(dataMaxValue), Math.abs(dataMinValue));
梯度应在-dataLimit和+dataLimit之间绘制
现在,将此数据值映射到图形y值。我相信这是用y函数完成的,但如果我错了,请替换为适当的方法
const yMax = y(dataLimit);
const yMin = y(-dataLimit);
此数据是您需要在渐变上设置的数据:
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", 0).attr("y1", yMax)
.attr("x2", 0).attr("y2", yMin)
偏移量保持不变
{offset: "0%", color: "darkblue"},
{offset: "50%", color: "lightblue"},
{offset: "100%", color: "darkblue"},
此解决方案将解决您的问题1和3
关于第二个,您可以将笔划宽度设置为0,这样线条的笔划就不可见了谢谢,我喜欢您的比率想法,它很聪明。然而,我真的需要一个蓝色到蓝色的渐变来匹配一个特定的品牌,所以虽然我理解从黑色到/到黑色的渐变使得{offset:“100%”,颜色:
rgba(0,0,0,${shorterPartToLongerPartRatio})}
计算起来很实用,但我不能依赖黑色阴影。你会如何替换那条线?你会如何画线显示呢?如果没有线条笔划,这些区域看起来是断开的和奇怪的。至于失真,我想我应该更清楚。我希望在缩放时不要移动颜色,例如在现实生活中,缩放对象时不会看到其颜色变化/迁移。我想这需要(x0/y0)和(x1/y1)在缩放函数中重新计算渐变元素。关于颜色,我会使用一种方法,使用与rgba相同的比率搜索中间颜色。我在getIntermediateColor()
中进行了编辑。我觉得这条线不错。想象一下,它与值的颜色相同——你最好根本不画线,只留下渐变。还有变焦。这需要对缩放进行重新计算。我认为获取缩放区域坐标可能有点困难,以获得计算缩放的位置。但是,如果你稍微概括一下getGradientData
,它也可以以类似的方式实现。@BuZz移动梯度的xy坐标就是我在回答中所说的….attr(“x1”,0)。attr(“y1”,y(0)*2)
和.attr(“x2”,0)。attr(“y2”,y(yExtent[1]))
没有考虑到数据的变化,因此无论数据数组如何,都会绘制整个颜色范围。关于问题2,我不同意,在拓扑问题3上,区域看起来非常不连续,没有线条划过,我错误地解释道:缩放子区域时,该子区域的颜色不应改变。目前他们这样做是因为相同的渐变被应用到更小的区域,因此改变了颜色。e、 g.围绕y轴上的0进行缩放不应在缩放后开始将该区域绘制为深蓝色。嗯,我理解您的第一条评论,但对于第二条评论,您指的是笔划线“蓝线”,对吗?对于我现在得到的第三条评论,我会检查我是否能做到,还有一件事我想问,把画笔改成缩放平移可以吗?这会让你更容易避免第三期,我今天会看一看,然后再给你回复。
{offset: "0%", color: "darkblue"},
{offset: "50%", color: "lightblue"},
{offset: "100%", color: "darkblue"},