Skip to content

Commit

Permalink
Add tooltip to barbreakdown chart and style zonedetails a bit (electr…
Browse files Browse the repository at this point in the history
…icitymaps#87)

* Add tooltip functionality

* style zonedetails

* rename variable
  • Loading branch information
Markus Killendahl authored Dec 21, 2022
1 parent 936a1e2 commit 40b252e
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 37 deletions.
6 changes: 3 additions & 3 deletions web/src/components/tooltips/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ export const getOffsetTooltipPosition = ({
mousePositionX,
mousePositionY,
tooltipHeight,
isMinSM,
isBiggerThanMobile,
}: {
mousePositionX: number;
mousePositionY: number;
tooltipHeight: number;
isMinSM: boolean;
isBiggerThanMobile: boolean;
}) => {
const xOffset = 10;
const yOffset = tooltipHeight - 40;

// For smaller screens we translate the tooltip to the top
if (!isMinSM) {
if (!isBiggerThanMobile) {
return {
x: 0,
y: 40, // Provides space for the header to still be visible
Expand Down
4 changes: 2 additions & 2 deletions web/src/features/charts/BreakdownChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function BreakdownChart({
const titleDisplayMode = displayByEmissions ? 'emissions' : 'electricity';
const titleMixMode = mixMode === Mode.CONSUMPTION ? 'origin' : 'production';
return (
<div className="ml-4">
<>
<ChartTitle translationKey={`country-history.${titleDisplayMode}${titleMixMode}`} />
<AreaGraph
testId="history-mix-graph"
Expand All @@ -46,7 +46,7 @@ function BreakdownChart({
tooltip={BreakdownChartTooltip}
tooltipSize={displayByEmissions ? 'small' : 'large'}
/>
</div>
</>
);
}

Expand Down
4 changes: 2 additions & 2 deletions web/src/features/charts/CarbonChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function CarbonChart({ datetimes, timeAverage }: CarbonChartProps) {
const { chartData, layerFill, layerKeys } = data;

return (
<div className="ml-4">
<>
<ChartTitle translationKey="country-history.carbonintensity" />
<AreaGraph
testId="history-carbon-graph"
Expand All @@ -37,7 +37,7 @@ function CarbonChart({ datetimes, timeAverage }: CarbonChartProps) {
selectedTimeAggregate={timeAverage}
tooltip={CarbonChartTooltip}
/>
</div>
</>
);
}

Expand Down
4 changes: 2 additions & 2 deletions web/src/features/charts/EmissionChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function EmissionChart({ timeAverage, datetimes }: EmissionChartProps) {
const { chartData, layerFill, layerKeys } = data;

return (
<div className="ml-4">
<>
<ChartTitle translationKey="country-history.emissions" />
<AreaGraph
testId="history-emissions-graph"
Expand All @@ -38,7 +38,7 @@ function EmissionChart({ timeAverage, datetimes }: EmissionChartProps) {
height="8em"
tooltip={EmissionChartTooltip}
/>
</div>
</>
);
}

Expand Down
4 changes: 2 additions & 2 deletions web/src/features/charts/PriceChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function PriceChart({ datetimes, timeAverage }: PriceChartProps) {
data;

return (
<div className="ml-4">
<>
<ChartTitle translationKey="country-history.electricityprices" />
<AreaGraph
testId="history-prices-graph"
Expand All @@ -42,7 +42,7 @@ function PriceChart({ datetimes, timeAverage }: PriceChartProps) {
isOverlayEnabled={false}
tooltip={PriceChartTooltip}
/>
</div>
</>
);
}

Expand Down
71 changes: 54 additions & 17 deletions web/src/features/charts/bar-breakdown/BarBreakdownChart.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import * as Portal from '@radix-ui/react-portal';
import { getOffsetTooltipPosition } from 'components/tooltips/utilities';
import { useAtom } from 'jotai';
import React, { useState } from 'react';
import { useTranslation } from 'translation/translation';
import { ZoneDetail } from 'types';
import { displayByEmissionsAtom } from 'utils/state/atoms';
import { useBreakpoint } from 'utils/styling';
import { useReferenceWidthHeightObserver } from 'utils/viewport';
import useBarBreakdownChartData from '../hooks/useBarBreakdownProductionChartData';
import BreakdownChartTooltip from '../tooltips/BreakdownChartTooltip';
import BarBreakdownEmissionsChart from './BarBreakdownEmissionsChart';
import BarBreakdownProductionChart from './BarBreakdownProductionChart';
import BySource from './BySource';
Expand All @@ -20,6 +26,13 @@ function BarBreakdownChart() {
const [displayByEmissions] = useAtom(displayByEmissionsAtom);
const { ref, width } = useReferenceWidthHeightObserver();
const { __ } = useTranslation();
const isBiggerThanMobile = useBreakpoint('sm');

const [tooltipData, setTooltipData] = useState<{
selectedLayerKey: string;
x: number;
y: number;
} | null>(null);

if (isLoading) {
return null;
Expand All @@ -38,29 +51,53 @@ function BarBreakdownChart() {
);
}

// TODO: Show CountryTableOverlayIfNoData when required
const onMouseOver = (layerKey: string, _: ZoneDetail, event: React.MouseEvent) => {
const { clientX, clientY } = event;

const position = getOffsetTooltipPosition({
mousePositionX: clientX || 0,
mousePositionY: clientY || 0,
tooltipHeight: displayByEmissions ? 190 : 360,
isBiggerThanMobile,
});

const todoHandler = () => {
console.warn('TODO: Handle tooltips');
// see countrytable.jsx
// handleProductionRowMouseOver
//handleProductionRowMouseOut
//handleExchangeRowMouseOver
//handleExchangeRowMouseOut
setTooltipData({
selectedLayerKey: layerKey,
x: position.x,
y: position.y,
});
};

const onMouseOut = () => {
setTooltipData(null);
};

return (
<div className="relative w-full text-md " ref={ref}>
<div className="text-sm" ref={ref}>
<BySource />
{tooltipData && (
<Portal.Root
className="absolute left-0 top-0 h-full w-full bg-black/20 p-2 sm:h-0 sm:w-0 sm:p-0"
style={{
left: tooltipData?.x,
top: tooltipData?.y,
}}
>
<BreakdownChartTooltip
selectedLayerKey={tooltipData?.selectedLayerKey}
zoneDetail={currentZoneDetail}
/>
</Portal.Root>
)}
{displayByEmissions ? (
<BarBreakdownEmissionsChart
data={currentZoneDetail}
productionData={productionData}
exchangeData={exchangeData}
onProductionRowMouseOver={todoHandler}
onProductionRowMouseOut={todoHandler}
onExchangeRowMouseOver={todoHandler}
onExchangeRowMouseOut={todoHandler}
onProductionRowMouseOver={onMouseOver}
onProductionRowMouseOut={onMouseOut}
onExchangeRowMouseOver={onMouseOver}
onExchangeRowMouseOut={onMouseOut}
width={width}
height={height}
isMobile={false}
Expand All @@ -71,10 +108,10 @@ function BarBreakdownChart() {
currentData={currentZoneDetail}
productionData={productionData}
exchangeData={exchangeData}
onProductionRowMouseOver={todoHandler}
onProductionRowMouseOut={todoHandler}
onExchangeRowMouseOver={todoHandler}
onExchangeRowMouseOut={todoHandler}
onProductionRowMouseOver={onMouseOver}
onProductionRowMouseOut={onMouseOut}
onExchangeRowMouseOver={onMouseOver}
onExchangeRowMouseOut={onMouseOut}
width={width}
height={height}
isMobile={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ interface BarBreakdownEmissionsChartProps {
exchangeData: ExchangeDataType[];
productionData: ProductionDataType[];
isMobile: boolean;
onProductionRowMouseOver: (data: ZoneDetail) => void;
onProductionRowMouseOver: (
mode: string,
data: ZoneDetail,
event: React.MouseEvent<SVGPathElement, MouseEvent>
) => void;
onProductionRowMouseOut: () => void;
onExchangeRowMouseOver: (data: ZoneDetail) => void;
onExchangeRowMouseOver: (
mode: string,
data: ZoneDetail,
event: React.MouseEvent<SVGPathElement, MouseEvent>
) => void;
onExchangeRowMouseOut: () => void;
}

Expand Down
4 changes: 2 additions & 2 deletions web/src/features/charts/elements/AreaGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function AreaGraph({

const [selectedDate] = useAtom(selectedDatetimeIndexAtom);
const [tooltipData, setTooltipData] = useState<TooltipData | null>(null);
const isMinSM = useBreakpoint('sm');
const isBiggerThanMobile = useBreakpoint('sm');

// Build layers
const layers = useMemo(
Expand Down Expand Up @@ -267,7 +267,7 @@ function AreaGraph({
selectedLayerIndex !== null ? layerKeys[selectedLayerIndex] : undefined
}
tooltipSize={tooltipSize}
isMinSM={isMinSM}
isBiggerThanMobile={isBiggerThanMobile}
>
{(props) => tooltip(props)}
</AreaGraphTooltip>
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/panels/zone/DisplayByEmissionToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function EmissionToggle(): ReactElement {
};

return (
<div className="px-2 pt-3 pb-4 xl:px-10">
<div className="px-2 pt-3 xl:px-10">
<ToggleButton
options={options}
selectedOption={displayByEmissions.toString()}
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/panels/zone/NoInformationMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from 'translation/translation';
export default function NoInformationMessage() {
const { __ } = useTranslation();
return (
<div data-test-id="no-parser-message" className="text-base">
<div data-test-id="no-parser-message" className="pt-4 text-base">
<span
className="message"
dangerouslySetInnerHTML={{
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/panels/zone/ZoneDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default function ZoneDetails(): JSX.Element {
<>
<ZoneHeader zoneId={zoneId} {...selectedData} />
<DisplayByEmissionToggle />
<div className="h-[calc(100%-290px)] overflow-y-scroll pb-48">
<div className="h-[calc(100%-290px)] overflow-y-scroll p-4 pt-0 pb-48">
<ZoneDetailsContent
isLoading={isLoading}
isError={isError}
Expand Down
8 changes: 6 additions & 2 deletions web/src/features/time/TimeControllerWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ function FloatingTimeController() {
}

export default function TimeControllerWrapper() {
const isMinSM = useBreakpoint('sm');
return isMinSM ? <FloatingTimeController /> : <BottomSheetWrappedTimeController />;
const isBiggerThanMobile = useBreakpoint('sm');
return isBiggerThanMobile ? (
<FloatingTimeController />
) : (
<BottomSheetWrappedTimeController />
);
}

0 comments on commit 40b252e

Please sign in to comment.