Skip to content

Commit

Permalink
releasef no hoover for tooltip on a big window size
Browse files Browse the repository at this point in the history
  • Loading branch information
Sammers21 committed Oct 1, 2024
1 parent 7fd9b6e commit 824a96c
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 157 deletions.
293 changes: 161 additions & 132 deletions frontend/src/containers/Meta/Grid/columnGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,132 +1,161 @@
import { LinearProgress, Tooltip } from '@mui/material';
import { getClassNameColor, getSpecIcon } from '@/utils/table';

import type { IMetaSpec, IMetaSpecSizing, IMeta } from '@/types';
import type {
GridAlignment,
GridColDef,
GridColumnGroup,
GridRenderCellParams,
GridValidRowModel,
} from '@mui/x-data-grid';

const PercentageCell = (params: GridRenderCellParams & { colDef: { maxVal: number } }) => {
const progressColor = params.field.includes('presence') ? 'red' : 'green';

const progress = (params.value / params.colDef.maxVal) * 100;
const trueVal = (params.value * 100).toFixed(2) + '%';

if (params.value === 0) {
return (
<div className="w-full">
<span className="text-base">-</span>
</div>
);
}

return (
<div className="w-full">
<span className="text-base">{trueVal}</span>
<LinearProgress
sx={{
backgroundColor: 'transparent',
'& .MuiLinearProgress-bar': { backgroundColor: progressColor },
}}
variant="determinate"
value={progress}
/>
</div>
);
};

function numericColumn(
fieldName: string,
headerName: string,
maxVal: number
): GridColDef & { maxVal: number } {
return {
field: fieldName,
maxVal: maxVal,
headerName: headerName,
minWidth: 50,
editable: false,
flex: 1,
renderCell: PercentageCell as any,
};
}

export function specNameColumn(isMobile: boolean): GridColDef {
return {
field: 'spec_name',
headerName: 'Spec',
width: isMobile ? 10 : 250,
editable: false,
renderCell: (params) => {
const specIcon = getSpecIcon(params.value);

return (
<div className="flex justify-start items-center">
<img src={specIcon} className="w-6 h-6" alt="spec-icon" />
{!isMobile && (
<span className="pl-2 text-base" style={{ color: getClassNameColor(params.value) }}>
{params.value}
</span>
)}
</div>
);
},
};
}

export function getColumnGroup(
data: null | IMeta,
field: string,
rankIcons: string[]
): { columns: GridColDef<GridValidRowModel>[]; columnGroup: GridColumnGroup } {
const popularity = `${field}_presence` as keyof IMetaSpec;
const winrate = `${field}_win_rate` as keyof IMetaSpec;

let maxPopularity = 0;
let maxWr = 0;
if (data?.specs) {
data?.specs.forEach((spec) => {
maxPopularity = Math.max(maxPopularity, spec[popularity] as number);
maxWr = Math.max(maxWr, spec[winrate] as number);
});
}

let columnTitle = `No data for ${field}`;
if (data?.specs_sizing) {
const charCount = data.specs_sizing[`${field}_total` as keyof IMetaSpecSizing] || 0;
const from = data.specs_sizing[`${field}_min` as keyof IMetaSpecSizing] || 0;
const to = data.specs_sizing[`${field}_max` as keyof IMetaSpecSizing] || 0;

columnTitle = `Based on ${charCount} characters between ${from} and ${to} rating`;
}

const columns = [
numericColumn(popularity, 'Popularity %', maxPopularity),
numericColumn(winrate, 'Win %', maxWr),
];

const columnGroup = {
groupId: field,
children: [{ field: popularity }, { field: winrate }],
headerAlign: 'center' as GridAlignment,
renderHeaderGroup: () => (
<Tooltip title={columnTitle} placement="top-end">
<div className="flex justify-center">
{rankIcons.map((icon) => (
<img
className="h-9 w-9 mr-2"
src={require('../../../assets/ranks/' + icon)}
alt="Rank icon"
/>
))}
</div>
</Tooltip>
),
};

return { columns, columnGroup };
}
import { LinearProgress, Tooltip } from "@mui/material";
import { getClassNameColor, getSpecIcon } from "@/utils/table";

import type { IMetaSpec, IMetaSpecSizing, IMeta } from "@/types";
import type {
GridAlignment,
GridColDef,
GridColumnGroup,
GridRenderCellParams,
GridValidRowModel,
} from "@mui/x-data-grid";

const PercentageCell = (
params: GridRenderCellParams & { colDef: { maxVal: number } }
) => {
const progressColor = params.field.includes("presence") ? "red" : "green";

const progress = (params.value / params.colDef.maxVal) * 100;
const trueVal = (params.value * 100).toFixed(2) + "%";

if (params.value === 0) {
return (
<div className="w-full">
<span className="text-base">-</span>
</div>
);
}

return (
<div className="w-full">
<span className="text-base">{trueVal}</span>
<LinearProgress
sx={{
backgroundColor: "transparent",
"& .MuiLinearProgress-bar": { backgroundColor: progressColor },
}}
variant="determinate"
value={progress}
/>
</div>
);
};

function numericColumn(
fieldName: string,
headerName: string,
maxVal: number
): GridColDef & { maxVal: number } {
return {
field: fieldName,
maxVal: maxVal,
headerName: headerName,
minWidth: 50,
editable: false,
flex: 1,
renderCell: PercentageCell as any,
};
}

export function specNameColumn(isMobile: boolean): GridColDef {
return {
field: "spec_name",
headerName: "Spec",
width: isMobile ? 10 : 250,
editable: false,
renderCell: (params) => {
const specIcon = getSpecIcon(params.value);

return (
<div className="flex justify-start items-center">
<img src={specIcon} className="w-6 h-6" alt="spec-icon" />
{!isMobile && (
<span
className="pl-2 text-base"
style={{ color: getClassNameColor(params.value) }}
>
{params.value}
</span>
)}
</div>
);
},
};
}

export function getColumnGroup(
data: null | IMeta,
field: string,
rankIcons: string[],
wh: number
): { columns: GridColDef<GridValidRowModel>[]; columnGroup: GridColumnGroup } {
const popularity = `${field}_presence` as keyof IMetaSpec;
const winrate = `${field}_win_rate` as keyof IMetaSpec;

let maxPopularity = 0;
let maxWr = 0;
if (data?.specs) {
data?.specs.forEach((spec) => {
maxPopularity = Math.max(maxPopularity, spec[popularity] as number);
maxWr = Math.max(maxWr, spec[winrate] as number);
});
}

let columnTitle = `No data for ${field}`;
let charCount = 0;
let from = 0;
let to = 3000;
if (data?.specs_sizing) {
charCount =
data.specs_sizing[`${field}_total` as keyof IMetaSpecSizing] || 0;
from = data.specs_sizing[`${field}_min` as keyof IMetaSpecSizing] || 0;
to = data.specs_sizing[`${field}_max` as keyof IMetaSpecSizing] || 0;

columnTitle = `Based on ${charCount} characters between ${from} and ${to} rating`;
}

const columns = [
numericColumn(popularity, "Popularity %", maxPopularity),
numericColumn(winrate, "Win %", maxWr),
];

// const textTip
const topText = `Based on ${charCount} characters`;
const bottomText = `From ${from} to ${to} rating`;



const columnGroup = {
groupId: field,
children: [{ field: popularity }, { field: winrate }],
headerAlign: "center" as GridAlignment,
renderHeaderGroup: () => (
<Tooltip title={columnTitle} placement="top-end">
<div className="flex flex-row items-center">
<div className="flex justify-center">
{rankIcons.map((icon) => (
<img
className="h-9 w-9 mr-2"
src={require("../../../assets/ranks/" + icon)}
alt="Rank icon"
/>
))}
</div>
{/* Text on top */}
{ wh > 1600 && (
<div className="flex flex-col items-center">
<p className="text-sm font-mono ">
{topText}
</p>
<p className="text-sm font-mono ">
{bottomText}
</p>
</div>
)}
</div>
</Tooltip>
),
};

return { columns, columnGroup };
}
9 changes: 5 additions & 4 deletions frontend/src/containers/Meta/Grid/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import { useParams, useSearchParams } from 'react-router-dom';
import { createBreakpoint } from 'react-use';
import { createBreakpoint, useWindowSize } from 'react-use';

import { DataGrid, gridClasses } from '@mui/x-data-grid';
import { styled, alpha } from '@mui/material/styles';
Expand Down Expand Up @@ -55,12 +55,13 @@ function paramFromString(str: string) {
return str.toLowerCase().replace(' ', '_');
}

const useBreakpoint = createBreakpoint({ S: 758, L: 900, XL: 1280 });
const useBreakpoint = createBreakpoint({ S: 758, L: 900, XL: 1280, XXL: 1600 });

const Grid = () => {
const { region = REGION.eu } = useParams();
const [data, setData] = useState<IMeta | null>(null);
const breakpoint = useBreakpoint();
const {width} = useWindowSize();

let [searchParams, setSearchParams] = useSearchParams();
const [filterValues, setFilterValues] = useState<IFilterValue>(valuesFromSearch());
Expand All @@ -78,7 +79,7 @@ const Grid = () => {
const newGroups: GridColumnGroup[] = [];

columnGroups.forEach((col) => {
const { columns, columnGroup } = getColumnGroup(data, col.field, col.icons);
const { columns, columnGroup } = getColumnGroup(data, col.field, col.icons, width);
newColumns.push(...columns);
newGroups.push(columnGroup);
});
Expand Down Expand Up @@ -129,7 +130,7 @@ const Grid = () => {
const newGroups: GridColumnGroup[] = [];

columnGroups.forEach((col) => {
const { columns, columnGroup } = getColumnGroup(data, col.field, col.icons);
const { columns, columnGroup } = getColumnGroup(data, col.field, col.icons, width);
newColumns.push(...columns);
newGroups.push(columnGroup);
});
Expand Down
42 changes: 21 additions & 21 deletions frontend/src/containers/Meta/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { useEffect } from 'react';
import AppBar from '@/components/Header';
import Footer from '@/components/Footer';

import Grid from './Grid';

const Meta = () => {
useEffect(() => {
document.title = `Meta`;
}, []);

return (
<>
<AppBar />
<Grid />
<Footer />
</>
);
};

export default Meta;
import { useEffect } from 'react';
import Header from '@/components/Header';
import Footer from '@/components/Footer';

import Grid from './Grid';

const Meta = () => {
useEffect(() => {
document.title = `Meta`;
}, []);

return (
<>
<Header />
<Grid />
<Footer />
</>
);
};

export default Meta;

0 comments on commit 824a96c

Please sign in to comment.