Skip to content

Commit

Permalink
feat: add scroll to chart functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
cadeban committed Oct 18, 2024
1 parent 90dd51a commit 1ae738d
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 17 deletions.
4 changes: 3 additions & 1 deletion web/src/features/charts/BreakdownChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Factory, Zap } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { ElectricityModeType } from 'types';
import trackEvent from 'utils/analytics';
import { TimeAverages, TrackEvent } from 'utils/constants';
import { Charts, TimeAverages, TrackEvent } from 'utils/constants';
import { formatCo2 } from 'utils/formatting';
import {
dataSourcesCollapsedBreakdownAtom,
Expand Down Expand Up @@ -76,6 +76,7 @@ function BreakdownChart({
if (!hasEnoughDataToDisplay) {
return (
<NotEnoughDataMessage
id={Charts.ORIGIN_CHART}
title={`country-history.${titleDisplayMode}${titleMixMode}`}
/>
);
Expand All @@ -87,6 +88,7 @@ function BreakdownChart({
translationKey={`country-history.${titleDisplayMode}${titleMixMode}`}
badge={badge}
unit={valueAxisLabel}
id={Charts.ORIGIN_CHART}
/>
<div className="relative ">
<AreaGraph
Expand Down
10 changes: 8 additions & 2 deletions web/src/features/charts/CarbonChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useAtom } from 'jotai';
import { Factory, Zap } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import trackEvent from 'utils/analytics';
import { TimeAverages, TrackEvent } from 'utils/constants';
import { Charts, TimeAverages, TrackEvent } from 'utils/constants';
import { dataSourcesCollapsedEmissionAtom } from 'utils/state/atoms';

import { ChartTitle } from './ChartTitle';
Expand Down Expand Up @@ -50,14 +50,20 @@ function CarbonChart({ datetimes, timeAverage }: CarbonChartProps) {
const badge = <EstimationBadge text={text} Icon={icon} />;

if (!hasEnoughDataToDisplay) {
return <NotEnoughDataMessage title="country-history.carbonintensity" />;
return (
<NotEnoughDataMessage
title="country-history.carbonintensity"
id={Charts.CARBON_CHART}
/>
);
}
return (
<RoundedCard className="pb-2">
<ChartTitle
translationKey="country-history.carbonintensity"
badge={badge}
unit={'gCO₂eq / kWh'}
id={Charts.CARBON_CHART}
/>
<AreaGraph
testId="details-carbon-graph"
Expand Down
7 changes: 5 additions & 2 deletions web/src/features/charts/ChartTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ type Props = {
translationKey: string;
unit?: string;
badge?: React.ReactElement;
id: string;
};

export function ChartTitle({ translationKey, unit, badge }: Props) {
export function ChartTitle({ translationKey, unit, badge, id }: Props) {
const { t } = useTranslation();
const timeAverage = useAtomValue(timeAverageAtom);
/*
Expand All @@ -18,7 +19,9 @@ export function ChartTitle({ translationKey, unit, badge }: Props) {
return (
<div className="flex flex-col pb-0.5">
<div className="flex items-center gap-1.5 pt-4">
<h2 className="grow">{t(`${translationKey}.${timeAverage}`)}</h2>
<h2 id={id} className="grow">
{t(`${translationKey}.${timeAverage}`)}
</h2>
{badge}
</div>
{unit && <div className="text-sm dark:text-gray-300">{unit}</div>}
Expand Down
3 changes: 2 additions & 1 deletion web/src/features/charts/EmissionChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAtom } from 'jotai';
import { Factory, Zap } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import trackEvent from 'utils/analytics';
import { TimeAverages, TrackEvent } from 'utils/constants';
import { Charts, TimeAverages, TrackEvent } from 'utils/constants';
import { formatCo2 } from 'utils/formatting';
import { dataSourcesCollapsedEmissionAtom } from 'utils/state/atoms';

Expand Down Expand Up @@ -52,6 +52,7 @@ function EmissionChart({ timeAverage, datetimes }: EmissionChartProps) {
translationKey="country-history.emissions"
badge={badge}
unit={'CO₂eq'}
id={Charts.EMISSION_CHART}
/>
<AreaGraph
testId="history-emissions-graph"
Expand Down
8 changes: 6 additions & 2 deletions web/src/features/charts/NetExchangeChart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useAtom } from 'jotai';
import { TimeAverages } from 'utils/constants';
import { Charts, TimeAverages } from 'utils/constants';
import { formatCo2 } from 'utils/formatting';
import { displayByEmissionsAtom, productionConsumptionAtom } from 'utils/state/atoms';

Expand Down Expand Up @@ -42,7 +42,11 @@ function NetExchangeChart({ datetimes, timeAverage }: NetExchangeChartProps) {

return (
<RoundedCard className="pb-2">
<ChartTitle translationKey="country-history.netExchange" unit={valueAxisLabel} />
<ChartTitle
translationKey="country-history.netExchange"
unit={valueAxisLabel}
id={Charts.NET_EXCHANGE_CHART}
/>
<div className="relative">
<AreaGraph
testId="history-exchange-graph"
Expand Down
4 changes: 2 additions & 2 deletions web/src/features/charts/NotEnoughDataMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { useTranslation } from 'react-i18next';

import { ChartTitle } from './ChartTitle';

export function NotEnoughDataMessage({ title }: { title: string }) {
export function NotEnoughDataMessage({ title, id }: { title: string; id: string }) {
const { t } = useTranslation();
return (
<div className="w-full">
<ChartTitle translationKey={title} />
<ChartTitle translationKey={title} id={id} />
<div className="my-2 rounded bg-gray-200 py-4 text-center text-sm dark:bg-gray-800">
<p>{t('country-history.not-enough-data')}</p>
</div>
Expand Down
10 changes: 8 additions & 2 deletions web/src/features/charts/PriceChart.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useTranslation } from 'react-i18next';
import { TimeAverages } from 'utils/constants';
import { Charts, TimeAverages } from 'utils/constants';

import { ChartTitle } from './ChartTitle';
import { DisabledMessage } from './DisabledMessage';
Expand Down Expand Up @@ -51,14 +51,20 @@ function PriceChart({ datetimes, timeAverage }: PriceChartProps) {
const hasEnoughDataToDisplay = datetimes?.length > 2;

if (!hasEnoughDataToDisplay) {
return <NotEnoughDataMessage title="country-history.electricityprices" />;
return (
<NotEnoughDataMessage
id={Charts.ELECTRICITY_PRICES_CHART}
title="country-history.electricityprices"
/>
);
}

return (
<RoundedCard>
<ChartTitle
translationKey="country-history.electricityprices"
unit={valueAxisLabel}
id={Charts.ELECTRICITY_PRICES_CHART}
/>
<div className="relative">
{isPriceDisabled && (
Expand Down
5 changes: 3 additions & 2 deletions web/src/features/charts/bar-breakdown/BarBreakdownChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useTranslation } from 'react-i18next';
import { ElectricityModeType, ZoneKey } from 'types';
import useResizeObserver from 'use-resize-observer';
import trackEvent from 'utils/analytics';
import { TrackEvent } from 'utils/constants';
import { Charts, TrackEvent } from 'utils/constants';
import {
dataSourcesCollapsedBarBreakdownAtom,
displayByEmissionsAtom,
Expand Down Expand Up @@ -88,7 +88,7 @@ function BarBreakdownChart({
if (!currentZoneDetail) {
return (
<div className="text-md relative w-full" ref={ref}>
<BySource className="opacity-40" />
<BySource className="opacity-40" id={Charts.BAR_BREAKDOWN_CHART} />
<EmptyBarBreakdownChart
height={height}
width={width}
Expand Down Expand Up @@ -137,6 +137,7 @@ function BarBreakdownChart({
estimatedPercentage={currentZoneDetail.estimatedPercentage}
unit={graphUnit}
estimationMethod={currentZoneDetail.estimationMethod}
id={Charts.BAR_BREAKDOWN_CHART}
/>
{!displayByEmissions && (
<CapacityLegend>
Expand Down
4 changes: 3 additions & 1 deletion web/src/features/charts/bar-breakdown/elements/BySource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ export default function BySource({
estimatedPercentage,
unit,
estimationMethod,
id,
}: {
className?: string;
hasEstimationPill?: boolean;
estimatedPercentage?: number;
unit?: string | number;
estimationMethod?: EstimationMethods;
id: string;
}) {
const { t } = useTranslation();
const [timeAverage] = useAtom(timeAverageAtom);
Expand All @@ -64,7 +66,7 @@ export default function BySource({
className={`text-md relative flex flex-row justify-between font-bold ${className}`}
>
<div className="flex gap-1">
<h2>{text}</h2>
<h2 id={id}>{text}</h2>
</div>
{hasEstimationPill && (
<EstimationBadge
Expand Down
21 changes: 19 additions & 2 deletions web/src/features/panels/zone/ZoneDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { CommercialApiButton } from 'components/buttons/CommercialApiButton';
import LoadingSpinner from 'components/LoadingSpinner';
import BarBreakdownChart from 'features/charts/bar-breakdown/BarBreakdownChart';
import { useAtomValue, useSetAtom } from 'jotai';
import { useEffect } from 'react';
import { Navigate, useParams } from 'react-router-dom';
import { useCallback, useEffect } from 'react';

Check warning

Code scanning / ESLint

Disallow unused variables Warning

'useCallback' is defined but never used. Allowed unused vars must match /^_/u.
import { Navigate, useLocation, useNavigate, useParams } from 'react-router-dom';
import { twMerge } from 'tailwind-merge';
import { ZoneMessage } from 'types';
import { EstimationMethods, SpatialAggregate } from 'utils/constants';
Expand Down Expand Up @@ -54,6 +54,8 @@ export default function ZoneDetails(): JSX.Element {
}
}, [hasSubZones, isSubZone, setViewMode]);

useScrollHashIntoView(isLoading);

if (!zoneId) {
return <Navigate to="/" replace />;
}
Expand Down Expand Up @@ -190,3 +192,18 @@ function ZoneDetailsContent({

return children as JSX.Element;
}

const useScrollHashIntoView = (isLoading: boolean) => {
const { hash, pathname, search } = useLocation();
const navigate = useNavigate();
useEffect(() => {
const hashElement = hash ? document.querySelector(hash) : null;
if (!isLoading && hashElement) {
hashElement.scrollIntoView({
behavior: 'smooth',
inline: 'nearest',
});
}
navigate(`${pathname}${search}`);
}, [hash, isLoading, navigate, pathname, search]);
};
9 changes: 9 additions & 0 deletions web/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ export enum LeftPanelToggleOptions {
EMISSIONS = 'emissions',
}

export enum Charts {
ELECTRICITY_PRICES_CHART = 'electricity_prices_chart',
ORIGIN_CHART = 'origin_chart',
BAR_BREAKDOWN_CHART = 'bar_breakdown_chart',
CARBON_CHART = 'carbon_chart',
EMISSION_CHART = 'emission_chart',
NET_EXCHANGE_CHART = 'net_exchange_chart',
}

export enum TrackEvent {
DATA_SOURCES_CLICKED = 'Data Sources Clicked',
APP_BANNER_CTA_CLICKED = 'App Banner CTA Clicked',
Expand Down

0 comments on commit 1ae738d

Please sign in to comment.