Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.component('chartThreshold', {
disabled: '<?'
kpiTargetMode: '<?'
kpiCreateLabel: '<?'
thresholdColor: '@'
onComplete: '&?'
controller: ($timeout, $log, ImpacKpisSvc, ImpacUtilities, toastr)->
ctrl = this
Expand All @@ -30,6 +31,7 @@ module.component('chartThreshold', {
ctrl.disabled ||= false
ctrl.kpiTargetMode ||= 'min'
ctrl.kpiCreateLabel ||= 'Get alerted when the target threshold goes below'
ctrl.thresholdColor ||= 'rgba(0, 0, 0, 0.7)'
# Get attachable kpi templates
ImpacKpisSvc.getAttachableKpis(ctrl.widget.endpoint).then(
(templates)->
Expand Down Expand Up @@ -74,17 +76,23 @@ module.component('chartThreshold', {
}]
return unless ImpacKpisSvc.validateKpiTargets(params.targets)
promise = if ctrl.isEditingKpi
ImpacKpisSvc.update(getKpi(), params, false)
ImpacKpisSvc.update(getKpi(), params, false).then(
(kpi)->
# Remove old threshold from chart
ctrl.chart.removeThreshold(kpi.id)
angular.extend(getKpi(), kpi)
)
else
params.metadata.hist_parameters = ctrl.widget.metadata.hist_parameters
params.widget_id = ctrl.widget.id
ImpacKpisSvc.create('impac', ctrl.kpi.endpoint, ctrl.kpi.watchables[0], params)
ImpacKpisSvc.create('impac', ctrl.kpi.endpoint, ctrl.kpi.watchables[0], params).then(
(kpi)->
ctrl.widget.kpis.push(kpi)
kpi
)
promise.then(
(kpi)->
ctrl.widget.kpis.push(kpi)
ctrl.onComplete($event: { kpi: kpi }) if _.isFunction(ctrl.onComplete)
(err)->
toastr.error('Failed to save KPI', 'Error')
).finally(->
ctrl.cancelCreateKpi()
)
Expand All @@ -97,6 +105,7 @@ module.component('chartThreshold', {
->
toastr.success("Deleted #{kpiDesc} KPI")
_.remove(ctrl.widget.kpis, (k)-> k.id == kpi.id)
ctrl.chart.removeThreshold(kpi.id)
ctrl.onComplete($event: {}) if _.isFunction(ctrl.onComplete)
->
toastr.error("Failed to delete #{kpiDesc} KPI", 'Error')
Expand All @@ -111,12 +120,12 @@ module.component('chartThreshold', {

onChartNotify = (chart)->
ctrl.chart = chart
validateHistParameters()
Highcharts.addEvent(chart.container, 'click', onChartClick)
thresholdSeries = _.filter(chart.series, (s) -> _.includes(s.name.toLowerCase(), 'threshold'))
_.each(thresholdSeries, (t)->
Highcharts.addEvent(t, 'click', (event)-> onThresholdClick(t))
)
return unless validateHistParameters()
Highcharts.addEvent(chart.hc.container, 'click', onChartClick)
_.each buildThresholdsFromKpis(), (threshold)->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice 👍

thresholdSerie = ctrl.chart.findThreshold(threshold.kpiId)
thresholdSerie = ctrl.chart.addThreshold(threshold) unless thresholdSerie?
ctrl.chart.addThresholdEvent(thresholdSerie, 'click', onThresholdClick)
return

onChartClick = (event)->
Expand Down Expand Up @@ -148,19 +157,25 @@ module.component('chartThreshold', {

shrinkChart = ->
return unless ctrl.chart
ctrl.chart.setSize(null, ctrl.chart.chartHeight - ctrl.chartShrinkSize, false)
ctrl.chart.container.parentElement.style.height = "#{ctrl.chart.chartHeight}px"
ctrl.chart.hc.setSize(null, ctrl.chart.hc.chartHeight - ctrl.chartShrinkSize, false)
ctrl.chart.hc.container.parentElement.style.height = "#{ctrl.chart.hc.chartHeight}px"

growChart = ->
return unless ctrl.chart
ctrl.chart.setSize(null, ctrl.chart.chartHeight + ctrl.chartShrinkSize, false)
ctrl.chart.container.parentElement.style.height = "#{ctrl.chart.chartHeight}px"
ctrl.chart.hc.setSize(null, ctrl.chart.hc.chartHeight + ctrl.chartShrinkSize, false)
ctrl.chart.hc.container.parentElement.style.height = "#{ctrl.chart.hc.chartHeight}px"

# Disable threshold when selected time period is strictly in the past
validateHistParameters = ->
widgetHistParams = ctrl.widget.metadata && ctrl.widget.metadata.hist_parameters
ctrl.disabled = widgetHistParams? && moment(widgetHistParams.to) <= moment.utc().startOf('day')
return
return !ctrl.disabled

# Validate and build threshold data from widget kpi templates
buildThresholdsFromKpis = ->
targets = ctrl.widget.kpis? && ctrl.widget.kpis[0] && ctrl.widget.kpis[0].targets
return [] unless ImpacKpisSvc.validateKpiTargets(targets)
[{ kpiId: ctrl.widget.kpis[0].id, value: targets.threshold[0].min, name: 'Alert Threshold', color: ctrl.thresholdColor }]

return ctrl
})
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ module.controller('WidgetAccountsCashProjectionCtrl', ($scope, $q, $filter, Impa
currency: w.metadata.currency
showToday: true
showLegend: true
thresholds: getThresholds()

$scope.chart ||= new HighchartsFactory($scope.chartId(), w.content.chart, options)
$scope.chart.render(w.content.chart, options)
Expand All @@ -131,7 +130,7 @@ module.controller('WidgetAccountsCashProjectionCtrl', ($scope, $q, $filter, Impa
$scope.chart.addCustomLegend(legendFormatter)
$scope.chart.addSeriesEvent('click', onClickBar)

$scope.chartDeferred.notify($scope.chart.hc)
$scope.chartDeferred.notify($scope.chart)

$scope.chartId = ->
"cashProjectionChart-#{w.id}"
Expand All @@ -147,11 +146,6 @@ module.controller('WidgetAccountsCashProjectionCtrl', ($scope, $q, $filter, Impa
getPeriod = ->
w.metadata? && w.metadata.hist_parameters? && w.metadata.hist_parameters.period || 'MONTHLY'

getThresholds = ->
targets = w.kpis? && w.kpis[0] && w.kpis[0].targets
return [] unless ImpacKpisSvc.validateKpiTargets(targets)
[{ kpiId: w.kpis[0].id, value: targets.threshold[0].min }]

# Widget is ready: can trigger the "wait for settings to be ready"
# --------------------------------------
$scope.widgetDeferred.resolve(settingsPromises)
Expand Down
54 changes: 26 additions & 28 deletions src/services/highcharts-factory/highcharts-factory.svc.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ angular
@hc = Highcharts.stockChart(@id, chartConfig)
else
@hc.update(chartConfig)
@addThresholds()
return @

template: ->
Expand Down Expand Up @@ -78,7 +77,7 @@ angular
xAxis:
plotLines: [{
color: _.get(@options, 'todayMarkerColor', 'rgba(0, 85, 255, 0.2)')
value: moment.utc().startOf('day').unix() * 1000
value: moment.utc().startOf('day').unix() * 1000
width: 1
label:
text: null
Expand All @@ -88,42 +87,41 @@ angular
y: -5
}]

addThresholds: (options = @options)->
addThreshold: (thresholdOptions)->
return if _.isEmpty(@hc)
# Remove existing thresholds
for s in @hc.series
s.remove() if s? && _.includes(s.name.toLowerCase(), 'threshold')
# Initialize data matrix
data = angular.copy @data.series[0].data
for vector in data
# When in the past, set y-axis value at null
if !thresholdOptions.fullLengthThresholds && moment.unix(vector[0] / 1000) < moment.utc().startOf('day')
vector[1] = null
# When in the future, set y-axis value at thresholdOptions.value
else
vector[1] = parseFloat(thresholdOptions.value)
# Build & add threshold serie
threshold = angular.extend(
{ data: data, showInLegend: false, marker: { enabled: false } },
thresholdOptions
)
@hc.addSeries(threshold)

return @hc if _.isEmpty(options.thresholds)
removeThreshold: (kpiId)->
thresholdSerie = @findThreshold(kpiId)
thresholdSerie.remove() if thresholdSerie?

for threshold in options.thresholds
# Initialize data matrix
data = angular.copy @data.series[0].data
for vector in data
# When in the past, set y-axis value at null
if !options.fullLengthThresholds && moment.unix(vector[0] / 1000) < moment.utc().startOf('day')
vector[1] = null
# When in the future, set y-axis value at threshold.value
else
vector[1] = parseFloat(threshold.value)
findThreshold: (kpiId)->
_.find(@hc.series, (s)-> s.options.kpiId == kpiId)

@hc.addSeries({
name: 'Threshold KPI'
kpiId: threshold.kpiId
data: data
color: _.get(options, 'thresholdsColor', 'rgba(255, 0, 0, 0.5)')
showInLegend: false
marker: { enabled: false }
}, true)

return @hc
addThresholdEvent: (thresholdSerie, eventName, callback)->
return unless thresholdSerie? && eventName? && _.isFunction(callback)
Highcharts.addEvent(thresholdSerie, eventName, (_event)-> callback(thresholdSerie))

# Extend default chart formatters to add custom legend img icon
addCustomLegend: (formatterCallback, useHTML = true) ->
@hc.legend.update({
useHTML: useHTML
labelFormatter: formatterCallback
}, true)
})

# Adds events to series objects
addSeriesEvent: (eventName, callback) ->
Expand Down