From c00e038fba62564f5d54d2064745d299b0aece75 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Thu, 23 Jan 2020 19:27:08 +0100 Subject: [PATCH] Add trip display to departures --- resources/components/departures.html | 2 +- .../components/departures/departure.html | 13 +++ resources/styles/_stop.scss | 2 +- resources/styles/_trigonometry.scss | 66 +++++++++++++ resources/styles/_trip.scss | 97 +++++++++++++++++++ resources/styles/main.scss | 1 + resources/ts/components/departures.ts | 16 +++ resources/ts/model/departure.ts | 4 +- resources/ts/model/identity.ts | 3 + resources/ts/model/index.ts | 3 +- resources/ts/urls.ts | 3 +- .../Database/GenericScheduleRepository.php | 2 +- .../ZtmGdanskDepartureRepository.php | 2 +- 13 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 resources/styles/_trigonometry.scss create mode 100644 resources/styles/_trip.scss create mode 100644 resources/ts/model/identity.ts diff --git a/resources/components/departures.html b/resources/components/departures.html index b5bcc5a..d8f3557 100644 --- a/resources/components/departures.html +++ b/resources/components/departures.html @@ -1,6 +1,6 @@
diff --git a/resources/components/departures/departure.html b/resources/components/departures/departure.html index f14a0c2..50c58d9 100644 --- a/resources/components/departures/departure.html +++ b/resources/components/departures/departure.html @@ -34,5 +34,18 @@
+
+
    +
  1. +
    +
    + +
    +
  2. +
+
+
+ +
diff --git a/resources/styles/_stop.scss b/resources/styles/_stop.scss index 5151334..c6d5346 100644 --- a/resources/styles/_stop.scss +++ b/resources/styles/_stop.scss @@ -6,7 +6,7 @@ .stop__name { flex: 1 0; - line-height: 1.2; + line-height: 1.1; } .stop__variant { diff --git a/resources/styles/_trigonometry.scss b/resources/styles/_trigonometry.scss new file mode 100644 index 0000000..d5f8fb4 --- /dev/null +++ b/resources/styles/_trigonometry.scss @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////// +// Plain SASS Trigonometry Algorithm in Taylor Expansion // +// // +// Based on // +// http://japborst.net/posts/sass-sines-and-cosines // +/////////////////////////////////////////////////////////// + +$pi: 3.14159265359; +$_precision: 5; + +@function pow($base, $exp) { + $value: $base; + @if $exp > 1 { + @for $i from 2 through $exp { + $value: $value * $base; + } + } + @if $exp < 1{ + @for $i from 0 through -$exp { + $value: $value / $base; + } + } + @return $value; +} + +@function fact($num) { + $fact: 1; + @if $num > 0{ + @for $i from 1 through $num { + $fact: $fact * $i; + } + } + @return $fact; +} + +@function _to_unitless_rad($angle) { + @if unit($angle) == "deg" { + $angle: $angle / 180deg * $pi; + } + @if unit($angle) == "rad" { + $angle: $angle / 1rad; + } + @return $angle; +} + +@function sin($angle){ + $a: _to_unitless_rad($angle); + $sin: $a; + @for $n from 1 through $_precision { + $sin: $sin + (pow(-1, $n) / fact(2 * $n + 1) ) * pow($a, (2 * $n + 1)); + } + @return $sin; +} + +@function cos($angle){ + $a: _to_unitless_rad($angle); + $cos: 1; + @for $n from 1 through $_precision { + $cos: $cos + ( pow(-1,$n) / fact(2*$n) ) * pow($a,2*$n); + } + @return $cos; +} + +@function tan($angle){ + @return sin($angle) / cos($angle); +} diff --git a/resources/styles/_trip.scss b/resources/styles/_trip.scss new file mode 100644 index 0000000..10729ff --- /dev/null +++ b/resources/styles/_trip.scss @@ -0,0 +1,97 @@ +@import "trigonometry"; + +$description-rotation: 60deg; +$description-width: 250px; + +$trip-stop-marker-size: .9rem; +$trip-stop-line-width: .2rem; + +.trip { + display: flex; + justify-content: center; +} + +.trip__stops { + padding-top: sin($description-rotation) * $description-width; + padding-right: cos($description-rotation) * $description-width; + padding-left: 0; + display: flex; + list-style: none; + overflow-x: auto; +} + +.trip-stop { + width: 2.5rem; + position: relative; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; +} + +.trip-stop:first-child { + .trip-stop__marker::before { + content: none; + } +} + +.trip-stop:last-child { + .trip-stop__marker::after { + content: none; + } +} + +.trip-stop__marker { + width: $trip-stop-marker-size; + height: $trip-stop-marker-size; + border: $dark $trip-stop-line-width solid; + border-radius: 100%; + background: white; + margin: .75rem 0; + + &::before, &::after { + content: ""; + display: block; + height: $trip-stop-line-width; + background: $dark; + width: 50%; + position: absolute; + top: 50%; + transform: translateY(-50%); + z-index: -1; + } + + &::after { + right: 0; + } + + &::before { + left: 0; + } +} + +@each $type, $color in $line-types { + .trip--#{$type} { + .trip-stop__marker { + border-color: $color; + + &::before, &::after { + background: $color; + } + } + } +} + +.trip-stop__description { + display: flex; + transform: rotate(-$description-rotation) translateX(.75rem); + transform-origin: 0 50%; + max-width: $description-width; + position: absolute; + left: 50%; + top: 0; + + .stop { + width: max-content; + } +} diff --git a/resources/styles/main.scss b/resources/styles/main.scss index 653bc87..956b9b8 100644 --- a/resources/styles/main.scss +++ b/resources/styles/main.scss @@ -51,6 +51,7 @@ $grid-gutter-width: $spacer * 2; @import "animations"; @import "form"; @import "fabourites"; +@import "trip"; body { min-height: 100vh; diff --git a/resources/ts/components/departures.ts b/resources/ts/components/departures.ts index 7e864b6..6b43d76 100644 --- a/resources/ts/components/departures.ts +++ b/resources/ts/components/departures.ts @@ -3,6 +3,8 @@ import { Departure, Stop } from "../model"; import { Component, Prop, Watch } from "vue-property-decorator"; import { namespace } from 'vuex-class'; import store from '../store' +import { Trip } from "../model/trip"; +import urls from "../urls"; const { State } = namespace('departures'); @@ -19,6 +21,7 @@ export class DepartureComponent extends Vue { @Prop(Object) departure: Departure; showTrip: boolean = false; + trip: Trip = null; get timeDiffers() { const departure = this.departure; @@ -29,6 +32,19 @@ export class DepartureComponent extends Vue { get time() { return this.departure.estimated || this.departure.scheduled; } + + @Watch('showTrip') + async downloadTrips() { + if (this.showTrip != true || this.trip != null) { + return; + } + + const response = await fetch(urls.prepare(urls.trip, { id: this.departure.trip.id })); + + if (response.ok) { + this.trip = await response.json(); + } + } } Vue.component('Departures', DeparturesComponent); diff --git a/resources/ts/model/departure.ts b/resources/ts/model/departure.ts index ece154b..f855a55 100644 --- a/resources/ts/model/departure.ts +++ b/resources/ts/model/departure.ts @@ -1,9 +1,10 @@ import { Stop } from "./stop"; import { Line } from "./line"; import { Moment } from "moment"; +import { Identity } from "./identity"; export interface Departure { - id: string; + key: string; display: string; estimated: Moment; scheduled?: Moment; @@ -12,6 +13,7 @@ export interface Departure { delay: number; vehicle?: Vehicle; + trip?: Identity; } export interface Vehicle { diff --git a/resources/ts/model/identity.ts b/resources/ts/model/identity.ts new file mode 100644 index 0000000..7982cc4 --- /dev/null +++ b/resources/ts/model/identity.ts @@ -0,0 +1,3 @@ +export type Identity = { + id: string; +} diff --git a/resources/ts/model/index.ts b/resources/ts/model/index.ts index 4a7a5f3..e4ca6d0 100644 --- a/resources/ts/model/index.ts +++ b/resources/ts/model/index.ts @@ -1,4 +1,5 @@ export * from './stop' export * from './departure' export * from './line' -export * from './error' \ No newline at end of file +export * from './error' +export * from './identity' diff --git a/resources/ts/urls.ts b/resources/ts/urls.ts index 1528e7a..e3bb5d1 100644 --- a/resources/ts/urls.ts +++ b/resources/ts/urls.ts @@ -56,5 +56,6 @@ export default { get: `${base}/stops/{id}`, tracks: `${base}/stops/{id}/tracks` }, + trip: `${base}/trips/{id}`, prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: window['data'].provider }, params)) -} \ No newline at end of file +} diff --git a/src/Provider/Database/GenericScheduleRepository.php b/src/Provider/Database/GenericScheduleRepository.php index dabcccf..551c288 100644 --- a/src/Provider/Database/GenericScheduleRepository.php +++ b/src/Provider/Database/GenericScheduleRepository.php @@ -60,7 +60,7 @@ class GenericScheduleRepository extends DatabaseRepository implements ScheduleRe $last = $entity->getTrip()->getTrack()->getStopsInTrack()->last()->getStop(); return Departure::createFromArray([ - 'id' => sprintf('%s::%s', $entity->getTrip()->getId(), $entity->getDeparture()->format('H:i')), + 'key' => sprintf('%s::%s', $this->id->of($entity->getTrip()), $entity->getDeparture()->format('H:i')), 'scheduled' => $entity->getDeparture(), 'stop' => $stop, 'display' => $last->getName(), diff --git a/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php b/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php index d1c3b99..ba01778 100644 --- a/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php +++ b/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php @@ -70,7 +70,7 @@ class ZtmGdanskDepartureRepository implements DepartureRepository $estimated = (clone $scheduled)->addSeconds($delay['delayInSeconds']); return Departure::createFromArray([ - 'id' => sprintf('%s::%s', $delay['routeId'], $scheduled->format('H:i')), + 'key' => sprintf('%s::%s', $delay['routeId'], $scheduled->format('H:i')), 'scheduled' => $scheduled, 'estimated' => $estimated, 'stop' => $stop,