修复柱状图与日期标签对齐:flex 布局统一使用 justify-between,移除峰值加粗
This commit is contained in:
parent
66e61ef51b
commit
31f4d247fe
|
|
@ -1,42 +1,27 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const BarChart = ({ data = [], width = 400, height = 80, color = 'currentColor' }) => {
|
const BarChart = ({ data = [], height = 80, barW = 24 }) => {
|
||||||
if (!data || data.length === 0) return null;
|
if (!data || data.length === 0) return null;
|
||||||
|
|
||||||
const max = Math.max(...data, 1);
|
const max = Math.max(...data, 1);
|
||||||
const barCount = data.length;
|
|
||||||
const gap = 4;
|
|
||||||
const totalGap = (barCount - 1) * gap;
|
|
||||||
const barWidth = Math.max(8, (width - totalGap) / barCount);
|
|
||||||
const totalUsed = barCount * barWidth + totalGap;
|
|
||||||
const offsetX = (width - totalUsed) / 2;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<div className='flex w-full items-end justify-between' style={{ height }}>
|
||||||
width='100%'
|
|
||||||
height={height}
|
|
||||||
viewBox={`0 0 ${width} ${height}`}
|
|
||||||
preserveAspectRatio='none'
|
|
||||||
>
|
|
||||||
{data.map((v, i) => {
|
{data.map((v, i) => {
|
||||||
const barH = Math.max(2, (v / max) * (height - 4));
|
const pct = Math.max(2, Math.round((v / max) * 100));
|
||||||
const x = offsetX + i * (barWidth + gap);
|
|
||||||
const y = height - barH;
|
|
||||||
const rx = Math.min(3, barWidth / 3);
|
|
||||||
return (
|
return (
|
||||||
<rect
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
x={x}
|
className='w-full flex justify-center'
|
||||||
y={y}
|
>
|
||||||
width={barWidth}
|
<div
|
||||||
height={barH}
|
className='rounded-sm bg-blue-500'
|
||||||
rx={rx}
|
style={{ height: `${pct}%`, width: barW }}
|
||||||
fill={color}
|
/>
|
||||||
opacity={0.85}
|
</div>
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</svg>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,27 +224,20 @@ const BentoTrend = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex min-h-[80px] flex-1 items-end text-blue-500'>
|
<div className='flex min-h-[80px] flex-1 items-end text-blue-500'>
|
||||||
<BarChart data={counts} width={400} height={80} />
|
<BarChart data={counts} height={80} barW={26} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex items-center justify-between text-[11px]'>
|
<div className='flex items-center justify-between text-[11px]'>
|
||||||
<div className='flex w-full items-center justify-between tabular-nums'>
|
<div className='flex w-full items-center justify-between tabular-nums'>
|
||||||
{dailyStats.map((d, i) => {
|
{dailyStats.map((d, i) => (
|
||||||
const isPeak = d.count === peak && peak > 0;
|
<span
|
||||||
return (
|
key={i}
|
||||||
<span
|
className='text-center text-xs text-slate-500 dark:text-white/50'
|
||||||
key={i}
|
title={`${d.date.getMonth() + 1}月${d.date.getDate()}日 ${d.count} 次`}
|
||||||
className={`text-center text-xs ${
|
>
|
||||||
isPeak
|
{formatMD(d.date)}
|
||||||
? 'font-semibold text-slate-900 dark:text-white'
|
</span>
|
||||||
: 'text-slate-500 dark:text-white/50'
|
))}
|
||||||
}`}
|
|
||||||
title={`${d.date.getMonth() + 1}月${d.date.getDate()}日 ${d.count} 次`}
|
|
||||||
>
|
|
||||||
{formatMD(d.date)}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
</div>
|
||||||
<div className='ml-4 shrink-0 text-slate-500 tabular-nums dark:text-white/50'>
|
<div className='ml-4 shrink-0 text-slate-500 tabular-nums dark:text-white/50'>
|
||||||
峰值{' '}
|
峰值{' '}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue