2025-01-19 11:27:21 +01:00

464 lines
11 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.

@extends('base')
@section('body-class', 'property')
@section('header')
<nav>
<strong>Mietobjekt: {{ $base['latlng'] }} ({{ $base['region_name'] }})</strong>
<ul>
<li><a href="/">Start</a></li>
@foreach($regions as $r)
<li><a href="/region/{{ $r['id'] }}">{{ $r['name'] }}</a></li>
@endforeach
</ul>
</nav>
<button popovertarget="prop-details"></button>
<div popover id="prop-details">
<dl>
<dt>Region</dt>
<dd>{{ $base['region_name'] }}</dd>
<dt>Zum ersten mal gefunden</dt>
<dd>{{ $base['first_found'] }}</dd>
<dt>Zum letzten mal gefunden</dt>
<dd>{{ $base['last_found'] }}</dd>
</dl>
</div>
@endsection
@section('main')
<article style="grid-area: timeline;">
<div id="timeline"></div>
</article>
<article class="header" style="grid-area: chart2;">
<header>
<h2 id="belegung-title">
Kalenderansicht der Verfügbarkeit am <span class="date">{{ $startDate }}</span>
</h2><button popovertarget="popup-cal"></button>
<div popover id="popup-cal">
<p>
Das Kalenderdiagram zeigt die drei Verfügbarkeitskategorien des Mietobjekts.
</p>
</div>
</header>
<div id="chart-calendar"></div>
</article>
<article class="header map" style="grid-area: chart5;">
<header>
<h2 id="belegung-title">
Kurzzeitmietobjekte in der Nähe
</h2>
</header>
<div id="chart-map"></div>
</article>
<article class="header" style="grid-area: chart3;">
<header>
<h2>
Verfügbarkeit Mietobjekt Monate am <span class="date">{{ $startDate }}</span>
</h2>
</header>
<div id="chart-capacity-monthly">
</div>
</article>
<article class="header" style="grid-area: chart1;">
<header>
<h2>
Entwicklung der Verfügbarkeit
</h2>
<button popovertarget="chart-capacity-popover"></button>
<div id="chart-capacity-popover" popover>
<h2>Erkläung zum Diagramm</h2>
<p>Das Liniendiagramm zeigt, wie sich die insgesamte Verfügbarkeit des Kurzzeitmietobjekts entwickelt hat.</p>
</div>
</header>
<div id="chart-capacity"></div>
</article>
<article class="header" style="grid-area: chart4;">
<header>
<h2>
Verfügbarkeit Mietobjekt Tage am <span class="date">{{ $startDate }}</span>
</h2>
</header>
<div id="chart-capacity-daily">
</article>
<script type="module">
const sharedOptions = {
extractiondates: {!! $diagramsOptions['shared']['extractiondates']!!},
basic: {
color: {!!$diagramsOptions['shared']['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 chartTimeline = document.getElementById('timeline');
const cTimeline = echarts.init(chartTimeline);
const cTimelineOptions = {
grid: {
show: false,
},
timeline: {
data: sharedOptions.extractiondates,
playInterval: 1000,
axisType: 'time',
left: 8,
right: 8,
bottom: 0,
label: {
show: false
}
},
};
cTimeline.setOption(cTimelineOptions);
const chartCapacityMonthly = document.getElementById('chart-capacity-monthly');
const cCapacityMonthly = echarts.init(chartCapacityMonthly);
const cCapacityMonthlyOptions = {
tooltip: sharedOptions.basic.tooltip,
timeline: {
show: false,
data: sharedOptions.extractiondates,
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',
},
options: [
@foreach ($diagramsOptions['capacityMonthly']['options'] as $cM)
{
yAxis: {
data: {!! json_encode($cM['months']) !!}
},
series: [{
type: 'bar',
itemStyle: {
color: sharedOptions.basic.color[3]
},
data: {!! json_encode($cM['capacities']) !!}
}]
},
@endforeach
]
};
cCapacityMonthly.setOption(cCapacityMonthlyOptions);
const chartCapacityDaily = document.getElementById('chart-capacity-daily');
const cCapacityDaily = echarts.init(chartCapacityDaily);
const cCapacityDailyOptions = {
tooltip: sharedOptions.basic.tooltip,
timeline: {
show: false,
data: sharedOptions.extractiondates,
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',
},
options: [
@foreach ($diagramsOptions['capacityDaily']['options'] as $cD)
{
yAxis: {
data: {!! json_encode($cD['weekdays']) !!}
},
series: [{
type: 'bar',
itemStyle: {
color: sharedOptions.basic.color[3]
},
data: {!! json_encode($cD['capacities']) !!}
}]
},
@endforeach
]
};
cCapacityDaily.setOption(cCapacityDailyOptions);
const chartCapacity = document.getElementById('chart-capacity');
const cCapacity = echarts.init(chartCapacity);
const cCapacityOptions = {
color: sharedOptions.basic.color,
legend: {
show: true
},
tooltip: {
trigger: 'axis',
valueFormatter: (value) => value.toFixed(2)+'%'
},
grid: {
top: 40,
left: 25,
right: 10,
bottom: 20,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: {!! $diagramsOptions['capacities']['xAxis']['data'] !!},
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 Mietobjekt',
type: 'line',
symbolSize: 7,
data: {!! $diagramsOptions['capacities']["series"][0]["data"] !!}
},
{
name: 'Verfügbarkeit {{ $base['region_name'] }}',
type: 'line',
symbolSize: 7,
data: {!! $diagramsOptions['capacities']["series"][1]["data"] !!}
},
{
name: 'Verfügbarkeit alle Regionen',
type: 'line',
symbolSize: 7,
data: {!! $diagramsOptions['capacities']["series"][2]["data"] !!}
}
]
};
cCapacity.setOption(cCapacityOptions);
const chartCalendar = document.getElementById('chart-calendar');
const cCalendar = echarts.init(chartCalendar);
const h2Belegung = document.getElementById('belegung-title');
const cCalendarOptions = {
timeline: {
show: false,
data: sharedOptions.extractiondates,
axisType: 'time',
},
visualMap: {
categories: [0,1,2],
inRange: {
color: ['#ca0020', '#92c5de', '#0571b0']
},
formatter: (cat) => {
switch (cat) {
case 0:
return 'Ausgebucht';
case 1:
return 'Verfügbar (kein Anreisetag)';
case 2:
return 'Verfügbar';
}
},
type: 'piecewise',
orient: 'horizontal',
left: 'center',
top: 0
},
calendar:[
{
orient: 'horizontal',
range: '2024',
top: '15%',
right: 10,
bottom: '65%',
left: 50,
dayLabel: {
fontSize: 10
}
},
{
orient: 'horizontal',
range: '2025',
top: '47%',
right: 10,
bottom: '33%',
left: 50,
dayLabel: {
fontSize: 10
}
},
{
orient: 'horizontal',
range: '2026',
top: '79%',
right: 10,
bottom: '1%',
left: 50,
dayLabel: {
fontSize: 10
}
}
],
options: [
@foreach ($diagramsOptions['calendar']['series'] as $c)
{
series: [{
type: 'heatmap',
coordinateSystem: 'calendar',
calendarIndex: 0,
data: {!! json_encode($c) !!}
},
{
type: 'heatmap',
coordinateSystem: 'calendar',
calendarIndex: 1,
data: {!! json_encode($c) !!}
},
{
type: 'heatmap',
coordinateSystem: 'calendar',
calendarIndex: 2,
data: {!! json_encode($c) !!}
}]
},
@endforeach
]
};
cCalendar.setOption(cCalendarOptions);
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
});
cCalendar.dispatchAction({
type: 'timelineChange',
currentIndex: e.currentIndex
});
cCapacity.setOption({
series: {
markPoint: {
data: [{
coord: [x, y]
}]
}
}
});
})
/* Map w/ neighbours*/
const map = L.map('chart-map');
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
function icon(id = 0){
return L.divIcon({
className: "region"+id,
html: '<span></span>'
})
}
const markers = L.featureGroup([
L.marker([{{ $base['latlng'] }}], {icon: icon(1)}),
@foreach($neighbours as $n)
L.marker([{{ $n['lat'] }}, {{ $n['lon'] }}], {icon: icon()}).bindPopup('<a href="/property/{{ $n['id'] }}">{{ $n['lat'] }}, {{ $n['lon'] }}</a>'),
@endforeach
]).addTo(map);
map.fitBounds(markers.getBounds(), {padding: [20,20]})
cCapacity.on('click', 'series', (e) => {
// Switch to correct calendar in the timeline
cTimeline.dispatchAction({
type: 'timelineChange',
currentIndex: e.dataIndex
});
});
</script>
@endsection