@extends('base') @section('body-class', 'region') @section('header') <nav> <strong>{{ $region['name'] }}</strong> <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> @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> <button popovertarget="chart-prediction-popover"></button> <div id="chart-prediction-popover" popover> <h2>Gleitender Mittelwert für die Verfügbarkeit der Region</h2> <p>Das Diagramm...</p> <ul> <li>X-Achse: Zeitpunkt der Beobachtung</li> <li>Y-Achse: Verfügbarkeit einer Region. 0% = Alle Mietobjekte der Region sind komplett ausgebucht; 100% = Alle Mietobjekte der Region können zu allen verfügbaren Daten gebucht werden. </li> </ul> </div> </header> <div id="chart-prediction"></div> </article> <article class="header" style="grid-area: chart1;"> <header> <h2 id="belegung-title">Verfügbarkeit aller Mietobjekte der Region über gesamten beobachteten Zeitraum</h2> <button popovertarget="popup-heat"></button><div popover id="popup-heat"> <h2>Verfügbarkeit aller Mietobjekte der Region über gesamten beobachteten Zeitraum</h2> <p> Das Diagramm zeigt die Verfügbarkeit aller Mietobjekte der Region zu allen beobachteten Zeitpunkten. </p> <ul> <li>X-Achse: Zeitpunkt Beobachtung.</li> <li>Y-Achse: Mietobjekte.</li> <li>Kategorien: 0% = Das Mietobjekt ist komplett Ausgebucht; 100% = Das Mietobjekt kann zu allen Verfügbaren Daten gebucht werden.</li> </ul> <h3>Berrechnung Verfügbarkeit</h3> <p>Die Verfügbarkeit eines Mietobjekt errechnet sich folgendermassen:</p> <p class="formula"> Verfügbarkeit = (100 / (Anzahl Buchungsdaten * 2)) * Summe Status </p> <ul> <li>Status: Jeder verfügbare Kalendertag kann den Status «Nicht Verfügbar» (0), «Verfügbar (kein Anreisetag)» (1) oder «Verfügbar» (2) aufweisen.</li> <li>Anzahl Buchungsdaten: Die Summe aller angebotenen Buchungsdaten mit zwei multipliziert (= Alle Buchungdaten haben den Status «Verfügbar»)</li> </ul> </div> <div> </header> <div id="chart-heatmap"></div> </article> <article class="header" style="grid-area: chart3;"> <header> <h2> Verfügbarkeit 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>Entwicklung der Verfügbarkeit</h2> <p>Das Liniendiagramm zeigt die Entwicklung Verfügbarkeit der Region im Vergleich zu allen Regionen an.</p> <ul> <li>X-Achse: Zeitpunkt der Beobachtung</li> <li>Y-Achse: Verfügbarkeit einer Region. 0% = Alle Mietobjekte der Region sind komplett ausgebucht; 100% = Alle Mietobjekte der Region können zu allen verfügbaren Daten gebucht werden. </li> </ul> </div> </header> <div id="chart-capacity"></div> </article> <article class="header" style="grid-area: chart4;"> <header> <h2> Verfügbarkeit nach Wochentage am <span class="date">{{ $startDate }}</span> </h2> </header> <div id="chart-capacity-daily"> </article> <script type="module"> const sharedOptions = { basic: { color: {!! $diagramsOptions['shared']['colors'] !!}, grid: { top: 20, left: 60, right: 0, bottom: 50 }, tooltip: { show: true, trigger: 'axis', valueFormatter: (value) => value == null ? 'N/A' : 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: {!! $diagramsOptions['capacity']['xAxis']['data'] !!}, name: 'Zeitpunkt Beobachtung', 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: {!! $diagramsOptions['capacity']['series']['all']['data'] !!} }, { name: 'Verfügbarkeit Region', type: 'line', symbolSize: 7, data: {!! $diagramsOptions['capacity']['series']['region']['data'] !!} }] }; cCapacity.setOption(cCapacityOptions); const chartCapacityMonthly = document.getElementById('chart-capacity-monthly'); const cCapacityMonthly = echarts.init(chartCapacityMonthly); const cCapacityMonthlyOptions = { timeline: { show: false, data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!}, 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 ($diagramsOptions['capacityMonthly']['options'] 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: {!! $diagramsOptions['capacity']['xAxis']['data'] !!}, 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 ($diagramsOptions['capacityDaily']['options'] 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[0], sharedOptions.basic.color[4], sharedOptions.basic.color[5]], timeline: { show: false, data: {!! $diagramsOptions['capacity']['xAxis']['data'] !!}, 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 Beobachtung', 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 ($diagramsOptions['predictions']['options'] 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', showSymbol: false, connectNulls: true, type: 'line', symbolSize: 7, data: {!! json_encode($p['capacities_moving_average']) !!} }, { name: 'Ausgangsdaten', showSymbol: false, connectNulls: true, type: 'line', symbolSize: 7, data: {!! json_encode($p['capacities_timeframe_before']) !!} }, { name: 'Vergleichsdaten', showSymbol: false, connectNulls: true, type: 'line', symbolSize: 7, data: {!! json_encode($p['capacities_timeframe_after']) !!} } ] }, @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 Beobachtung', type: 'category', data: {!! $diagramsOptions['heatmap']['xAxis']['data'] !!}, 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: {!! $diagramsOptions['heatmap']['yAxis']['data'] !!}, 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: {!! $diagramsOptions['heatmap']['series']['data'] !!}, label: { show: false }, tooltip: { formatter: (data) => { return `Kurzzeitmietobjekte-ID: ${data.data[1]}<br />Beobachtungszeitpunkt: ${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: {!! $diagramsOptions['capacity']['xAxis']['data'] !!}, 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