blob: e0210752f6c082c9c0425c53a8f755dd5948abb8 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Component, Input} from '@angular/core';
import * as d3 from 'd3';
import {TimeGraphComponent} from '@app/classes/components/graph/time-graph.component';
import {GraphScaleItem} from '@app/classes/graph';
@Component({
selector: 'time-histogram',
templateUrl: './time-histogram.component.html',
styleUrls: [
'../../classes/components/graph/graph.component.less', '../../classes/components/graph/time-graph.component.less',
'./time-histogram.component.less'
]
})
export class TimeHistogramComponent extends TimeGraphComponent {
constructor() {
super();
}
@Input()
columnWidth = {
second: 40,
minute: 30,
hour: 25,
day: 20,
base: 20
};
protected setYScaleDomain(data: GraphScaleItem[]): void {
const keys = Object.keys(this.labels);
const maxYValue = d3.max(data, item => keys.reduce((sum: number, key: string): number => sum + item[key], 0));
this.yScale.domain([0, maxYValue]);
}
protected populate(): void {
const keys = Object.keys(this.colors);
const data = this.data;
const timeStamps = Object.keys(data);
// we create a more consumable data structure for d3
const formattedData = timeStamps.map((timeStamp: string): GraphScaleItem => Object.assign({
tick: Number(timeStamp)
}, data[timeStamp]));
const layers = d3.stack().keys(keys)(formattedData);
// after we have the data we set the domain values both scales
this.setXScaleDomain(formattedData);
this.setYScaleDomain(formattedData);
// Setting the timegap label above the chart
this.setChartTimeGapByXScale();
const unitD3TimeProp = this.chartTimeGap.unit.charAt(0).toUpperCase() + this.chartTimeGap.unit.slice(1);
this.xScale.nice(d3[`time${unitD3TimeProp}`], 2);
const columnWidth = this.columnWidth[this.chartTimeGap.unit] || this.columnWidth.base;
// drawing the axis
this.drawXAxis();
this.drawYAxis();
// populate the data and drawing the bars
const layer = this.svg.selectAll().data(d3.transpose<any>(layers))
.enter().append('g')
.attr('class', 'value');
layer.selectAll().data(item => item).enter().append('rect')
.attr('x', item => this.xScale(item.data.tick) - columnWidth / 2)
.attr('y', item => this.yScale(item[1]))
.attr('height', item => this.yScale(item[0]) - this.yScale(item[1]))
.attr('width', columnWidth.toString())
.style('fill', (item, index) => this.orderedColors[index])
.on('mouseover', this.handleMouseOver)
.on('mousemove', this.handleMouseMove)
.on('mouseout', this.handleMouseOut);
this.setDragBehavior();
}
}