自定义d3时间轴

Flink流处理
• 阅读 2214

d3的时间比例尺scaleTime在使用的时候遇到过展示格式是YYYY-MM-DD HH:mm:ss的时候,出现文字覆盖的问题,内部的ticks方法并不能很好的控制间距,因为ticks只是一个参考值,实际展示时,坐标轴label个数可能多于ticks,也就比较难避免覆盖问题。
如果要解决时间展示覆盖问题,一个方案是实际展示的个数不大于ticks,这样就可以避免覆盖。d3提供了tickValues方法用于完全自定义坐标轴的显示,当然也需要自己实现时间轴的处理,包括间距的计算,缩放时候的处理,时分秒的处理,尽量让时间可读性更好。下面给出供参考的方案

// scale 缩放函数,坐标轴对应的domain和range,最大的ticks

export function getTickValues(scale, domain, range, ticks = 10) {
//找到开始结束位置对应的时间戳
//优化开始时间和结束时间
let left = nice(scale.invert(range[0]))
let right = nice(scale.invert(range[1]))
let leftRightRange = (right - left) / 1000
let interval = Math.ceil(leftRightRange / ticks)
let count = Math.ceil((domain[1] - domain[0]) / 1000 / interval)

// 时间取整
if (interval / 86400 > 0.5) {
  interval = Math.ceil(interval / 86400) * 86400
} else if (interval > 3600) {
  interval = Math.ceil(interval / 3600) * 3600
} else if (interval > 1800) {
  interval = Math.ceil(interval / 1800) * 1800
} else if (interval > 900) {
  interval = Math.ceil(interval / 900) * 900
} else if (interval > 600) {
  interval = Math.ceil(interval / 600) * 600
} else if (interval > 300) {
  interval = Math.ceil(interval / 300) * 300
} else if (interval > 60) {
  interval = Math.ceil(interval / 60) * 60
}

let tickValues = d3.range(count).map(item => {
  return item * interval * 1000 + domain[0]
})
// 过滤不在范围内的值
return tickValues.filter(item => {
  return item >= left && item <= right
})
}

通过invert函数,找出range对应的domain,然后处理每一段的间距,然后取整。从开始时间获得所有间距,过滤不可见的数据。
适用于折线图的展示,对于柱状图,类似的方式,不过需要在此基础上多处理一步。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
美凌格栋栋酱 美凌格栋栋酱
6个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Flink流处理
Flink流处理
Lv1
故园渺何处,归思方悠哉。
文章
5
粉丝
0
获赞
0