Adds employee revenue and utilization chart

Updates package dependencies and charts for employee performance visualization

Includes:
- Upgrade to latest charting library version
- New chart displaying revenue and utilization metrics
- Forecast and actual data visualization with dual axis support
This commit is contained in:
Janus C. H. Knudsen 2025-12-28 23:31:31 +01:00
parent 85b006e0d6
commit 6c3662f571
4 changed files with 156 additions and 5 deletions

View file

@ -1895,6 +1895,13 @@
color: var(--color-text-secondary);
}
swp-chart-subtitle {
display: block;
font-size: 12px;
color: var(--color-text-muted);
margin-top: 2px;
}
swp-chart-legend {
display: flex;
gap: 16px;
@ -2658,6 +2665,17 @@
</swp-stat-card>
</div>
<!-- Omsætning & Belægningsgrad chart -->
<swp-card style="margin-bottom: 24px;">
<swp-chart-section>
<swp-chart-header>
<swp-chart-title>Omsætning & Belægningsgrad</swp-chart-title>
<swp-chart-subtitle>3 måneder bagud · 3 måneder frem</swp-chart-subtitle>
</swp-chart-header>
<swp-chart-container id="revenueUtilizationChart" style="height: 300px;"></swp-chart-container>
</swp-chart-section>
</swp-card>
<div class="grid-2">
<swp-card>
<swp-chart-section>
@ -3489,6 +3507,72 @@
height: 200,
legend: false
});
// Revenue & Utilization chart - dual axis (3 mdr bagud + 3 mdr frem)
fetch('data/employee-revenue-utilization.json')
.then(res => res.json())
.then(data => {
createChart(document.getElementById('revenueUtilizationChart'), {
xAxis: { categories: data.categories },
yAxis: [
{ min: 0, max: 50000, format: v => `${(v/1000).toFixed(0)}k` }, // Left: Revenue
{ min: 0, max: 100, format: v => `${v}%` }, // Right: Utilization
],
series: [
// Actual revenue (solid bars)
{
name: 'Omsætning',
color: '#3b82f6',
type: 'bar',
yAxisIndex: 0,
unit: 'kr',
data: data.actual.revenue,
bar: { radius: 2 },
},
// Forecast revenue (transparent bars)
{
name: 'Omsætning (forecast)',
color: '#3b82f6',
type: 'bar',
yAxisIndex: 0,
unit: 'kr',
data: data.forecast.revenue,
bar: { radius: 2, opacity: 0.35 },
},
// Actual utilization (solid line)
{
name: 'Belægning',
color: '#00897b',
type: 'line',
yAxisIndex: 1,
unit: '%',
data: data.actual.utilization,
line: { width: 2.5 },
point: { radius: 0 },
showArea: false,
},
// Forecast utilization (dashed line)
{
name: 'Belægning (forecast)',
color: '#00897b',
type: 'line',
yAxisIndex: 1,
unit: '%',
data: data.forecast.utilization,
line: { width: 2.5, dashArray: '4 4' },
point: { radius: 0 },
showArea: false,
},
],
annotations: [
{ type: 'region', x: data.forecastStartCategory, x2: data.categories[data.categories.length - 1], backgroundColor: 'rgba(0,0,0,0.03)' },
{ type: 'verticalLine', x: data.nowCategory, dashArray: '4 4', label: 'Nu', labelPosition: 'top' },
],
legend: { position: 'top', align: 'end' },
padding: { right: 60 },
height: 280,
});
});
</script>
</body>