📈 修复趋势坐标轴与移动日期选择
This commit is contained in:
@@ -212,6 +212,32 @@ const updatePart = (part: DatePart, value: string) => {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.native-date-strip {
|
||||
min-height: 2.35rem;
|
||||
padding-inline: 0.35ch;
|
||||
}
|
||||
|
||||
.native-date-part {
|
||||
height: 2.25rem;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.native-date-year {
|
||||
width: 3.7ch;
|
||||
}
|
||||
|
||||
.native-date-month,
|
||||
.native-date-day {
|
||||
width: 1.8ch;
|
||||
}
|
||||
|
||||
.native-date-separator {
|
||||
margin-inline: 0.15ch;
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
}
|
||||
|
||||
.dark .native-date-strip {
|
||||
background: rgba(38, 57, 65, 0.62);
|
||||
color: #d8e3e5;
|
||||
|
||||
@@ -44,10 +44,11 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
type DragState = {
|
||||
startX: number
|
||||
startOffset: number
|
||||
lastX: number
|
||||
time: number
|
||||
pointerType: string
|
||||
isTimeline: boolean
|
||||
moved: boolean
|
||||
}
|
||||
|
||||
@@ -162,10 +163,11 @@ const draw = (timestamp = performance.now()) => {
|
||||
const padBottom = mobile ? 42 : 36
|
||||
const width = Math.max(1, rect.width - padLeft - padRight)
|
||||
const height = Math.max(1, rect.height - padTop - padBottom)
|
||||
const max = Math.max(
|
||||
1,
|
||||
const rawMax = Math.max(
|
||||
0,
|
||||
...visible.flatMap((row) => [Number(row.downloads || 0), Number(row.uploads || 0)])
|
||||
)
|
||||
const max = rawMax <= 2 ? 3 : Math.ceil(rawMax / 3) * 3
|
||||
const muted = props.isDarkMode ? '#9ca3af' : '#6b7280'
|
||||
const border = props.isDarkMode ? '#374151' : '#e5e7eb'
|
||||
const downloadColor = props.isDarkMode ? '#8fb6c5' : '#5f8fa3'
|
||||
@@ -185,17 +187,23 @@ const draw = (timestamp = performance.now()) => {
|
||||
}
|
||||
|
||||
const denominator = Math.max(1, windowSize.value - 1)
|
||||
const plotLeft = padLeft
|
||||
const plotRight = padLeft + width
|
||||
const buildPoints = (field: 'downloads' | 'uploads') =>
|
||||
visible
|
||||
.map((row, index) => {
|
||||
const sourceIndex = start + index
|
||||
return {
|
||||
x: padLeft + ((sourceIndex - offset.value) / denominator) * width,
|
||||
x: clamp(
|
||||
padLeft + ((sourceIndex - offset.value) / denominator) * width,
|
||||
plotLeft,
|
||||
plotRight
|
||||
),
|
||||
y: padTop + height - (Number(row[field] || 0) / max) * height,
|
||||
row
|
||||
}
|
||||
})
|
||||
.filter((point) => point.x >= padLeft - 50 && point.x <= padLeft + width + 50)
|
||||
.filter((point) => point.x >= plotLeft && point.x <= plotRight)
|
||||
|
||||
const drawSeries = (points: ChartPoint[], color: string) => {
|
||||
ctx.strokeStyle = color
|
||||
@@ -392,17 +400,21 @@ const setHoverFromClientX = (clientX: number) => {
|
||||
}
|
||||
|
||||
const handlePointerDown = (event: PointerEvent) => {
|
||||
const rect = canvasRef.value?.getBoundingClientRect()
|
||||
canvasRef.value?.setPointerCapture(event.pointerId)
|
||||
cancelInertia()
|
||||
velocity.value = 0
|
||||
setHoverFromClientX(event.clientX)
|
||||
const isTimeline = Boolean(rect && event.clientY - rect.top >= rect.height - 52)
|
||||
drag.value = {
|
||||
startX: event.clientX,
|
||||
startOffset: offset.value,
|
||||
lastX: event.clientX,
|
||||
time: event.timeStamp || performance.now(),
|
||||
pointerType: event.pointerType,
|
||||
isTimeline,
|
||||
moved: false
|
||||
}
|
||||
if (isTimeline) canvasRef.value!.style.touchAction = 'none'
|
||||
}
|
||||
|
||||
const handlePointerMove = (event: PointerEvent) => {
|
||||
@@ -416,12 +428,12 @@ const handlePointerMove = (event: PointerEvent) => {
|
||||
return
|
||||
}
|
||||
|
||||
if (drag.value.pointerType === 'touch') {
|
||||
if (drag.value.pointerType === 'touch' && !drag.value.isTimeline) {
|
||||
scheduleDraw()
|
||||
return
|
||||
}
|
||||
|
||||
const totalDistance = Math.abs(latestEvent.clientX - drag.value.startX)
|
||||
const totalDistance = Math.abs(latestEvent.clientX - drag.value.lastX)
|
||||
const threshold = 3
|
||||
if (!drag.value.moved && totalDistance < threshold) {
|
||||
scheduleDraw()
|
||||
@@ -440,15 +452,18 @@ const handlePointerMove = (event: PointerEvent) => {
|
||||
}
|
||||
|
||||
const handlePointerUp = () => {
|
||||
const timelineDrag = drag.value?.isTimeline
|
||||
const shouldInertia = Boolean(drag.value?.moved)
|
||||
drag.value = null
|
||||
if (canvasRef.value) canvasRef.value.style.touchAction = ''
|
||||
cancelInertia()
|
||||
if (shouldInertia) inertiaRafId.value = window.requestAnimationFrame(applyInertia)
|
||||
if (shouldInertia && !timelineDrag) inertiaRafId.value = window.requestAnimationFrame(applyInertia)
|
||||
else scheduleDraw()
|
||||
}
|
||||
|
||||
const handlePointerCancel = () => {
|
||||
drag.value = null
|
||||
if (canvasRef.value) canvasRef.value.style.touchAction = ''
|
||||
}
|
||||
|
||||
const handlePointerLeave = () => {
|
||||
|
||||
Reference in New Issue
Block a user