some polishing
This commit is contained in:
		
							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,16 +11,44 @@ | ||||
| </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"> | ||||
|     <button popovertarget="pop2"> | ||||
|       <span>Erklärungen zum Diagramm</span> | ||||
|     </button> | ||||
|         <div popover id="pop1"> | ||||
|           <p>Das Diagram zeigt...</p> | ||||
|     <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> | ||||
| @ -31,36 +59,41 @@ | ||||
|     <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> | ||||
| </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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Giò Diani
						Giò Diani