mirror of
https://github.com/supabase/supabase.git
synced 2026-10-18 07:39:07 +03:00
chart updates
This commit is contained in:
1 parent
c02c1b9ce4
commit
5efafef89c
4 files changed
+114
-35
No files matched your search
@@ -29,6 +29,7 @@ export default function ProjectsPage() {
|
||||
<div className="flex gap-10">
|
||||
<QueriesChart />
|
||||
<ReadAndWritesChart />
|
||||
<QueriesChart />
|
||||
</div>
|
||||
{/* <IOPSChart /> */}
|
||||
{/* <StorageChart /> */}
|
||||
|
||||
@@ -14,11 +14,13 @@ export default function TopHeader() {
|
||||
selectedOrg,
|
||||
selectedProject,
|
||||
selectedEnv: { type },
|
||||
settingsAllPreviews,
|
||||
} = config
|
||||
|
||||
const isPreview =
|
||||
type !== 'prod' &&
|
||||
!resolveHideBranchesDropdown(pathName, selectedOrg?.key, selectedProject?.key)
|
||||
(settingsAllPreviews && pathName.includes(`${selectedOrg?.key}/settings`)) ||
|
||||
(type !== 'prod' &&
|
||||
!resolveHideBranchesDropdown(pathName, selectedOrg?.key, selectedProject?.key))
|
||||
|
||||
const pickersHidden =
|
||||
resolveHideBranchesDropdown(pathName, selectedOrg?.key, selectedProject?.key) &&
|
||||
|
||||
@@ -1,17 +1,47 @@
|
||||
'use client'
|
||||
|
||||
import React from 'react'
|
||||
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'
|
||||
import React, { useRef, useEffect, useState } from 'react'
|
||||
import { BarChart, Bar, XAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'
|
||||
|
||||
const generateBarChartData = () => {
|
||||
// Generate initial data with timestamps, query values, and unique IDs
|
||||
const generateInitialBarChartData = () => {
|
||||
return Array.from({ length: 120 }, (_, i) => ({
|
||||
time: `${14 + Math.floor(i / 4)}:${(i % 4) * 15}`,
|
||||
id: i,
|
||||
time: `${14 + Math.floor(i / 4)}:${String((i % 4) * 15).padStart(2, '0')}`,
|
||||
queries: Math.floor(Math.random() * 3000),
|
||||
}))
|
||||
}
|
||||
|
||||
// Calculate the next time value based on the last data point
|
||||
const getNextTime = (lastTime) => {
|
||||
const [hours, minutes] = lastTime.split(':').map(Number)
|
||||
const newMinutes = (minutes + 15) % 60
|
||||
const newHours = newMinutes === 0 ? hours + 1 : hours
|
||||
return `${String(newHours).padStart(2, '0')}:${String(newMinutes).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
const QueriesChart = () => {
|
||||
const data = generateBarChartData()
|
||||
const [data, setData] = useState(generateInitialBarChartData())
|
||||
const dataRef = useRef(data)
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
const lastDataPoint = dataRef.current[dataRef.current.length - 1]
|
||||
const newTime = getNextTime(lastDataPoint.time)
|
||||
const newQueries = Math.floor(Math.random() * 3000)
|
||||
const newData = [
|
||||
...dataRef.current.slice(1),
|
||||
{ id: lastDataPoint.id + 1, time: newTime, queries: newQueries },
|
||||
]
|
||||
dataRef.current = newData
|
||||
setData(newData)
|
||||
}, 5000)
|
||||
|
||||
return () => clearInterval(interval)
|
||||
}, [])
|
||||
|
||||
console.log('render')
|
||||
console.log(data)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 grow">
|
||||
@@ -21,19 +51,21 @@ const QueriesChart = () => {
|
||||
</div>
|
||||
<ResponsiveContainer width="100%" height={200}>
|
||||
<BarChart
|
||||
width={200}
|
||||
height={200}
|
||||
data={data}
|
||||
barGap={4}
|
||||
className="[&_.recharts-bar-rectangle>path]:fill-foreground/50 [&_.recharts-bar-rectangle:last-of-type>path]:fill-foreground"
|
||||
>
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
vertical={false}
|
||||
className="stroke-border-secondary"
|
||||
/>
|
||||
|
||||
<XAxis dataKey="time" className="text-xs text-foreground-muted" />
|
||||
{/* <YAxis /> */}
|
||||
<CartesianGrid strokeDasharray="3 3" vertical={false} className="stroke-border" />
|
||||
{/* <XAxis dataKey="time" className="text-xs text-foreground-muted" /> */}
|
||||
<Tooltip />
|
||||
<Bar dataKey="queries" className="border-b border-red-900" />
|
||||
<Bar
|
||||
isAnimationActive={false}
|
||||
dataKey="queries"
|
||||
animationDuration={1000}
|
||||
maxBarSize={1.5}
|
||||
/>
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Area, AreaChart, CartesianGrid, ResponsiveContainer, Tooltip, XAxis } f
|
||||
|
||||
const generateLineChartData = () => {
|
||||
let reads = 12400
|
||||
let writes = 300
|
||||
let writes = 1000
|
||||
|
||||
return Array.from({ length: 20 }, (_, i) => {
|
||||
reads = reads + (Math.random() - 0.5) * 5000 // Add variation to reads
|
||||
@@ -17,6 +17,7 @@ const generateLineChartData = () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const ReadAndWritesChart = () => {
|
||||
const data = generateLineChartData()
|
||||
|
||||
@@ -27,56 +28,99 @@ const ReadAndWritesChart = () => {
|
||||
<div className="h-2 w-4 rounded-full bg-foreground"></div>
|
||||
<div className="flex items-baseline gap-2">
|
||||
<h2 className="text-2xl font-mono font-extralight text-foreground">3,402</h2>
|
||||
<span className="text-xs font-mono text-foreground-lighter">Reads</span>
|
||||
<span className="text-xs font-mono text-foreground-lighter">Rows read</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="h-2 w-4 rounded-full bg-brand"></div>
|
||||
<div className="flex items-baseline gap-2">
|
||||
<h2 className="text-2xl font-mono font-extralight text-foreground">242</h2>
|
||||
<span className="text-xs font-mono text-foreground-lighter">Writes</span>
|
||||
<span className="text-xs font-mono text-foreground-lighter">Rows write</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ResponsiveContainer width="100%" height={200}>
|
||||
<AreaChart
|
||||
data={data}
|
||||
// className="[&_.recharts-area>.recharts-layer>path]:fill-foreground/50
|
||||
// "
|
||||
className="[&_.recharts-area-dots>circle]:hidden [&_.recharts-area-dots>circle:last-of-type]:block"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="colorUv" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="hsl(var(--foreground-default))" stopOpacity={0.2} />
|
||||
<stop offset="95%" stopColor="#8884d8" stopOpacity={0} />
|
||||
</linearGradient>
|
||||
<linearGradient id="colorPv" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor="hsl(var(--brand-default))" stopOpacity={0.2} />
|
||||
<stop offset="95%" stopColor="#82ca9d" stopOpacity={0} />
|
||||
<linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="0%" stopColor="white" stopOpacity="1" />
|
||||
<stop offset="100%" stopColor="white" stopOpacity="0" />
|
||||
</linearGradient>
|
||||
|
||||
<mask id="fadeMask">
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="url(#fade)" />
|
||||
</mask>
|
||||
|
||||
<pattern
|
||||
id="pattern1"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
patternTransform="rotate(45)"
|
||||
>
|
||||
<line
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="0"
|
||||
y2="6"
|
||||
stroke="hsl(var(--foreground-default)/10%)"
|
||||
strokeWidth="1"
|
||||
/>
|
||||
</pattern>
|
||||
|
||||
<pattern
|
||||
id="pattern2"
|
||||
patternUnits="userSpaceOnUse"
|
||||
width="6"
|
||||
height="6"
|
||||
patternTransform="rotate(45)"
|
||||
>
|
||||
<line
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="0"
|
||||
y2="6"
|
||||
stroke="hsl(var(--brand-default)/10%)"
|
||||
strokeWidth="1"
|
||||
/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<CartesianGrid
|
||||
strokeDasharray="3 3"
|
||||
vertical={false}
|
||||
className="stroke-border-secondary"
|
||||
/>
|
||||
<XAxis dataKey="time" className="text-xs text-foreground-muted" />
|
||||
{/* <YAxis className="text-xs [&_line]:stroke-border-secondary [&_text]:fill-foreground-muted" /> */}
|
||||
<Tooltip />
|
||||
<Area
|
||||
isAnimationActive={false}
|
||||
type="monotone"
|
||||
dataKey="reads"
|
||||
stroke="hsl(var(--foreground-default))"
|
||||
fill="url(#colorUv)"
|
||||
stroke="hsl(var(--foreground-default)/50%)"
|
||||
fill="url(#pattern1)"
|
||||
fillOpacity={1}
|
||||
dot={false}
|
||||
strokeWidth={1.5}
|
||||
dot={{
|
||||
stroke: 'hsl(var(--foreground-default))',
|
||||
strokeWidth: 2,
|
||||
className: 'z-10 foreground-foreground',
|
||||
}}
|
||||
/>
|
||||
<Area
|
||||
isAnimationActive={false}
|
||||
type="monotone"
|
||||
dataKey="writes"
|
||||
stroke="hsl(var(--brand-default))"
|
||||
fill="url(#colorPv)"
|
||||
fill="url(#pattern2)"
|
||||
fillOpacity={1}
|
||||
dot={false}
|
||||
strokeWidth={1.5}
|
||||
dot={{
|
||||
stroke: 'hsl(var(--brand-default))',
|
||||
strokeWidth: 2,
|
||||
className: 'z-10 foreground-brand',
|
||||
}}
|
||||
/>
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
|
||||
Reference in new issue
Block a user