javascript - 绘制具有 2 个或 3 个彩色区域的密度函数?

标签 javascript d3.js svg htmlwidgets

我刚开始学习 javascriptd3.js,参加了几个 lynda.com 类(class)。我的目标是创建一个函数,该函数采用数字数组和截止值并生成如下图:

density

我能够编写生成此代码的 javascript 代码:

enter image description here

唉,我很难找到一种方法来告诉 d3.js 应该读取 -opts.threshold 左边的区域,该区域在 -opts.thresholdopts.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/

相关文章:

javascript - 使用动态生成在屏幕上和屏幕外动画 SVG 对象

javascript - D3 对象全部渲染为 0px x 0px,没有属性

javascript - SVG 中 dashArray 的输出与 Chrome 和 IE 不同

javascript - 在滚动条上连续减少 SVG 长度

javascript - AttachEvent 在 IE11 上不起作用

javascript - d3 添加 html 链接到表中的数据列

javascript - 如何在 d3 中换行以适合屏幕?

javascript - Vue.js 数据未通过 HTML 表单提交发送

javascript - 选择特定 href 的第一个实例

javascript - 未找到 JQuery .autocomplete?