自定義d3時間軸

d3的時間比例尺scaleTime在使用的時候遇到過展現格式是YYYY-MM-DD HH:mm:ss的時候,出現文字覆蓋的問題,內部的ticks方法並不能很好的控制間距,由於ticks只是一個參考值,實際展現時,座標軸label個數可能多於ticks,也就比較難避免覆蓋問題。
若是要解決時間展現覆蓋問題,一個方案是實際展現的個數不大於ticks,這樣就能夠避免覆蓋。d3提供了tickValues方法用於徹底自定義座標軸的顯示,固然也須要本身實現時間軸的處理,包括間距的計算,縮放時候的處理,時分秒的處理,儘可能讓時間可讀性更好。下面給出供參考的方案dom

// 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,而後處理每一段的間距,而後取整。從開始時間得到全部間距,過濾不可見的數據。
適用於折線圖的展現,對於柱狀圖,相似的方式,不過須要在此基礎上多處理一步。函數

相關文章
相關標籤/搜索