From ade1754dcaa26350b236377db310c8f8c98d9096 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 1 Jan 2024 22:48:06 +1300 Subject: [PATCH] search on charts --- client/src/components/GamePieChart.tsx | 32 +++++++++++++++-- client/src/components/GameSessionList.tsx | 2 +- client/src/components/GameTreeMapChart.tsx | 42 +++++++++++++++++++--- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/client/src/components/GamePieChart.tsx b/client/src/components/GamePieChart.tsx index 6bba2fe..2ddd965 100644 --- a/client/src/components/GamePieChart.tsx +++ b/client/src/components/GamePieChart.tsx @@ -1,4 +1,4 @@ -import React, { useContext } from "react"; +import React, { useContext, useState } from "react"; import { Chart as ChartJS, ArcElement, @@ -9,6 +9,7 @@ import { import { Pie } from "react-chartjs-2"; import { GameSession } from "../models/GameSession"; import { GoodplaysContext } from "../models/GoodplaysContextType"; +import Fuse from "fuse.js"; ChartJS.register(ArcElement, Tooltip, Legend); @@ -41,12 +42,28 @@ export const data2 = { const GamePieChart: React.FC = () => { const { gameSessions } = useContext(GoodplaysContext); + const [search, setSearch] = useState(''); + const fuseOptions = { + keys: ['gameName'], + includeScore: true, + threshold: 0.3 + }; + + const fuse = new Fuse(gameSessions, fuseOptions); + function dataToChartData( gameSessions: GameSession[] ): ChartData<"pie", number[], unknown> { + let filteredSessions; + if (search) { + const result = fuse.search(search); + filteredSessions = result.map(({ item }) => item); + } else { + filteredSessions = gameSessions; + } const gameNames = [ - ...new Set(gameSessions.map((session) => session.gameName)), + ...new Set(filteredSessions.map((session) => session.gameName)), ]; const data = gameNames.map( (gameName) => @@ -77,7 +94,16 @@ const GamePieChart: React.FC = () => { return (
- ; + setSearch(e.target.value)} + placeholder="Search game sessions, e.g. 'craft' for StarCraft, Warcraft, and World of Warcraft" + style={{ width: '500px' }} + /> +
+ + ;
); }; diff --git a/client/src/components/GameSessionList.tsx b/client/src/components/GameSessionList.tsx index ab90d5b..69403ff 100644 --- a/client/src/components/GameSessionList.tsx +++ b/client/src/components/GameSessionList.tsx @@ -111,7 +111,7 @@ const GameSessionList: React.FC = () => { value={search} onChange={(e) => setSearch(e.target.value)} placeholder="Search game sessions, e.g. 'craft' for StarCraft, Warcraft, and World of Warcraft" - style={{ width: '500px' }} // Adjust the width as needed + style={{ width: '500px' }} />
diff --git a/client/src/components/GameTreeMapChart.tsx b/client/src/components/GameTreeMapChart.tsx index 0fb66f6..430aad6 100644 --- a/client/src/components/GameTreeMapChart.tsx +++ b/client/src/components/GameTreeMapChart.tsx @@ -1,7 +1,8 @@ -import React, { useContext, useEffect, useRef } from "react"; +import React, { useContext, useEffect, useMemo, useRef, useState } from "react"; import * as d3 from "d3"; import { GoodplaysContext } from "../models/GoodplaysContextType"; import { GameSession } from "../models/GameSession"; +import Fuse from "fuse.js"; type Data = { name: string; @@ -28,10 +29,28 @@ function transformData(gameSessions: GameSession[]): Data[] { const GameTreeMapChart: React.FC = () => { const { gameSessions } = useContext(GoodplaysContext); const ref = useRef(null); - + const [search, setSearch] = useState(''); + + const data = useMemo(() => { + const fuseOptions = { + keys: ['gameName'], + includeScore: true, + threshold: 0.3 + }; + + const fuse = new Fuse(gameSessions, fuseOptions); + + let filteredSessions; + if (search) { + const result = fuse.search(search); + filteredSessions = result.map(({ item }) => item); + } else { + filteredSessions = gameSessions; + } + return transformData(filteredSessions); + }, [search, gameSessions]); + useEffect(() => { - const data = transformData(gameSessions); - if (ref.current) { const svg = d3.select(ref.current); @@ -88,7 +107,20 @@ const GameTreeMapChart: React.FC = () => { } }); - return ; + return ( +
+ setSearch(e.target.value)} + placeholder="Search game sessions, e.g. 'craft' for StarCraft, Warcraft, and World of Warcraft" + style={{ width: '500px' }} + /> +
+ + +
+ ); }; export default GameTreeMapChart;