2025-01-17 13:49:43 +01:00

543 lines
12 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('base')
@section('body-class', 'region')
@section('header')
<nav>
<strong>{{ $region[0]['region_name'] }}</strong>
<ul>
<li><a href="/">Start</a></li>
@foreach($regions as $r)
@if($r['region_id'] != $region_id)
<li><a href="/region/{{ $r['region_id'] }}">{{ $r['region_name'] }}</a></li>
@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>
<h2 id="prediction-title">Gleitender Mittelwert für die Verfügbarkeit der Region</h2>
</header>
<div id="chart-prediction"></div>
</article>
<article class="header" style="grid-area: chart1;">
<header>
<h2 id="belegung-title">Verfügbarkeit aller Mietobjekte über Gesamte Zeit der Region</h2>
</header>
<div id="chart-heatmap"></div>
</article>
<article class="header" style="grid-area: chart3;">
<header>
<h2>
Verfügbarkeit Region nach Monat am <span class="date">{{ $startDate }}</span>
</h2>
</header>
<div id="chart-capacity-monthly">
</div>
</article>
<article class="header" style="grid-area: chart2;">
<header>
<h2>
Entwicklung der Verfügbarkeit
</h2>
<button popovertarget="chart-capacity-popover"></button>
<div id="chart-capacity-popover" popover>
<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>
</div>
</header>
<div id="chart-capacity"></div>
</article>
<article class="header" style="grid-area: chart4;">
<header>
<h2>
Verfügbarkeit Wochentage am <span class="date">{{ $startDate }}</span>
</h2>
</header>
<div id="chart-capacity-daily">
</article>
<script type="module">
const sharedOptions = {
basic: {
color: {!! $chartOptions['colors'] !!},
grid: {
top: 20,
left: 60,
right: 0,
bottom: 50
},
tooltip: {
show: true,
trigger: 'axis',
valueFormatter: (value) => value.toFixed(2)+'%'
},
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: {
show: true
},
tooltip: sharedOptions.basic.tooltip,
color: sharedOptions.basic.color,
grid: {
top: 20,
left: 25,
right: 10,
bottom: 20,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: {!! json_encode($regionCapacities['region']['dates']) !!},
name: 'Zeitpunkt Scraping',
nameLocation: 'center',
nameGap: 24,
nameTextStyle: {
fontWeight: 'bold',
}
},
yAxis: {
type: 'value',
min: 0,
max: 100,
name: 'Verfügbarkeit in %',
nameLocation: 'center',
nameGap: 38,
nameTextStyle: {
fontWeight: 'bold',
}
},
series: [{
name: 'Verfügbarkeit alle Regionen',
type: 'line',
symbolSize: 7,
data: {!! json_encode($regionCapacities['all']['capacities']) !!}
},
{
name: 'Verfügbarkeit Region',
type: 'line',
symbolSize: 7,
data: {!! json_encode($regionCapacities['region']['capacities']) !!}
}]
};
cCapacity.setOption(cCapacityOptions);
const chartCapacityMonthly = document.getElementById('chart-capacity-monthly');
const cCapacityMonthly = echarts.init(chartCapacityMonthly);
const cCapacityMonthlyOptions = {
timeline: {
show: false,
data: {!! json_encode($regionCapacities['region']['dates']) !!},
axisType: 'time',
},
grid: {
top: 5,
bottom: 40,
left: 70,
right: 10
},
xAxis: {
type: 'value',
max: 100,
name: 'Verfügbarkeit in %',
nameLocation: 'center',
nameGap: 25,
nameTextStyle: {
fontWeight: 'bold',
}
},
yAxis: {
type: 'category',
},
tooltip: sharedOptions.basic.tooltip,
options: [
@foreach ($regionCapacities['region_monthly'] as $m)
{
yAxis: {
data: {!! json_encode($m['months']) !!}
},
series: [{
type: 'bar',
itemStyle: {
color: sharedOptions.basic.color[3]
},
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: {!! json_encode($regionCapacities['region']['dates']) !!},
axisType: 'time',
},
tooltip: sharedOptions.basic.tooltip,
grid: {
top: 5,
bottom: 40,
left: 70,
right: 10
},
xAxis: {
type: 'value',
max: 100,
name: 'Verfügbarkeit in %',
nameLocation: 'center',
nameGap: 25,
nameTextStyle: {
fontWeight: 'bold',
}
},
yAxis: {
type: 'category',
},
options: [
@foreach ($regionCapacities['region_daily'] as $d)
{
yAxis: {
data: {!! json_encode($d['weekdays']) !!}
},
series: [{
type: 'bar',
itemStyle: {
color: sharedOptions.basic.color[3]
},
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,
timeline: {
show: false,
data: {!! json_encode($regionCapacities['region']['dates']) !!},
axisType: 'time',
replaceMerge: ['graphic', 'series']
},
legend: {
show: true
},
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',
},
},
yAxis: {
type: 'value',
min: 0,
max: 100,
name: 'Verfügbarkeit in %',
nameLocation: 'center',
nameGap: 38,
nameTextStyle: {
fontWeight: 'bold',
}
},
options: [
@foreach ($predictions as $p)
@if($p === null)
{
graphic: {
elements: [
{
type: 'text',
left: 'center',
top: 'center',
style: {
text: 'Keine Daten für Zeitspanne',
fontSize: 44,
fontWeight: 'bold',
}
}
]
}
},
@else
{
color: sharedOptions.basic.color,
graphic: {
elements: []
},
xAxis: {
data: {!! json_encode($p['dates']) !!}
},
series: [
{
name: 'Gleitender Mittelwert',
type: 'line',
symbolSize: 7,
data: {!! json_encode($p['movAvg']) !!}
},
{
name: 'Ausgangsdaten',
type: 'line',
symbolSize: 7,
data: {!! json_encode($p['cap_earlierTimeframe']) !!}
},
{
name: 'Vergleichsdaten',
type: 'line',
symbolSize: 7,
data: {!! json_encode($p['cap_laterTimeframe']) !!}
}
]
},
@endif
@endforeach
]
};
cPrediction.setOption(cPredictionOptions);
const chartHeatmap = document.getElementById('chart-heatmap');
const cHeatmap = echarts.init(chartHeatmap);
const cHeatmapOptions = {
animation: false,
tooltip: {
position: 'top'
},
grid: {
show: true,
borderWidth: 1,
borderColor: '#aaa',
top: 30,
right: 45,
bottom: 70,
left: 30
},
dataZoom: [{
type: 'slider'
},
{
type: 'slider',
show: true,
yAxisIndex: 0,
}],
xAxis: {
show: true,
name: 'Zeitpunkt Scraping',
type: 'category',
data: {!! json_encode($regionPropertiesCapacities['scrapeDates']) !!},
splitArea: {
show: false
},
splitArea: {
show: false
},
axisLabel: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
nameLocation: 'center',
nameGap: 10,
nameTextStyle: {
fontWeight: 'bold',
}
},
yAxis: {
show: true,
type: 'category',
data: {!! json_encode($regionPropertiesCapacities['property_ids']) !!},
splitArea: {
show: false
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel: {
show: false,
},
name: 'Mietobjekte',
nameLocation: 'center',
nameGap: 10,
nameTextStyle: {
fontWeight: 'bold',
}
},
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: [
{
name: 'Verfügbarkeit',
type: 'heatmap',
blurSize: 0,
data: {!! json_encode($regionPropertiesCapacities['values']) !!},
label: {
show: false
},
tooltip: {
formatter: (data) => {
return `Kurzzeitmietobjekte-ID: ${data.data[1]}<br />Datum Scraping: ${data.data[0]}<br/>Verfügbarkeit: ${data.data[2].toFixed(2)}%`
},
},
emphasis: {
itemStyle: {
borderColor: '#000',
borderWidth: 2
}
}
}
]
}
cHeatmap.setOption(cHeatmapOptions);
const chartTimeline = document.getElementById('timeline');
const cTimeline = echarts.init(chartTimeline);
const cTimelineOptions = {
grid: {
show: false,
},
timeline: {
data: {!! json_encode($regionCapacities['region']['dates']) !!},
playInterval: 2000,
axisType: 'time',
left: 8,
right: 8,
bottom: 0,
label: {
show: false
}
},
};
cTimeline.setOption(cTimelineOptions);
cTimeline.on('timelinechanged', (e) => {
let dateTitles = document.querySelectorAll('span.date');
dateTitles.forEach(el => {
el.innerText = cTimelineOptions.timeline.data[e.currentIndex];
});
// 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]
}]
}
}
});
})
document.querySelector('header').addEventListener('click', () => {
console.log('test');
cCapacityMonthly.dispatchAction({
type: 'timelineChange',
currentIndex: 10
});
})
cCapacity.on('click', 'series', (e) => {
// Switch to correct calendar in the timeline
cTimeline.dispatchAction({
type: 'timelineChange',
currentIndex: e.dataIndex
});
});
cHeatmap.on('click', 'series', (e) => {
window.open(`/property/${e.value[1]}?date=${e.value[0]}`, '_self');
})
</script>
@endsection