首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >D3.js tick格式:显示月份变化

D3.js tick格式:显示月份变化
EN

Stack Overflow用户
提问于 2018-12-11 22:16:16
回答 2查看 1.8K关注 0票数 3

我正在使用D3 (v4)显示一个在x轴上带有日期的条形图。

我正在尝试让tick显示月份的日期,除非它是我想让它显示月份的第1天,即指示月份发生变化的时间。我甚至不知道该从何说起。

当前格式如下所示:

但我希望它看起来更像这样:

生成轴的当前代码如下所示:

let timeFormat = "%b %d"
xAxis = g => g
      .attr("transform", `translate(0, ${height - margin.bottom})`)
      .call(d3.axisBottom(x).tickFormat(d3.timeFormat(timeFormat)))

我基本上需要一些类似的东西

let timeFormat = "%d == 0" ? "%b" :  "%d"

我知道在这个上下文中这是胡说八道的JS,但是它说明了我正在寻找的逻辑

以下是我的图表的简化版本的代码片段:

let keys = [];

var w = 400;
var h = 200;

var margin = {
  top: 30,
  bottom: 40,
  left: 50,
  right: 20,
}

var width = w - margin.left - margin.right
var height = h - margin.top - margin.bottom


var data = [
   {
      "count":100,
      "date":"2018-11-30T00:00:00"
   },
   {

      "count":50,
      "date":"2018-12-01T00:00:00"
   },
   {

      "count":75,
      "date":"2018-12-02T00:00:00"
   },
]


var x = d3.scaleTime()
  .domain(d3.extent(data, function(d) { return new Date(d.date) }))
  .range([0, width]);

var y = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.count)])
  .range([height, 0]);

var svg = d3.select('body').append('svg')
  .attr('class', 'chart')
  .attr('width', w)
  .attr('height', h);

var chart = svg.append('g')
  .classed('graph', true)
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
 
let timeFormat = "%b %d"
  
chart.append('g')
  .classed('x axis', true)
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x)
    .tickFormat(d3.timeFormat(timeFormat))
    .ticks(2)
  )

chart.append('g')
  .classed('y axis', true)
  .call(d3.axisLeft(y))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.min.js"></script>

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-11 22:37:37

您可以从scale获取ticks,并使用它来查看上一个刻度是否为另一个月,并基于此选择您的格式:

const longFormat = d3.timeFormat('%b');
const shortFormat = d3.timeFormat('%d');
const axis = d3.axisBottom(x);
axis.tickFormat((d, i) => {
    const ticks = axis.scale().ticks();

    if (i > 0 && ticks[i - 1].getMonth() === d.getMonth()) {
        return shortFormat(d);
    }
    else {
        return longFormat(d);
    }
});

xAxis = g => g
    .attr("transform", `translate(0, ${height - margin.bottom})`)
    .call(axis)

编辑:如果你使用的不是time scale而是scaleBand,你应该能够使用域来计算格式:

const ticks = axis.scale().domain();
票数 4
EN

Stack Overflow用户

发布于 2018-12-14 19:17:25

另一个版本:

    function multiFormat(date) {
      var formatMillisecond = d3.timeFormat(".%L"),
        formatSecond = d3.timeFormat(":%S"),
        formatMinute = d3.timeFormat("%I:%M"),
        formatHour = d3.timeFormat("%I %p"),
        formatDay = d3.timeFormat("%_d"),
        formatWeek = d3.timeFormat("%_d"),
        formatMonth = d3.timeFormat("%b"),
        formatYear = d3.timeFormat("%Y");
      return (d3.timeSecond(date) < date ? formatMillisecond
          : d3.timeMinute(date) < date ? formatSecond
          : d3.timeHour(date) < date ? formatMinute
          : d3.timeDay(date) < date ? formatHour
          : d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
          : d3.timeYear(date) < date ? formatMonth
          : formatYear)(date);
    }
...
.tickFormat(function(d){return multiFormat(d);})
...

let keys = [];

var w = 400;
var h = 200;

var margin = {
  top: 30,
  bottom: 40,
  left: 50,
  right: 20,
}

var width = w - margin.left - margin.right
var height = h - margin.top - margin.bottom


var data = [
   {
      "count":100,
      "date":"2018-11-30T00:00:00"
   },
   {

      "count":50,
      "date":"2018-12-01T00:00:00"
   },
   {

      "count":75,
      "date":"2018-12-02T00:00:00"
   },
]


var x = d3.scaleTime()
  .domain(d3.extent(data, function(d) { return new Date(d.date) }))
  .range([0, width]);

var y = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.count)])
  .range([height, 0]);

var svg = d3.select('body').append('svg')
  .attr('class', 'chart')
  .attr('width', w)
  .attr('height', h);

var chart = svg.append('g')
  .classed('graph', true)
  .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

function multiFormat(date) {
  var formatMillisecond = d3.timeFormat(".%L"),
    formatSecond = d3.timeFormat(":%S"),
    formatMinute = d3.timeFormat("%I:%M"),
    formatHour = d3.timeFormat("%I %p"),
    formatDay = d3.timeFormat("%_d"),
    formatWeek = d3.timeFormat("%_d"),
    formatMonth = d3.timeFormat("%b"),
    formatYear = d3.timeFormat("%Y");
  return (d3.timeSecond(date) < date ? formatMillisecond
      : d3.timeMinute(date) < date ? formatSecond
      : d3.timeHour(date) < date ? formatMinute
      : d3.timeDay(date) < date ? formatHour
      : d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
      : d3.timeYear(date) < date ? formatMonth
      : formatYear)(date);
}


  
chart.append('g')
  .classed('x axis', true)
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x)
    .tickFormat(function(d){return multiFormat(d);})
    .ticks(2)
  )

chart.append('g')
  .classed('y axis', true)
  .call(d3.axisLeft(y))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.min.js"></script>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53726046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档