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