From 9887d5f2b5a6022bbfdb6dc6c7942397c2038700 Mon Sep 17 00:00:00 2001 From: CHAE Date: Wed, 13 Dec 2023 18:06:58 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=8D=A8=ED=81=B4=EC=97=90=20hover?= =?UTF-8?q?=EC=8B=9C=20=ED=88=B4=ED=8C=81=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#254] --- .../frontend/src/components/graph/Graph.tsx | 7 ++++ .../src/components/graph/renderTooltip.ts | 33 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/components/graph/Graph.tsx b/packages/frontend/src/components/graph/Graph.tsx index 337a00a9..49e2ad97 100644 --- a/packages/frontend/src/components/graph/Graph.tsx +++ b/packages/frontend/src/components/graph/Graph.tsx @@ -6,6 +6,7 @@ import { QuizGitGraphCommit } from "../../types/quiz"; import fillColor from "./fillColor"; import { InitialDataProps, parsingMultipleParents } from "./parsing"; +import renderTooltip from "./renderTooltip"; const { grey500 } = color.$scale; @@ -87,6 +88,12 @@ function renderD3(svgRef: RefObject, data: InitialDataProps[]) { (exit) => exit.transition().duration(DURATION).style("opacity", 0).remove(), ) + .on("mouseover", (event, d) => { + const existingTooltip = svg.select("#tooltip"); + if (existingTooltip.empty()) { + renderTooltip(svg, d); + } + }) .attr("cx", (d) => d.x) .attr("cy", (d) => d.y) .attr("r", 13) diff --git a/packages/frontend/src/components/graph/renderTooltip.ts b/packages/frontend/src/components/graph/renderTooltip.ts index 5b5a859b..75eece69 100644 --- a/packages/frontend/src/components/graph/renderTooltip.ts +++ b/packages/frontend/src/components/graph/renderTooltip.ts @@ -79,5 +79,36 @@ export default function renderTooltip( .append("tspan") .attr("fill", color.$scale.grey700) .text((tooltipData: TooltipProps) => tooltipData.value) - .attr("id", (tooltipData: TooltipProps) => tooltipData.id); + .attr("id", (tooltipData: TooltipProps) => tooltipData.id) + .each(() => { + const currentValueNode: d3.Selection< + SVGTSpanElement | null, + unknown, + HTMLElement, + undefined + > = d3.select("#value"); + + if (!currentValueNode.empty() && currentValueNode.node()) { + const tspanMaxWidth = 110; + const originalText = currentValueNode.text(); + + let start = 0; + let end = tspanMaxWidth; + let mid; + while (start < end) { + mid = Math.floor((start + end) / 2); + const truncatedText = `${originalText.slice(0, mid)}...`; + currentValueNode.text(truncatedText); // Set text here for width calculation + const textWidth = + currentValueNode?.node()?.getComputedTextLength() || 0; + if (textWidth > tspanMaxWidth) { + end = mid; + } else { + start = mid + 1; + } + } + const truncatedText = `${originalText.slice(0, start - 1)}...`; + currentValueNode.text(truncatedText); + } + }); }