mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-22 22:03:39 +03:00
B OpenNebula/one#6638: Fix charting (#3133)
* Fixes handling of showback + accounting records - Previously only worked for groups * Fixes rendering of multichart XAxis labels - Now uses a custom XAxis component to truncate long label names - Displays the full name on hover * Fixes rendering of showback data in non-fullscreen - Now all 3 charts have sufficient screen space in both modes Signed-off-by: Victor Hansson <vhansson@opennebula.io>
This commit is contained in:
parent
42c0df339b
commit
262f435cdd
@ -17,6 +17,44 @@ import PropTypes from 'prop-types'
|
|||||||
import { CartesianGrid, PolarAngleAxis, Cell } from 'recharts'
|
import { CartesianGrid, PolarAngleAxis, Cell } from 'recharts'
|
||||||
import { Component, Fragment } from 'react'
|
import { Component, Fragment } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Truncate long labels with ellipsis.
|
||||||
|
*
|
||||||
|
* @param {string} label - The label to be truncated.
|
||||||
|
* @param {number} maxLength - The maximum length of the label.
|
||||||
|
* @returns {string} The truncated label.
|
||||||
|
*/
|
||||||
|
const truncateLabel = (label, maxLength) => {
|
||||||
|
if (label.length > maxLength) {
|
||||||
|
return `${label.substring(0, maxLength)}...`
|
||||||
|
}
|
||||||
|
|
||||||
|
return label
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom tick component for the XAxis that displays the full label on hover.
|
||||||
|
*
|
||||||
|
* @param {object} props - Props.
|
||||||
|
* @param {number} props.x - The x position of the tick.
|
||||||
|
* @param {number} props.y - The y position of the tick.
|
||||||
|
* @param {object} props.payload - The payload of the tick.
|
||||||
|
* @returns {Component} The rendered tick.
|
||||||
|
*/
|
||||||
|
export const CustomXAxisTick = ({ x, y, payload }) => {
|
||||||
|
const fullLabel = payload?.value
|
||||||
|
const truncatedLabel = truncateLabel(fullLabel, 10)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<g transform={`translate(${x},${y})`}>
|
||||||
|
<title>{fullLabel}</title>
|
||||||
|
<text x={0} y={0} dy={16}>
|
||||||
|
{truncatedLabel}
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a color based on the metric, datasetId, and theme type.
|
* Generates a color based on the metric, datasetId, and theme type.
|
||||||
*
|
*
|
||||||
@ -234,6 +272,12 @@ export const GetChartElementConfig = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CustomXAxisTick.propTypes = {
|
||||||
|
x: PropTypes.number,
|
||||||
|
y: PropTypes.number,
|
||||||
|
payload: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
GetChartElementConfig.propTypes = {
|
GetChartElementConfig.propTypes = {
|
||||||
chartType: PropTypes.string.isRequired,
|
chartType: PropTypes.string.isRequired,
|
||||||
metric: PropTypes.object.isRequired,
|
metric: PropTypes.object.isRequired,
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
GetChartDefs,
|
GetChartDefs,
|
||||||
GetChartConfig,
|
GetChartConfig,
|
||||||
GetChartElementConfig,
|
GetChartElementConfig,
|
||||||
|
CustomXAxisTick,
|
||||||
} from 'client/components/Charts/MultiChart/helpers/scripts/chartDefs'
|
} from 'client/components/Charts/MultiChart/helpers/scripts/chartDefs'
|
||||||
import { exportDataToPDF } from 'client/components/Charts/MultiChart/helpers/scripts/exportPDF'
|
import { exportDataToPDF } from 'client/components/Charts/MultiChart/helpers/scripts/exportPDF'
|
||||||
import { exportDataToCSV } from 'client/components/Charts/MultiChart/helpers/scripts/exportCSV'
|
import { exportDataToCSV } from 'client/components/Charts/MultiChart/helpers/scripts/exportCSV'
|
||||||
@ -35,6 +36,7 @@ export {
|
|||||||
GetChartDefs,
|
GetChartDefs,
|
||||||
GetChartConfig,
|
GetChartConfig,
|
||||||
GetChartElementConfig,
|
GetChartElementConfig,
|
||||||
|
CustomXAxisTick,
|
||||||
exportDataToPDF,
|
exportDataToPDF,
|
||||||
exportDataToCSV,
|
exportDataToCSV,
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ import {
|
|||||||
generateColorByMetric,
|
generateColorByMetric,
|
||||||
GetChartConfig,
|
GetChartConfig,
|
||||||
GetChartElementConfig,
|
GetChartElementConfig,
|
||||||
|
CustomXAxisTick,
|
||||||
} from 'client/components/Charts/MultiChart/helpers/scripts'
|
} from 'client/components/Charts/MultiChart/helpers/scripts'
|
||||||
import {
|
import {
|
||||||
FormatPolarDataset,
|
FormatPolarDataset,
|
||||||
@ -174,7 +175,11 @@ export const ChartRenderer = ({
|
|||||||
|
|
||||||
{coordinateType === 'CARTESIAN' && (
|
{coordinateType === 'CARTESIAN' && (
|
||||||
<>
|
<>
|
||||||
<XAxis interval={0} dataKey={groupBy} />
|
<XAxis
|
||||||
|
interval={0}
|
||||||
|
dataKey={groupBy}
|
||||||
|
tick={<CustomXAxisTick />}
|
||||||
|
/>
|
||||||
<YAxis />
|
<YAxis />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -69,7 +69,6 @@ const topMetricNames = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const commonStyles = {
|
const commonStyles = {
|
||||||
minHeight: '250px',
|
|
||||||
width: '100%',
|
width: '100%',
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
marginTop: 2,
|
marginTop: 2,
|
||||||
@ -204,7 +203,15 @@ const generateShowbackInfoTab = ({ groups }) => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box padding={2} display="flex" flexDirection="column" height="100%">
|
<Box
|
||||||
|
padding={2}
|
||||||
|
display="flex"
|
||||||
|
flexDirection="column"
|
||||||
|
sx={{
|
||||||
|
height: '100vh',
|
||||||
|
minHeight: '1000px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Box
|
<Box
|
||||||
display="flex"
|
display="flex"
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
@ -231,8 +238,9 @@ const generateShowbackInfoTab = ({ groups }) => {
|
|||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
justifyContent="space-between"
|
justifyContent="space-between"
|
||||||
mb={2}
|
mb={2}
|
||||||
|
flex={5}
|
||||||
>
|
>
|
||||||
<Box flexGrow={1} mr={1} {...commonStyles}>
|
<Box flex={1} mr={1} {...commonStyles}>
|
||||||
<MultiChart
|
<MultiChart
|
||||||
datasets={topChartsData}
|
datasets={topChartsData}
|
||||||
chartType={'table'}
|
chartType={'table'}
|
||||||
@ -242,7 +250,7 @@ const generateShowbackInfoTab = ({ groups }) => {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box flexGrow={1} ml={1} {...commonStyles}>
|
<Box flex={1} ml={1} {...commonStyles}>
|
||||||
<MultiChart
|
<MultiChart
|
||||||
datasets={topChartsData}
|
datasets={topChartsData}
|
||||||
chartType={'bar'}
|
chartType={'bar'}
|
||||||
@ -254,7 +262,7 @@ const generateShowbackInfoTab = ({ groups }) => {
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box flexGrow={1} minHeight="400px" {...commonStyles}>
|
<Box flex={7} {...commonStyles}>
|
||||||
<MultiChart
|
<MultiChart
|
||||||
datasets={[
|
datasets={[
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,8 @@ const accounting = (
|
|||||||
responseData.HISTORY_RECORDS.HISTORY = history.filter(
|
responseData.HISTORY_RECORDS.HISTORY = history.filter(
|
||||||
(item) => item.VM.GID === groupId
|
(item) => item.VM.GID === groupId
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
responseData.HISTORY_RECORDS.HISTORY = history
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,16 +181,21 @@ const showback = (
|
|||||||
const responseData = value
|
const responseData = value
|
||||||
|
|
||||||
// Filter if there is not userId and there is a groupId
|
// Filter if there is not userId and there is a groupId
|
||||||
if (!userId && groupId && responseData && responseData.SHOWBACK_RECORDS) {
|
if (responseData && responseData.SHOWBACK_RECORDS) {
|
||||||
// Filter data by group id
|
// Filter data by group id
|
||||||
const showbackHistory = Array.isArray(
|
const showbackHistory = Array.isArray(
|
||||||
responseData.SHOWBACK_RECORDS.SHOWBACK
|
responseData.SHOWBACK_RECORDS.SHOWBACK
|
||||||
)
|
)
|
||||||
? responseData.SHOWBACK_RECORDS.SHOWBACK
|
? responseData.SHOWBACK_RECORDS.SHOWBACK
|
||||||
: [responseData.SHOWBACK_RECORDS.SHOWBACK]
|
: [responseData.SHOWBACK_RECORDS.SHOWBACK]
|
||||||
responseData.SHOWBACK_RECORDS.SHOWBACK = showbackHistory.filter(
|
|
||||||
(item) => item.GID === groupId
|
if (!userId && groupId) {
|
||||||
)
|
responseData.SHOWBACK_RECORDS.SHOWBACK = showbackHistory.filter(
|
||||||
|
(item) => item.GID === groupId
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
responseData.SHOWBACK_RECORDS.SHOWBACK = showbackHistory
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return response
|
// Return response
|
||||||
|
Loading…
x
Reference in New Issue
Block a user