From be59339ccda714d1993d2ad910d28e8f6766c869 Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Wed, 17 Jul 2024 15:20:04 +0300 Subject: [PATCH 1/8] Chart Tooltip --- .../src/components/HURUmap/Chart/index.js | 2 +- .../components/HURUmap/ChartTooltip/index.js | 92 ----------------- .../HURUmap/ChartTooltip/index.stories.js | 47 --------- .../src/components/HURUmap/Chart/index.js | 2 +- .../components/HURUmap/ChartTooltip/index.js | 92 ----------------- .../src/ChartTooltip/ChartTooltip.js | 99 +++++++++++++++++++ .../src/ChartTooltip/ChartTooltip.test.js | 11 +++ .../hurumap-core/src/ChartTooltip/index.js | 3 + .../src}/ChartTooltip/index.stories.js | 2 +- packages/hurumap-core/src/index.js | 1 + 10 files changed, 117 insertions(+), 234 deletions(-) delete mode 100644 apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.js delete mode 100644 apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.stories.js delete mode 100644 apps/pesayetu/src/components/HURUmap/ChartTooltip/index.js create mode 100644 packages/hurumap-core/src/ChartTooltip/ChartTooltip.js create mode 100644 packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js create mode 100644 packages/hurumap-core/src/ChartTooltip/index.js rename {apps/pesayetu/src/components/HURUmap => packages/hurumap-core/src}/ChartTooltip/index.stories.js (90%) diff --git a/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js b/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js index 2ecc33ebe..48159692e 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js +++ b/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js @@ -1,3 +1,4 @@ +import { ChartTooltip } from "@hurumap/core"; import { useMediaQuery } from "@mui/material"; import { ThemeProvider, StyledEngineProvider } from "@mui/material/styles"; import makeStyles from "@mui/styles/makeStyles"; @@ -10,7 +11,6 @@ import configureScope from "./configureScope"; import Filters from "./Filters"; import { calculateTooltipPosition, idify } from "./utils"; -import ChartTooltip from "@/climatemappedafrica/components/HURUmap/ChartTooltip"; import IndicatorTitle from "@/climatemappedafrica/components/HURUmap/IndicatorTitle"; import Source from "@/climatemappedafrica/components/HURUmap/Source"; import theme from "@/climatemappedafrica/theme"; diff --git a/apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.js b/apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.js deleted file mode 100644 index dbdd6b32c..000000000 --- a/apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.js +++ /dev/null @@ -1,92 +0,0 @@ -import { Typography, Grid } from "@mui/material"; -import makeStyles from "@mui/styles/makeStyles"; -import clsx from "clsx"; -import PropTypes from "prop-types"; -import React from "react"; - -const useStyles = makeStyles(({ palette, typography }) => ({ - root: { - background: palette.grey.dark, - boxShadow: "0px 3px 6px #00000029", - borderRadius: typography.pxToRem(4), - opacity: 0.8, - color: palette.text.secondary, - padding: typography.pxToRem(12.5), - paddingRight: 0, - display: "inline-block", - width: "fit-content", - }, - text: { - marginRight: typography.pxToRem(12.5), - maxWidth: typography.pxToRem(148), - }, - value: { - fontWeight: 600, - }, - item: { - fontSize: typography.pxToRem(11), - }, - content: { - display: "flex", - alignItems: "center", - }, - circle: (props) => { - return { - width: typography.pxToRem(10), - height: typography.pxToRem(10), - border: `1px solid ${palette.background.default}`, - background: props.itemColor, - borderRadius: "100%", - marginRight: typography.pxToRem(7), - }; - }, -})); - -function ChartTooltip({ title, value, formattedValue, item, ...props }) { - const classes = useStyles(props); - return ( - - {item && ( - -
- {item} - - )} - - - {title} - - {formattedValue && ( - - {formattedValue} - - )} - - {value} - - - - ); -} - -ChartTooltip.propTypes = { - title: PropTypes.string, - value: PropTypes.string, - formattedValue: PropTypes.string, - item: PropTypes.string, - itemColor: PropTypes.string, -}; - -ChartTooltip.defaultProps = { - title: undefined, - value: undefined, - formattedValue: undefined, - item: undefined, - itemColor: undefined, -}; - -export default ChartTooltip; diff --git a/apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.stories.js b/apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.stories.js deleted file mode 100644 index 8bd3025d3..000000000 --- a/apps/climatemappedafrica/src/components/HURUmap/ChartTooltip/index.stories.js +++ /dev/null @@ -1,47 +0,0 @@ -import React from "react"; - -import ChartTooltip from "@/climatemappedafrica/components/HURUmap/ChartTooltip"; - -export default { - title: "Components/HURUmap/ChartTooltip", - argTypes: { - title: { - control: { - type: "text", - }, - }, - value: { - control: { - type: "text", - }, - }, - formattedValue: { - control: { - type: "text", - }, - }, - group: { - control: { - type: "text", - }, - }, - groupColor: { - control: { - type: "text", - }, - }, - }, -}; - -function Template({ ...args }) { - return ; -} - -export const Default = Template.bind({}); - -Default.args = { - title: "15-24", - value: "1456000", - group: "cat2", - groupColor: "#7DB2D3", -}; diff --git a/apps/pesayetu/src/components/HURUmap/Chart/index.js b/apps/pesayetu/src/components/HURUmap/Chart/index.js index 0aaa02790..635fea6e6 100644 --- a/apps/pesayetu/src/components/HURUmap/Chart/index.js +++ b/apps/pesayetu/src/components/HURUmap/Chart/index.js @@ -1,3 +1,4 @@ +import { ChartTooltip } from "@hurumap/core"; import { useMediaQuery } from "@mui/material"; import { ThemeProvider, StyledEngineProvider } from "@mui/material/styles"; import makeStyles from "@mui/styles/makeStyles"; @@ -10,7 +11,6 @@ import configureScope from "./configureScope"; import Filters from "./Filters"; import { calculateTooltipPosition, idify } from "./utils"; -import ChartTooltip from "@/pesayetu/components/HURUmap/ChartTooltip"; import IndicatorTitle from "@/pesayetu/components/HURUmap/IndicatorTitle"; import Source from "@/pesayetu/components/HURUmap/Source"; import theme from "@/pesayetu/theme"; diff --git a/apps/pesayetu/src/components/HURUmap/ChartTooltip/index.js b/apps/pesayetu/src/components/HURUmap/ChartTooltip/index.js deleted file mode 100644 index dbdd6b32c..000000000 --- a/apps/pesayetu/src/components/HURUmap/ChartTooltip/index.js +++ /dev/null @@ -1,92 +0,0 @@ -import { Typography, Grid } from "@mui/material"; -import makeStyles from "@mui/styles/makeStyles"; -import clsx from "clsx"; -import PropTypes from "prop-types"; -import React from "react"; - -const useStyles = makeStyles(({ palette, typography }) => ({ - root: { - background: palette.grey.dark, - boxShadow: "0px 3px 6px #00000029", - borderRadius: typography.pxToRem(4), - opacity: 0.8, - color: palette.text.secondary, - padding: typography.pxToRem(12.5), - paddingRight: 0, - display: "inline-block", - width: "fit-content", - }, - text: { - marginRight: typography.pxToRem(12.5), - maxWidth: typography.pxToRem(148), - }, - value: { - fontWeight: 600, - }, - item: { - fontSize: typography.pxToRem(11), - }, - content: { - display: "flex", - alignItems: "center", - }, - circle: (props) => { - return { - width: typography.pxToRem(10), - height: typography.pxToRem(10), - border: `1px solid ${palette.background.default}`, - background: props.itemColor, - borderRadius: "100%", - marginRight: typography.pxToRem(7), - }; - }, -})); - -function ChartTooltip({ title, value, formattedValue, item, ...props }) { - const classes = useStyles(props); - return ( - - {item && ( - -
- {item} - - )} - - - {title} - - {formattedValue && ( - - {formattedValue} - - )} - - {value} - - - - ); -} - -ChartTooltip.propTypes = { - title: PropTypes.string, - value: PropTypes.string, - formattedValue: PropTypes.string, - item: PropTypes.string, - itemColor: PropTypes.string, -}; - -ChartTooltip.defaultProps = { - title: undefined, - value: undefined, - formattedValue: undefined, - item: undefined, - itemColor: undefined, -}; - -export default ChartTooltip; diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js new file mode 100644 index 000000000..13ded290f --- /dev/null +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js @@ -0,0 +1,99 @@ +import { Box, Typography, Grid } from "@mui/material"; +import React, { forwardRef } from "react"; + +const ChartTooltip = forwardRef(function ChartTooltip( + { title, value, formattedValue, item, ...props }, + ref, +) { + return ( + { + return { + backgroundColor: "red", + boxShadow: "0px 3px 6px #00000029", + borderRadius: theme.typography.pxToRem(4), + opacity: 0.8, + color: theme.palette.text.secondary, + padding: theme.typography.pxToRem(12.5), + paddingRight: 0, + display: "inline-block", + width: "fit-content", + }; + }} + > + {item && ( + + { + return { + width: theme.typography.pxToRem(10), + height: theme.typography.pxToRem(10), + border: `1px solid ${theme.palette.background.default}`, + background: props.itemColor, + borderRadius: "100%", + marginRight: theme.typography.pxToRem(7), + }; + }} + /> + ({ + fontSize: typography.pxToRem(11), + })} + > + {item} + + + )} + + ({ + marginRight: typography.pxToRem(12.5), + maxWidth: typography.pxToRem(148), + })} + > + {title} + + {formattedValue && ( + ({ + marginRight: typography.pxToRem(12.5), + maxWidth: typography.pxToRem(148), + })} + > + {formattedValue} + + )} + ({ + marginRight: typography.pxToRem(12.5), + maxWidth: typography.pxToRem(148), + })} + > + {value} + + + + ); +}); + +export default ChartTooltip; diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js new file mode 100644 index 000000000..3fe489c67 --- /dev/null +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js @@ -0,0 +1,11 @@ +import { render } from "@commons-ui/testing-library"; +import React from "react"; + +import ChartTooltip from "./ChartTooltip"; + +describe("ChartTooltip", () => { + it("renders unchanged", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/hurumap-core/src/ChartTooltip/index.js b/packages/hurumap-core/src/ChartTooltip/index.js new file mode 100644 index 000000000..265c70533 --- /dev/null +++ b/packages/hurumap-core/src/ChartTooltip/index.js @@ -0,0 +1,3 @@ +import ChartTooltip from "./ChartTooltip"; + +export default ChartTooltip; diff --git a/apps/pesayetu/src/components/HURUmap/ChartTooltip/index.stories.js b/packages/hurumap-core/src/ChartTooltip/index.stories.js similarity index 90% rename from apps/pesayetu/src/components/HURUmap/ChartTooltip/index.stories.js rename to packages/hurumap-core/src/ChartTooltip/index.stories.js index 15b919885..881bc58f3 100644 --- a/apps/pesayetu/src/components/HURUmap/ChartTooltip/index.stories.js +++ b/packages/hurumap-core/src/ChartTooltip/index.stories.js @@ -1,6 +1,6 @@ import React from "react"; -import ChartTooltip from "@/pesayetu/components/HURUmap/ChartTooltip"; +import ChartTooltip from "./index"; export default { title: "HURUmap/Components/ChartTooltip", diff --git a/packages/hurumap-core/src/index.js b/packages/hurumap-core/src/index.js index 881ae0422..267a5d70d 100644 --- a/packages/hurumap-core/src/index.js +++ b/packages/hurumap-core/src/index.js @@ -1,3 +1,4 @@ /* eslint-disable import/prefer-default-export */ export { default as LocationTag } from "./LocationTag"; export { default as LocationHighlight } from "./LocationHighlight"; +export { default as ChartTooltip } from "./ChartTooltip"; From 02c6c88672172f21f7f985b4e39702edad75316c Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 18 Jul 2024 08:38:53 +0300 Subject: [PATCH 2/8] Fix failing tests --- .../src/ChartTooltip/ChartTooltip.snap.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js new file mode 100644 index 000000000..2d2e78b57 --- /dev/null +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ChartTooltip renders unchanged 1`] = ` +
+
+
+
+
+
+
+
+`; From fa3019451b2372c49018b542999db51cf20ceedc Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 18 Jul 2024 15:01:16 +0300 Subject: [PATCH 3/8] Use style instead of sx --- .../src/components/HURUmap/Chart/index.js | 1 + .../HURUmap/core/ChartTooltip.stories.js | 5 +- .../src/ChartTooltip/ChartTooltip.js | 62 +++++++++---------- 3 files changed, 33 insertions(+), 35 deletions(-) rename packages/hurumap-core/src/ChartTooltip/index.stories.js => apps/uibook/stories/HURUmap/core/ChartTooltip.stories.js (88%) diff --git a/apps/pesayetu/src/components/HURUmap/Chart/index.js b/apps/pesayetu/src/components/HURUmap/Chart/index.js index d98d8ca14..d8a8fa1c2 100644 --- a/apps/pesayetu/src/components/HURUmap/Chart/index.js +++ b/apps/pesayetu/src/components/HURUmap/Chart/index.js @@ -101,6 +101,7 @@ function Chart({ , ); + console.log(el); el.classList.add("visible"); const { x, y } = calculateTooltipPosition( diff --git a/packages/hurumap-core/src/ChartTooltip/index.stories.js b/apps/uibook/stories/HURUmap/core/ChartTooltip.stories.js similarity index 88% rename from packages/hurumap-core/src/ChartTooltip/index.stories.js rename to apps/uibook/stories/HURUmap/core/ChartTooltip.stories.js index 881bc58f3..076527a98 100644 --- a/packages/hurumap-core/src/ChartTooltip/index.stories.js +++ b/apps/uibook/stories/HURUmap/core/ChartTooltip.stories.js @@ -1,9 +1,8 @@ +import { ChartTooltip } from "@hurumap/core"; import React from "react"; -import ChartTooltip from "./index"; - export default { - title: "HURUmap/Components/ChartTooltip", + title: "@hurumap/core/ChartTooltip", argTypes: { title: { control: { diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js index 13ded290f..8a0a635b0 100644 --- a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js @@ -1,52 +1,50 @@ -import { Box, Typography, Grid } from "@mui/material"; +import { Box, Typography, Grid, useTheme } from "@mui/material"; import React, { forwardRef } from "react"; const ChartTooltip = forwardRef(function ChartTooltip( { title, value, formattedValue, item, ...props }, ref, ) { + const theme = useTheme(); + const { typography, palette } = theme; return ( { - return { - backgroundColor: "red", - boxShadow: "0px 3px 6px #00000029", - borderRadius: theme.typography.pxToRem(4), - opacity: 0.8, - color: theme.palette.text.secondary, - padding: theme.typography.pxToRem(12.5), - paddingRight: 0, - display: "inline-block", - width: "fit-content", - }; + style={{ + background: palette.grey.dark, + boxShadow: "0px 3px 6px #00000029", + borderRadius: theme.typography.pxToRem(4), + opacity: 0.8, + color: theme.palette.text.secondary, + padding: theme.typography.pxToRem(12.5), + paddingRight: 0, + display: "inline-block", + width: "fit-content", }} > {item && ( { - return { - width: theme.typography.pxToRem(10), - height: theme.typography.pxToRem(10), - border: `1px solid ${theme.palette.background.default}`, - background: props.itemColor, - borderRadius: "100%", - marginRight: theme.typography.pxToRem(7), - }; + style={{ + width: theme.typography.pxToRem(10), + height: theme.typography.pxToRem(10), + border: `1px solid ${theme.palette.background.default}`, + background: props.itemColor, + borderRadius: "100%", + marginRight: theme.typography.pxToRem(7), }} /> ({ + style={{ fontSize: typography.pxToRem(11), - })} + }} > {item} @@ -54,7 +52,7 @@ const ChartTooltip = forwardRef(function ChartTooltip( )} ({ + style={{ marginRight: typography.pxToRem(12.5), maxWidth: typography.pxToRem(148), - })} + }} > {title} @@ -73,10 +71,10 @@ const ChartTooltip = forwardRef(function ChartTooltip( ({ + style={{ marginRight: typography.pxToRem(12.5), maxWidth: typography.pxToRem(148), - })} + }} > {formattedValue} @@ -84,10 +82,10 @@ const ChartTooltip = forwardRef(function ChartTooltip( ({ + style={{ marginRight: typography.pxToRem(12.5), maxWidth: typography.pxToRem(148), - })} + }} > {value} From bfe5d36c0ec04ebb01fa759ad81d1ee1bef217fb Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 18 Jul 2024 15:11:51 +0300 Subject: [PATCH 4/8] update tooltip --- .../src/ChartTooltip/ChartTooltip.snap.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js index 2d2e78b57..2d304be5e 100644 --- a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js @@ -3,16 +3,20 @@ exports[`ChartTooltip renders unchanged 1`] = `
From dfe9f56b22eeb8f2238c7152c855150351c8fd8c Mon Sep 17 00:00:00 2001 From: KEVIN KOECH Date: Fri, 19 Jul 2024 10:40:21 +0300 Subject: [PATCH 5/8] Update apps/pesayetu/src/components/HURUmap/Chart/index.js Co-authored-by: Clemence Kyara --- apps/pesayetu/src/components/HURUmap/Chart/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/pesayetu/src/components/HURUmap/Chart/index.js b/apps/pesayetu/src/components/HURUmap/Chart/index.js index d8a8fa1c2..d98d8ca14 100644 --- a/apps/pesayetu/src/components/HURUmap/Chart/index.js +++ b/apps/pesayetu/src/components/HURUmap/Chart/index.js @@ -101,7 +101,6 @@ function Chart({ , ); - console.log(el); el.classList.add("visible"); const { x, y } = calculateTooltipPosition( From 661a99950c0009da5d75b519280e6cad5f07cb96 Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 25 Jul 2024 13:40:53 +0300 Subject: [PATCH 6/8] Configure tooltip to use sx --- .../src/components/HURUmap/Chart/index.js | 158 ++++------------ .../src/components/HURUmap/Chart/Tooltip.js | 0 .../src/components/HURUmap/Chart/index.js | 141 +++----------- .../src/ChartTooltip/ChartTooltip.js | 175 ++++++++---------- .../src/ChartTooltip/ChartTooltip.snap.js | 23 +-- .../src/ChartTooltip/ChartTooltip.test.js | 12 +- .../hurumap-core/src/ChartTooltip/Tooltip.js | 95 ++++++++++ 7 files changed, 246 insertions(+), 358 deletions(-) delete mode 100644 apps/pesayetu/src/components/HURUmap/Chart/Tooltip.js create mode 100644 packages/hurumap-core/src/ChartTooltip/Tooltip.js diff --git a/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js b/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js index c564b387c..11c25bc9c 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js +++ b/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js @@ -1,19 +1,15 @@ import { ChartTooltip } from "@hurumap/core"; import { Source } from "@hurumap/next"; import { useMediaQuery } from "@mui/material"; -import { ThemeProvider, StyledEngineProvider } from "@mui/material/styles"; import makeStyles from "@mui/styles/makeStyles"; -import PropTypes from "prop-types"; -import React, { useEffect, useState, useRef, useCallback } from "react"; -import ReactDOMServer from "react-dom/server"; +import React, { useState, useRef, useCallback, useEffect } from "react"; import embed from "vega-embed"; import configureScope from "./configureScope"; import Filters from "./Filters"; -import { calculateTooltipPosition, idify } from "./utils"; +import { idify } from "./utils"; import IndicatorTitle from "@/climatemappedafrica/components/HURUmap/IndicatorTitle"; -import theme from "@/climatemappedafrica/theme"; const useStyles = makeStyles(() => ({ root: { @@ -28,7 +24,7 @@ const useStyles = makeStyles(() => ({ function Chart({ indicator, indicatorTitle, - secondaryIndicator: { indicator: secondaryIndicator }, + secondaryIndicator: sI, title, geoCode, profileNames, @@ -39,8 +35,10 @@ function Chart({ const chartRef = useRef(); const [view, setView] = useState(null); const [cSpec, setCSpec] = useState(null); - // For charts, cnsider anything less than 600px as mobile const isMobile = !useMediaQuery("(min-width:600px)"); + const [tooltipData, setTooltipData] = useState(null); + const [tooltipEvent, setTooltipEvent] = useState(null); + const secondaryIndicator = sI?.indicator; const { id, @@ -65,56 +63,10 @@ function Chart({ const handler = useCallback( (_, event, item, value) => { - const className = `charttooltip-${id}-${geoCode}`; - /* eslint-env browser */ - let el = document.getElementsByClassName(className)[0]; - if (!el) { - /* eslint-env browser */ - el = document.createElement("div"); - el.classList.add(className); - /* eslint-env browser */ - document.body.appendChild(el); - } - - /* eslint-env browser */ - const tooltipContainer = document.fullscreenElement || document.body; - tooltipContainer.appendChild(el); - // hide tooltip for null objects, undefined - if (!value) { - el.remove(); - return; - } - el.innerHTML = ReactDOMServer.renderToString( - - - - - , - ); - - el.classList.add("visible"); - const { x, y } = calculateTooltipPosition( - event, - el.getBoundingClientRect(), - 0, - 10, - ); - el.setAttribute( - "style", - `top: ${y}px; left: ${x}px; z-index: 1230; position: absolute`, - ); + setTooltipEvent(event); + setTooltipData({ item, value, id, geoCode }); }, - [defaultType, disableToggle, geoCode, id], + [id, geoCode], ); useEffect(() => { @@ -128,16 +80,13 @@ function Chart({ ); setCSpec(spec); if (chartRef?.current) { - try { - const newView = await embed(chartRef.current, spec, { - renderer: "canvas", - actions: false, - tooltip: handler, - }); - setView(newView.view); - } catch (e) { - console.error("Error rendering chart: ", e); - } + const newView = await embed(chartRef.current, spec, { + renderer: "canvas", + actions: false, + tooltip: handler, + }); + + setView(newView.view); } } renderChart(); @@ -208,6 +157,7 @@ function Chart({ if (!indicator?.data) { return null; } + return (
{!isMobile && ( {source} + {tooltipData && tooltipEvent && ( + + )}
); } -Chart.propTypes = { - indicator: PropTypes.shape({ - id: PropTypes.number, - chart_configuration: PropTypes.shape({ - disableToggle: PropTypes.bool, - defaultType: PropTypes.string, - filter: PropTypes.PropTypes.shape({ - defaults: PropTypes.arrayOf(PropTypes.shape({})), - }), - stacked_field: PropTypes.string, - }), - description: PropTypes.string, - metadata: PropTypes.shape({ - source: PropTypes.string, - url: PropTypes.string, - groups: PropTypes.arrayOf(PropTypes.shape({})), - primary_group: PropTypes.string, - }), - data: PropTypes.arrayOf(PropTypes.shape({})), - }), - indicatorTitle: PropTypes.string, - secondaryIndicator: PropTypes.shape({ - indicator: PropTypes.shape({ - id: PropTypes.number, - chart_configuration: PropTypes.shape({ - disableToggle: PropTypes.bool, - defaultType: PropTypes.string, - filter: PropTypes.PropTypes.shape({ - defaults: PropTypes.arrayOf(PropTypes.shape({})), - }), - stacked_field: PropTypes.string, - }), - description: PropTypes.string, - metadata: PropTypes.shape({ - source: PropTypes.string, - url: PropTypes.string, - groups: PropTypes.arrayOf(PropTypes.shape({})), - primary_group: PropTypes.string, - }), - data: PropTypes.arrayOf(PropTypes.shape({})), - }), - }), - title: PropTypes.string, - geoCode: PropTypes.string, - profileNames: PropTypes.shape({}), - isCompare: PropTypes.bool, -}; - -Chart.defaultProps = { - indicator: undefined, - indicatorTitle: undefined, - secondaryIndicator: {}, - title: undefined, - geoCode: undefined, - profileNames: undefined, - isCompare: false, -}; - export default Chart; diff --git a/apps/pesayetu/src/components/HURUmap/Chart/Tooltip.js b/apps/pesayetu/src/components/HURUmap/Chart/Tooltip.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/pesayetu/src/components/HURUmap/Chart/index.js b/apps/pesayetu/src/components/HURUmap/Chart/index.js index d98d8ca14..b7b98c3e3 100644 --- a/apps/pesayetu/src/components/HURUmap/Chart/index.js +++ b/apps/pesayetu/src/components/HURUmap/Chart/index.js @@ -1,19 +1,15 @@ import { ChartTooltip } from "@hurumap/core"; import { Source } from "@hurumap/next"; import { useMediaQuery } from "@mui/material"; -import { ThemeProvider, StyledEngineProvider } from "@mui/material/styles"; import makeStyles from "@mui/styles/makeStyles"; -import PropTypes from "prop-types"; -import React, { useEffect, useState, useRef, useCallback } from "react"; -import ReactDOMServer from "react-dom/server"; +import React, { useState, useRef, useCallback, useEffect } from "react"; import embed from "vega-embed"; import configureScope from "./configureScope"; import Filters from "./Filters"; -import { calculateTooltipPosition, idify } from "./utils"; +import { idify } from "./utils"; import IndicatorTitle from "@/pesayetu/components/HURUmap/IndicatorTitle"; -import theme from "@/pesayetu/theme"; const useStyles = makeStyles(() => ({ root: { @@ -28,7 +24,7 @@ const useStyles = makeStyles(() => ({ function Chart({ indicator, indicatorTitle, - secondaryIndicator: { indicator: secondaryIndicator }, + secondaryIndicator: sI, title, geoCode, profileNames, @@ -39,8 +35,10 @@ function Chart({ const chartRef = useRef(); const [view, setView] = useState(null); const [cSpec, setCSpec] = useState(null); - // For charts, cnsider anything less than 600px as mobile const isMobile = !useMediaQuery("(min-width:600px)"); + const [tooltipData, setTooltipData] = useState(null); + const [tooltipEvent, setTooltipEvent] = useState(null); + const secondaryIndicator = sI?.indicator; const { id, @@ -65,56 +63,10 @@ function Chart({ const handler = useCallback( (_, event, item, value) => { - const className = `charttooltip-${id}-${geoCode}`; - /* eslint-env browser */ - let el = document.getElementsByClassName(className)[0]; - if (!el) { - /* eslint-env browser */ - el = document.createElement("div"); - el.classList.add(className); - /* eslint-env browser */ - document.body.appendChild(el); - } - - /* eslint-env browser */ - const tooltipContainer = document.fullscreenElement || document.body; - tooltipContainer.appendChild(el); - // hide tooltip for null objects, undefined - if (!value) { - el.remove(); - return; - } - el.innerHTML = ReactDOMServer.renderToString( - - - - - , - ); - - el.classList.add("visible"); - const { x, y } = calculateTooltipPosition( - event, - el.getBoundingClientRect(), - 0, - 10, - ); - el.setAttribute( - "style", - `top: ${y}px; left: ${x}px; z-index: 1230; position: absolute`, - ); + setTooltipEvent(event); + setTooltipData({ item, value, id, geoCode }); }, - [defaultType, disableToggle, geoCode, id], + [id, geoCode], ); useEffect(() => { @@ -205,6 +157,7 @@ function Chart({ if (!indicator?.data) { return null; } + return (
{!isMobile && ( {source} + {tooltipData && tooltipEvent && ( + + )}
); } -Chart.propTypes = { - indicator: PropTypes.shape({ - id: PropTypes.number, - chart_configuration: PropTypes.shape({ - disableToggle: PropTypes.bool, - defaultType: PropTypes.string, - filter: PropTypes.PropTypes.shape({ - defaults: PropTypes.arrayOf(PropTypes.shape({})), - }), - stacked_field: PropTypes.string, - }), - description: PropTypes.string, - metadata: PropTypes.shape({ - source: PropTypes.string, - url: PropTypes.string, - groups: PropTypes.arrayOf(PropTypes.shape({})), - primary_group: PropTypes.string, - }), - data: PropTypes.arrayOf(PropTypes.shape({})), - }), - indicatorTitle: PropTypes.string, - secondaryIndicator: PropTypes.shape({ - indicator: PropTypes.shape({ - id: PropTypes.number, - chart_configuration: PropTypes.shape({ - disableToggle: PropTypes.bool, - defaultType: PropTypes.string, - filter: PropTypes.PropTypes.shape({ - defaults: PropTypes.arrayOf(PropTypes.shape({})), - }), - stacked_field: PropTypes.string, - }), - description: PropTypes.string, - metadata: PropTypes.shape({ - source: PropTypes.string, - url: PropTypes.string, - groups: PropTypes.arrayOf(PropTypes.shape({})), - primary_group: PropTypes.string, - }), - data: PropTypes.arrayOf(PropTypes.shape({})), - }), - }), - title: PropTypes.string, - geoCode: PropTypes.string, - profileNames: PropTypes.shape({}), - isCompare: PropTypes.bool, -}; - -Chart.defaultProps = { - indicator: undefined, - indicatorTitle: undefined, - secondaryIndicator: {}, - title: undefined, - geoCode: undefined, - profileNames: undefined, - isCompare: false, -}; - export default Chart; diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js index 8a0a635b0..8d963895b 100644 --- a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.js @@ -1,97 +1,86 @@ -import { Box, Typography, Grid, useTheme } from "@mui/material"; -import React, { forwardRef } from "react"; +import { StyledEngineProvider } from "@mui/material/styles"; +import React, { useEffect, useRef } from "react"; +import ReactDOM from "react-dom"; -const ChartTooltip = forwardRef(function ChartTooltip( - { title, value, formattedValue, item, ...props }, - ref, -) { - const theme = useTheme(); - const { typography, palette } = theme; - return ( - - {item && ( - - - - {item} - - - )} - - - {title} - - {formattedValue && ( - - {formattedValue} - - )} - - {value} - - - +import Tooltip from "./Tooltip"; // Import your ChartTooltip component + +function calculateTooltipPosition(event, tooltipBox, offsetX, offsetY) { + let x = event.pageX + offsetX; + /* eslint-env browser */ + if (x + tooltipBox.width > window.innerWidth) { + x = +event.pageX - offsetX - tooltipBox.width; + } + let y = event.pageY + offsetY; + /* eslint-env browser */ + if (y < window.innerHeight) { + /* eslint-env browser */ + y = window.innerHeight + offsetY; + } + /* eslint-env browser */ + if (y + tooltipBox.height > window.innerHeight) { + y = +event.pageY - offsetY - tooltipBox.height; + } + return { x, y }; +} + +function ChartTooltip({ + id, + geoCode, + value, + itemColor, + title, + formattedValue, + event, +}) { + const tooltipRef = useRef(); + + useEffect(() => { + const el = document.createElement("div"); + el.className = `charttooltip-${id}-${geoCode}`; + document.body.appendChild(el); + tooltipRef.current = el; + + const tooltipContainer = document.fullscreenElement || document.body; + tooltipContainer.appendChild(el); + + return () => { + if (el) { + el.remove(); + } + }; + }, [id, geoCode]); + + useEffect(() => { + if (tooltipRef.current && value) { + const { x, y } = calculateTooltipPosition( + event, + tooltipRef.current.getBoundingClientRect(), + 0, + 10, + ); + tooltipRef.current.style.top = `${y}px`; + tooltipRef.current.style.left = `${x}px`; + tooltipRef.current.style.zIndex = 1230; + tooltipRef.current.style.position = "absolute"; + } + }, [value, event]); + + if (!tooltipRef.current || !value) { + return null; + } + + return ReactDOM.createPortal( + + + , + tooltipRef.current, ); -}); +} export default ChartTooltip; diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js index 2d304be5e..b6d8e7c9a 100644 --- a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.snap.js @@ -1,24 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`ChartTooltip renders unchanged 1`] = ` -
-
-
-
-
-
-
-
-`; +exports[`ChartTooltip renders unchanged 1`] = `
`; diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js index 3fe489c67..75fb60709 100644 --- a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js @@ -3,9 +3,19 @@ import React from "react"; import ChartTooltip from "./ChartTooltip"; +const defaultTooltipProps = { + id: "1", + geoCode: "6672", + value: null, + itemColor: "", + event: null, + title: "", + formattedValue: undefined, +}; + describe("ChartTooltip", () => { it("renders unchanged", () => { - const { container } = render(); + const { container } = render(); expect(container).toMatchSnapshot(); }); }); diff --git a/packages/hurumap-core/src/ChartTooltip/Tooltip.js b/packages/hurumap-core/src/ChartTooltip/Tooltip.js new file mode 100644 index 000000000..e9ca39f95 --- /dev/null +++ b/packages/hurumap-core/src/ChartTooltip/Tooltip.js @@ -0,0 +1,95 @@ +import { Box, Typography, Grid } from "@mui/material"; +import React, { forwardRef } from "react"; + +const Tooltip = forwardRef(function Tooltip( + { title, value, formattedValue, item, ...props }, + ref, +) { + return ( + ({ + background: theme.palette.grey.dark, + boxShadow: "0px 3px 6px #00000029", + borderRadius: theme.typography.pxToRem(4), + opacity: 0.8, + color: theme.palette.text.secondary, + padding: theme.typography.pxToRem(12.5), + paddingRight: 0, + display: "inline-block", + width: "fit-content", + })} + > + {item && ( + + ({ + width: theme.typography.pxToRem(10), + height: theme.typography.pxToRem(10), + border: `1px solid ${theme.palette.background.default}`, + background: props.itemColor, + borderRadius: "100%", + marginRight: theme.typography.pxToRem(7), + })} + /> + ({ + fontSize: typography.pxToRem(11), + })} + > + {item} + + + )} + + ({ + marginRight: typography.pxToRem(12.5), + maxWidth: typography.pxToRem(148), + })} + > + {title} + + {formattedValue && ( + ({ + marginRight: typography.pxToRem(12.5), + maxWidth: typography.pxToRem(148), + })} + > + {formattedValue} + + )} + ({ + marginRight: typography.pxToRem(12.5), + maxWidth: typography.pxToRem(148), + })} + > + {value} + + + + ); +}); + +export default Tooltip; From 92e52153e6d62ec85ee43e1ca164d6e5621ddea6 Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 25 Jul 2024 17:49:01 +0300 Subject: [PATCH 7/8] Configure tooltip to use sx --- .../src/components/HURUmap/Chart/index.js | 22 ++++++++--- .../src/components/HURUmap/Chart/index.js | 22 ++++++++--- .../src/ChartTooltip/ChartTooltip.js | 39 +++++-------------- .../hurumap-core/src/ChartTooltip/Tooltip.js | 3 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js b/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js index 11c25bc9c..29ec03c4f 100644 --- a/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js +++ b/apps/climatemappedafrica/src/components/HURUmap/Chart/index.js @@ -7,7 +7,7 @@ import embed from "vega-embed"; import configureScope from "./configureScope"; import Filters from "./Filters"; -import { idify } from "./utils"; +import { calculateTooltipPosition, idify } from "./utils"; import IndicatorTitle from "@/climatemappedafrica/components/HURUmap/IndicatorTitle"; @@ -33,11 +33,11 @@ function Chart({ }) { const classes = useStyles(props); const chartRef = useRef(); + const tooltipRef = useRef(); const [view, setView] = useState(null); const [cSpec, setCSpec] = useState(null); const isMobile = !useMediaQuery("(min-width:600px)"); const [tooltipData, setTooltipData] = useState(null); - const [tooltipEvent, setTooltipEvent] = useState(null); const secondaryIndicator = sI?.indicator; const { @@ -63,8 +63,7 @@ function Chart({ const handler = useCallback( (_, event, item, value) => { - setTooltipEvent(event); - setTooltipData({ item, value, id, geoCode }); + setTooltipData({ item, value, id, geoCode, event }); }, [id, geoCode], ); @@ -154,6 +153,15 @@ function Chart({ }), ]; + let position = {}; + if (tooltipData?.event && tooltipRef?.current) { + position = calculateTooltipPosition( + tooltipData?.event, + tooltipRef?.current?.getBoundingClientRect(), + 0, + 10, + ); + } if (!indicator?.data) { return null; } @@ -196,14 +204,16 @@ function Chart({ > {source} - {tooltipData && tooltipEvent && ( + {tooltipData && tooltipData?.event && ( { - setTooltipEvent(event); - setTooltipData({ item, value, id, geoCode }); + setTooltipData({ item, value, id, geoCode, event }); }, [id, geoCode], ); @@ -154,6 +153,15 @@ function Chart({ }), ]; + let position = {}; + if (tooltipData?.event && tooltipRef?.current) { + position = calculateTooltipPosition( + tooltipData?.event, + tooltipRef?.current?.getBoundingClientRect(), + 0, + 10, + ); + } if (!indicator?.data) { return null; } @@ -196,14 +204,16 @@ function Chart({ > {source} - {tooltipData && tooltipEvent && ( + {tooltipData && tooltipData?.event && ( window.innerWidth) { - x = +event.pageX - offsetX - tooltipBox.width; - } - let y = event.pageY + offsetY; - /* eslint-env browser */ - if (y < window.innerHeight) { - /* eslint-env browser */ - y = window.innerHeight + offsetY; - } - /* eslint-env browser */ - if (y + tooltipBox.height > window.innerHeight) { - y = +event.pageY - offsetY - tooltipBox.height; - } - return { x, y }; -} - function ChartTooltip({ id, geoCode, @@ -31,9 +13,11 @@ function ChartTooltip({ title, formattedValue, event, + position, + ...props }) { - const tooltipRef = useRef(); - + const { tooltipRef } = props; + const { x, y } = position; useEffect(() => { const el = document.createElement("div"); el.className = `charttooltip-${id}-${geoCode}`; @@ -48,22 +32,16 @@ function ChartTooltip({ el.remove(); } }; - }, [id, geoCode]); + }, [id, geoCode, tooltipRef]); useEffect(() => { if (tooltipRef.current && value) { - const { x, y } = calculateTooltipPosition( - event, - tooltipRef.current.getBoundingClientRect(), - 0, - 10, - ); tooltipRef.current.style.top = `${y}px`; tooltipRef.current.style.left = `${x}px`; tooltipRef.current.style.zIndex = 1230; tooltipRef.current.style.position = "absolute"; } - }, [value, event]); + }, [value, event, x, y, tooltipRef]); if (!tooltipRef.current || !value) { return null; @@ -77,6 +55,7 @@ function ChartTooltip({ formattedValue={formattedValue} item={value?.category} itemColor={itemColor} + {...props} /> , tooltipRef.current, diff --git a/packages/hurumap-core/src/ChartTooltip/Tooltip.js b/packages/hurumap-core/src/ChartTooltip/Tooltip.js index e9ca39f95..9582c334a 100644 --- a/packages/hurumap-core/src/ChartTooltip/Tooltip.js +++ b/packages/hurumap-core/src/ChartTooltip/Tooltip.js @@ -2,7 +2,7 @@ import { Box, Typography, Grid } from "@mui/material"; import React, { forwardRef } from "react"; const Tooltip = forwardRef(function Tooltip( - { title, value, formattedValue, item, ...props }, + { title, value, formattedValue, item, sx, ...props }, ref, ) { return ( @@ -19,6 +19,7 @@ const Tooltip = forwardRef(function Tooltip( paddingRight: 0, display: "inline-block", width: "fit-content", + ...(typeof sx === "function" ? sx(theme) : sx), })} > {item && ( From fdcaf7d3e6871842aa7cea1282acbc26b4b5eb0a Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 25 Jul 2024 18:03:29 +0300 Subject: [PATCH 8/8] Fix failing test --- packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js index 75fb60709..b5dfce2d6 100644 --- a/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js +++ b/packages/hurumap-core/src/ChartTooltip/ChartTooltip.test.js @@ -11,6 +11,8 @@ const defaultTooltipProps = { event: null, title: "", formattedValue: undefined, + position: { x: 10, y: 10 }, + tooltipRef: { current: null }, }; describe("ChartTooltip", () => {