有没有办法使用具有子域的域创建比例?

时间:2013-07-12 17:37:24

标签: javascript d3.js

我正在尝试创建一个曼哈顿的情节,类似于下面看到的情节。到目前为止,我所遵循的是什么。

这就是我要创建的内容: This is what I'm trying to create

这是我到目前为止编写的内容(笑):

This is what I've coded up so far.

有两个因素决定了点的x位置。 (1)染色体指数的范围为[1, 22],(2)位置坐标范围为[1, 10,000,000]。染色体指数越大,位置坐标越大。

问题是:如何设置位置坐标的域,使点保持在染色体索引边界内,如第一张图片所示。

以下是一些相关代码:

var x0 = d3.scale.linear().range([0, width]),
    x1 = d3.scale.linear().range([0, width]),
     y = d3.scale.linear().range([height, 0]),
 xAxis = d3.svg.axis().scale(x0).orient("bottom"),
 yAxis = d3.svg.axis().scale(y).orient("left").tickPadding(6),
 color = d3.scale.category20c();

var positions = [],
    pvalues = [];
this.data.forEach(function (d) {
    d.values.forEach(function (v) {
        positions.push(v.position);
        pvalues.push(v.pvalue);
    });
});

var xMax = d3.max(positions),
    ymax = d3.max(pvalues);

x0.domain([1, 22]);
x1.domain([0, xMax]);
y.domain([0, ymax]);

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);

svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    .append("text")
    .attr("class", "label")
    .attr("transform", "rotate(-90)")
    .attr("y", 8)
    .attr("dy", ".71em")
    .style("text-anchor", "end")
    .text("p-value");

var chromosome = svg.selectAll(".chr")
    .data(this.data)
    .enter().append("g")
    .attr("class", "chr")
    .attr("x", function (d) {
        return x0(d.chr);
    })
    .attr("width", width / 22)
    .style("fill", function (d) {
        return color(d.chr);
    });

chromosome.selectAll("circle")
    .data(function (d) {
        return d.values;
    })
    .enter().append("circle")
    .attr("r", 3)
    .attr("cx", function (d) {
        return x1(d.position);
    })
    .attr("cy", function (d) {
        return y(d.pvalue);
    });

更新:因此,我按照grouped barchart example切换到d3.scale.ordinal()两个x比例。我想我离得更近了,但现在,我如何防止在同一x位置画出点? enter image description here

数据格式

this.data

[
  {
    chr: 1,
    values: [
      {
        snp: rs182799,
        position: 1478180,
        pvalue: 3.26E-05
      },
      {
        snp: rs182349,
        position: 1598180,
        pvalue: 3.26E-05
      },
    ...
    ]
  },

  chr: 2,
    values: [
      {
        snp: rs199799,
        position: 2678180,
        pvalue: 3.26E-05
      },
      {
        snp: rs182349,
        position: 2998180,
        pvalue: 3.26E-05
      },
    ...
    ]
  },
  ...
]

2 个答案:

答案 0 :(得分:1)

xMax为22,因此除了1到22之间的枚举成员之外,你不会得到任何点。this.data中的对象最多value.position 22表示您使用染色体值来确定position。实际上,您希望使用非常细粒度的position值(从1到10000000)来确定点的实际x位置,但只显示图形前端的数字1到22。据我所知,这就是问题所在。

如果我们能看到this.data所指的内容,那会有所帮助。

答案 1 :(得分:1)

对主要域[1, 22]进行顺序扩展是正确的做法。

对于每个主要横坐标[1, 1e7]子域,执行此操作的方法是为每个横坐标生成一个刻度。关于范围的一些问题应该首先回答:

  1. positions是否均匀分布?
  2. 在主要图表中,当主要横坐标增加时,看起来子域的range正在缩小(例如,x = 22的面积宽度远小于{{1}的面积宽度}})。每个染色体索引的x = 2具有相同的范围position
  3. 假设所有染色体索引[1, 1e7]均匀分布在position中,[1, 1e7]的最大值为position(似乎并非如此) ,这样做的方法是1e7子域内每个圆的nudge轴值:

    x

    此处子域的chromosome.selectAll("circle") // ... .attr("cx", function (d, i) { /* Assuming that data provided is in the "correct" order * and `x1` is the ordinal scale. */ return x1(i) - x1.rangeBand() / 2 + d.position / 1e7; }) // ... 是隐式域,而不是scale