Skip to content

Commit

Permalink
Bring graphs to outcome block
Browse files Browse the repository at this point in the history
  • Loading branch information
terotik committed Oct 13, 2024
1 parent 6aa7495 commit 300c3ab
Show file tree
Hide file tree
Showing 12 changed files with 1,892 additions and 47 deletions.
23 changes: 17 additions & 6 deletions common/links.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React, { ReactElement, PropsWithChildren, ReactNode } from 'react';
import { default as NextLink, LinkProps } from 'next/link';
import { getCategoryString } from './categories';
import { isAbsoluteUrl, stripLocaleAndPlan, stripSlashes } from '@/utils/urls';
import React, { PropsWithChildren, ReactElement, ReactNode } from 'react';

import { useLocale } from 'next-intl';
import NextLink, { LinkProps } from 'next/link';

import { ACTIONS_PATH, INDICATORS_PATH } from '@/constants/routes';
import { usePlan } from '@/context/plan';
import { isAbsoluteUrl, stripLocaleAndPlan, stripSlashes } from '@/utils/urls';

import { PlanContextFragment } from './__generated__/graphql';
import { ACTIONS_PATH, INDICATORS_PATH } from '@/constants/routes';
import { useLocale } from 'next-intl';
import { getCategoryString } from './categories';

export function usePrependPlanAndLocale(path: string) {
const plan = usePlan();
Expand Down Expand Up @@ -89,6 +92,14 @@ export function IndicatorLink({
return <NextLink passHref {...other} href={href} legacyBehavior />;
}

export function PathsNodeLink({
id,
...other
}: { id: string | number; children: ReactNode } & LinkProps) {
// TODO: implement this
return <span {...other} data-id={id} />;
}

export type ActionLinkProps = {
action: {
identifier: string;
Expand Down
15 changes: 9 additions & 6 deletions components/paths/contentblocks/PathsOutcomeBlock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { Card, CardBody, Col, Container, Row } from 'reactstrap';
import styled from 'styled-components';

import ContentLoader from '@/components/common/ContentLoader';
import OutcomeCardSet from '@/components/paths/OutcomeCardSet';
import OutcomeCardSet from '@/components/paths/outcome/OutcomeCardSet';
import { activeScenarioVar, yearRangeVar } from '@/context/paths/cache';
import { usePaths } from '@/context/paths/paths';
import GET_PAGE from '@/queries/paths/get-paths-page';
import { getHttpHeaders } from '@/utils/paths/paths.utils';
import { useSuspenseQuery } from '@apollo/client';
import { useReactiveVar, useSuspenseQuery } from '@apollo/client';

const ErrorBackground = styled.div`
background-color: ${(props) => props.theme.brandDark};
Expand All @@ -31,7 +32,7 @@ const StyledCard = styled(Card)`
margin-bottom: 2rem;
}
svg {
svg.what-this {
width: 4rem;
margin-bottom: 2rem;
fill: ${(props) => props.theme.brandDark};
Expand All @@ -53,6 +54,8 @@ export default function PathsOutcomeBlock(props) {
const { heading, helpText, outcomeNodeId } = props;
const t = useTranslations();
const pathsInstance = usePaths();
const yearRange = useReactiveVar(yearRangeVar);
const activeScenario = useReactiveVar(activeScenarioVar);
const path = '';
const { data } = useSuspenseQuery(GET_PAGE, {
variables: { path, goal: null },
Expand Down Expand Up @@ -104,9 +107,9 @@ export default function PathsOutcomeBlock(props) {
}
nodeMap={allNodes}
rootNode={node}
startYear={1990}
endYear={2020}
activeScenario="ohyeah"
startYear={yearRange[0]}
endYear={yearRange[1]}
activeScenario={activeScenario?.name}
parentColor="#666"
activeNodeId={
index < visibleNodes.length - 1
Expand Down
132 changes: 132 additions & 0 deletions components/paths/graphs/DataTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { useTranslations } from 'next-intl';
import { Table } from 'reactstrap';
import Styled from 'styled-components';

import { formatNumber } from '@/common/paths/preprocess';

// import { useFeatures } from '@/common/instance';

const TableWrapper = Styled.div`
margin: 0 auto;
max-width: 100%;
overflow-x: auto;
overflow-y: visible;
width: calc(100% - 1rem);
bottom: -1rem;
max-height: 100%;
z-index: 1;
scroll-behavior: smooth;
font-size: 70%;
`;

const DataTable = (props) => {
const { node, subNodes, startYear, endYear } = props;
const t = useTranslations();
const totalHistoricalValues = node.metric.historicalValues.filter(
(value) => value.year >= startYear && value.year <= endYear
);
const totalForecastValues = node.metric.forecastValues.filter(
(value) => value.year >= startYear && value.year <= endYear
);
//const maximumFractionDigits = useFeatures().maximumFractionDigits ?? undefined;
const maximumFractionDigits = 3;

const hasTotalValues =
totalHistoricalValues.some((val) => val.value !== null) ||
totalForecastValues.some((val) => val.value !== null);

return (
<TableWrapper>
<h5>
{node.name} ({startYear} - {endYear})
</h5>
<Table bordered size="sm" responsive>
<thead>
<tr>
<th>{t('table-year')}</th>
<th>{t('table-measure-type')}</th>
{subNodes?.map((subNode) => (
<th key={subNode.id}>{subNode.name}</th>
))}
{hasTotalValues && <th>{node.metric.name}</th>}
<th>{t('table-unit')}</th>
</tr>
</thead>
<tbody>
{totalHistoricalValues.map((metric) => (
<tr key={`h-${metric.year}`}>
<td>{metric.year}</td>
<td>{t('table-historical')}</td>
{subNodes?.map((subNode) => (
<td key={`${subNode.id}-${metric.year}`}>
{subNode.metric.historicalValues.find(
(value) => value.year === metric.year
)
? formatNumber(
subNode.metric.historicalValues.find(
(value) => value.year === metric.year
).value,
t.language,
maximumFractionDigits
)
: '-'}
</td>
))}
{hasTotalValues && (
<td>
{formatNumber(
metric.value,
t.language,
maximumFractionDigits
)}
</td>
)}
<td
dangerouslySetInnerHTML={{
__html: node.metric?.unit?.htmlShort,
}}
/>
</tr>
))}
{totalForecastValues.map((metric) => (
<tr key={`f-${metric.year}`}>
<td>{metric.year}</td>
<td>{t('table-scenario-forecast')}</td>
{subNodes?.map((subNode) => (
<td key={`${subNode.id}-${metric.year}`}>
{subNode.metric.forecastValues.find(
(value) => value.year === metric.year
)
? formatNumber(
subNode.metric.forecastValues.find(
(value) => value.year === metric.year
).value,
t.language,
maximumFractionDigits
)
: '-'}
</td>
))}
{hasTotalValues && (
<td>
{formatNumber(
metric.value,
t.language,
maximumFractionDigits
)}
</td>
)}
<td
dangerouslySetInnerHTML={{
__html: node.metric?.unit?.htmlShort,
}}
/>
</tr>
))}
</tbody>
</Table>
</TableWrapper>
);
};

export default DataTable;
Loading

0 comments on commit 300c3ab

Please sign in to comment.