Skip to content
This repository has been archived by the owner on Mar 3, 2022. It is now read-only.

Feature/brush zoom implementation #240

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
547dae8
Merge pull request #239 from RADAR-CNS/develop
herkulano Aug 16, 2017
b273cb1
add initial brush zoom to graphs
mpgxvii Aug 16, 2017
0c47783
add initial brush zoom to graphs
mpgxvii Aug 16, 2017
540ffac
chore: udpate deps
herkulano Aug 17, 2017
c67e57a
fix: metareducer
herkulano Aug 17, 2017
c3d2bba
chore: update deps
herkulano Aug 18, 2017
c5c64cf
fix brush zoom implementation
mpgxvii Aug 21, 2017
2f15396
Merge branch 'feature/brush-zoom-implementation' of https://github.co…
mpgxvii Aug 21, 2017
d98f720
add show last day's data on load of graphs
mpgxvii Aug 22, 2017
6bf1f35
fix show last day's data of graphs
mpgxvii Aug 22, 2017
d8230f6
add mock aggregate messages for volume chart
mpgxvii Aug 22, 2017
f1dad1f
fix rxjs imports
mpgxvii Aug 22, 2017
20f9062
transfer html of source graphs component
mpgxvii Aug 22, 2017
d851432
fix imports
mpgxvii Aug 22, 2017
7e66dda
chore: update deps
herkulano Aug 22, 2017
1135f5f
chore: add rxjs linter
herkulano Aug 22, 2017
77e9cb4
remove rxjs import
herkulano Aug 22, 2017
59c42e9
chore: add --build-optimizer flag to build
herkulano Aug 22, 2017
8017108
Merge branch 'develop' into feature/brush-zoom-implementation
herkulano Aug 22, 2017
607798b
fix: import
herkulano Aug 22, 2017
187068f
fix zoom bug
mpgxvii Aug 23, 2017
b0399b6
fix zoom bug
mpgxvii Aug 23, 2017
bfb6841
Update package-lock.json
Aug 23, 2017
96b3f16
Merge branch 'develop' into feature/brush-zoom-implementation
herkulano Aug 23, 2017
27bea6e
update from develop
mpgxvii Aug 29, 2017
14b67af
Merge branch 'feature/brush-zoom-implementation' of https://github.co…
mpgxvii Aug 29, 2017
3addb83
fix conflicts
mpgxvii Sep 5, 2017
701de72
fix conflicts
mpgxvii Sep 5, 2017
74a65b1
fix data format in sensors store
mpgxvii Sep 5, 2017
ce156ba
fix sensors tooltip reducer
mpgxvii Sep 6, 2017
99e693e
fix merge
mpgxvii Sep 6, 2017
407d360
fix merge
mpgxvii Sep 6, 2017
5721ba9
add tooltip selector and data
mpgxvii Sep 6, 2017
459bc05
Merge branch 'feature/graph-tooltip-store' into feature/brush-zoom-im…
herkulano Sep 6, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@
"@angular/language-service": "^5.0.0-beta.6",
"@ngrx/store-devtools": "^4.0.0",
"@types/d3": "^4.10.0",
"@types/hammerjs": "^2.0.34",
"@types/jasmine": "^2.5.53",
"@types/hammerjs": "^2.0.35",
"@types/jasmine": "^2.5.54",
"@types/jasminewd2": "~2.0.2",
"@types/node": "^8.0.25",
"browserstack-local": "^1.3.0",
Expand Down Expand Up @@ -95,7 +95,7 @@
"tslint": "^5.7.0",
"tslint-config-standard": "^6.0.1",
"tslint-language-service": "^0.9.6",
"typescript": "^2.4.2"
"typescript": "^2.5.1"
},
"importSort": {
".js": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
@import '../../../../styles/common';
@import '../charts.common';

:host /deep/ {
.zoom {
cursor: move;
pointer-events: all;
fill: none;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { StoreModule } from '@ngrx/store'

import { reducers } from '../../../shared/store'
import {
MockTimeSeriesData,
parseMockTimeSeriesData
} from '../../../shared/testing/mocks/mock-timeseries-data'
MockTimeSeriesDataDates,
MockTimeSeriesDataValues
} from '../../../shared/testing/mocks/mock-timeseries-data2'
import { ChartBaseLineComponent } from './chart-base-line.component'

describe('ChartBaseLineComponent', () => {
Expand Down Expand Up @@ -47,7 +47,8 @@ describe('ChartBaseLineComponent', () => {
expect(component.chartData).toBeFalsy()

// with data // needs to be parsed //
component.chartData = parseMockTimeSeriesData(MockTimeSeriesData)
component.dates = MockTimeSeriesDataDates
component.chartData = MockTimeSeriesDataValues
expect(component.width).toBeGreaterThan(0)
expect(component.height).toBeGreaterThan(0)
})
Expand All @@ -60,7 +61,8 @@ describe('ChartBaseLineComponent', () => {
expect(inner.length).toEqual(0)

// with data // needs to be parsed //
component.chartData = parseMockTimeSeriesData(MockTimeSeriesData)
component.dates = MockTimeSeriesDataDates
component.chartData = MockTimeSeriesDataValues

// wait for transition
setTimeout(() => {
Expand All @@ -86,7 +88,9 @@ describe('ChartBaseLineComponent', () => {

it('linearGradient should have attributes "y1, y2" when data changes', () => {
// with data // needs to be parsed //
component.chartData = parseMockTimeSeriesData(MockTimeSeriesData)
component.dates = MockTimeSeriesDataDates
component.chartData = MockTimeSeriesDataValues

const gradient = de.nativeElement.querySelector(
'linearGradient#hr-gradient'
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Component, Input } from '@angular/core'
import * as d3 from 'd3'
import { lineChunked } from 'd3-line-chunked'

import { TimeSeries } from '../../../shared/models/time-series.model'
import { AppConfig } from '../../../shared/utils/config'
import { ChartBaseComponent } from '../chart-base/chart-base.component'

Expand All @@ -12,11 +11,13 @@ import { ChartBaseComponent } from '../chart-base/chart-base.component'
styleUrls: ['./chart-base-line.component.scss']
})
export class ChartBaseLineComponent extends ChartBaseComponent {
data: number[]
dates: Date[]

@Input() gradientEnabled = false
@Input() gradientColors = AppConfig.charts.GRADIENT_COLORS
@Input() gradientStops = AppConfig.charts.GRADIENT_STOPS

data: TimeSeries[]
svg: any
chart: any
width: number
Expand Down Expand Up @@ -49,28 +50,28 @@ export class ChartBaseLineComponent extends ChartBaseComponent {
.attr('stop-color', d => d.color)
}

this.lineEl = this.chart.append('path').attr('class', 'line')

this.lineEl = this.chart.append('g')
this.lineEl = this.chart.append('g').attr('clip-path', 'url(#clip)')

super.init()
}

draw() {
const data = this.data
const newData = this.dates.map(function(d, i) {
return { date: d, value: data[i] }
})

this.xScale = d3
.scaleTime()
.range([0, this.width])
.domain(d3.extent(this.data, d => d.date))
.domain(d3.extent(this.dates))

this.yScale = d3
.scaleLinear()
.range([this.height, 0])
.domain(d3.extent(this.data, d => d.value))

this.xAxis
.attr('transform', `translate(0, ${this.height})`)
.call(d3.axisBottom(this.xScale))
.domain(d3.extent(this.data))

this.xAxis.remove()
this.yAxis.call(d3.axisLeft(this.yScale).tickSize(-this.width))

// Add HR Gradient
Expand All @@ -86,6 +87,12 @@ export class ChartBaseLineComponent extends ChartBaseComponent {
.curve(d3.curveLinear)
.defined((d: any) => d.value)

this.lineEl.datum(this.data).call(this.lineChunked)
this.lineEl.selectAll('.main').remove()

this.lineEl
.append('g')
.datum(newData)
.call(this.lineChunked)
.attr('class', 'main')
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ describe('ChartBaseMultiLineComponent', () => {
expect(component.chartData).toBeFalsy()

// with data // needs to be parsed //
component.chartData = MockMultiTimeSeriesData
component.dates = MockMultiTimeSeriesData.dates
component.chartData = {
keys: MockMultiTimeSeriesData.keys,
values: MockMultiTimeSeriesData.values
}
expect(component.width).toBeGreaterThan(0)
expect(component.height).toBeGreaterThan(0)
})
Expand All @@ -63,8 +67,11 @@ describe('ChartBaseMultiLineComponent', () => {
})

// with data // needs to be parsed //
component.chartData = MockMultiTimeSeriesData

component.dates = MockMultiTimeSeriesData.dates
component.chartData = {
keys: MockMultiTimeSeriesData.keys,
values: MockMultiTimeSeriesData.values
}
// wait for transition
tick(500)
Object.getOwnPropertyNames(lineElements).forEach(prop => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,30 @@ export class ChartBaseMultiLineComponent extends ChartBaseComponent {
lines: any
line: any
newData: any
lineEl: any

init() {
this.lineEl = this.chart.append('g').attr('clip-path', 'url(#clip)')

super.init()
}

draw() {
const minDate = d3.min(this.data.dates)
const maxDate = d3.max(this.data.dates)
const dates = this.data.dates
const minDate = d3.min(this.dates)
const maxDate = d3.max(this.dates)
const dates = this.dates
const keys = this.data.keys.map(k => k.key)

this.xScale = d3
.scaleTime()
.range([0, this.width])
.domain([minDate, maxDate])

const minValue = d3.min(
this.data.keys.map(k => d3.min(this.data.values[k.key]))
const minValue = Number(
d3.min(this.data.keys.map(k => d3.min(this.data.values[k.key])))
)
const maxValue = d3.max(
this.data.keys.map(k => d3.max(this.data.values[k.key]))
const maxValue = Number(
d3.max(this.data.keys.map(k => d3.max(this.data.values[k.key])))
)

this.yScale = d3
Expand All @@ -61,9 +64,7 @@ export class ChartBaseMultiLineComponent extends ChartBaseComponent {
.domain(keys)
.range(this.lineColors)

this.xAxis
.attr('transform', `translate(0, ${this.height})`)
.call(d3.axisBottom(this.xScale))
this.xAxis.remove()

this.yAxis.call(d3.axisLeft(this.yScale).tickSize(-this.width))

Expand All @@ -74,7 +75,7 @@ export class ChartBaseMultiLineComponent extends ChartBaseComponent {
this.lineChunked = lineChunked()
.x(d => this.xScale(d.x))
.y(d => this.yScale(d.y))
.curve(d3.curveLinear)
.curve(d3.curveBasis)
.defined(function(d) {
return d.y != null
})
Expand All @@ -90,7 +91,14 @@ export class ChartBaseMultiLineComponent extends ChartBaseComponent {
})
)

this.lines = this.chart.selectAll('.line').data(this.newData)
this.lineEl.selectAll('.main').remove()

this.lineEl.append('g').attr('class', 'main')

this.lines = this.lineEl
.select('.main')
.selectAll('.line')
.data(this.newData)

this.line = this.lines.enter().append('g')

Expand Down
40 changes: 31 additions & 9 deletions src/app/components/charts/chart-base/chart-base.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ export class ChartBaseComponent implements AfterViewInit, OnDestroy {
@ViewChild('svg') svgRef: ElementRef

@Input() margin = AppConfig.charts.MARGIN
@Input() dates: Date[]
@Input() tooltipData

@Input()
get chartData() {
return this.data
Expand All @@ -49,17 +52,20 @@ export class ChartBaseComponent implements AfterViewInit, OnDestroy {
svg: any
chart: any
tooltip: any
tooltipInfo: any
width: number
height: number
xScale: any
yScale: any
xAxis: any
yAxis: any
window$: Subscription
clipPath: any
bisect: any

ngAfterViewInit() {
this.svg = d3.select(this.svgRef.nativeElement)

this.beforeInit()
}

Expand Down Expand Up @@ -88,18 +94,22 @@ export class ChartBaseComponent implements AfterViewInit, OnDestroy {
const chartTranslate = `translate(${this.margin.left}, ${this.margin.top})`

this.bisect = d3.bisector(function(d) {
return d['date']
return d
}).right

this.chart = this.svg
.append('g')
.attr('class', 'chart')
.attr('transform', chartTranslate)

this.tooltipInfo = d3.selectAll('#tooltip')

this.xAxis = this.chart.append('g').attr('class', 'axis axis--x')

this.yAxis = this.chart.append('g').attr('class', 'axis axis--y')

this.clipPath = this.chart.append('clipPath').attr('id', 'clip')

this.tooltip = this.svg
.append('g')
.attr('transform', chartTranslate)
Expand All @@ -113,15 +123,20 @@ export class ChartBaseComponent implements AfterViewInit, OnDestroy {
private tooltipMouseMove() {
if (!this.xScale) return

const dates = this.data.map(d => d.date)
const date =
dates[
this.bisect(
this.data,
this.xScale.invert(d3.mouse(this.tooltip.node())[0])
)
]
const date = this.dates[
this.bisect(
this.dates,
this.xScale.invert(d3.mouse(this.tooltip.node())[0])
)
]
this.onMove.emit(date)

let t = ''
const data = this.tooltipData.data
Object.keys(this.tooltipData.data).map(function(d) {
t = t + data[d].label['EN'] + ' : ' + data[d].value + '<br>'
})
this.tooltipInfo.html(date + '<br>' + t)
}

private beforeUpdate() {
Expand All @@ -141,6 +156,13 @@ export class ChartBaseComponent implements AfterViewInit, OnDestroy {
this.chart.attr('width', this.width).attr('height', this.height)
this.tooltip.attr('width', this.width).attr('height', this.height)

this.clipPath.selectAll('rect').remove()

this.clipPath
.append('rect')
.attr('width', this.width)
.attr('height', this.height)

this.draw()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@import '../../../../styles/common';
@import '../charts.common';

:host /deep/ {
margin-top: -5px;
margin-bottom: 10px;
height: 100%;

.zoom {
cursor: move;
pointer-events: all;
fill: none;
}

.area {
fill: $cl-base-80;
}

.brush {
fill: $cl-base-40;
}
}