add acc slider to the pp graph
Some checks failed
Deploy Website / docker (ubuntu-latest) (push) Has been cancelled
Some checks failed
Deploy Website / docker (ubuntu-latest) (push) Has been cancelled
This commit is contained in:
parent
b7349f0226
commit
077bb6d73b
@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import GenericChart, { DatasetConfig } from "@/components/chart/generic-chart";
|
||||
import ScoreSaberLeaderboard from "@ssr/common/leaderboard/impl/scoresaber-leaderboard";
|
||||
import { scoresaberService } from "@ssr/common/service/impl/scoresaber";
|
||||
import Card from "@/components/card";
|
||||
import { DualRangeSlider } from "@/components/ui/dual-range-slider";
|
||||
import { useDebounce } from "@uidotdev/usehooks";
|
||||
|
||||
type Props = {
|
||||
/**
|
||||
@ -14,10 +16,15 @@ type Props = {
|
||||
};
|
||||
|
||||
export default function LeaderboardPpChart({ leaderboard }: Props) {
|
||||
const [values, setValues] = useState([60, 100]);
|
||||
const debouncedMin = useDebounce(values[0], 100);
|
||||
|
||||
const histories: Record<string, (number | null)[]> = {};
|
||||
const labels: string[] = [];
|
||||
const min = debouncedMin;
|
||||
const precision = min >= 60 ? 0.1 : 0.2;
|
||||
|
||||
for (let accuracy = 60; accuracy <= 100; accuracy += 0.2) {
|
||||
for (let accuracy = min; accuracy <= 100; accuracy += precision) {
|
||||
const label = accuracy.toFixed(2) + "%";
|
||||
labels.push(label);
|
||||
|
||||
@ -45,9 +52,24 @@ export default function LeaderboardPpChart({ leaderboard }: Props) {
|
||||
];
|
||||
|
||||
return (
|
||||
<Card className="h-64 w-full">
|
||||
<Card className="w-full gap-7">
|
||||
<div className="flex flex-col h-64">
|
||||
<p className="font-semibold">PP Curve</p>
|
||||
<GenericChart labels={labels} datasetConfig={datasetConfig} histories={histories} />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center">
|
||||
<div className="w-[95%]">
|
||||
<DualRangeSlider
|
||||
label={value => <span>{value}%</span>}
|
||||
value={values}
|
||||
onValueChange={setValues}
|
||||
min={5}
|
||||
max={100}
|
||||
step={1}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
48
projects/website/src/components/ui/dual-range-slider.tsx
Normal file
48
projects/website/src/components/ui/dual-range-slider.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as SliderPrimitive from "@radix-ui/react-slider";
|
||||
import { cn } from "@/common/utils";
|
||||
|
||||
interface DualRangeSliderProps extends React.ComponentProps<typeof SliderPrimitive.Root> {
|
||||
labelPosition?: "top" | "bottom";
|
||||
label?: (value: number | undefined) => React.ReactNode;
|
||||
}
|
||||
|
||||
const DualRangeSlider = React.forwardRef<React.ElementRef<typeof SliderPrimitive.Root>, DualRangeSliderProps>(
|
||||
({ className, label, labelPosition = "top", ...props }, ref) => {
|
||||
const initialValue = Array.isArray(props.value) ? props.value : [props.min, props.max];
|
||||
|
||||
return (
|
||||
<SliderPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn("relative flex w-full touch-none select-none items-center text-[15px]", className)}
|
||||
{...props}
|
||||
>
|
||||
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
|
||||
<SliderPrimitive.Range className="absolute h-full bg-primary" />
|
||||
</SliderPrimitive.Track>
|
||||
{initialValue.map((value, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<SliderPrimitive.Thumb className="block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50">
|
||||
{label && (
|
||||
<span
|
||||
className={cn(
|
||||
"absolute flex w-full justify-center",
|
||||
labelPosition === "top" && "-top-7",
|
||||
labelPosition === "bottom" && "top-4"
|
||||
)}
|
||||
>
|
||||
{label(value)}
|
||||
</span>
|
||||
)}
|
||||
</SliderPrimitive.Thumb>
|
||||
</React.Fragment>
|
||||
))}
|
||||
</SliderPrimitive.Root>
|
||||
);
|
||||
}
|
||||
);
|
||||
DualRangeSlider.displayName = "DualRangeSlider";
|
||||
|
||||
export { DualRangeSlider };
|
Reference in New Issue
Block a user