1
0
Fork 0

New web ui

This commit is contained in:
Jan Kuri 2018-04-27 13:12:04 +02:00 committed by Traefiker Bot
parent e09d5cb4ec
commit 9c651ae913
105 changed files with 7314 additions and 5514 deletions

View file

@ -0,0 +1,7 @@
<div class="bar-chart" [class.is-hidden]="loading"></div>
<div class="loading-text" [class.is-hidden]="!loading">
<span>
<span>Loading, please wait...</span>
<img src="./assets/images/loader.svg" class="main-loader">
</span>
</div>

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BarChartComponent } from './bar-chart.component';
describe('BarChartComponent', () => {
let component: BarChartComponent;
let fixture: ComponentFixture<BarChartComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BarChartComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BarChartComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,114 @@
import { Component, Input, OnInit, ElementRef, OnChanges, SimpleChanges } from '@angular/core';
import { WindowService } from '../../services/window.service';
import {
min,
max,
easeLinear,
select,
axisLeft,
axisBottom,
scaleBand,
scaleLinear
} from 'd3';
@Component({
selector: 'app-bar-chart',
templateUrl: './bar-chart.component.html'
})
export class BarChartComponent implements OnInit, OnChanges {
@Input() value: any;
barChartEl: HTMLElement;
svg: any;
x: any;
y: any;
g: any;
bars: any;
width: number;
height: number;
margin = { top: 40, right: 40, bottom: 40, left: 40 };
loading: boolean;
data: any[];
constructor(public elementRef: ElementRef, public windowService: WindowService) {
this.loading = true;
}
ngOnInit() {
this.barChartEl = this.elementRef.nativeElement.querySelector('.bar-chart');
this.setup();
setTimeout(() => this.loading = false, 4000);
this.windowService.resize.subscribe(w => this.draw());
}
ngOnChanges(changes: SimpleChanges) {
if (!this.value || !this.svg) {
return;
}
this.data = this.value;
this.draw();
}
setup(): void {
this.width = this.barChartEl.clientWidth - this.margin.left - this.margin.right;
this.height = this.barChartEl.clientHeight - this.margin.top - this.margin.bottom;
this.svg = select(this.barChartEl).append('svg')
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom);
this.g = this.svg.append('g')
.attr('transform', `translate(${this.margin.left}, ${this.margin.top})`);
this.x = scaleBand().padding(0.05);
this.y = scaleLinear();
this.g.append('g')
.attr('class', 'axis axis--x');
this.g.append('g')
.attr('class', 'axis axis--y');
}
draw(): void {
this.x.domain(this.data.map((d: any) => d.code));
this.y.domain([0, max(this.data, (d: any) => d.count)]);
this.width = this.barChartEl.clientWidth - this.margin.left - this.margin.right;
this.height = this.barChartEl.clientHeight - this.margin.top - this.margin.bottom;
this.svg
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom);
this.x.rangeRound([0, this.width]);
this.y.rangeRound([this.height, 0]);
this.g.select('.axis--x')
.attr('transform', `translate(0, ${this.height})`)
.call(axisBottom(this.x));
this.g.select('.axis--y')
.call(axisLeft(this.y).tickSize(-this.width));
const bars = this.g.selectAll('.bar').data(this.data);
bars.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', (d: any) => d.code)
.attr('y', (d: any) => d.count)
.attr('width', this.x.bandwidth())
.attr('height', (d: any) => (this.height - this.y(d.count)) < 0 ? 0 : this.height - this.y(d.count));
bars.attr('x', (d: any) => this.x(d.code))
.attr('y', (d: any) => this.y(d.count))
.attr('width', this.x.bandwidth())
.attr('height', (d: any) => (this.height - this.y(d.count)) < 0 ? 0 : this.height - this.y(d.count));
bars.exit().remove();
}
}

View file

@ -0,0 +1,7 @@
<div class="line-chart" [class.is-hidden]="loading"></div>
<div class="loading-text" [class.is-hidden]="!loading">
<span>
<span>Loading, please wait...</span>
<img src="./assets/images/loader.svg" class="main-loader">
</span>
</div>

View file

@ -0,0 +1,162 @@
import { Component, Input, OnInit, ElementRef, OnChanges, SimpleChanges } from '@angular/core';
import { WindowService } from '../../services/window.service';
import {
range,
scaleTime,
scaleLinear,
min,
max,
curveLinear,
line,
easeLinear,
select,
axisLeft,
axisBottom,
timeSecond,
timeFormat
} from 'd3';
@Component({
selector: 'app-line-chart',
templateUrl: 'line-chart.component.html'
})
export class LineChartComponent implements OnChanges, OnInit {
@Input() value: { count: number, date: string };
lineChartEl: HTMLElement;
svg: any;
g: any;
line: any;
path: any;
x: any;
y: any;
data: number[];
now: Date;
duration: number;
limit: number;
options: any;
xAxis: any;
yAxis: any;
height: number;
width: number;
margin = { top: 40, right: 40, bottom: 60, left: 60 };
loading = true;
constructor(private elementRef: ElementRef, public windowService: WindowService) { }
ngOnInit() {
this.lineChartEl = this.elementRef.nativeElement.querySelector('.line-chart');
this.limit = 40;
this.duration = 3000;
this.now = new Date(Date.now() - this.duration);
this.options = {
title: '',
color: '#3A84C5'
};
this.render();
setTimeout(() => this.loading = false, 4000);
this.windowService.resize.subscribe(w => {
if (this.svg) {
const el = this.lineChartEl.querySelector('svg');
el.parentNode.removeChild(el);
this.render();
}
});
}
render() {
this.width = this.lineChartEl.clientWidth - this.margin.left - this.margin.right;
this.height = this.lineChartEl.clientHeight - this.margin.top - this.margin.bottom;
this.svg = select(this.lineChartEl).append('svg')
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', `translate(${this.margin.left}, ${this.margin.top})`);
if (!this.data) {
this.data = range(this.limit).map(i => 0);
}
this.x = scaleTime().range([0, this.width]);
this.y = scaleLinear().range([this.height, 0]);
this.x.domain([<any>this.now - (this.limit - 2), <any>this.now - this.duration]);
this.y.domain([0, max(this.data, (d: any) => d)]);
this.line = line()
.x((d: any, i: number) => this.x(<any>this.now - (this.limit - 1 - i) * this.duration))
.y((d: any) => this.y(d))
.curve(curveLinear);
this.svg.append('defs').append('clipPath')
.attr('id', 'clip')
.append('rect')
.attr('width', this.width)
.attr('height', this.height);
this.xAxis = this.svg.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0, ${this.height})`)
.call(axisBottom(this.x).tickSize(-this.height).ticks(timeSecond, 5).tickFormat(timeFormat('%H:%M:%S')));
this.yAxis = this.svg.append('g')
.attr('class', 'y axis')
.call(axisLeft(this.y).tickSize(-this.width));
this.path = this.svg.append('g')
.attr('clip-path', 'url(#clip)')
.append('path')
.data([this.data])
.attr('class', 'line');
}
ngOnChanges(changes: SimpleChanges) {
if (!this.value || !this.svg) {
return;
}
this.updateData(this.value.count);
}
updateData = (value: number) => {
this.data.push(value * 1000000);
this.now = new Date();
this.x.domain([<any>this.now - (this.limit - 2) * this.duration, <any>this.now - this.duration]);
const minv = min(this.data, (d: any) => d) > 0 ? min(this.data, (d: any) => d) - 4 : 0;
const maxv = max(this.data, (d: any) => d) + 4;
this.y.domain([minv, maxv]);
this.xAxis
.transition()
.duration(this.duration)
.ease(easeLinear)
.call(axisBottom(this.x).tickSize(-this.height).ticks(timeSecond, 5).tickFormat(timeFormat('%H:%M:%S')))
.selectAll('text')
.style('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.attr('transform', 'rotate(-65)');
this.yAxis
.transition()
.duration(500)
.ease(easeLinear)
.call(axisLeft(this.y).tickSize(-this.width));
this.path
.transition()
.duration(0)
.attr('d', this.line(this.data))
.attr('transform', null)
.transition()
.duration(this.duration)
.ease(easeLinear)
.attr('transform', `translate(${this.x(<any>this.now - (this.limit - 1) * this.duration)})`);
this.data.shift();
}
}