我刚开始学习 javascript
和 d3.js
,参加了几个 lynda.com 类(class)。我的目标是创建一个函数,该函数采用数字数组和截止值并生成如下图:
我能够编写生成此代码的 javascript 代码:
唉,我很难找到一种方法来告诉 d3.js
应该读取 -opts.threshold
左边的区域,该区域在 -opts.threshold
和 opts.threshold
之间为蓝色,其余为绿色。
这是我的 javascript
代码:
HTMLWidgets.widget({
name: 'IMposterior',
type: 'output',
factory: function(el, width, height) {
// TODO: define shared variables for this instance
return {
renderValue: function(opts) {
console.log("MME: ", opts.MME);
console.log("threshold: ", opts.threshold);
console.log("prob: ", opts.prob);
console.log("colors: ", opts.colors);
var margin = {left:50,right:50,top:40,bottom:0};
var xMax = opts.x.reduce(function(a, b) {
return Math.max(a, b);
});
var yMax = opts.y.reduce(function(a, b) {
return Math.max(a, b);
});
var xMin = opts.x.reduce(function(a, b) {
return Math.min(a, b);
});
var yMin = opts.y.reduce(function(a, b) {
return Math.min(a, b);
});
var y = d3.scaleLinear()
.domain([0,yMax])
.range([height,0]);
var x = d3.scaleLinear()
.domain([xMin,xMax])
.range([0,width]);
var yAxis = d3.axisLeft(y);
var xAxis = d3.axisBottom(x);
var area = d3.area()
.x(function(d,i){ return x(opts.x[i]) ;})
.y0(height)
.y1(function(d){ return y(d); });
var svg = d3.select(el).append('svg').attr("height","100%").attr("width","100%");
var chartGroup = svg.append("g").attr("transform","translate("+margin.left+","+margin.top+")");
chartGroup.append("path")
.attr("d", area(opts.y));
chartGroup.append("g")
.attr("class","axis x")
.attr("transform","translate(0,"+height+")")
.call(xAxis);
},
resize: function(width, height) {
// TODO: code to re-render the widget with a new size
}
};
}
});
如果这有帮助,我将所有代码保存在 public github repo 上.
最佳答案
在这个 answer 中有两个建议的解决方案,使用渐变或使用多个区域。我将提出一个替代解决方案:使用该区域作为三个矩形的剪辑路径,这三个矩形共同覆盖整个绘图区域。
通过创建一个包含每个矩形左右边缘的数据数组来制作矩形。附加矩形时,矩形高度和 y 属性可以分别设置为 svg 高度和零,因此不需要包含在数组中。
第一个矩形的左边缘为 xScale.range()[0]
,最后一个矩形的右边缘为 xScale.range()[1]
。中间坐标可以用xScale(1)
, xScale(-1)
等放置
这样的数组可能看起来像(使用您建议的配置和 x 刻度名称):
var rects = [
[x.range()[0],x(-1)],
[x(-1),x(1)],
[x(1),x.range()[1]]
]
然后放置它们:
.enter()
.append("rect")
.attr("x", function(d) { return d[0]; })
.attr("width", function(d) { return d[1] - d[0]; })
.attr("y", 0)
.attr("height",height)
不要忘记为矩形设置一个 clip-path
属性:
.attr("clip-path","url(#areaID)")
,并将填充设置为三种不同的颜色。
现在您所要做的就是将您的区域的填充和描边设置为无,并将您的区域附加到具有指定 id 的剪辑路径:
svg.append("clipPath)
.attr("id","area")
.append("path")
.attr( // area attributes
...
Here这是实际的概念(尽管使用的是 v3,它不应影响矩形或文本路径。
关于javascript - 绘制具有 2 个或 3 个彩色区域的密度函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47381413/