Skip to content

Commit

Permalink
Improve the waterfall chart formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
dyang415 committed Oct 7, 2023
1 parent 4add38f commit 144b476
Showing 1 changed file with 46 additions and 27 deletions.
73 changes: 46 additions & 27 deletions frontend/src/components/main-dashboard/waterfall/WaterfallChart.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Divider, Flex } from "@tremor/react";
import { useState } from "react";
import {
Bar,
BarChart,
Expand Down Expand Up @@ -54,13 +55,26 @@ const CustomizedGroupTick = (props: any) => {
<g transform={`translate(${x},${y})`}>
{rows.map((row, idx) => (
<text x={0} y={0} dy={18 * (idx + 1)} textAnchor="middle" fill="#666">
{row}
{idx > 4 ? "..." : row}
</text>
))}
</g>
);
};

function shortenNumber(value: number) {
const number = Math.abs(value);
if (number > 1000000000) {
return formatNumber(value / 1000000000) + "B";
} else if (number > 1000000) {
return formatNumber(value / 1000000) + "M";
} else if (number > 1000) {
return formatNumber(value / 1000) + "K";
} else {
return formatNumber(value);
}
}

const CustomTooltip = ({ active, payload, label }: any) => {
if (active && payload && payload.length) {
const data = payload.find((p: any) => p.dataKey === "overlap").payload;
Expand All @@ -73,21 +87,23 @@ const CustomTooltip = ({ active, payload, label }: any) => {
alignItems="start"
>
<Flex className="gap-2" justifyContent="start">
{(label as string).split(" AND ").map((component, idx) => {
return (
<>
<Flex className="gap-2">
{(label as string).split(" AND ").flatMap((component, idx) => {
const result = [
<span
className="text-black border-2 bg-gray-100 p-1"
key={component}
key={`${label}-${component}`}
>
{component}
</span>
{idx < (label as string).split(" AND ").length - 1 && (
<span>AND</span>
)}
</>
);
})}
</span>,
];

if (idx < (label as string).split(" AND ").length - 1) {
result.push(<span>AND</span>);
}
return result;
})}
</Flex>
</Flex>
<Divider className="my-3" />
<p>Change: {formatNumber(change)}</p>
Expand All @@ -100,6 +116,7 @@ const CustomTooltip = ({ active, payload, label }: any) => {
};

export default function WaterfallChart({ waterfallRows, totalImpact }: Props) {
const [width, setWidth] = useState<number>(0);
let pv = 0;
const data = Object.values(waterfallRows)
.slice(0, 8)
Expand Down Expand Up @@ -142,8 +159,13 @@ export default function WaterfallChart({ waterfallRows, totalImpact }: Props) {
overlap: 0,
flipped: false,
});

return (
<ResponsiveContainer width="100%" height={450}>
<ResponsiveContainer
width="100%"
height={450}
onResize={(w) => setWidth(w)}
>
<BarChart
width={1650}
height={450}
Expand All @@ -159,26 +181,18 @@ export default function WaterfallChart({ waterfallRows, totalImpact }: Props) {
dataKey="name"
tick={CustomizedGroupTick}
height={120}
interval={0}
interval={
width === 0 ? 0 : Math.floor(waterfallRows.length / (width / 200))
}
type="category"
/>
<YAxis
label={{ value: "Contribution", angle: -90, position: "insideLeft" }}
padding={{
bottom: 5,
}}
tickFormatter={(tickValue) => {
const number = Math.abs(tickValue);
if (number > 1000000000) {
return (tickValue / 1000000000).toString() + "B";
} else if (number > 1000000) {
return (tickValue / 1000000).toString() + "M";
} else if (number > 1000) {
return (tickValue / 1000).toString() + "K";
} else {
return tickValue.toString();
}
}}
width={100}
tickFormatter={shortenNumber}
/>
<Tooltip content={<CustomTooltip />} />
{data.map((row, idx) => {
Expand Down Expand Up @@ -226,7 +240,12 @@ export default function WaterfallChart({ waterfallRows, totalImpact }: Props) {
position="top"
formatter={(num: number) => {
const prefix = num > 0 ? "+ " : "";
return prefix + formatNumber(num);
const result = prefix + formatNumber(num);

if (result.length * 8 > width / (waterfallRows.length + 2)) {
return prefix + shortenNumber(num);
}
return result;
}}
/>
{data.map((item, index) => {
Expand Down

0 comments on commit 144b476

Please sign in to comment.