Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用d3.js在插值曲线中的单点周围划线_Javascript_Css_D3.js_Svg - Fatal编程技术网

Javascript 使用d3.js在插值曲线中的单点周围划线

Javascript 使用d3.js在插值曲线中的单点周围划线,javascript,css,d3.js,svg,Javascript,Css,D3.js,Svg,我想画一条曲线,对一些给定的点进行插值。在这里,这些点表示太阳能电池板可以产生多少太阳能,因此一天中每小时有一个点有太阳。积分的数量可能因一年中的月份而异(例如,12月10分,6月16分,因为这两个月每天分别有10小时和16小时的日照) 在此之前,一切都很好,但现在我们想在您看到图形的一天中添加一个太阳图像。为此,我创建了两行:一行在当前小时之前,一行在当前小时之后,并将太阳图像放置在当前小时位置。6月的情况是这样的,下午1点16分: 这个看起来不错。问题是当点较少时,当前小时前后的点之间的空

我想画一条曲线,对一些给定的点进行插值。在这里,这些点表示太阳能电池板可以产生多少太阳能,因此一天中每小时有一个点有太阳。积分的数量可能因一年中的月份而异(例如,12月10分,6月16分,因为这两个月每天分别有10小时和16小时的日照)

在此之前,一切都很好,但现在我们想在您看到图形的一天中添加一个太阳图像。为此,我创建了两行:一行在当前小时之前,一行在当前小时之后,并将太阳图像放置在当前小时位置。6月的情况是这样的,下午1点16分:

这个看起来不错。问题是当点较少时,当前小时前后的点之间的空间较大,并且在图形上变得过大。这是1月9日上午10点(错误的图形渲染):

(在两幅图像中,底部的结束/开始时间都是静态的)

我想要留给太阳的空白空间总是一样的。

我尝试过各种方法:

  • 在数据中添加一些“离太阳更近”的点:不起作用,因为它会弄乱比例,即使在添加点后更新了比例,曲线的顶部也不再居中
  • 在太阳图像上放置背景:图形必须集成在透明容器中
  • 使用stroke dasharray:我无法理解足够的百分比/像素值来计算它。例如,当“到短划线的距离”为100%时,它将在直线终点之前短划线。对于像素单元,我没有找到任何方法来计算曲线绘制生成的像素数,因此无法计算虚线的确切位置
  • 使用linearGradiant:我无法缩放适当的百分比定位。无论如何,渲染是丑陋的,因为它垂直剪切线颜色,这在图形上不是很好

如果有人知道如何正确地完成这一点,那就太好了。另外,我可能错过了一些明显的东西,或者对这个问题想了一个错误的方法,但是经过3天的思考,我有点超载了,哈哈。感谢您阅读

您可能想得太多了。你有没有考虑过画一条完整的线,在你的太阳图标周围画一个白色的圆圈?只要在线条后绘制图标,就会留下适当的空间。

您应该能够将数据与渲染模型分离。您没有包含代码,因此您的具体解决方案会有所不同。但总体思路是将实际数据转换为更适合渲染需要的数据。例如:

// If this is your actual data ...
var numberOfHours = 10;
var showSunAt = 3;

// ... and this is your desired "resolution" for the path ...
var resolution = 16;

// ... map your data to work with this resolution.
var mapped = showSunAt / numberOfHours * resolution;

// Define the "space" to leave between segments.
var spaceBetweenSegments = 1;

// Then, dynamically set the start/end points for each segment.
var firstSegmentEndsAt = mapped - (spaceBetweenSegmenets / 2);
var secondSegmenetStartsAt = mapped + (spaceBetweenSegmenets / 2);

现在,您已经拥有了沿路径的确切点,其中第一段应该结束,图标应该呈现,第二段应该开始。

这个问题的一个解决方案是使用svg掩码


正如这里所解释的,您可以创建遮罩,该遮罩将创建应用它的元素的“非显示”区域。换句话说,我创建了一个遮罩,上面有一个始终位于太阳位置的圆,它隐藏了圆内的曲线部分。

听起来你有答案,但我将提出一种不同的方法。使用
stroke dasharray
,这听起来很容易解决。下面是一个快速演示:


var svg=d3.选择(“主体”)
.append(“svg”)
.attr(“宽度”,500)
.attr(“高度”,500);
var line=d3.line()
.曲线(d3.曲线中心)
.x(功能(d){
返回d[0];
})
.y(功能(d){
返回d[1];
});
var数据=[[10450]、[250,50]、[490450];
var p=svg.append(“路径”)
.基准(数据)
.attr(“d”,行)
.style(“笔划”、“橙色”)
.style(“笔划宽度”、“5px”)
.样式(“填充”、“无”);
var l=p.node().getTotalLength(),
太阳空间=l/12;
函数createSpace(){
var sunPos=Math.random()*l;
p、 attr(“数组”(sunPos-sunSpace/2)+”、“sunSpace+”和“+l”);
}
createSpace();
设置间隔(createSpace,1000);

这是我的第一个想法。但是通读它:“图形必须集成在一个透明的容器中”。有大量关于裁剪和屏蔽SVG的文档(例如)。试试看!如果你努力建立一个有效的演示,肯定会有人很快想出一个优雅的解决方案。谢谢你,我会调查的!BestIt可以很好地进行剪裁!只有一个小的图形渲染“问题”:被两个矩形切割,曲线垂直切割,因此不会以直线的方式进行。下面是它的渲染方式。我在想,有没有一种方法可以与剪辑相反呢?比如说,在太阳的地方画一个圆圈,这样在穿过它的时候就不会画线了?如果这是不可能的实际渲染将是可以接受的,因此,感谢您在理论基础上这样做的麻烦。就像我说的:设置一个小演示,当我自己仍在研究一个合适的解决方案时,可能会有人比我抢先一步。我认为甚至会有不止一个优雅的解决方案。在剪辑时,你不局限于矩形。clipPath可能是任意形状的:。谢谢您的回答。这是一个想法,但这意味着在数据中添加一个点,在太阳前后的曲线中考虑它,这会弄乱比例。嘿,好主意。我不知道node.getTotalLength函数。虽然在这里它也不起作用。太阳以水平x比例放置,y与绘制曲线时计算的y相同(因此每个x之间的空间是恒定的)。尝试你的方法,我创建了一个水平x r的刻度