controlled-rising-skyline
Version:
This library provides a rising skyline chart with an horizontal control panel control. This widget is linked to a dynamic history of buildings. An animation displays the rising of the skyline.
82 lines • 14.6 kB
JavaScript
import { Component, HostBinding, Input } from '@angular/core';
import { ColorService, RisingSkylineService } from 'rising-skyline';
export class PanelControlComponent {
constructor(skylineService, colorService) {
this.skylineService = skylineService;
this.colorService = colorService;
/**
* Slider color of the panel control
*/
this.sliderColor = 'violet';
/**
* __Debug__ mode default value is **False**.
*/
this.debug = false;
/**
* The Skyline subscription.
*/
this.skylineSubscription = null;
this.formatYearWeek = (value) => {
return this.skylineService.currentYear + '/'
+ ((this.skylineService.currentWeek < 10) ? '0' + this.skylineService.currentWeek : this.skylineService.currentWeek);
};
}
ngOnInit() {
}
ngAfterViewInit() {
this.skylineService.episode$
.subscribe(floors => {
if (floors.length > 0) {
const allIndex = floors
.filter(floor => floor.height > 0)
.map(floor => floor.index)
.reduce((theSum, index) => theSum + index, 0);
const meanIndex = Math.floor(allIndex / floors.filter(floor => floor.height > 0).length);
if (this.debug) {
console.log('Index of color used for the thumb coin', meanIndex);
}
const htmlThumbLabelCoin = document.getElementsByClassName('mat-slider-thumb-label').item(0);
if (htmlThumbLabelCoin) {
const color = this.colorService.color(meanIndex);
if (this.debug) {
console.log('Index of color used for the thumb coin %d is processing the color %s', meanIndex, color);
}
htmlThumbLabelCoin.setAttribute('style', 'background-color:' + color);
}
}
});
}
ngOnDestroy() {
if (this.skylineSubscription) {
this.skylineSubscription.unsubscribe();
}
}
onSliderChange($event) {
const yw = this.skylineService.yearWeeks[Math.max(0, $event.value - 2)];
this.skylineService.currentYear = yw.year;
this.skylineService.currentWeek = yw.week;
this.skylineService.currentEpisode = $event.value - 2;
if (this.debug) {
console.log('Position %d points to (%d; %d)', $event.value, yw.year, yw.week);
}
const episode = this.skylineService.extractSkylineEpisode(yw.year, yw.week);
this.skylineService.drawEpisode(episode);
}
}
PanelControlComponent.decorators = [
{ type: Component, args: [{
selector: 'app-panel-control',
template: "<div id=\"controlPanel\" class=\"container-fluid\" *ngIf=\"(skylineService.episode$|async).length > 0\">\n\n <div class=\"row\">\n\n <div class=\"col-1\"></div>\n\n <div id=\"firstDate\" class=\"col-1 my-auto\">\n {{skylineService.toYearWeek(skylineService.firstDate).year}}/{{skylineService.toYearWeek(skylineService.firstDate).week | number : '2.0-0'}}\n </div>\n\n <div id=\"slider\" class=\"col-6 my-auto\">\n <mat-slider class=\"cdk-focused\" \n aria-label=\"Episodes timeline\" role=\"slider\"\n min=\"1\" max=\"{{this.skylineService.countEpisodes}}\" [value]=\"this.skylineService.currentEpisode\"\n thumbLabel [displayWith]=\"formatYearWeek\"\n (change)=\"onSliderChange($event)\" >\n </mat-slider>\n </div>\n\n <div id=\"lastDate\" class=\"col-4 my-auto\">\n <span>\n {{skylineService.toYearWeek(skylineService.lastDate).year}}/{{skylineService.toYearWeek(skylineService.lastDate).week | number : '2.0-0'}}\n </span>\n <button *ngIf=\"!skylineService.pause\" \n class=\"btn btn-outline-primary btn-circle control-button\" \n (click)=\"skylineService.pauseRising()\"\n aria-label=\"Pause the animation\">\n <em class=\"fas fa-pause\"></em>\n </button>\n \n <button \n *ngIf=\"skylineService.pause\" \n class=\"btn btn-outline-primary btn-circle control-button\" \n (click)=\"skylineService.playRising()\"\n aria-label=\"Start or restart the animation\">\n <i class=\"fas fa-play\"></i>\n </button>\n\n <button \n class=\"btn btn-outline-primary btn-circle control-button\" \n (click)=\"skylineService.rotateVariation()\"\n aria-label=\"Increase or decrease the speed of the animation\">\n <span class=\"speed number\" innerHTML = \"{{skylineService.variation.title}}\"></span><span class=\"speed x\">x</span>\n </button>\n </div>\n\n </div>\n\n</div>",
styles: ["#controlPanel{height:60px;width:100%;display:block;background-color:var(--control-background-color);padding-top:5px}.mat-slider{width:100%;padding-right:0;padding-left:0}:host ::ng-deep .mat-slider-horizontal .mat-slider-thumb-label{width:42px;height:42px;transform:translateY(20px) scale(1) rotate(45deg);color:#fff}:host ::ng-deep .mat-slider-thumb-label-text{opacity:1;font-size:10px;color:#fff}:host ::ng-deep .mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label{width:42px;height:42px;margin-top:20px;right:-20px;background-color:#006400;color:#fff}:host ::ng-deep .mat-slider.mat-slider-horizontal .mat-slider-track-background,.mat-slider.mat-slider-horizontal .mat-slider-track-fill{height:100%}:host ::ng-deep .mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label-text{opacity:1;font-size:10px}:host ::ng-deep .mat-slider:not(.mat-slider-disabled).cdk-focused .mat-slider-thumb-label{border-radius:50%;color:#fff}:host ::ng-deep .mat-slider.mat-slider-horizontal .mat-slider-track-fill{background-color:var(--slider-color)}button.pause{height:30px;width:30px}#slider{padding-left:15px;padding-right:13px}#firstDate{padding-right:0;text-align:right;height:100%}#lastDate{padding-left:0;padding-right:0;text-align:left}button.control-button{color:var(--slider-color);border-color:gray;border-radius:50%;margin-left:4px;padding-bottom:7px;padding-left:12px}button.control-button:hover{color:#fff;background-color:var(--slider-color)}span.speed{font-size:13px}span.x{position:relative;bottom:1px}\n"]
},] }
];
PanelControlComponent.ctorParameters = () => [
{ type: RisingSkylineService },
{ type: ColorService }
];
PanelControlComponent.propDecorators = {
backgroundColor: [{ type: HostBinding, args: ['style.--control-background-color',] }, { type: Input }],
sliderColor: [{ type: HostBinding, args: ['style.--slider-color',] }, { type: Input }],
debug: [{ type: Input }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFuZWwtY29udHJvbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb250cm9sbGVkLXJpc2luZy1za3lsaW5lL3NyYy9saWIvcGFuZWwtY29udHJvbC9wYW5lbC1jb250cm9sLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLFNBQVMsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFxQixNQUFNLGVBQWUsQ0FBQztBQUVoRyxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFTcEUsTUFBTSxPQUFPLHFCQUFxQjtJQXdCaEMsWUFBbUIsY0FBb0MsRUFBUyxZQUEwQjtRQUF2RSxtQkFBYyxHQUFkLGNBQWMsQ0FBc0I7UUFBUyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQWhCMUY7O1dBRUc7UUFFTSxnQkFBVyxHQUFHLFFBQVEsQ0FBQztRQUVoQzs7V0FFRztRQUNNLFVBQUssR0FBRyxLQUFLLENBQUM7UUFFdkI7O1dBRUc7UUFDSyx3QkFBbUIsR0FBaUIsSUFBSSxDQUFDO1FBSWpELG1CQUFjLEdBQUcsQ0FBQyxLQUFhLEVBQUUsRUFBRTtZQUNqQyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxHQUFHLEdBQUc7a0JBQzFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3ZILENBQUMsQ0FBQTtJQUw2RixDQUFDO0lBTy9GLFFBQVE7SUFDUixDQUFDO0lBR0QsZUFBZTtRQUNiLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUTthQUN6QixTQUFTLENBQ1IsTUFBTSxDQUFDLEVBQUU7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bnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBIb3N0QmluZGluZywgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXRTbGlkZXJDaGFuZ2UgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbGlkZXInO1xuaW1wb3J0IHsgQ29sb3JTZXJ2aWNlLCBSaXNpbmdTa3lsaW5lU2VydmljZSB9IGZyb20gJ3Jpc2luZy1za3lsaW5lJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtcGFuZWwtY29udHJvbCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9wYW5lbC1jb250cm9sLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcGFuZWwtY29udHJvbC5jb21wb25lbnQuY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgUGFuZWxDb250cm9sQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8qKlxuICAgKiBCYWNrZ3JvdW5kIGNvbG9yIG9mIHRoZSBjb250cm9sIGZvb3RlciBwYW5lbFxuICAgKi9cbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS4tLWNvbnRyb2wtYmFja2dyb3VuZC1jb2xvcicpXG4gIEBJbnB1dCgpIGJhY2tncm91bmRDb2xvcjtcblxuICAvKipcbiAgICogU2xpZGVyIGNvbG9yIG9mIHRoZSBwYW5lbCBjb250cm9sXG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ3N0eWxlLi0tc2xpZGVyLWNvbG9yJylcbiAgQElucHV0KCkgc2xpZGVyQ29sb3IgPSAndmlvbGV0JztcblxuICAvKipcbiAgICogX19EZWJ1Z19fIG1vZGUgZGVmYXVsdCB2YWx1ZSBpcyAqKkZhbHNlKiouXG4gICAqL1xuICBASW5wdXQoKSBkZWJ1ZyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBUaGUgU2t5bGluZSBzdWJzY3JpcHRpb24uXG4gICAqL1xuICBwcml2YXRlIHNreWxpbmVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IocHVibGljIHNreWxpbmVTZXJ2aWNlOiBSaXNpbmdTa3lsaW5lU2VydmljZSwgcHVibGljIGNvbG9yU2VydmljZTogQ29sb3JTZXJ2aWNlKSB7IH1cblxuICBmb3JtYXRZZWFyV2VlayA9ICh2YWx1ZTogbnVtYmVyKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuc2t5bGluZVNlcnZpY2UuY3VycmVudFllYXIgKyAnLydcbiAgICArICgodGhpcy5za3lsaW5lU2VydmljZS5jdXJyZW50V2VlayA8IDEwKSA/ICcwJyArIHRoaXMuc2t5bGluZVNlcnZpY2UuY3VycmVudFdlZWsgOiB0aGlzLnNreWxpbmVTZXJ2aWNlLmN1cnJlbnRXZWVrKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICB9XG5cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5za3lsaW5lU2VydmljZS5lcGlzb2RlJFxuICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgZmxvb3JzID0+IHtcbiAgICAgICAgICBpZiAoZmxvb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGFsbEluZGV4ID0gZmxvb3JzXG4gICAgICAgICAgICAgIC5maWx0ZXIoZmxvb3IgPT4gZmxvb3IuaGVpZ2h0ID4gMClcbiAgICAgICAgICAgICAgLm1hcChmbG9vciA9PiBmbG9vci5pbmRleClcbiAgICAgICAgICAgICAgLnJlZHVjZSgodGhlU3VtLCBpbmRleCkgPT4gdGhlU3VtICsgaW5kZXgsIDAgKTtcbiAgICAgICAgICAgIGNvbnN0IG1lYW5JbmRleCA9IE1hdGguZmxvb3IoYWxsSW5kZXggLyBmbG9vcnMuZmlsdGVyKGZsb29yID0+IGZsb29yLmhlaWdodCA+IDApLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWJ1ZykgIHtcbiAgICAgICAgICAgICAgY29uc29sZS5sb2cgKCdJbmRleCBvZiBjb2xvciB1c2VkIGZvciB0aGUgdGh1bWIgY29pbicsIG1lYW5JbmRleCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGh0bWxUaHVtYkxhYmVsQ29pbiA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ21hdC1zbGlkZXItdGh1bWItbGFiZWwnKS5pdGVtKDApO1xuICAgICAgICAgICAgaWYgKGh0bWxUaHVtYkxhYmVsQ29pbikge1xuICAgICAgICAgICAgICBjb25zdCBjb2xvciA9ICB0aGlzLmNvbG9yU2VydmljZS5jb2xvcihtZWFuSW5kZXgpO1xuICAgICAgICAgICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nICgnSW5kZXggb2YgY29sb3IgdXNlZCBmb3IgdGhlIHRodW1iIGNvaW4gJWQgaXMgcHJvY2Vzc2luZyB0aGUgY29sb3IgJXMnLCBtZWFuSW5kZXgsIGNvbG9yKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBodG1sVGh1bWJMYWJlbENvaW4uc2V0QXR0cmlidXRlKCdzdHlsZScsICdiYWNrZ3JvdW5kLWNvbG9yOicgKyBjb2xvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5za3lsaW5lU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnNreWxpbmVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBvblNsaWRlckNoYW5nZSgkZXZlbnQ6IE1hdFNsaWRlckNoYW5nZSk6IHZvaWQge1xuICAgIGNvbnN0IHl3ID0gdGhpcy5za3lsaW5lU2VydmljZS55ZWFyV2Vla3NbTWF0aC5tYXgoMCwgJGV2ZW50LnZhbHVlIC0gMildO1xuICAgIHRoaXMuc2t5bGluZVNlcnZpY2UuY3VycmVudFllYXIgPSB5dy55ZWFyO1xuICAgIHRoaXMuc2t5bGluZVNlcnZpY2UuY3VycmVudFdlZWsgPSB5dy53ZWVrO1xuICAgIHRoaXMuc2t5bGluZVNlcnZpY2UuY3VycmVudEVwaXNvZGUgPSAkZXZlbnQudmFsdWUgLSAyO1xuICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICBjb25zb2xlLmxvZyAoJ1Bvc2l0aW9uICVkIHBvaW50cyB0byAoJWQ7ICVkKScsICRldmVudC52YWx1ZSwgeXcueWVhciwgeXcud2Vlayk7XG4gICAgfVxuICAgIGNvbnN0IGVwaXNvZGUgPSB0aGlzLnNreWxpbmVTZXJ2aWNlLmV4dHJhY3RTa3lsaW5lRXBpc29kZSh5dy55ZWFyLCB5dy53ZWVrKTtcbiAgICB0aGlzLnNreWxpbmVTZXJ2aWNlLmRyYXdFcGlzb2RlKGVwaXNvZGUpO1xuICB9XG59XG4iXX0=