Skip to content

Commit

Permalink
Mantine charts (inventree#7419)
Browse files Browse the repository at this point in the history
* Install @mantine/charts

* Import charts styles

* Refactor <PricingOverviewPanel />

* Refactor internal price panel

* Refactor variant price panel

* BOM bar chart

* BOM donut

* Refactor supplier pricing panel

* More refaactoring

* Cleanup unused imports

* Fix typo

* playwright test updates
  • Loading branch information
SchrodingersGat authored and martonmiklos committed Jun 24, 2024
1 parent b20d7a2 commit 4186394
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 310 deletions.
1 change: 1 addition & 0 deletions src/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@lingui/core": "^4.10.0",
"@lingui/react": "^4.10.0",
"@mantine/carousel": "^7.8.0",
"@mantine/charts": "^7.10.1",
"@mantine/core": "^7.10.0",
"@mantine/dates": "^7.8.0",
"@mantine/dropzone": "^7.8.0",
Expand Down
20 changes: 10 additions & 10 deletions src/frontend/src/components/charts/colors.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export const CHART_COLORS: string[] = [
'#ffa8a8',
'#8ce99a',
'#74c0fc',
'#ffe066',
'#63e6be',
'#ffc078',
'#d8f5a2',
'#66d9e8',
'#e599f7',
'#dee2e6'
'blue',
'teal',
'lime',
'yellow',
'grape',
'red',
'orange',
'green',
'indigo',
'pink'
];
9 changes: 6 additions & 3 deletions src/frontend/src/components/charts/tooltipFormatter.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { formatCurrency } from '../../defaults/formatters';

export function tooltipFormatter(label: any, currency: string) {
/*
* Render a chart label for a currency graph
*/
export function tooltipFormatter(value: any, currency?: string) {
return (
formatCurrency(label, {
formatCurrency(value, {
currency: currency
})?.toString() ?? ''
})?.toString() ?? value.toString()
);
}
1 change: 1 addition & 0 deletions src/frontend/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import '@mantine/carousel/styles.css';
import '@mantine/charts/styles.css';
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
import '@mantine/spotlight/styles.css';
Expand Down
110 changes: 37 additions & 73 deletions src/frontend/src/pages/part/pricing/BomPricingPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import { t } from '@lingui/macro';
import { BarChart, DonutChart } from '@mantine/charts';
import {
Center,
Group,
SegmentedControl,
SimpleGrid,
Stack,
Text
} from '@mantine/core';
import { ReactNode, useMemo, useState } from 'react';
import {
Bar,
BarChart,
Cell,
Legend,
Pie,
PieChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis
} from 'recharts';

import { CHART_COLORS } from '../../../components/charts/colors';
import { tooltipFormatter } from '../../../components/charts/tooltipFormatter';
Expand All @@ -44,42 +34,30 @@ function BomPieChart({
readonly data: any[];
readonly currency: string;
}) {
// Construct donut data
const maxPricing = useMemo(() => {
return data.map((entry, index) => {
return {
name: entry.name,
value: entry.total_price_max,
color: CHART_COLORS[index % CHART_COLORS.length] + '.5'
};
});
}, [data]);

return (
<ResponsiveContainer width="100%" height={500}>
<PieChart>
<Pie
data={data}
dataKey="total_price_min"
nameKey="name"
innerRadius={20}
outerRadius={100}
>
{data.map((_entry, index) => (
<Cell
key={`cell-${index}`}
fill={CHART_COLORS[index % CHART_COLORS.length]}
/>
))}
</Pie>
<Pie
data={data}
dataKey="total_price_max"
nameKey="name"
innerRadius={120}
outerRadius={240}
>
{data.map((_entry, index) => (
<Cell
key={`cell-${index}`}
fill={CHART_COLORS[index % CHART_COLORS.length]}
/>
))}
</Pie>
<Tooltip
formatter={(label, payload) => tooltipFormatter(label, currency)}
/>
</PieChart>
</ResponsiveContainer>
<Center>
<DonutChart
data={maxPricing}
size={500}
thickness={80}
withLabels={false}
withLabelsLine={false}
tooltipDataSource="segment"
chartLabel={t`Total Price`}
valueFormatter={(value) => tooltipFormatter(value, currency)}
/>
</Center>
);
}

Expand All @@ -92,32 +70,18 @@ function BomBarChart({
readonly currency: string;
}) {
return (
<ResponsiveContainer width="100%" height={500}>
<BarChart data={data}>
<XAxis dataKey="name" />
<YAxis
tickFormatter={(value, index) =>
formatCurrency(value, {
currency: currency
})?.toString() ?? ''
}
/>
<Tooltip
formatter={(label, payload) => tooltipFormatter(label, currency)}
/>
<Legend />
<Bar
dataKey="total_price_min"
fill={CHART_COLORS[0]}
label={t`Minimum Total Price`}
/>
<Bar
dataKey="total_price_max"
fill={CHART_COLORS[1]}
label={t`Maximum Total Price`}
/>
</BarChart>
</ResponsiveContainer>
<BarChart
h={500}
dataKey="name"
data={data}
xAxisLabel={t`Component`}
yAxisLabel={t`Price Range`}
series={[
{ name: 'total_price_min', label: t`Minimum Price`, color: 'blue.6' },
{ name: 'total_price_max', label: t`Maximum Price`, color: 'teal.6' }
]}
valueFormatter={(value) => tooltipFormatter(value, currency)}
/>
);
}

Expand Down
42 changes: 9 additions & 33 deletions src/frontend/src/pages/part/pricing/PriceBreakPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import { t } from '@lingui/macro';
import { BarChart } from '@mantine/charts';
import { SimpleGrid } from '@mantine/core';
import { useCallback, useMemo, useState } from 'react';
import {
Bar,
BarChart,
Legend,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis
} from 'recharts';

import { AddItemButton } from '../../../components/buttons/AddItemButton';
import { CHART_COLORS } from '../../../components/charts/colors';
import { tooltipFormatter } from '../../../components/charts/tooltipFormatter';
import { ApiFormFieldSet } from '../../../components/forms/fields/ApiFormField';
import { formatCurrency } from '../../../defaults/formatters';
Expand Down Expand Up @@ -169,29 +160,14 @@ export default function PriceBreakPanel({
}}
/>
{table.records.length > 0 ? (
<ResponsiveContainer width="100%" height={500}>
<BarChart data={table.records}>
<XAxis dataKey="quantity" />
<YAxis
tickFormatter={(value, index) =>
formatCurrency(value, {
currency: currency
})?.toString() ?? ''
}
/>
<Tooltip
formatter={(label, payload) =>
tooltipFormatter(label, currency)
}
/>
<Legend />
<Bar
dataKey="price"
fill={CHART_COLORS[0]}
label={t`Price Break`}
/>
</BarChart>
</ResponsiveContainer>
<BarChart
dataKey="quantity"
data={table.records}
series={[{ name: 'price', label: t`Price`, color: 'blue.6' }]}
xAxisLabel={t`Quantity`}
yAxisLabel={t`Unit Price`}
valueFormatter={(value) => tooltipFormatter(value, currency)}
/>
) : (
<NoPricingData />
)}
Expand Down
50 changes: 12 additions & 38 deletions src/frontend/src/pages/part/pricing/PricingOverviewPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { t } from '@lingui/macro';
import { BarChart } from '@mantine/charts';
import {
Alert,
Anchor,
Expand All @@ -19,17 +20,7 @@ import {
} from '@tabler/icons-react';
import { DataTable } from 'mantine-datatable';
import { ReactNode, useMemo } from 'react';
import {
Bar,
BarChart,
Legend,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis
} from 'recharts';

import { CHART_COLORS } from '../../../components/charts/colors';
import { tooltipFormatter } from '../../../components/charts/tooltipFormatter';
import { formatCurrency, renderDate } from '../../../defaults/formatters';
import { panelOptions } from '../PartPricingPanel';
Expand Down Expand Up @@ -192,34 +183,17 @@ export default function PricingOverviewPanel({
columns={columns}
/>
</Stack>
<ResponsiveContainer width="100%" height={500}>
<BarChart data={overviewData} id="pricing-overview-chart">
<XAxis dataKey="title" />
<YAxis
tickFormatter={(value, index) =>
formatCurrency(value, {
currency: pricing?.currency
})?.toString() ?? ''
}
/>
<Tooltip
formatter={(label, payload) =>
tooltipFormatter(label, pricing?.currency)
}
/>
<Legend />
<Bar
dataKey="min_value"
fill={CHART_COLORS[0]}
label={t`Minimum Price`}
/>
<Bar
dataKey="max_value"
fill={CHART_COLORS[1]}
label={t`Maximum Price`}
/>
</BarChart>
</ResponsiveContainer>
<BarChart
aria-label="pricing-overview-chart"
dataKey="title"
data={overviewData}
title={t`Pricing Overview`}
series={[
{ name: 'min_value', label: t`Minimum Value`, color: 'blue.6' },
{ name: 'max_value', label: t`Maximum Value`, color: 'teal.6' }
]}
valueFormatter={(value) => tooltipFormatter(value, pricing?.currency)}
/>
</SimpleGrid>
</Stack>
);
Expand Down
45 changes: 8 additions & 37 deletions src/frontend/src/pages/part/pricing/PurchaseHistoryPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
import { t } from '@lingui/macro';
import { BarChart } from '@mantine/charts';
import { Group, SimpleGrid, Text } from '@mantine/core';
import { ReactNode, useCallback, useMemo } from 'react';
import {
Bar,
BarChart,
Legend,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis
} from 'recharts';

import { CHART_COLORS } from '../../../components/charts/colors';
import { tooltipFormatter } from '../../../components/charts/tooltipFormatter';
import { formatCurrency, renderDate } from '../../../defaults/formatters';
import { ApiEndpoints } from '../../../enums/ApiEndpoints';
import { useTable } from '../../../hooks/UseTable';
Expand Down Expand Up @@ -131,32 +121,13 @@ export default function PurchaseHistoryPanel({
}}
/>
{purchaseHistoryData.length > 0 ? (
<ResponsiveContainer width="100%" height={500}>
<BarChart data={purchaseHistoryData}>
<XAxis dataKey="name" />
<YAxis
tickFormatter={(value, index) =>
formatCurrency(value, {
currency: currency
})?.toString() ?? ''
}
/>
<Tooltip
formatter={(label, payload) => tooltipFormatter(label, currency)}
/>
<Legend />
<Bar
dataKey="unit_price"
fill={CHART_COLORS[0]}
label={t`Unit Price`}
/>
<Bar
dataKey="purchase_price"
fill={CHART_COLORS[1]}
label={t`Purchase Price`}
/>
</BarChart>
</ResponsiveContainer>
<BarChart
data={purchaseHistoryData}
dataKey="name"
series={[
{ name: 'unit_price', label: t`Unit Price`, color: 'blue.5' }
]}
/>
) : (
<NoPricingData />
)}
Expand Down
Loading

0 comments on commit 4186394

Please sign in to comment.