带序号 x 轴的多线图

Multi line graph with ordinal x-axis

我使用下面的代码在 d3 中制作了一个带有线性 x 轴的多线图,它工作得很好。现在我想使 x 轴成为序数,但我不知道该怎么做。任何帮助都会很棒!

代码:

<!DOCTYPE html>
<html>
  <body>
    <center><h1>ZNF expression DFC</h1></center>
    <meta charset="utf-8">
    <style>

    .axis--x path {
      display: none;
    }

    .line {
      fill: none;
      stroke: steelblue;
      stroke-width: 3.0px;
    }

    div.tooltip { 
        position: absolute;     
        text-align: center;     
        width: 60px;          
        height: 18px;         
        padding: 2px;       
        font: 12px sans-serif;    
        background: lightsteelblue; 
        border: 0px;    
        border-radius: 8px;     
        pointer-events: none;     
    }


    </style>
    <svg width="1560" height="1000"></svg>
    <script src="//d3js.org/d3.v4.min.js"></script>
    <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
    <script>

    var svg = d3.select("svg"),
        margin = {top: 20, right: 80, bottom: 30, left: 50},
        width = svg.attr("width") - margin.left - margin.right,
        height = svg.attr("height") - margin.top - margin.bottom,
        g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var x = d3.scaleLinear().range([0, width]),
        y = d3.scaleLinear().range([height, 0]),
        z = d3.scaleOrdinal(d3.schemeCategory20);

    // Define the div for the tooltip
    var div = d3.select("body").append("div") 
        .attr("class", "tooltip")       
        .style("opacity", 0);

    var line = d3.line()
        .x(function(d) { return x(d.Age); })
        .y(function(d) { return y(d.expression); });

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

      var znfs = data.columns.slice(1).map(function(id) {
        return {
          id: id,
          values: data.map(function(d) {
            return {Age: d.Age, expression: d[id]};
          })
        };
      });

      x.domain([0, data.length]).range([0, width]);
      y.domain([0, 40]).range([height,0]);
      z.domain(znfs.map(function(c) { return c.id; }));

      g.append("g")
          .attr("class", "axis axis--x")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));

      g.append("g")
          .attr("class", "axis axis--y")
          .call(d3.axisLeft(y))
        .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", "0.71em")
          .attr("fill", "#000")
          .text("expression"  );

      var city = g.selectAll(".city")
        .data(znfs)
        .enter().append("g")
          .attr("class", "city");

      city.append("path")
          .attr("class", "line")
          .attr("d", function(d) { return line(d.values); })
          .style("stroke", function(d) { return z(d.id); })
          .on("mouseover", function(d) {    
                div.transition()    
                    .duration(200)    
                    .style("opacity", .9);    
                div .html(d.id)  
                    .style("left", (d3.event.pageX) + "px")   
                    .style("top", (d3.event.pageY - 28) + "px");  
                })          
            .on("mouseout", function(d) {   
                div.transition()    
                    .duration(500)    
                    .style("opacity", 0); 
            });
    });

    </script>
  </body>
</html>

我要处理的数据是一个 csv 文件,如下所示:

年龄,ZNF8,ZNF18,ZNF136,ZNF140 .... ZNF778,

"8pwc", 13.654, 12.643, 10.593, 8,124, .... 9.900,

"9pwc", 4.364, 1.004, 3.576, 0.032, .... 5.512,

“2 岁”, 65.345, 53.278, 33.001, 68.844, .... 54.544,

.....

谢谢!

在这种特殊情况下,您必须使用 point scale,这是一种序数比例:

Point scales are a variant of band scales with the bandwidth fixed to zero. Point scales are typically used for scatterplots with an ordinal or categorical dimension.

点刻度允许您将分类(定性)变量映射到连续数字输出。

因此,您的比例应该是:

var x = d3.scalePoint().range([0, width])

并且它的域应该定义为 map:

x.domain(data.map(d=>d.Age));

这是工作代码:https://plnkr.co/edit/2nOLP5fEIHbs2U8OQB2y?p=preview