简体   繁体   中英

D3.js: set axis position based on data

I'm trying to draw multiple graphs in one svg image, based on chromosomal data. The purpose is to draw 1 graph per chromosome. I want to transpose the axis (and the data) based on the chromosome number in de data.

Data entries look like this (in JSON):

[{
    "chrom": 1,
    "pos": 2000000,
    "ratio": 0.0253,
    "average": 0.0408,
    "stdev": 0.0257,
    "z-score": - 0.6021
}, {
    "chrom": 1,
    "pos": 2250000,
    "ratio": 0.0304,
    "average": 0.0452,
    "stdev": 0.0245,
    "z-score": - 0.6021
}, {
    "chrom": 1,
    "pos": 2500000,
    "ratio": 0.0357,
    "average": 0.0498,
    "stdev": 0.024,
    "z-score": - 0.5885
}, {
    "chrom": 1,
    "pos": 2750000,
    "ratio": 0.0381,
    "average": 0.0522,
    "stdev": 0.0228,
    "z-score": - 0.6146
},
{etc..}

Currently my code looks like this:

d3.json("data.json", function(error, data) {
      if (error) throw error;

      x.domain(d3.extent(data, function(d) { return d.pos; }));
      y.domain(d3.extent(data, function(d) { return d['ratio']; }));


      svg.append("g")
      .attr("class", "x axis")
      .data(data)
      //.attr("transform", "translate(0," + graph_height + ")")
      .attr('transform', function(d) {
        if (d.chrom > Math.ceil(chrnumber / 2)) {
          console.log('translate('+ graph_width + graph_margin.center + ',' + graph_height + d.chrom * (graph_height + graph_margin.top) + ')');
          return 'translate('+ graph_width + graph_margin.center + ',' + graph_height + d.chrom * (graph_height + graph_margin.top) + ')';
        }else {
          console.log('translate(0,' + graph_height + d.chrom * (graph_height + graph_margin.top) + ')');
          return 'translate(0,' + graph_height + d.chrom * (graph_height + graph_margin.top) + ')';
        }
      })
      .call(xAxis);
    });

But this yields no errors, nor any output. I suppose there is some kind of error in the code above, because the svg image isn't generated on the page.

Does anyone have an idea where I went wrong?

The lines here:

svg.append("g")
  .attr("class", "x axis")
  .data(data)

are not enough to create one axis per chromosome. One way to do it (might not be the simplest, but a very "d3-friendly" one) is to create an array representing your set of chromosomes.

var chromList = d3.set(                  //data structure removing duplicates
                  data.map(function(d) { // create a list from data by ...
                    return d.chrom       // ...keeping only the chrom field
                  }).values();           // export the set as an array
   //chromList=[1,2,3 ..], according to the values of chrom seen in your data.

Now you bind this list to your axis, in order to create one axis per element:

svg.append("g")       //holder of all x axis
  .selectAll(".axis") //creates an empty selection at first, but it will be filled next.
  .data(chromList)    //bind the list of chrom ids to the selection
  .enter()            //the selection was empty, so each chromosome is "entering"
  .append("g")        //for each chromosome, insert a g element: this is the corresponding axis
  .attr("class", "x axis")
  .attr('transform', function(d) {
         //use d here as your chromosome identifier
     });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM