Skip to content

Commit

Permalink
feat(web): add production source legends to data source accordion for…
Browse files Browse the repository at this point in the history
… carbon and emission chart (electricitymaps#6728)

* add production source legends to data sources for carbon and emission chart

* add legends to bar-breakdown

* fix: assumes is not shown in data sources

* add power generation and emission factor to all charts

* remove data sources when graph is disabled

* fix source alignment

* hide when no sources

* fix: use not ! instead of == undefined | null

* fix: based on tonys comments

* fix: create hook useZoneDataSources

* renameing

* fix: remove productionSourceLegendList from breakdownChart when it is disabled

* remove padding and move files around

* fix: sort imports
  • Loading branch information
silkeholmebonnen committed Jun 4, 2024
1 parent 4829414 commit 64f2912
Show file tree
Hide file tree
Showing 21 changed files with 366 additions and 217 deletions.
73 changes: 46 additions & 27 deletions web/src/features/charts/BreakdownChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Accordion from 'components/Accordion';
import { max, sum } from 'd3-array';
import Divider from 'features/panels/zone/Divider';
import { CircleBoltIcon } from 'icons/circleBoltIcon';
import { IndustryIcon } from 'icons/industryIcon';
import { WindTurbineIcon } from 'icons/windTurbineIcon';
import { useTranslation } from 'react-i18next';
import { ElectricityModeType } from 'types';
Expand All @@ -10,15 +11,16 @@ import { Mode, TimeAverages, TrackEvent } from 'utils/constants';
import { formatCo2 } from 'utils/formatting';
import { dataSourcesCollapsedBreakdown } from 'utils/state/atoms';

import { DataSources } from './bar-breakdown/DataSources';
import ProductionSourceLegendList from './bar-breakdown/ProductionSourceLegendList';
import { RoundedCard } from './bar-breakdown/RoundedCard';
import { ChartTitle } from './ChartTitle';
import { DataSources } from './DataSources';
import { DisabledMessage } from './DisabledMessage';
import AreaGraph from './elements/AreaGraph';
import { getBadgeText, getGenerationTypeKey, noop } from './graphUtils';
import useBreakdownChartData from './hooks/useBreakdownChartData';
import useZoneDataSources from './hooks/useZoneDataSources';
import { NotEnoughDataMessage } from './NotEnoughDataMessage';
import ProductionSourceLegendList from './ProductionSourceLegendList';
import { RoundedCard } from './RoundedCard';
import BreakdownChartTooltip from './tooltips/BreakdownChartTooltip';
import { AreaGraphElement } from './types';

Expand All @@ -33,7 +35,12 @@ function BreakdownChart({
datetimes,
timeAverage,
}: BreakdownChartProps) {
const { sources, data, mixMode } = useBreakdownChartData();
const { data, mixMode } = useBreakdownChartData();
const {
emissionFactorSources,
powerGenerationSources,
emissionFactorSourcesToProductionSources,
} = useZoneDataSources();
const { t } = useTranslation();

if (!data) {
Expand Down Expand Up @@ -101,29 +108,41 @@ function BreakdownChart({
dangerouslySetInnerHTML={{ __html: t('country-panel.exchangesAreMissing') }}
/>
)}
<ProductionSourceLegendList
sources={getProductionSourcesInChart(chartData)}
className="py-1.5"
/>
<Divider />
<Accordion
onOpen={() => {
trackEvent(TrackEvent.DATA_SOURCES_CLICKED, {
chart: displayByEmissions
? 'emission-origin-chart'
: 'electricity-origin-chart',
});
}}
title={t('data-sources.title')}
className="text-md"
isCollapsedAtom={dataSourcesCollapsedBreakdown}
>
<DataSources
title={t('data-sources.power')}
icon={<WindTurbineIcon />}
sources={sources}
/>
</Accordion>
{!isBreakdownGraphOverlayEnabled && (
<>
<ProductionSourceLegendList
sources={getProductionSourcesInChart(chartData)}
className="py-1.5"
/>
<Divider />
<Accordion
onOpen={() => {
trackEvent(TrackEvent.DATA_SOURCES_CLICKED, {
chart: displayByEmissions
? 'emission-origin-chart'
: 'electricity-origin-chart',
});
}}
title={t('data-sources.title')}
className="text-md"
isCollapsedAtom={dataSourcesCollapsedBreakdown}
>
<DataSources
title={t('data-sources.power')}
icon={<WindTurbineIcon />}
sources={powerGenerationSources}
/>
<DataSources
title={t('data-sources.emission')}
icon={<IndustryIcon />}
sources={emissionFactorSources}
emissionFactorSourcesToProductionSources={
emissionFactorSourcesToProductionSources
}
/>
</Accordion>
</>
)}
</RoundedCard>
);
}
Expand Down
24 changes: 19 additions & 5 deletions web/src/features/charts/CarbonChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import Accordion from 'components/Accordion';
import Divider from 'features/panels/zone/Divider';
import { CloudArrowUpIcon } from 'icons/cloudArrowUpIcon';
import { IndustryIcon } from 'icons/industryIcon';
import { WindTurbineIcon } from 'icons/windTurbineIcon';
import { useTranslation } from 'react-i18next';
import trackEvent from 'utils/analytics';
import { TimeAverages, TrackEvent } from 'utils/constants';
import { dataSourcesCollapsedEmission } from 'utils/state/atoms';

import { DataSources } from './bar-breakdown/DataSources';
import { RoundedCard } from './bar-breakdown/RoundedCard';
import { ChartTitle } from './ChartTitle';
import { DataSources } from './DataSources';
import AreaGraph from './elements/AreaGraph';
import { getBadgeText, noop } from './graphUtils';
import { useCarbonChartData } from './hooks/useCarbonChartData';
import useZoneDataSources from './hooks/useZoneDataSources';
import { NotEnoughDataMessage } from './NotEnoughDataMessage';
import { RoundedCard } from './RoundedCard';
import CarbonChartTooltip from './tooltips/CarbonChartTooltip';

interface CarbonChartProps {
Expand All @@ -22,8 +24,12 @@ interface CarbonChartProps {
}

function CarbonChart({ datetimes, timeAverage }: CarbonChartProps) {
const { data, emissionSourceToProductionSource, isLoading, isError } =
useCarbonChartData();
const { data, isLoading, isError } = useCarbonChartData();
const {
emissionFactorSources,
powerGenerationSources,
emissionFactorSourcesToProductionSources,
} = useZoneDataSources();
const { t } = useTranslation();

if (isLoading || isError || !data) {
Expand Down Expand Up @@ -69,10 +75,18 @@ function CarbonChart({ datetimes, timeAverage }: CarbonChartProps) {
className="text-md"
isCollapsedAtom={dataSourcesCollapsedEmission}
>
<DataSources
title={t('data-sources.power')}
icon={<WindTurbineIcon />}
sources={powerGenerationSources}
/>
<DataSources
title={t('data-sources.emission')}
icon={<IndustryIcon />}
sources={[...emissionSourceToProductionSource.keys()].sort()}
sources={emissionFactorSources}
emissionFactorSourcesToProductionSources={
emissionFactorSourcesToProductionSources
}
/>
</Accordion>
</RoundedCard>
Expand Down
51 changes: 51 additions & 0 deletions web/src/features/charts/DataSources.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { ElectricityModeType } from 'types';

import ProductionSourceLegend from './ProductionSourceLegend';

export function DataSources({
title,
icon,
sources,
emissionFactorSourcesToProductionSources,
}: {
title: string;
icon: React.ReactNode;
sources: string[];
emissionFactorSourcesToProductionSources?: { [key: string]: string[] };
}) {
const showDataSources = Boolean(
(sources && sources?.length > 0) || emissionFactorSourcesToProductionSources
);
if (showDataSources == false) {
return null;
}

return (
<div className="flex flex-col py-2">
<div className="flex flex-row pb-2">
<div className="mr-1">{icon}</div>
<div className="text-md font-semibold">{title}</div>
</div>
<div className="flex flex-col gap-2 pl-5">
{sources.sort().map((source, index) => (
<div key={index} className="text-sm">
{source}
{emissionFactorSourcesToProductionSources && (
<span className="inline-flex translate-y-1 gap-1 pl-1.5">
{emissionFactorSourcesToProductionSources[source]?.map(
(productionSource, index) => (
<span key={index} className="self-center object-center text-xs">
<ProductionSourceLegend
electricityType={productionSource as ElectricityModeType}
/>
</span>
)
)}
</span>
)}
</div>
))}
</div>
</div>
);
}
24 changes: 19 additions & 5 deletions web/src/features/charts/EmissionChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import Accordion from 'components/Accordion';
import Divider from 'features/panels/zone/Divider';
import { CloudArrowUpIcon } from 'icons/cloudArrowUpIcon';
import { IndustryIcon } from 'icons/industryIcon';
import { WindTurbineIcon } from 'icons/windTurbineIcon';
import { useTranslation } from 'react-i18next';
import trackEvent from 'utils/analytics';
import { TimeAverages, TrackEvent } from 'utils/constants';
import { formatCo2 } from 'utils/formatting';
import { dataSourcesCollapsedEmission } from 'utils/state/atoms';

import { DataSources } from './bar-breakdown/DataSources';
import { RoundedCard } from './bar-breakdown/RoundedCard';
import { ChartTitle } from './ChartTitle';
import { DataSources } from './DataSources';
import AreaGraph from './elements/AreaGraph';
import { getBadgeText, noop } from './graphUtils';
import { useEmissionChartData } from './hooks/useEmissionChartData';
import useZoneDataSources from './hooks/useZoneDataSources';
import { RoundedCard } from './RoundedCard';
import EmissionChartTooltip from './tooltips/EmissionChartTooltip';

interface EmissionChartProps {
Expand All @@ -22,8 +24,12 @@ interface EmissionChartProps {
}

function EmissionChart({ timeAverage, datetimes }: EmissionChartProps) {
const { data, emissionSourceToProductionSource, isLoading, isError } =
useEmissionChartData();
const { data, isLoading, isError } = useEmissionChartData();
const {
emissionFactorSources,
powerGenerationSources,
emissionFactorSourcesToProductionSources,
} = useZoneDataSources();
const { t } = useTranslation();
if (isLoading || isError || !data) {
return null;
Expand Down Expand Up @@ -67,10 +73,18 @@ function EmissionChart({ timeAverage, datetimes }: EmissionChartProps) {
className="text-md"
isCollapsedAtom={dataSourcesCollapsedEmission}
>
<DataSources
title={t('data-sources.power')}
icon={<WindTurbineIcon />}
sources={powerGenerationSources}
/>
<DataSources
title={t('data-sources.emission')}
icon={<IndustryIcon />}
sources={[...emissionSourceToProductionSource.keys()].sort()}
sources={emissionFactorSources}
emissionFactorSourcesToProductionSources={
emissionFactorSourcesToProductionSources
}
/>
</Accordion>
</RoundedCard>
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/charts/NetExchangeChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { TimeAverages } from 'utils/constants';
import { formatCo2 } from 'utils/formatting';
import { displayByEmissionsAtom, productionConsumptionAtom } from 'utils/state/atoms';

import { RoundedCard } from './bar-breakdown/RoundedCard';
import { ChartTitle } from './ChartTitle';
import AreaGraph from './elements/AreaGraph';
import { noop } from './graphUtils';
import { useNetExchangeChartData } from './hooks/useNetExchangeChartData';
import { RoundedCard } from './RoundedCard';
import NetExchangeChartTooltip from './tooltips/NetExchangeChartTooltip';

interface NetExchangeChartProps {
Expand Down
2 changes: 1 addition & 1 deletion web/src/features/charts/PriceChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { CoinsIcon } from 'icons/coinsIcon';
import { useTranslation } from 'react-i18next';
import { TimeAverages } from 'utils/constants';

import { RoundedCard } from './bar-breakdown/RoundedCard';
import { ChartTitle } from './ChartTitle';
import { DisabledMessage } from './DisabledMessage';
import AreaGraph from './elements/AreaGraph';
import { noop } from './graphUtils';
import { usePriceChartData } from './hooks/usePriceChartData';
import { NotEnoughDataMessage } from './NotEnoughDataMessage';
import { RoundedCard } from './RoundedCard';
import PriceChartTooltip from './tooltips/PriceChartTooltip';

interface PriceChartProps {
Expand Down
File renamed without changes.
Loading

0 comments on commit 64f2912

Please sign in to comment.