Update charting library and how it is used. Closes #2658
This commit is contained in:
@@ -1,15 +1,35 @@
|
|||||||
import ChartJs from 'chart.js/auto';
|
|
||||||
import Chartkick from 'chartkick';
|
|
||||||
import format from 'date-fns/format';
|
import format from 'date-fns/format';
|
||||||
import { LineChart } from 'react-chartkick';
|
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
|
||||||
// from https://github.com/ankane/chartkick.js/blob/master/chart.js/chart.esm.js
|
import {
|
||||||
Chartkick.use(ChartJs);
|
Chart as ChartJS,
|
||||||
|
CategoryScale,
|
||||||
|
LinearScale,
|
||||||
|
PointElement,
|
||||||
|
LineElement,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
LogarithmicScale,
|
||||||
|
} from 'chart.js';
|
||||||
|
import { Line } from 'react-chartjs-2';
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
CategoryScale,
|
||||||
|
LogarithmicScale,
|
||||||
|
LinearScale,
|
||||||
|
PointElement,
|
||||||
|
LineElement,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
);
|
||||||
|
|
||||||
interface TimedValue {
|
interface TimedValue {
|
||||||
time: Date;
|
time: Date;
|
||||||
value: number;
|
value: number;
|
||||||
|
pointStyle?: boolean | string;
|
||||||
|
pointRadius?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ChartProps = {
|
export type ChartProps = {
|
||||||
@@ -45,47 +65,46 @@ export const Chart: FC<ChartProps> = ({
|
|||||||
|
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
renderData.push({
|
renderData.push({
|
||||||
name: title,
|
id: title,
|
||||||
color,
|
label: title,
|
||||||
|
backgroundColor: color,
|
||||||
|
borderColor: color,
|
||||||
|
borderWidth: 3,
|
||||||
data: createGraphDataset(data),
|
data: createGraphDataset(data),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dataCollections.forEach(collection => {
|
dataCollections.forEach(collection => {
|
||||||
renderData.push({
|
renderData.push({
|
||||||
name: collection.name,
|
id: collection.name,
|
||||||
|
label: collection.name,
|
||||||
data: createGraphDataset(collection.data),
|
data: createGraphDataset(collection.data),
|
||||||
color: collection.color,
|
backgroundColor: collection.color,
|
||||||
dataset: collection.options,
|
borderColor: collection.color,
|
||||||
|
borderWidth: 3,
|
||||||
|
pointStyle: collection.pointStyle || 'circle',
|
||||||
|
radius: collection.pointRadius || 1,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// ChartJs.defaults.scales.linear.reverse = true;
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
|
responsive: true,
|
||||||
|
|
||||||
scales: {
|
scales: {
|
||||||
y: { reverse: false, type: 'linear' },
|
y: {
|
||||||
x: {
|
type: yLogarithmic ? ('logarithmic' as const) : ('linear' as const),
|
||||||
type: 'time',
|
reverse: yFlipped,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: unit,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
options.scales.y.reverse = yFlipped;
|
|
||||||
options.scales.y.type = yLogarithmic ? 'logarithmic' : 'linear';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="line-chart-container">
|
<div className="line-chart-container">
|
||||||
<LineChart
|
<Line data={{ datasets: renderData }} options={options} height="70vh" />
|
||||||
xtitle="Time"
|
|
||||||
ytitle={title}
|
|
||||||
suffix={unit}
|
|
||||||
legend="bottom"
|
|
||||||
color={color}
|
|
||||||
data={renderData}
|
|
||||||
download={title}
|
|
||||||
library={options}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
256
web/package-lock.json
generated
256
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -25,10 +25,9 @@
|
|||||||
"@xstate/react": "3.0.2",
|
"@xstate/react": "3.0.2",
|
||||||
"antd": "4.24.7",
|
"antd": "4.24.7",
|
||||||
"autoprefixer": "10.4.13",
|
"autoprefixer": "10.4.13",
|
||||||
"chart.js": "4.2.0",
|
"chart.js": "^4.2.0",
|
||||||
"chartkick": "5.0.1",
|
|
||||||
"classnames": "2.3.2",
|
"classnames": "2.3.2",
|
||||||
"date-fns": "2.29.3",
|
"date-fns": "^2.29.3",
|
||||||
"entities": "^4.4.0",
|
"entities": "^4.4.0",
|
||||||
"linkify-html": "^4.1.0",
|
"linkify-html": "^4.1.0",
|
||||||
"linkifyjs": "^4.1.0",
|
"linkifyjs": "^4.1.0",
|
||||||
@@ -39,7 +38,8 @@
|
|||||||
"postcss-flexbugs-fixes": "5.0.2",
|
"postcss-flexbugs-fixes": "5.0.2",
|
||||||
"prop-types": "15.8.1",
|
"prop-types": "15.8.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-chartkick": "0.5.3",
|
"react-chartjs-2": "^5.2.0",
|
||||||
|
"react-chartkick": "^0.5.3",
|
||||||
"react-crossfade-img": "1.0.0",
|
"react-crossfade-img": "1.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-highlighter-ts": "18.0.1",
|
"react-highlighter-ts": "18.0.1",
|
||||||
|
|||||||
@@ -69,16 +69,19 @@ export default function HardwareInfo() {
|
|||||||
name: 'CPU',
|
name: 'CPU',
|
||||||
color: '#B63FFF',
|
color: '#B63FFF',
|
||||||
data: hardwareStatus.cpu,
|
data: hardwareStatus.cpu,
|
||||||
|
pointStyle: 'rect',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Memory',
|
name: 'Memory',
|
||||||
color: '#2087E2',
|
color: '#2087E2',
|
||||||
data: hardwareStatus.memory,
|
data: hardwareStatus.memory,
|
||||||
|
pointStyle: 'circle',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Disk',
|
name: 'Disk',
|
||||||
color: '#FF7700',
|
color: '#FF7700',
|
||||||
data: hardwareStatus.disk,
|
data: hardwareStatus.disk,
|
||||||
|
pointStyle: 'rectRounded',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -130,13 +130,13 @@ const StreamHealth = () => {
|
|||||||
{
|
{
|
||||||
name: 'Errors',
|
name: 'Errors',
|
||||||
color: '#B63FFF',
|
color: '#B63FFF',
|
||||||
options: { radius: 3 },
|
|
||||||
data: errors,
|
data: errors,
|
||||||
|
pointStyle: 'crossRot',
|
||||||
|
pointRadius: 7,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Quality changes',
|
name: 'Quality changes',
|
||||||
color: '#2087E2',
|
color: '#2087E2',
|
||||||
options: { radius: 2 },
|
|
||||||
data: qualityVariantChanges,
|
data: qualityVariantChanges,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -145,19 +145,16 @@ const StreamHealth = () => {
|
|||||||
{
|
{
|
||||||
name: 'Median stream latency',
|
name: 'Median stream latency',
|
||||||
color: '#00FFFF',
|
color: '#00FFFF',
|
||||||
options: { radius: 2 },
|
|
||||||
data: medianLatency,
|
data: medianLatency,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Lowest stream latency',
|
name: 'Lowest stream latency',
|
||||||
color: '#02FD0D',
|
color: '#02FD0D',
|
||||||
options: { radius: 2 },
|
|
||||||
data: lowestLatency,
|
data: lowestLatency,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Highest stream latency',
|
name: 'Highest stream latency',
|
||||||
color: '#B63FFF',
|
color: '#B63FFF',
|
||||||
options: { radius: 2 },
|
|
||||||
data: highestLatency,
|
data: highestLatency,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -188,6 +185,7 @@ const StreamHealth = () => {
|
|||||||
time: item.time,
|
time: item.time,
|
||||||
value: segmentLength,
|
value: segmentLength,
|
||||||
})),
|
})),
|
||||||
|
pointStyle: 'dash' as const,
|
||||||
options: { radius: 0 },
|
options: { radius: 0 },
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -358,7 +356,7 @@ const StreamHealth = () => {
|
|||||||
title="Seconds"
|
title="Seconds"
|
||||||
dataCollections={segmentDownloadDurationChart}
|
dataCollections={segmentDownloadDurationChart}
|
||||||
color="#FF7700"
|
color="#FF7700"
|
||||||
unit="s"
|
unit="seconds"
|
||||||
yLogarithmic
|
yLogarithmic
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -420,7 +418,7 @@ const StreamHealth = () => {
|
|||||||
title="Viewer Latency"
|
title="Viewer Latency"
|
||||||
description="An approximate number of seconds that your viewers are behind your live video. The largest cause of latency spikes is buffering. High latency itself is not a problem, and optimizing for low latency can result in buffering, resulting in even higher latency."
|
description="An approximate number of seconds that your viewers are behind your live video. The largest cause of latency spikes is buffering. High latency itself is not a problem, and optimizing for low latency can result in buffering, resulting in even higher latency."
|
||||||
/>
|
/>
|
||||||
<Chart title="Seconds" dataCollections={latencyChart} color="#FF7700" unit="s" />
|
<Chart title="Seconds" dataCollections={latencyChart} color="#FF7700" unit="seconds" />
|
||||||
</Card>
|
</Card>
|
||||||
</Space>
|
</Space>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ export default function ViewersOverTime() {
|
|||||||
</button>
|
</button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
{viewerInfo.length > 0 && (
|
{viewerInfo.length > 0 && (
|
||||||
<Chart title="Viewers" data={viewerInfo} color="#2087E2" unit="" />
|
<Chart title="Viewers" data={viewerInfo} color="#2087E2" unit="viewers" />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ViewerTable data={viewerDetails} />
|
<ViewerTable data={viewerDetails} />
|
||||||
|
|||||||
Reference in New Issue
Block a user