- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试按照 https://dribbble.com/shots/2673159-Funnel-UI-concept/attachments/538068 的思路构建一些东西
我查看了 d3/vx 提供的所有曲线,但似乎没有一条曲线出现在每个不同的步骤之间,并且直线在数据点处是平坦的。是否有我缺少的曲线类型看起来与上述类似?如果没有并且它需要自定义曲线,是否有比 d3 文档更深入地描述如何实现自定义曲线的地方?
最佳答案
没有标准曲线可以做到这一点;但是,如果复制添加额外的点以强制标准 d3 曲线在需要的地方变平,则有可能。例如,在具有相同 y 值的阶段变化之前和之后添加点。
但是,自定义曲线可以工作并避免数据操作的需要。贝塞尔曲线应该可以解决问题。起点、终点和控制点类似于:
图片来自 this codepen
为了实现这个想法,我们可以用绘制贝塞尔曲线的函数替换标准曲线中的点函数,例如 d3.curveLinear。
比较d3.curveLinear的点函数:
function(x, y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
case 1: this._point = 2; // proceed
default: this._context.lineTo(x, y); break;
}
以及新的点函数:
function(x,y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
this.x0 = x; this.y0 = y;
break;
case 1: this._point = 2;
default:
var x1 = this.x0 * 0.5 + x * 0.5;
this._context.bezierCurveTo(x1,this.y0,x1,y,x,y); // bezierCurveTo(controlPoint1X,controlPoint1Y,controlPoint2X,controlPoint2Y,endPointX,endPointY)
this.x0 = x; this.y0 = y;
break;
}
}
return custom;
}
我为每个控制点使用相同的 x 值,这可能不太理想,因为它们在末端可能不够平坦,但它很容易改变
我们可以使用 d3.curveLinear 并代入这个新的点函数来创建自定义曲线:
var curve = function(context) {
var custom = d3.curveLinear(context);
custom._context = context;
custom.point = function(x,y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
this.x0 = x; this.y0 = y;
break;
case 1: this._point = 2;
default:
var x1 = this.x0 * 0.5 + x * 0.5;
this._context.bezierCurveTo(x1,this.y0,x1,y,x,y);
this.x0 = x; this.y0 = y;
break;
}
}
return custom;
}
这很容易工作:
var curve = function(context) {
var custom = d3.curveLinear(context);
custom._context = context;
custom.point = function(x,y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
this.x0 = x; this.y0 = y;
break;
case 1: this._point = 2;
default:
var x1 = this.x0 * 0.5 + x * 0.5;
this._context.bezierCurveTo(x1,this.y0,x1,y,x,y);
this.x0 = x; this.y0 = y;
break;
}
}
return custom;
}
var data = [
[10,10],
[160,50],
[310,100]
];
var line = d3.line()
.curve(curve);
d3.select("svg")
.append("path")
.attr("d",line(data));
d3.select("svg")
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("transform", function(d) {
return "translate("+d+")";
})
.attr("r",3)
path {
fill: none;
stroke: black;
stroke-width:1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="500" height="500"></svg>
下面是一个为每个阶段绘制漏斗的区域演示。 根据您的数据,这可能更可取,也可能不是。我的假数据是按阶段构建的,因此最容易单独绘制每个阶段。将所有阶段统一到一个路径/区域中可能有点困难。
var curve = function(context) {
var custom = d3.curveLinear(context);
custom._context = context;
custom.point = function(x,y) {
x = +x, y = +y;
switch (this._point) {
case 0: this._point = 1;
this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y);
this.x0 = x; this.y0 = y;
break;
case 1: this._point = 2;
default:
var x1 = this.x0 * 0.5 + x * 0.5;
this._context.bezierCurveTo(x1,this.y0,x1,y,x,y);
this.x0 = x; this.y0 = y;
break;
}
}
return custom;
}
var data = [
{stage:1, start:1,end:0.5},
{stage:2, start:0.5,end:0.2},
{stage:3, start:0.2,end:0.1},
{stage:4, start:0.1,end:0.005}
]
var yRangeMax = 100;
var y = d3.scaleLinear()
.range([yRangeMax,0]);
var x = d3.scaleBand()
.range([50,400])
.domain(data.map(function(d) {
return d.stage;
}))
var svg = d3.select("svg");
var area = d3.area()
.curve(curve)
.y1(function(d) { return yRangeMax*2-d[1]; })
.y0(function(d) { return d[1]; })
svg.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("d", function(d) {
var p1 = [x(d.stage),y(d.start)]
var p2 = [x(d.stage)+x.step(),y(d.end)]
return area([p1,p2])
})
path{
stroke: #bbb;
stroke-width: 1px;
fill:#ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.6.0/d3.min.js"></script>
<svg width="600" height="400"></svg>
关于javascript - d3 + vx react 图表曲线在每个数据点平坦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55231234/
这个问题在这里已经有了答案: Prolog - count repetitions in list (3 个答案) 关闭 7 年前。 所以我正在尝试创建一种方法来确定列表中 N 的数量。我已经试验了
使用 sscanf 或任何其他命令从分号后的文件读取的最佳方法是什么,例如,如果我的文件有 5: 4 5 6 7。如何将冒号后的值存储在数组中。此外,分号后面的整数数量可能会有所不同,即在上面给出的示
我正在尝试返回第 n 个数字。如果数字是 3 或 7 的倍数,则从 1 开始,则跳过该数字并获取下一个数字。但是,如果数字是 3 和 7 的倍数,则不会跳过该数字。 public int Multip
如何有效地从末尾获取一定数量的元素? 1 looks like 2 three!! 例如,如何获取最后 2 个 div 的内容? 最佳答案 $(document).ready(function(){
//Generate Food Personality for(i=0; i
我试图在给定的排序数组中找到最大的 K 个数。 例如:输入 -> [ 5, 12, 45, 32, 9, 20, 15]输出 -> K = 3, [45, 32, 20] 到目前为止我编写的代码返回最
两个数字表 a 和 b 被写入并按升序合并在一起,并删除重复项。现在的问题是在这个 super 表中找到比 O(n) 复杂度更好的 nth 数。 Limits 1 #include using nam
给定一个包含 N 个元素的数组 A,我需要找到对 (i,j) 使得 i 不等于 j 并且如果我们为所有对 (i, j) 然后它来到第k个位置。 示例:让 N=4 和数组 A=[1 2 3 4] 如果
给定一组跳过的数字,我需要找到该组中不存在的第 N 个数字。示例: 给定一组 [1, 4, 5] 一些结果: 对于 N = 1 结果 0 对于 N = 2 结果 2(因为 1 被跳过) 对于 N =
几个月前在亚马逊的招聘挑战中遇到了这个问题。 给定两个数字 a 和 b 及其倍数的升序列表,找出第 n 个倍数。 例如,如果 a = 4 , b = 6 和 n = 6 那么答案是 18因为列表是 4
所以我最近一直在研究 Python,我试图找到一种方法来在单个表达式中输出斐波那契数列的第 n 个数。这是我到目前为止编写的代码: (lambda f: f if f 1 # n == 2 -> 1
作业是编写一个 C++ 程序,它接受输入数字 n 并输出序列中的第 n 个数字: 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 ... 这是我到目前为止想出的:
问题很简单(答案很可能):如何找到数组中最小的 2 个数字? for ( i = 1; i 关于c++ - 数组中最小的 2 个数,我们在Stack Overflow上找到一个类似的问题: ht
您可以调用Nokogiri::XML::Node#ancestors.size 来查看节点的嵌套深度。但是有没有办法确定嵌套最深的子节点的嵌套深度呢? 或者,您如何找到从一个节点下降的所有叶节点? 最
这个任务是找到n个数字的fibanocci。任务: 1.找出n个数的斐波那契数。 2.使用变量n,first=0,second=1,next,c。输入格式:使用 printf 语句。使用 scanf
我想添加每 10 个元素的数量。 例如, function myFunction() { for (var i = 1; i "; } } 输出: 1,2,3,4,5,6,7,8,9,
我想编写一个程序来计算斐波那契数列的第 n 个数,这是我使用 printf 和 scanf 完成的。但我希望更改我的程序,以便在命令行中输入序列号,而不是在程序提示时输入。这就是我想出的。它可以编译,
我有一个方案中的对象列表。每个对象都与一个可以在运行时计算的置信度值相关联。我想找到具有最高置信度值的前 50 个此类对象。示例:((WordPair1) (WordPair2)) 等等都是我的对象。
我正在寻找一种给定目标的算法,返回目标位为 0 的第 N 个数字。 例如,对于n={0,1,2,3}和target=1的输入,输出将是(二进制) 000,001,100,101 最佳答案 只写值N-1
我正在尝试创建一个函数来获取 vector 中的 3 个最大数字。例如:数字:1 6 2 5 3 7 4结果:5 6 7 我想我可以对它们进行 DESC 排序,在开始时获取 3 个数字,然后再对它们进
我是一名优秀的程序员,十分优秀!