2024-12-18 15:14:13 +01:00
|
|
|
|
@extends('base')
|
2025-01-05 13:26:51 +01:00
|
|
|
|
@section('body-class', 'overview')
|
2025-01-12 20:55:46 +01:00
|
|
|
|
@section('header')
|
|
|
|
|
<nav>
|
|
|
|
|
<strong>Start</strong>
|
|
|
|
|
<ul>
|
|
|
|
|
@foreach($regions as $r)
|
|
|
|
|
<li><a href="/region/{{ $r['region_id'] }}">{{ $r['region_name'] }}</a></li>
|
|
|
|
|
@endforeach
|
|
|
|
|
</ul>
|
|
|
|
|
</nav>
|
|
|
|
|
@endsection
|
2024-12-18 15:14:13 +01:00
|
|
|
|
@section('main')
|
2025-01-15 16:57:18 +01:00
|
|
|
|
<article class="header" style="grid-area: chart3;">
|
|
|
|
|
<header>
|
|
|
|
|
<h2>Auslastung aller Mietobjekte über Gesamte Zeit</h2>
|
|
|
|
|
<button popovertarget="pop1">
|
|
|
|
|
<span>Erklärungen zum Diagramm</span>
|
|
|
|
|
</button>
|
|
|
|
|
<div popover id="pop1">
|
|
|
|
|
<h2>Auslastung aller Mietobjekte über Gesamte Zeit</h2>
|
|
|
|
|
<p>
|
|
|
|
|
Das Diagramm gibt eine Übersicht, wie die Auslastung von Mietobjekten am Datum des Scrapings waren. Dazu wird für jedes Mietobjekt die durchschnittliche Verfügbarkeit ermittelt.
|
|
|
|
|
</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>X-Achse: Zeitpunkt Scraping.</li>
|
|
|
|
|
<li>Y-Achse: Mietobjekte.</li>
|
|
|
|
|
<li>Kategorien: 0% = Das Mietobjekt ist komplett verfügbar; 100% = Das Mietobjekt ist komplett ausgebucht.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
</header>
|
|
|
|
|
<div id="chart-heatmap"></div>
|
|
|
|
|
</article>
|
2025-01-05 13:26:51 +01:00
|
|
|
|
<article class="header" style="grid-area: chart1;">
|
2025-01-15 16:57:18 +01:00
|
|
|
|
<header>
|
|
|
|
|
<h2>
|
|
|
|
|
Anzahl jemals gefundene Kurzzeitmietobjekte pro Region
|
|
|
|
|
</h2>
|
|
|
|
|
<button popovertarget="pop2">
|
|
|
|
|
<span>Erklärungen zum Diagramm</span>
|
|
|
|
|
</button>
|
|
|
|
|
<div popover id="pop2">
|
|
|
|
|
<h2>Anzahl jemals gefundene Kurzzeitmietobjekte pro Region</h2>
|
|
|
|
|
<p>
|
|
|
|
|
Das Balkendiagramm zeigt wieviele Kurzzeitmietobjekte insgesamt pro Region über den gesamten Datenerhebungszeitraum, gefunden wurden.
|
|
|
|
|
</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>X-Achse: Bezeichnung der Region.</li>
|
|
|
|
|
<li>Y-Achse: Anzahl Mietobjekte.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
</header>
|
|
|
|
|
<div id="chart-props-per-region"></div>
|
2024-12-18 15:14:13 +01:00
|
|
|
|
</article>
|
2025-01-05 13:26:51 +01:00
|
|
|
|
<article class="header" style="grid-area: chart2;">
|
2025-01-15 16:57:18 +01:00
|
|
|
|
<header>
|
|
|
|
|
<h2>
|
|
|
|
|
Entwicklung der Anzahl jemals gefunden Kurzzeitmietobjekte
|
|
|
|
|
</h2>
|
|
|
|
|
<button popovertarget="pop3">
|
|
|
|
|
<span>Erklärungen zum Diagramm</span>
|
|
|
|
|
</button>
|
|
|
|
|
<div popover id="pop3">
|
|
|
|
|
<h2>Entwicklung Anzahl jemals gefundener Kurzzeitmietobjekte pro Region</h2>
|
|
|
|
|
<p>
|
|
|
|
|
Das Liniendiagramm zeigt die Entwicklung der gefundenen Mietobjekte pro Region.
|
|
|
|
|
</p>
|
|
|
|
|
<ul>
|
|
|
|
|
<li>X-Achse: Zeitpunkt Scraping.</li>
|
|
|
|
|
<li>Y-Achse: Anzahl Mietobjekte.</li>
|
|
|
|
|
</ul>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
</header>
|
|
|
|
|
<div id="extractions"></div>
|
2024-12-18 15:14:13 +01:00
|
|
|
|
</article>
|
2025-01-05 13:26:51 +01:00
|
|
|
|
<article style="grid-area: chart4;">
|
2025-01-15 16:57:18 +01:00
|
|
|
|
<div id="leaflet"></div>
|
2024-12-20 15:25:33 +01:00
|
|
|
|
</article>
|
2024-12-18 15:14:13 +01:00
|
|
|
|
<script type="module">
|
2025-01-03 16:25:30 +01:00
|
|
|
|
const sharedOptions = {
|
|
|
|
|
basic: {
|
2025-01-14 22:11:31 +01:00
|
|
|
|
color: {!! $chartOptions['colors'] !!},
|
2025-01-03 16:25:30 +01:00
|
|
|
|
grid: {
|
2025-01-15 16:57:18 +01:00
|
|
|
|
top: 30,
|
|
|
|
|
left: 70,
|
2025-01-03 16:25:30 +01:00
|
|
|
|
right: 0,
|
2025-01-15 16:57:18 +01:00
|
|
|
|
bottom: 45
|
2025-01-03 16:25:30 +01:00
|
|
|
|
},
|
|
|
|
|
name: (opt) => {
|
|
|
|
|
return {
|
|
|
|
|
name: opt.name,
|
|
|
|
|
nameLocation: opt.location,
|
2025-01-15 16:57:18 +01:00
|
|
|
|
nameGap: 50,
|
2025-01-03 16:25:30 +01:00
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-12-20 15:25:33 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-11 20:52:02 +01:00
|
|
|
|
const extractionDates = {!! json_encode($regionPropertiesCapacities['scrapeDates']) !!};
|
2024-12-20 15:25:33 +01:00
|
|
|
|
|
|
|
|
|
const chartHeatmap = document.getElementById('chart-heatmap');
|
|
|
|
|
const cHeatmap = echarts.init(chartHeatmap);
|
|
|
|
|
const cHeatmapOptions = {
|
2025-01-12 20:55:46 +01:00
|
|
|
|
animation: false,
|
2024-12-20 15:25:33 +01:00
|
|
|
|
tooltip: {
|
|
|
|
|
position: 'top'
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
2025-01-17 13:02:54 +01:00
|
|
|
|
show: true,
|
|
|
|
|
borderWidth: 1,
|
|
|
|
|
borderColor: '#aaa',
|
2025-01-05 13:26:51 +01:00
|
|
|
|
top: 30,
|
2025-01-12 20:55:46 +01:00
|
|
|
|
right: 45,
|
2025-01-17 13:22:05 +01:00
|
|
|
|
bottom: 70,
|
|
|
|
|
left: 30
|
2024-12-20 15:25:33 +01:00
|
|
|
|
},
|
2025-01-05 13:26:51 +01:00
|
|
|
|
dataZoom: [{
|
2025-01-12 20:55:46 +01:00
|
|
|
|
type: 'slider'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
type: 'slider',
|
|
|
|
|
show: true,
|
|
|
|
|
yAxisIndex: 0,
|
|
|
|
|
}],
|
2024-12-20 15:25:33 +01:00
|
|
|
|
xAxis: {
|
2025-01-17 13:22:05 +01:00
|
|
|
|
show: true,
|
|
|
|
|
name: 'Zeitpunkt Scraping',
|
2024-12-20 15:25:33 +01:00
|
|
|
|
type: 'category',
|
2025-01-11 20:52:02 +01:00
|
|
|
|
data: extractionDates,
|
2024-12-20 15:25:33 +01:00
|
|
|
|
splitArea: {
|
|
|
|
|
show: false
|
2025-01-03 16:25:30 +01:00
|
|
|
|
},
|
2025-01-17 13:22:05 +01:00
|
|
|
|
splitArea: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
2025-01-03 16:25:30 +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',
|
2024-12-20 15:25:33 +01:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
2025-01-17 13:22:05 +01:00
|
|
|
|
show: true,
|
2024-12-20 15:25:33 +01:00
|
|
|
|
type: 'category',
|
2025-01-11 20:52:02 +01:00
|
|
|
|
data: {!! json_encode($regionPropertiesCapacities['property_ids']) !!},
|
2024-12-20 15:25:33 +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',
|
2024-12-20 15:25:33 +01:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
visualMap: {
|
2025-01-03 16:25:30 +01:00
|
|
|
|
type: 'piecewise',
|
2024-12-20 15:25:33 +01:00
|
|
|
|
min: 0,
|
2024-12-20 21:46:54 +01:00
|
|
|
|
max: 100,
|
2024-12-20 15:25:33 +01:00
|
|
|
|
calculable: true,
|
|
|
|
|
orient: 'horizontal',
|
|
|
|
|
left: 'center',
|
2025-01-03 16:25:30 +01:00
|
|
|
|
top: 0,
|
2025-01-05 13:26:51 +01:00
|
|
|
|
formatter: (v1, v2) => {
|
|
|
|
|
return `${v1} – ${v2} %`;
|
|
|
|
|
},
|
2025-01-03 16:25:30 +01:00
|
|
|
|
inRange: {
|
2025-01-05 13:26:51 +01:00
|
|
|
|
color: sharedOptions.basic.color,
|
2025-01-03 16:25:30 +01:00
|
|
|
|
},
|
2024-12-20 15:25:33 +01:00
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
2025-01-03 16:25:30 +01:00
|
|
|
|
name: 'Auslastung',
|
2024-12-20 15:25:33 +01:00
|
|
|
|
type: 'heatmap',
|
2025-01-05 13:26:51 +01:00
|
|
|
|
blurSize: 0,
|
2025-01-11 20:52:02 +01:00
|
|
|
|
data: {!! json_encode($regionPropertiesCapacities['values']) !!},
|
2024-12-20 15:25:33 +01:00
|
|
|
|
label: {
|
|
|
|
|
show: false
|
|
|
|
|
},
|
2025-01-03 16:25:30 +01:00
|
|
|
|
tooltip: {
|
2025-01-05 13:26:51 +01:00
|
|
|
|
formatter: (data) => {
|
2025-01-12 20:55:46 +01:00
|
|
|
|
return `Kurzzeitmietobjekte-ID: ${data.data[1]}<br />Datum Scraping: ${data.data[0]}<br/>Auslastung: ${data.data[2].toFixed(2)} %`
|
2025-01-05 13:26:51 +01:00
|
|
|
|
},
|
2025-01-03 16:25:30 +01:00
|
|
|
|
},
|
2024-12-20 15:25:33 +01:00
|
|
|
|
emphasis: {
|
|
|
|
|
itemStyle: {
|
2025-01-03 16:25:30 +01:00
|
|
|
|
borderColor: '#000',
|
|
|
|
|
borderWidth: 2
|
2024-12-20 15:25:33 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cHeatmap.setOption(cHeatmapOptions);
|
|
|
|
|
|
2024-12-18 15:14:13 +01:00
|
|
|
|
const chartPropsPerRegion = document.getElementById('chart-props-per-region');
|
|
|
|
|
const cPropsPerRegion = echarts.init(chartPropsPerRegion);
|
|
|
|
|
const cPropsPerRegionOptions = {
|
2025-01-03 16:25:30 +01:00
|
|
|
|
grid: sharedOptions.basic.grid,
|
2025-01-13 17:06:54 +01:00
|
|
|
|
color: sharedOptions.basic.color,
|
2024-12-18 15:14:13 +01:00
|
|
|
|
xAxis: {
|
2025-01-03 16:25:30 +01:00
|
|
|
|
name: 'Region',
|
|
|
|
|
nameLocation: 'center',
|
2025-01-15 16:57:18 +01:00
|
|
|
|
nameGap: 30,
|
2025-01-03 16:25:30 +01:00
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
type: 'category',
|
2025-01-14 22:11:31 +01:00
|
|
|
|
data: {!! $propsPerRegion[1] !!}
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
2025-01-03 16:25:30 +01:00
|
|
|
|
type: 'value',
|
2025-01-15 16:57:18 +01:00
|
|
|
|
name: 'Anzahl Mietobjekte',
|
2025-01-03 16:25:30 +01:00
|
|
|
|
nameLocation: 'middle',
|
2025-01-15 16:57:18 +01:00
|
|
|
|
nameGap: 50,
|
2025-01-03 16:25:30 +01:00
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
2025-01-14 22:11:31 +01:00
|
|
|
|
data: {!! $propsPerRegion[2] !!},
|
2025-01-13 17:06:54 +01:00
|
|
|
|
type: 'bar',
|
|
|
|
|
itemStyle: {
|
|
|
|
|
color: (e) => {
|
|
|
|
|
return sharedOptions.basic.color[e.dataIndex];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
cPropsPerRegion.setOption(cPropsPerRegionOptions);
|
|
|
|
|
|
|
|
|
|
const chartExtractions = document.getElementById('extractions');
|
|
|
|
|
const cExtractions = echarts.init(chartExtractions);
|
|
|
|
|
|
|
|
|
|
const filters = {
|
2024-12-18 19:52:06 +01:00
|
|
|
|
regions: ["Alle", "Davos", "Engadin", "Heidiland", "St. Moritz"]
|
2024-12-18 15:14:13 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const cExtractionsOptions = {
|
2025-01-13 17:06:54 +01:00
|
|
|
|
color: sharedOptions.basic.color,
|
2024-12-18 15:14:13 +01:00
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis'
|
|
|
|
|
},
|
|
|
|
|
legend: {
|
|
|
|
|
data: filters.regions
|
|
|
|
|
},
|
2025-01-03 16:25:30 +01:00
|
|
|
|
grid: sharedOptions.basic.grid,
|
2024-12-18 15:14:13 +01:00
|
|
|
|
xAxis: {
|
2025-01-03 16:25:30 +01:00
|
|
|
|
name: 'Zeitpunkt Scraping',
|
|
|
|
|
nameLocation: 'center',
|
|
|
|
|
nameGap: 24,
|
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
type: 'category',
|
|
|
|
|
boundaryGap: false,
|
2024-12-20 15:25:33 +01:00
|
|
|
|
data: extractionDates
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
|
|
|
|
yAxis: {
|
2025-01-15 16:57:18 +01:00
|
|
|
|
name: 'Anzahl Mietobjekte',
|
2025-01-03 16:25:30 +01:00
|
|
|
|
nameLocation: 'center',
|
2025-01-15 16:57:18 +01:00
|
|
|
|
nameGap: 50,
|
2025-01-03 16:25:30 +01:00
|
|
|
|
nameTextStyle: {
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
type: 'value'
|
|
|
|
|
},
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: 'Alle',
|
|
|
|
|
type: 'line',
|
|
|
|
|
stack: 'Total',
|
2025-01-13 17:06:54 +01:00
|
|
|
|
data: {!! json_encode($growth['total_all']) !!},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'Davos',
|
|
|
|
|
type: 'line',
|
2024-12-18 19:52:06 +01:00
|
|
|
|
data: {!! json_encode($growth['total_davos']) !!}
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: 'Engadin',
|
|
|
|
|
type: 'line',
|
2024-12-18 19:52:06 +01:00
|
|
|
|
data: {!! json_encode($growth['total_engadin']) !!}
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
2025-01-13 17:06:54 +01:00
|
|
|
|
{
|
|
|
|
|
name: 'Heidiland',
|
|
|
|
|
type: 'line',
|
|
|
|
|
data: {!! json_encode($growth['total_heidiland']) !!}
|
|
|
|
|
},
|
2024-12-18 15:14:13 +01:00
|
|
|
|
{
|
|
|
|
|
name: 'St. Moritz',
|
|
|
|
|
type: 'line',
|
2024-12-18 19:52:06 +01:00
|
|
|
|
data: {!! json_encode($growth['total_stmoritz']) !!}
|
2024-12-18 15:14:13 +01:00
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
cExtractions.setOption(cExtractionsOptions);
|
2024-12-18 19:52:06 +01:00
|
|
|
|
|
2025-01-13 17:06:54 +01:00
|
|
|
|
const map = L.map('leaflet');
|
2024-12-18 19:52:06 +01:00
|
|
|
|
|
|
|
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
|
|
|
maxZoom: 19,
|
|
|
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
|
|
|
}).addTo(map);
|
|
|
|
|
|
2025-01-13 17:06:54 +01:00
|
|
|
|
function icon(id){
|
|
|
|
|
return L.divIcon({
|
|
|
|
|
className: "region"+id,
|
|
|
|
|
html: '<span></span>'
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const markers = L.featureGroup([
|
|
|
|
|
@foreach($geo as $g)
|
|
|
|
|
L.marker([{{ $g['latlng'] }}], {icon: icon({{ $g['region_id'] }})}).bindPopup('<a href="/property/{{ $g['property_id'] }}">{{ $g['latlng'] }}</a>'),
|
|
|
|
|
@endforeach
|
|
|
|
|
]).addTo(map);
|
|
|
|
|
|
|
|
|
|
map.fitBounds(markers.getBounds(), {padding: [20,20]})
|
|
|
|
|
|
|
|
|
|
cHeatmap.on('click', 'series', (e) => {
|
|
|
|
|
window.open(`/property/${e.value[1]}?date=${e.value[0]}`, '_self');
|
2024-12-18 19:52:06 +01:00
|
|
|
|
})
|
|
|
|
|
|
2025-01-13 17:06:54 +01:00
|
|
|
|
cPropsPerRegion.on('click', 'series', (e) => {
|
|
|
|
|
console.log(e.dataIndex);
|
|
|
|
|
//window.open(`/property/${e.value[1]}?date=${e.value[0]}`, '_self');
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2024-12-18 19:52:06 +01:00
|
|
|
|
|
2024-12-18 15:14:13 +01:00
|
|
|
|
</script>
|
|
|
|
|
@endsection
|