Switch to recharts.
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
Some checks failed
farmcontrol/farmcontrol-ui/pipeline/head There was a failure building this commit
This commit is contained in:
parent
afbab60ab9
commit
39111d81c8
@ -9,7 +9,6 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "./",
|
"homepage": "./",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/charts": "^2.6.5",
|
|
||||||
"@ant-design/icons": "^6.1.0",
|
"@ant-design/icons": "^6.1.0",
|
||||||
"@babel/plugin-transform-private-property-in-object": "^7.27.1",
|
"@babel/plugin-transform-private-property-in-object": "^7.27.1",
|
||||||
"@codemirror/lang-cpp": "^6.0.3",
|
"@codemirror/lang-cpp": "^6.0.3",
|
||||||
@ -61,6 +60,7 @@
|
|||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-responsive": "^10.0.1",
|
"react-responsive": "^10.0.1",
|
||||||
"react-router-dom": "^7.8.2",
|
"react-router-dom": "^7.8.2",
|
||||||
|
"recharts": "^3.8.1",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
"simplebar-react": "^3.3.2",
|
"simplebar-react": "^3.3.2",
|
||||||
"socket.io-client": "*",
|
"socket.io-client": "*",
|
||||||
|
|||||||
1215
pnpm-lock.yaml
generated
1215
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState, useContext, useMemo, lazy, Suspense } from 'react'
|
import { useEffect, useState, useContext, useMemo } from 'react'
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
Segmented,
|
Segmented,
|
||||||
@ -6,13 +6,18 @@ import {
|
|||||||
Popover,
|
Popover,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
Button,
|
Button,
|
||||||
Space,
|
Space
|
||||||
Skeleton
|
|
||||||
} from 'antd'
|
} from 'antd'
|
||||||
|
import {
|
||||||
const Column = lazy(() =>
|
ResponsiveContainer,
|
||||||
import('@ant-design/charts').then((module) => ({ default: module.Column }))
|
BarChart,
|
||||||
)
|
Bar,
|
||||||
|
CartesianGrid,
|
||||||
|
XAxis,
|
||||||
|
YAxis,
|
||||||
|
Tooltip,
|
||||||
|
Legend
|
||||||
|
} from 'recharts'
|
||||||
|
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { getModelByName } from '../../../database/ObjectModels'
|
import { getModelByName } from '../../../database/ObjectModels'
|
||||||
@ -285,39 +290,17 @@ const HistoryDisplay = ({
|
|||||||
return colors.default
|
return colors.default
|
||||||
})
|
})
|
||||||
|
|
||||||
const config = {
|
const chartRows = Array.from(
|
||||||
data: chartData,
|
chartData.reduce((acc, item) => {
|
||||||
height,
|
const existing = acc.get(item.date) || {
|
||||||
xField: 'dateFormatted',
|
date: item.date,
|
||||||
yField: 'value',
|
dateFormatted: item.dateFormatted
|
||||||
theme: {
|
|
||||||
type: isDarkMode ? 'dark' : 'light',
|
|
||||||
fontFamily: '"DM Sans", -apple-system, BlinkMacSystemFont, sans-serif'
|
|
||||||
},
|
|
||||||
stack: true,
|
|
||||||
colorField: 'category',
|
|
||||||
columnWidthRatio: 1,
|
|
||||||
scale: {
|
|
||||||
color: {
|
|
||||||
range: colorRange
|
|
||||||
}
|
|
||||||
},
|
|
||||||
smooth: true,
|
|
||||||
interaction: {
|
|
||||||
tooltip: {
|
|
||||||
marker: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
position: 'top'
|
|
||||||
},
|
|
||||||
animation: {
|
|
||||||
appear: {
|
|
||||||
animation: 'wave-in',
|
|
||||||
duration: 1000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
existing[item.category] = item.value
|
||||||
|
acc.set(item.date, existing)
|
||||||
|
return acc
|
||||||
|
}, new Map()).values()
|
||||||
|
).sort((a, b) => new Date(a.date) - new Date(b.date))
|
||||||
|
|
||||||
const customTimeRangeContent = (
|
const customTimeRangeContent = (
|
||||||
<Space.Compact>
|
<Space.Compact>
|
||||||
@ -391,22 +374,45 @@ const HistoryDisplay = ({
|
|||||||
<LoadingPlaceholder message='Loading history data...' />
|
<LoadingPlaceholder message='Loading history data...' />
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
{chartData.length > 0 && (
|
{chartRows.length > 0 && (
|
||||||
<Suspense
|
<div style={{ width: '100%', height: `${height}px` }}>
|
||||||
fallback={
|
<ResponsiveContainer width='100%' height='100%'>
|
||||||
<Flex
|
<BarChart data={chartRows}>
|
||||||
justify='center'
|
<CartesianGrid
|
||||||
align='center'
|
strokeDasharray='3 3'
|
||||||
style={{ height: `${height}px` }}
|
stroke={isDarkMode ? '#303030' : '#f0f0f0'}
|
||||||
>
|
/>
|
||||||
<Skeleton active paragraph={{ rows: 4 }} />
|
<XAxis
|
||||||
</Flex>
|
dataKey='dateFormatted'
|
||||||
}
|
tick={{ fill: isDarkMode ? '#d9d9d9' : '#595959', fontSize: 12 }}
|
||||||
>
|
/>
|
||||||
<Column {...config} />
|
<YAxis
|
||||||
</Suspense>
|
tick={{ fill: isDarkMode ? '#d9d9d9' : '#595959', fontSize: 12 }}
|
||||||
|
/>
|
||||||
|
<Tooltip
|
||||||
|
contentStyle={{
|
||||||
|
backgroundColor: isDarkMode ? '#1f1f1f' : '#ffffff',
|
||||||
|
border: `1px solid ${isDarkMode ? '#303030' : '#f0f0f0'}`,
|
||||||
|
borderRadius: 8
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Legend />
|
||||||
|
{modelStats.map((statDef, index) => {
|
||||||
|
const category = statDef.label || statDef.name
|
||||||
|
return (
|
||||||
|
<Bar
|
||||||
|
key={category}
|
||||||
|
dataKey={category}
|
||||||
|
stackId='history'
|
||||||
|
fill={colorRange[index] || colors.default}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</BarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
{loading == false && chartData.length == 0 && (
|
{loading == false && chartRows.length == 0 && (
|
||||||
<Flex justify='center' align='center' style={{ height: `${height}px` }}>
|
<Flex justify='center' align='center' style={{ height: `${height}px` }}>
|
||||||
<MissingPlaceholder message='No data available.' />
|
<MissingPlaceholder message='No data available.' />
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -423,7 +429,7 @@ HistoryDisplay.propTypes = {
|
|||||||
]),
|
]),
|
||||||
styles: PropTypes.object,
|
styles: PropTypes.object,
|
||||||
endDate: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
|
endDate: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
|
||||||
height: PropTypes.string
|
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
|
||||||
}
|
}
|
||||||
|
|
||||||
export default HistoryDisplay
|
export default HistoryDisplay
|
||||||
|
|||||||
@ -66,16 +66,6 @@ export default defineConfig({
|
|||||||
id.includes('node_modules/react-dom') ||
|
id.includes('node_modules/react-dom') ||
|
||||||
id.includes('node_modules/react-router-dom')
|
id.includes('node_modules/react-router-dom')
|
||||||
) {
|
) {
|
||||||
// EXCLUDE charts so they are handled by lazy loading in HistoryDisplay.jsx
|
|
||||||
if (
|
|
||||||
id.includes('node_modules/@ant-design/charts') ||
|
|
||||||
id.includes('node_modules/@ant-design/plots') ||
|
|
||||||
id.includes('node_modules/@ant-design/graphs') ||
|
|
||||||
id.includes('node_modules/@ant-design/charts-util') ||
|
|
||||||
id.includes('node_modules/@antv')
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return 'antd'
|
return 'antd'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user