some polishing
parent
959b84d1e1
commit
3290c1cce3
|
@ -5,7 +5,7 @@ namespace App;
|
|||
class Chart
|
||||
{
|
||||
public static function colors(int $count = 5){
|
||||
$colors = ['#bfd3e6','#8c96c6','#88419d','#810f7c','#4d004b'];
|
||||
$colors = ['#9ebcda','#8c96c6','#88419d','#810f7c','#4d004b'];
|
||||
return json_encode($colors);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,10 +54,19 @@ dd + dt{
|
|||
margin-top: .2em;
|
||||
}
|
||||
|
||||
nav + button,
|
||||
span + button{
|
||||
margin-left: .5em;
|
||||
}
|
||||
|
||||
ul{
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
p + ul{
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
button[popovertarget]{
|
||||
background: no-repeat center / .3em #4d004b url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 192 512'%3E%3C!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--%3E%3Cpath fill='%23fff' d='M48 80a48 48 0 1 1 96 0A48 48 0 1 1 48 80zM0 224c0-17.7 14.3-32 32-32l64 0c17.7 0 32 14.3 32 32l0 224 32 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32s14.3-32 32-32l32 0 0-192-32 0c-17.7 0-32-14.3-32-32z'/%3E%3C/svg%3E%0A");
|
||||
cursor: pointer;
|
||||
|
@ -95,6 +104,10 @@ button[popovertarget]>span{
|
|||
background-color: rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
[popover] h2{
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
9. Create a root stacking context
|
||||
|
@ -118,8 +131,7 @@ body>header{
|
|||
|
||||
body>header>nav{
|
||||
text-align: center;
|
||||
max-width: 10em;
|
||||
width: 100%;
|
||||
min-width: 10em;
|
||||
background: #fff;
|
||||
border-radius: .2em;
|
||||
position: relative;
|
||||
|
@ -174,25 +186,28 @@ body.overview main{
|
|||
"chart3 chart3 chart3 chart2 chart2 chart2 chart4 chart4"
|
||||
}
|
||||
|
||||
body.property main{
|
||||
body.region main{
|
||||
grid-template-columns: repeat(4, minmax(10%, 50%));
|
||||
grid-template-rows: repeat(3, 1fr) 4em;
|
||||
grid-template-rows: repeat(6, 1fr) 4em;
|
||||
grid-template-areas:
|
||||
"chart2 chart2 chart1 chart1"
|
||||
"chart5 chart5 chart1 chart1"
|
||||
"chart5 chart5 chart3 chart4"
|
||||
"chart5 chart5 timeline timeline";
|
||||
"chart1 chart1 chart2 chart2"
|
||||
"chart1 chart1 chart2 chart2"
|
||||
"chart1 chart1 chart3 chart4"
|
||||
"chart1 chart1 chart3 chart4"
|
||||
"chart1 chart1 chart6 chart6"
|
||||
"chart1 chart1 chart6 chart6"
|
||||
"chart1 chart1 timeline timeline";
|
||||
}
|
||||
|
||||
body.region main{
|
||||
body.property main{
|
||||
grid-template-columns: repeat(4, minmax(10%, 50%));
|
||||
grid-template-rows: repeat(4, 1fr) 4em;
|
||||
grid-template-areas:
|
||||
"chart1 chart1 chart2 chart2"
|
||||
"chart1 chart1 chart6 chart6"
|
||||
"chart1 chart1 chart3 chart4"
|
||||
"chart1 chart1 chart3 chart4"
|
||||
"chart1 chart1 timeline timeline";
|
||||
"chart2 chart2 chart1 chart1"
|
||||
"chart2 chart2 chart1 chart1"
|
||||
"chart5 chart5 chart3 chart4"
|
||||
"chart5 chart5 chart3 chart4"
|
||||
"chart5 chart5 timeline timeline";
|
||||
}
|
||||
|
||||
article{
|
||||
|
@ -205,7 +220,7 @@ article{
|
|||
|
||||
article.header{
|
||||
grid-template-columns: 100%;
|
||||
grid-template-rows: minmax(1%, 2.5em) 1fr;
|
||||
grid-template-rows: minmax(1%, 2em) 1fr;
|
||||
padding: .5em 1em 1em .5em;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,56 +11,89 @@
|
|||
</nav>
|
||||
@endsection
|
||||
@section('main')
|
||||
<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>
|
||||
<article class="header" style="grid-area: chart1;">
|
||||
<header>
|
||||
<h2>
|
||||
Anzahl jemals gefundene Kurzzeitmietobjekte pro Region
|
||||
</h2>
|
||||
<button popovertarget="pop1">
|
||||
<span>Erklärungen zum Diagramm</span>
|
||||
</button>
|
||||
<div popover id="pop1">
|
||||
<p>Das Diagram zeigt...</p>
|
||||
</div>
|
||||
<div>
|
||||
</header>
|
||||
<div id="chart-props-per-region"></div>
|
||||
<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>
|
||||
</article>
|
||||
<article class="header" style="grid-area: chart2;">
|
||||
<header>
|
||||
<h2>
|
||||
Entwicklung der Anzahl jemals gefunden Kurzzeitmietobjekte
|
||||
</h2>
|
||||
</header>
|
||||
<div id="extractions"></div>
|
||||
<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>
|
||||
</article>
|
||||
<article style="grid-area: chart4;">
|
||||
<div id="leaflet"></div>
|
||||
</article>
|
||||
<article class="header" style="grid-area: chart3;">
|
||||
<header>
|
||||
<h2>
|
||||
Gesamtauslastung
|
||||
</h2>
|
||||
</header>
|
||||
<div id="chart-heatmap"></div>
|
||||
<div id="leaflet"></div>
|
||||
</article>
|
||||
<script type="module">
|
||||
|
||||
const sharedOptions = {
|
||||
basic: {
|
||||
color: {!! $chartOptions['colors'] !!},
|
||||
grid: {
|
||||
top: 20,
|
||||
left: 60,
|
||||
top: 30,
|
||||
left: 70,
|
||||
right: 0,
|
||||
bottom: 50
|
||||
bottom: 45
|
||||
},
|
||||
name: (opt) => {
|
||||
return {
|
||||
name: opt.name,
|
||||
nameLocation: opt.location,
|
||||
nameGap: 24,
|
||||
nameGap: 50,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
@ -160,7 +193,7 @@ const cPropsPerRegionOptions = {
|
|||
xAxis: {
|
||||
name: 'Region',
|
||||
nameLocation: 'center',
|
||||
nameGap: 24,
|
||||
nameGap: 30,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
@ -169,9 +202,9 @@ const cPropsPerRegionOptions = {
|
|||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: 'Anzahl Kurzzeitmietobjekte',
|
||||
name: 'Anzahl Mietobjekte',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 38,
|
||||
nameGap: 50,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
@ -219,9 +252,9 @@ const cExtractionsOptions = {
|
|||
data: extractionDates
|
||||
},
|
||||
yAxis: {
|
||||
name: 'Anzahl Kurzzeitmietobjekte',
|
||||
name: 'Anzahl Mietobjekte',
|
||||
nameLocation: 'center',
|
||||
nameGap: 38,
|
||||
nameGap: 50,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
@extends('base')
|
||||
@section('body-class', 'property')
|
||||
@section('header')
|
||||
<span>Property {{ $base['property_platform_id'] }}</span><button popovertarget="prop-details"></button>
|
||||
<nav>
|
||||
<strong>Property: {{ $base['check_data'] }}</strong>
|
||||
<ul>
|
||||
<li><a href="/">Start</a></li>
|
||||
@foreach($regions as $r)
|
||||
<li><a href="/region/{{ $r['region_id'] }}">{{ $r['region_name'] }}</a></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</nav>
|
||||
<button popovertarget="prop-details"></button>
|
||||
<div popover id="prop-details">
|
||||
<dl>
|
||||
<dt>Region</dt>
|
||||
|
@ -80,6 +89,11 @@ const sharedOptions = {
|
|||
right: 0,
|
||||
bottom: 50
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
valueFormatter: (value) => value.toFixed(2)+' %'
|
||||
},
|
||||
name: (opt) => {
|
||||
return {
|
||||
name: opt.name,
|
||||
|
@ -102,7 +116,7 @@ const cTimelineOptions = {
|
|||
},
|
||||
timeline: {
|
||||
data: {!! $extractiondates !!},
|
||||
playInterval: 2000,
|
||||
playInterval: 1000,
|
||||
axisType: 'time',
|
||||
left: 8,
|
||||
right: 8,
|
||||
|
@ -119,20 +133,27 @@ const chartCapacityMonthly = document.getElementById('chart-capacity-monthly');
|
|||
const cCapacityMonthly = echarts.init(chartCapacityMonthly);
|
||||
|
||||
const cCapacityMonthlyOptions = {
|
||||
tooltip: sharedOptions.basic.tooltip,
|
||||
timeline: {
|
||||
show: false,
|
||||
data: {!! $extractiondates !!},
|
||||
axisType: 'time',
|
||||
},
|
||||
grid: {
|
||||
top: 0,
|
||||
bottom: 25,
|
||||
top: 5,
|
||||
bottom: 40,
|
||||
left: 70,
|
||||
right: 10
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
max: 100
|
||||
max: 100,
|
||||
name: 'Auslastung in %',
|
||||
nameLocation: 'center',
|
||||
nameGap: 25,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
|
@ -161,20 +182,27 @@ const chartCapacityDaily = document.getElementById('chart-capacity-daily');
|
|||
const cCapacityDaily = echarts.init(chartCapacityDaily);
|
||||
|
||||
const cCapacityDailyOptions = {
|
||||
tooltip: sharedOptions.basic.tooltip,
|
||||
timeline: {
|
||||
show: false,
|
||||
data: {!! $extractiondates !!},
|
||||
axisType: 'time',
|
||||
},
|
||||
grid: {
|
||||
top: 0,
|
||||
bottom: 25,
|
||||
top: 5,
|
||||
bottom: 40,
|
||||
left: 70,
|
||||
right: 10
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
max: 100
|
||||
max: 100,
|
||||
name: 'Auslastung in %',
|
||||
nameLocation: 'center',
|
||||
nameGap: 25,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
|
@ -277,7 +305,7 @@ const cCalendarOptions = {
|
|||
visualMap: {
|
||||
categories: [0,1,2],
|
||||
inRange: {
|
||||
color: ['#d95f02', '#7570b3', '#1b9e77']
|
||||
color: ['#ca0020', '#92c5de', '#0571b0']
|
||||
},
|
||||
formatter: (cat) => {
|
||||
switch (cat) {
|
||||
|
|
|
@ -19,20 +19,20 @@
|
|||
</article>
|
||||
<article class="header" style="grid-area: chart6;">
|
||||
<header>
|
||||
<h2 id="prediction-title">Gleitender Mittelwert für die Auslastung von {{ $region[0]['region_name'] }}</h2>
|
||||
<h2 id="prediction-title">Gleitender Mittelwert für die Auslastung der Region</h2>
|
||||
</header>
|
||||
<div id="chart-prediction"></div>
|
||||
</article>
|
||||
<article class="header" style="grid-area: chart1;">
|
||||
<header>
|
||||
<h2 id="belegung-title">Gesamtauslastung</h2>
|
||||
<h2 id="belegung-title">Auslastung aller Mietobjekte über Gesamte Zeit der Region</h2>
|
||||
</header>
|
||||
<div id="chart-heatmap"></div>
|
||||
</article>
|
||||
<article class="header" style="grid-area: chart3;">
|
||||
<header>
|
||||
<h2>
|
||||
Auslastung der Region nach Monat am <span class="date">{{ $startDate }}</span>
|
||||
Auslastung Region nach Monat am <span class="date">{{ $startDate }}</span>
|
||||
</h2>
|
||||
</header>
|
||||
<div id="chart-capacity-monthly">
|
||||
|
@ -54,7 +54,7 @@
|
|||
<article class="header" style="grid-area: chart4;">
|
||||
<header>
|
||||
<h2>
|
||||
Auslastung der Region nach Wochentage am <span class="date">{{ $startDate }}</span>
|
||||
Auslastung Wochentage am <span class="date">{{ $startDate }}</span>
|
||||
</h2>
|
||||
</header>
|
||||
<div id="chart-capacity-daily">
|
||||
|
@ -71,6 +71,11 @@ const sharedOptions = {
|
|||
right: 0,
|
||||
bottom: 50
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
valueFormatter: (value) => value.toFixed(2)+' %'
|
||||
},
|
||||
name: (opt) => {
|
||||
return {
|
||||
name: opt.name,
|
||||
|
@ -89,12 +94,9 @@ const cCapacity = echarts.init(chartCapacity);
|
|||
|
||||
const cCapacityOptions = {
|
||||
legend: {
|
||||
data: ['Auslastung Region', 'Auslastung alle Regionen']
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
valueFormatter: (value) => value.toFixed(2)+' %'
|
||||
show: true
|
||||
},
|
||||
tooltip: sharedOptions.basic.tooltip,
|
||||
color: sharedOptions.basic.color,
|
||||
grid: {
|
||||
top: 20,
|
||||
|
@ -151,18 +153,25 @@ const cCapacityMonthlyOptions = {
|
|||
axisType: 'time',
|
||||
},
|
||||
grid: {
|
||||
top: 0,
|
||||
bottom: 25,
|
||||
top: 5,
|
||||
bottom: 40,
|
||||
left: 70,
|
||||
right: 10
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
max: 100
|
||||
max: 100,
|
||||
name: 'Auslastung in %',
|
||||
nameLocation: 'center',
|
||||
nameGap: 25,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
},
|
||||
tooltip: sharedOptions.basic.tooltip,
|
||||
options: [
|
||||
@foreach ($regionCapacities['region_monthly'] as $m)
|
||||
{
|
||||
|
@ -192,15 +201,22 @@ const cCapacityDailyOptions = {
|
|||
data: {!! json_encode($regionCapacities['region']['dates']) !!},
|
||||
axisType: 'time',
|
||||
},
|
||||
tooltip: sharedOptions.basic.tooltip,
|
||||
grid: {
|
||||
top: 0,
|
||||
bottom: 25,
|
||||
top: 5,
|
||||
bottom: 40,
|
||||
left: 70,
|
||||
right: 10
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
max: 100
|
||||
max: 100,
|
||||
name: 'Auslastung in %',
|
||||
nameLocation: 'center',
|
||||
nameGap: 25,
|
||||
nameTextStyle: {
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
|
@ -229,6 +245,7 @@ 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']) !!},
|
||||
|
@ -238,10 +255,7 @@ const cPredictionOptions = {
|
|||
legend: {
|
||||
show: true
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
valueFormatter: (value) => value.toFixed(2)+' %'
|
||||
},
|
||||
tooltip: sharedOptions.basic.tooltip,
|
||||
grid: {
|
||||
top: 20,
|
||||
left: 25,
|
||||
|
@ -468,6 +482,16 @@ cTimeline.on('timelinechanged', (e) => {
|
|||
|
||||
})
|
||||
|
||||
|
||||
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
|
||||
|
|
|
@ -86,7 +86,8 @@ Route::get('/property/{id}', function (int $id) {
|
|||
$chartOptions = [
|
||||
'colors' => Chart::colors()
|
||||
];
|
||||
|
||||
$regionBaseAll = Api::regionBase(-1);
|
||||
$regionBaseAll[] = ['region_name' => 'Alle Regionen', 'region_id' => -1];
|
||||
$propertyBase = Api::propertyBase($id);
|
||||
$calendars = Api::propertyExtractions($id);
|
||||
$propertyCapacities = Api::propertyCapacities($id);
|
||||
|
@ -137,6 +138,7 @@ Route::get('/property/{id}', function (int $id) {
|
|||
'chartOptions' => $chartOptions,
|
||||
'startDate' => $propertyCapacities['dates'][0],
|
||||
'base' => $propertyBase[0],
|
||||
'regions' => $regionBaseAll,
|
||||
'extractiondates' => json_encode($propertyCapacities['dates']),
|
||||
'calendar' => $data,
|
||||
'propertyCapacities' => $propertyCapacities,
|
||||
|
|
Loading…
Reference in New Issue