ConsultancyProject_2_ETL/dashboard/resources/views/region.blade.php

543 lines
12 KiB
PHP
Raw Normal View History

2025-01-12 20:55:46 +01:00
@extends('base')
@section('body-class', 'region')
@section('header')
<nav>
<strong>{{ $region[0]['name'] }}</strong>
2025-01-12 20:55:46 +01:00
<ul>
<li><a href="/">Start</a></li>
@foreach($regions as $r)
@if($r['id'] != $regionId)
<li><a href="/region/{{ $r['id'] }}">{{ $r['name'] }}</a></li>
2025-01-12 20:55:46 +01:00
@endif
@endforeach
</ul>
</nav>
@endsection
@section('main')
<article style="grid-area: timeline;">
<div id="timeline"></div>
</article>
<article class="header" style="grid-area: chart6;">
<header>
2025-01-17 13:49:43 +01:00
<h2 id="prediction-title">Gleitender Mittelwert für die Verfügbarkeit der Region</h2>
</header>
<div id="chart-prediction"></div>
</article>
2025-01-12 20:55:46 +01:00
<article class="header" style="grid-area: chart1;">
<header>
2025-01-17 13:49:43 +01:00
<h2 id="belegung-title">Verfügbarkeit aller Mietobjekte über Gesamte Zeit der Region</h2>
2025-01-12 20:55:46 +01:00
</header>
<div id="chart-heatmap"></div>
</article>
<article class="header" style="grid-area: chart3;">
<header>
<h2>
2025-01-17 13:49:43 +01:00
Verfügbarkeit Region nach Monat am <span class="date">{{ $startDate }}</span>
2025-01-12 20:55:46 +01:00
</h2>
</header>
<div id="chart-capacity-monthly">
</div>
</article>
<article class="header" style="grid-area: chart2;">
<header>
<h2>
2025-01-17 13:49:43 +01:00
Entwicklung der Verfügbarkeit
2025-01-12 20:55:46 +01:00
</h2>
<button popovertarget="chart-capacity-popover"></button>
<div id="chart-capacity-popover" popover>
2025-01-17 13:49:43 +01:00
<h2>Erkläung zum Diagramm «Entwicklung der Verfügbarkeit»</h2>
<p>Das Liniendiagramm zeigt die Verfügbarkeit von Regionen. 100 % = die Region ist kaum ausgelastet; 100 % der Mietobjekte sind verfügbar. 0 % = Die Region ist komplett ausgelastet; Es stehen keine Mietangebote zur Verfügung.</p>
2025-01-12 20:55:46 +01:00
</div>
</header>
<div id="chart-capacity"></div>
</article>
<article class="header" style="grid-area: chart4;">
<header>
<h2>
2025-01-17 13:49:43 +01:00
Verfügbarkeit Wochentage am <span class="date">{{ $startDate }}</span>
2025-01-12 20:55:46 +01:00
</h2>
</header>
<div id="chart-capacity-daily">
</article>
<script type="module">
const sharedOptions = {
basic: {
color: {!! $diagramsOptions['shared']['colors'] !!},
2025-01-12 20:55:46 +01:00
grid: {
top: 20,
left: 60,
right: 0,
bottom: 50
},
2025-01-15 16:57:18 +01:00
tooltip: {
show: true,
trigger: 'axis',
valueFormatter: (value) => value == null ? 'N/A' : value.toFixed(2)+'%'
2025-01-15 16:57:18 +01:00
},
2025-01-12 20:55:46 +01:00
name: (opt) => {
return {
name: opt.name,
nameLocation: opt.location,
nameGap: 24,
nameTextStyle: {
fontWeight: 'bold',
},
}
}
}
}
const chartCapacity = document.getElementById('chart-capacity');
const cCapacity = echarts.init(chartCapacity);
const cCapacityOptions = {
legend: {
2025-01-15 16:57:18 +01:00
show: true
2025-01-12 20:55:46 +01:00
},
2025-01-15 16:57:18 +01:00
tooltip: sharedOptions.basic.tooltip,
2025-01-14 22:11:31 +01:00
color: sharedOptions.basic.color,
2025-01-12 20:55:46 +01:00
grid: {
top: 20,
left: 25,
right: 10,
bottom: 20,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!},
2025-01-12 20:55:46 +01:00
name: 'Zeitpunkt Scraping',
nameLocation: 'center',
nameGap: 24,
nameTextStyle: {
fontWeight: 'bold',
}
},
yAxis: {
type: 'value',
min: 0,
max: 100,
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit in %',
2025-01-12 20:55:46 +01:00
nameLocation: 'center',
nameGap: 38,
nameTextStyle: {
fontWeight: 'bold',
}
},
series: [{
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit alle Regionen',
2025-01-12 20:55:46 +01:00
type: 'line',
symbolSize: 7,
data: {!! $diagramsOptions['capacity']['series']['all']['data'] !!}
2025-01-12 20:55:46 +01:00
},
{
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit Region',
2025-01-12 20:55:46 +01:00
type: 'line',
symbolSize: 7,
data: {!! $diagramsOptions['capacity']['series']['region']['data'] !!}
2025-01-12 20:55:46 +01:00
}]
};
cCapacity.setOption(cCapacityOptions);
2025-01-13 22:50:03 +01:00
const chartCapacityMonthly = document.getElementById('chart-capacity-monthly');
const cCapacityMonthly = echarts.init(chartCapacityMonthly);
const cCapacityMonthlyOptions = {
timeline: {
show: false,
data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!},
2025-01-13 22:50:03 +01:00
axisType: 'time',
},
grid: {
2025-01-15 16:57:18 +01:00
top: 5,
bottom: 40,
2025-01-13 22:50:03 +01:00
left: 70,
right: 10
},
xAxis: {
type: 'value',
2025-01-15 16:57:18 +01:00
max: 100,
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit in %',
2025-01-15 16:57:18 +01:00
nameLocation: 'center',
nameGap: 25,
nameTextStyle: {
fontWeight: 'bold',
}
2025-01-13 22:50:03 +01:00
},
yAxis: {
type: 'category',
},
2025-01-15 16:57:18 +01:00
tooltip: sharedOptions.basic.tooltip,
2025-01-13 22:50:03 +01:00
options: [
@foreach ($diagramsOptions['capacityMonthly']['options'] as $m)
2025-01-13 22:50:03 +01:00
{
yAxis: {
data: {!! json_encode($m['months']) !!}
},
series: [{
type: 'bar',
2025-01-14 22:11:31 +01:00
itemStyle: {
color: sharedOptions.basic.color[3]
},
2025-01-13 22:50:03 +01:00
data: {!! json_encode($m['capacities']) !!}
}]
},
@endforeach
]
};
cCapacityMonthly.setOption(cCapacityMonthlyOptions);
const chartCapacityDaily = document.getElementById('chart-capacity-daily');
const cCapacityDaily = echarts.init(chartCapacityDaily);
const cCapacityDailyOptions = {
timeline: {
show: false,
data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!},
2025-01-13 22:50:03 +01:00
axisType: 'time',
},
2025-01-15 16:57:18 +01:00
tooltip: sharedOptions.basic.tooltip,
2025-01-13 22:50:03 +01:00
grid: {
2025-01-15 16:57:18 +01:00
top: 5,
bottom: 40,
2025-01-13 22:50:03 +01:00
left: 70,
right: 10
},
xAxis: {
type: 'value',
2025-01-15 16:57:18 +01:00
max: 100,
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit in %',
2025-01-15 16:57:18 +01:00
nameLocation: 'center',
nameGap: 25,
nameTextStyle: {
fontWeight: 'bold',
}
2025-01-13 22:50:03 +01:00
},
yAxis: {
type: 'category',
},
options: [
@foreach ($diagramsOptions['capacityDaily']['options'] as $d)
2025-01-13 22:50:03 +01:00
{
yAxis: {
data: {!! json_encode($d['weekdays']) !!}
},
series: [{
type: 'bar',
2025-01-14 22:11:31 +01:00
itemStyle: {
color: sharedOptions.basic.color[3]
},
2025-01-13 22:50:03 +01:00
data: {!! json_encode($d['capacities']) !!}
}]
},
@endforeach
]
};
cCapacityDaily.setOption(cCapacityDailyOptions);
const chartPrediction = document.getElementById('chart-prediction');
const cPrediction = echarts.init(chartPrediction);
const cPredictionOptions = {
color: sharedOptions.basic.color,
2025-01-13 22:50:03 +01:00
timeline: {
show: false,
data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!},
2025-01-13 22:50:03 +01:00
axisType: 'time',
replaceMerge: ['graphic', 'series']
},
legend: {
2025-01-13 22:50:03 +01:00
show: true
},
2025-01-15 16:57:18 +01:00
tooltip: sharedOptions.basic.tooltip,
grid: {
top: 20,
left: 25,
right: 10,
bottom: 20,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
name: 'Zeitpunkt Scraping',
nameLocation: 'center',
nameGap: 24,
nameTextStyle: {
fontWeight: 'bold',
2025-01-13 22:50:03 +01:00
},
},
yAxis: {
type: 'value',
min: 0,
2025-01-13 22:50:03 +01:00
max: 100,
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit in %',
nameLocation: 'center',
nameGap: 38,
nameTextStyle: {
fontWeight: 'bold',
}
},
2025-01-13 22:50:03 +01:00
options: [
@foreach ($diagramsOptions['predictions']['options'] as $p)
2025-01-13 22:50:03 +01:00
@if($p === null)
{
graphic: {
elements: [
{
type: 'text',
left: 'center',
top: 'center',
style: {
text: 'Keine Daten für Zeitspanne',
fontSize: 44,
fontWeight: 'bold',
}
}
]
}
},
2025-01-13 22:50:03 +01:00
@else
{
2025-01-14 22:11:31 +01:00
color: sharedOptions.basic.color,
2025-01-13 22:50:03 +01:00
graphic: {
elements: []
},
xAxis: {
data: {!! json_encode($p['dates']) !!}
},
series: [
{
name: 'Gleitender Mittelwert',
type: 'line',
symbolSize: 7,
data: {!! json_encode($p['movAvg']) !!}
},
{
name: 'Ausgangsdaten',
2025-01-13 22:50:03 +01:00
type: 'line',
symbolSize: 7,
data: {!! json_encode($p['cap_earlierTimeframe']) !!}
},
{
name: 'Vergleichsdaten',
2025-01-13 22:50:03 +01:00
type: 'line',
symbolSize: 7,
data: {!! json_encode($p['cap_laterTimeframe']) !!}
}
]
},
2025-01-13 22:50:03 +01:00
@endif
@endforeach
]
};
cPrediction.setOption(cPredictionOptions);
2025-01-12 20:55:46 +01:00
const chartHeatmap = document.getElementById('chart-heatmap');
const cHeatmap = echarts.init(chartHeatmap);
const cHeatmapOptions = {
animation: false,
2025-01-12 20:55:46 +01:00
tooltip: {
position: 'top'
},
grid: {
2025-01-17 13:02:54 +01:00
show: true,
borderWidth: 1,
borderColor: '#aaa',
2025-01-12 20:55:46 +01:00
top: 30,
right: 45,
2025-01-17 13:22:05 +01:00
bottom: 70,
left: 30
2025-01-12 20:55:46 +01:00
},
dataZoom: [{
type: 'slider'
},
{
type: 'slider',
show: true,
yAxisIndex: 0,
}],
2025-01-12 20:55:46 +01:00
xAxis: {
2025-01-17 13:22:05 +01:00
show: true,
name: 'Zeitpunkt Scraping',
2025-01-12 20:55:46 +01:00
type: 'category',
data: {!! $diagramsOptions['heatmap']['xAxis']['data'] !!},
2025-01-12 20:55:46 +01:00
splitArea: {
show: false
},
2025-01-17 13:22:05 +01:00
splitArea: {
show: false
},
2025-01-12 20:55:46 +01:00
axisLabel: {
2025-01-17 13:22:05 +01:00
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
nameLocation: 'center',
nameGap: 10,
nameTextStyle: {
fontWeight: 'bold',
2025-01-12 20:55:46 +01:00
}
},
yAxis: {
2025-01-17 13:22:05 +01:00
show: true,
2025-01-12 20:55:46 +01:00
type: 'category',
data: {!! $diagramsOptions['heatmap']['yAxis']['data'] !!},
2025-01-12 20:55:46 +01:00
splitArea: {
2025-01-17 13:22:05 +01:00
show: false
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
name: 'Mietobjekte',
nameLocation: 'center',
nameGap: 10,
nameTextStyle: {
fontWeight: 'bold',
2025-01-12 20:55:46 +01:00
}
},
visualMap: {
type: 'piecewise',
min: 0,
max: 100,
calculable: true,
orient: 'horizontal',
left: 'center',
top: 0,
formatter: (v1, v2) => {
return `${v1}${v2}%`;
},
inRange: {
color: sharedOptions.basic.color,
},
},
series: [
{
2025-01-17 13:49:43 +01:00
name: 'Verfügbarkeit',
2025-01-12 20:55:46 +01:00
type: 'heatmap',
blurSize: 0,
data: {!! json_encode($regionPropertiesCapacities['values']) !!},
label: {
show: false
},
tooltip: {
formatter: (data) => {
2025-01-17 13:49:43 +01:00
return `Kurzzeitmietobjekte-ID: ${data.data[1]}<br />Datum Scraping: ${data.data[0]}<br/>Verfügbarkeit: ${data.data[2].toFixed(2)}%`
2025-01-12 20:55:46 +01:00
},
},
emphasis: {
itemStyle: {
borderColor: '#000',
borderWidth: 2
}
}
}
]
}
cHeatmap.setOption(cHeatmapOptions);
2025-01-13 22:50:03 +01:00
const chartTimeline = document.getElementById('timeline');
const cTimeline = echarts.init(chartTimeline);
const cTimelineOptions = {
grid: {
show: false,
},
timeline: {
data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!},
2025-01-13 22:50:03 +01:00
playInterval: 2000,
axisType: 'time',
left: 8,
right: 8,
bottom: 0,
label: {
show: false
}
},
};
cTimeline.setOption(cTimelineOptions);
cTimeline.on('timelinechanged', (e) => {
2025-01-14 22:11:31 +01:00
let dateTitles = document.querySelectorAll('span.date');
dateTitles.forEach(el => {
el.innerText = cTimelineOptions.timeline.data[e.currentIndex];
});
2025-01-13 22:50:03 +01:00
// Set markpoint on linechart
let x = cCapacityOptions.xAxis.data[e.currentIndex];
let y = cCapacityOptions.series[0].data[e.currentIndex];
cCapacityMonthly.dispatchAction({
type: 'timelineChange',
currentIndex: e.currentIndex
});
cCapacityDaily.dispatchAction({
type: 'timelineChange',
currentIndex: e.currentIndex
});
cPrediction.dispatchAction({
type: 'timelineChange',
currentIndex: e.currentIndex
});
cCapacity.setOption({
series: {
markPoint: {
data: [{
coord: [x, y]
}]
}
}
});
})
2025-01-15 16:57:18 +01:00
document.querySelector('header').addEventListener('click', () => {
console.log('test');
cCapacityMonthly.dispatchAction({
type: 'timelineChange',
currentIndex: 10
});
})
2025-01-13 22:50:03 +01:00
cCapacity.on('click', 'series', (e) => {
// Switch to correct calendar in the timeline
cTimeline.dispatchAction({
type: 'timelineChange',
currentIndex: e.dataIndex
});
});
2025-01-14 22:11:31 +01:00
cHeatmap.on('click', 'series', (e) => {
window.open(`/property/${e.value[1]}?date=${e.value[0]}`, '_self');
})
2025-01-12 20:55:46 +01:00
</script>
@endsection