【问题标题】:Forcing area graph's X-Axis tick marks based on data points基于数据点强制面积图的 X 轴刻度线
【发布时间】:2019-03-12 18:46:56
【问题描述】:

我正在使用 D3 的面积图为具有这种结构的数据构建图表:

data = [
  {
    date: "2019-02-01", 
    value: 100
  }, {
    date: "2019-03-01", 
    value: 1
  }
]

当我使用D3's Area Chart Example 时,他们将 X 轴设置为:

const x = d3.scaleTime()
    .domain(d3.extent(data, d => Date.parse(d.date)))
    .range([margin.left, width - margin.right])
const xAxis = g => g
    .attr("transform", `translate(0,${height - margin.bottom})`)
    .call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0));

但是,这会在整个 X 轴上均匀添加刻度线。我尝试过类似的事情:

const xAxis = g => g
    .attr("transform", 'translate(0,' + (height + data.length) + ')')
    .call(d3.axisBottom(x).ticks(data.length).tickSizeOuter(0));

但是 X 轴上没有出现任何内容。如何让 X 轴仅在我的数据中给定的 date 值上显示刻度线(即对于上面的示例数据,我只想看看2019-02-012019-03-01 在 X 轴上)。

最好只显示这些日期的月份和年份(即2019-02-01 将在图表上显示为Feb. 2019)。

【问题讨论】:

    标签: javascript d3.js charts


    【解决方案1】:

    您可以通过向axis.tickValues() 提供一个包含所需刻度值的数组来指定哪些值应该是刻度。如果你的刻度应该是你的数据数组中的值,那么你只需要遍历你的数组并挑选出这些值。在您的情况下,这可能看起来像:

    var axis = d3.axisBottom()
      .scale(x)
      .tickValues(
         data.map(function(d) { return timeParse(d.date); })
      )
    

    如果您的刻度是时间刻度,则值必须是日期对象,因此我们无法传递格式化的日期。但是,如果我们想指定刻度的显示方式,那么我们也可以将格式传递给axis.tickFormat,这将让您设置日期的显示方式。我们一起得到:

    var svg = d3.select("svg");
    
    var data = data = [
      {
        date: "2019-02-01", 
        value: 100
      },
      {
        date: "2019-03-1", 
        value: 50
      },
      {
        date: "2019-05-01", 
        value: 1
      }
    
    ];
    
    var timeParse = d3.timeParse("%Y-%m-%d");
    var timeFormat = d3.timeFormat("%B %Y");
    
    var x = d3.scaleTime()
      .domain(d3.extent(data,function(d) { return timeParse(d.date); }))
      .range([20,300]);
      
    var y = d3.scaleLinear()
      .domain([0,100])
      .range([10,100]);
      
    var line = d3.line()
      .x(function(d) { return x(timeParse(d.date)); })
      .y(function(d) { return y(d.value); })
      
    svg.append("path")
      .datum(data)
      .attr("d", line);
      
    // Axis:
    var axisBottom = d3.axisBottom()
      .scale(x)
      .tickValues(data.map(function(d) {
        return timeParse(d.date); // specify which values should be ticks.
      }))
      .tickFormat(timeFormat);
      
    svg.append("g")
      .attr("transform","translate(0,100)")
      .call(axisBottom);
      
      
      
    svg.selectAll("text")
      .attr("text-anchor","start")
      .attr("transform","rotate(90)translate(10,-13)");
    path {
      fill: none;
      stroke: black;
      stroke-width: 1px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    <svg width="400" height="400"></svg>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 1970-01-01
      • 2014-12-24
      • 2014-08-16
      • 2021-10-29
      • 1970-01-01
      相关资源
      最近更新 更多