Alexey Velikiy
6 years ago
committed by
GitHub
9 changed files with 6 additions and 462 deletions
@ -1,237 +0,0 @@
|
||||
import 'jquery'; |
||||
import _ from 'lodash'; |
||||
|
||||
export class ThresholdManager { |
||||
plot: any; |
||||
placeholder: any; |
||||
height: any; |
||||
thresholds: any; |
||||
needsCleanup: boolean; |
||||
hasSecondYAxis: any; |
||||
|
||||
constructor(private panelCtrl) {} |
||||
|
||||
getHandleHtml(handleIndex, model, valueStr) { |
||||
var stateClass = model.colorMode; |
||||
if (model.colorMode === 'custom') { |
||||
stateClass = 'critical'; |
||||
} |
||||
|
||||
return ` |
||||
<div class="alert-handle-wrapper alert-handle-wrapper--T${handleIndex}"> |
||||
<div class="alert-handle-line alert-handle-line--${stateClass}"> |
||||
</div> |
||||
<div class="alert-handle" data-handle-index="${handleIndex}"> |
||||
<i class="icon-gf icon-gf-${stateClass} alert-state-${stateClass}"></i> |
||||
<span class="alert-handle-value">${valueStr}<i class="alert-handle-grip"></i></span> |
||||
</div> |
||||
</div>`;
|
||||
} |
||||
|
||||
initDragging(evt) { |
||||
var handleElem = $(evt.currentTarget).parents('.alert-handle-wrapper'); |
||||
var handleIndex = $(evt.currentTarget).data('handleIndex'); |
||||
|
||||
var lastY = null; |
||||
var posTop; |
||||
var plot = this.plot; |
||||
var panelCtrl = this.panelCtrl; |
||||
var model = this.thresholds[handleIndex]; |
||||
|
||||
function dragging(evt) { |
||||
if (lastY === null) { |
||||
lastY = evt.clientY; |
||||
} else { |
||||
var diff = evt.clientY - lastY; |
||||
posTop = posTop + diff; |
||||
lastY = evt.clientY; |
||||
handleElem.css({ top: posTop + diff }); |
||||
} |
||||
} |
||||
|
||||
function stopped() { |
||||
// calculate graph level
|
||||
var graphValue = plot.c2p({ left: 0, top: posTop }).y; |
||||
graphValue = parseInt(graphValue.toFixed(0)); |
||||
model.value = graphValue; |
||||
|
||||
handleElem.off('mousemove', dragging); |
||||
handleElem.off('mouseup', dragging); |
||||
handleElem.off('mouseleave', dragging); |
||||
|
||||
// trigger digest and render
|
||||
panelCtrl.$scope.$apply(function() { |
||||
panelCtrl.render(); |
||||
panelCtrl.events.emit('threshold-changed', { |
||||
threshold: model, |
||||
handleIndex: handleIndex, |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
lastY = null; |
||||
posTop = handleElem.position().top; |
||||
|
||||
handleElem.on('mousemove', dragging); |
||||
handleElem.on('mouseup', stopped); |
||||
handleElem.on('mouseleave', stopped); |
||||
} |
||||
|
||||
cleanUp() { |
||||
this.placeholder.find('.alert-handle-wrapper').remove(); |
||||
this.needsCleanup = false; |
||||
} |
||||
|
||||
renderHandle(handleIndex, defaultHandleTopPos) { |
||||
var model = this.thresholds[handleIndex]; |
||||
var value = model.value; |
||||
var valueStr = value; |
||||
var handleTopPos = 0; |
||||
|
||||
// handle no value
|
||||
if (!_.isNumber(value)) { |
||||
valueStr = ''; |
||||
handleTopPos = defaultHandleTopPos; |
||||
} else { |
||||
var valueCanvasPos = this.plot.p2c({ x: 0, y: value }); |
||||
handleTopPos = Math.round(Math.min(Math.max(valueCanvasPos.top, 0), this.height) - 6); |
||||
} |
||||
|
||||
var handleElem = $(this.getHandleHtml(handleIndex, model, valueStr)); |
||||
this.placeholder.append(handleElem); |
||||
|
||||
handleElem.toggleClass('alert-handle-wrapper--no-value', valueStr === ''); |
||||
handleElem.css({ top: handleTopPos }); |
||||
} |
||||
|
||||
shouldDrawHandles() { |
||||
return !this.hasSecondYAxis && this.panelCtrl.editingThresholds && this.panelCtrl.panel.thresholds.length > 0; |
||||
} |
||||
|
||||
prepare(elem, data) { |
||||
this.hasSecondYAxis = false; |
||||
for (var i = 0; i < data.length; i++) { |
||||
if (data[i].yaxis > 1) { |
||||
this.hasSecondYAxis = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (this.shouldDrawHandles()) { |
||||
var thresholdMargin = this.panelCtrl.panel.thresholds.length > 1 ? '220px' : '110px'; |
||||
elem.css('margin-right', thresholdMargin); |
||||
} else if (this.needsCleanup) { |
||||
elem.css('margin-right', '0'); |
||||
} |
||||
} |
||||
|
||||
draw(plot) { |
||||
this.thresholds = this.panelCtrl.panel.thresholds; |
||||
this.plot = plot; |
||||
this.placeholder = plot.getPlaceholder(); |
||||
|
||||
if (this.needsCleanup) { |
||||
this.cleanUp(); |
||||
} |
||||
|
||||
if (!this.shouldDrawHandles()) { |
||||
return; |
||||
} |
||||
|
||||
this.height = plot.height(); |
||||
|
||||
if (this.thresholds.length > 0) { |
||||
this.renderHandle(0, 10); |
||||
} |
||||
if (this.thresholds.length > 1) { |
||||
this.renderHandle(1, this.height - 30); |
||||
} |
||||
|
||||
this.placeholder.off('mousedown', '.alert-handle'); |
||||
this.placeholder.on('mousedown', '.alert-handle', this.initDragging.bind(this)); |
||||
this.needsCleanup = true; |
||||
} |
||||
|
||||
addFlotOptions(options, panel) { |
||||
if (!panel.thresholds || panel.thresholds.length === 0) { |
||||
return; |
||||
} |
||||
|
||||
var gtLimit = Infinity; |
||||
var ltLimit = -Infinity; |
||||
var i, threshold, other; |
||||
|
||||
for (i = 0; i < panel.thresholds.length; i++) { |
||||
threshold = panel.thresholds[i]; |
||||
if (!_.isNumber(threshold.value)) { |
||||
continue; |
||||
} |
||||
|
||||
var limit; |
||||
switch (threshold.op) { |
||||
case 'gt': { |
||||
limit = gtLimit; |
||||
// if next threshold is less then op and greater value, then use that as limit
|
||||
if (panel.thresholds.length > i + 1) { |
||||
other = panel.thresholds[i + 1]; |
||||
if (other.value > threshold.value) { |
||||
limit = other.value; |
||||
ltLimit = limit; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
case 'lt': { |
||||
limit = ltLimit; |
||||
// if next threshold is less then op and greater value, then use that as limit
|
||||
if (panel.thresholds.length > i + 1) { |
||||
other = panel.thresholds[i + 1]; |
||||
if (other.value < threshold.value) { |
||||
limit = other.value; |
||||
gtLimit = limit; |
||||
} |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
|
||||
var fillColor, lineColor; |
||||
switch (threshold.colorMode) { |
||||
case 'critical': { |
||||
fillColor = 'rgba(234, 112, 112, 0.12)'; |
||||
lineColor = 'rgba(237, 46, 24, 0.60)'; |
||||
break; |
||||
} |
||||
case 'warning': { |
||||
fillColor = 'rgba(235, 138, 14, 0.12)'; |
||||
lineColor = 'rgba(247, 149, 32, 0.60)'; |
||||
break; |
||||
} |
||||
case 'ok': { |
||||
fillColor = 'rgba(11, 237, 50, 0.090)'; |
||||
lineColor = 'rgba(6,163,69, 0.60)'; |
||||
break; |
||||
} |
||||
case 'custom': { |
||||
fillColor = threshold.fillColor; |
||||
lineColor = threshold.lineColor; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// fill
|
||||
if (threshold.fill) { |
||||
options.grid.markings.push({ |
||||
yaxis: { from: threshold.value, to: limit }, |
||||
color: fillColor, |
||||
}); |
||||
} |
||||
if (threshold.line) { |
||||
options.grid.markings.push({ |
||||
yaxis: { from: threshold.value, to: threshold.value }, |
||||
color: lineColor, |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,142 +0,0 @@
|
||||
|
||||
import coreModule from 'grafana/app/core/core_module'; |
||||
|
||||
export class ThresholdFormCtrl { |
||||
panelCtrl: any; |
||||
panel: any; |
||||
disabled: boolean; |
||||
|
||||
/** @ngInject */ |
||||
constructor($scope) { |
||||
this.panel = this.panelCtrl.panel; |
||||
|
||||
if (this.panel.alert) { |
||||
this.disabled = true; |
||||
} |
||||
|
||||
var unbindDestroy = $scope.$on('$destroy', () => { |
||||
this.panelCtrl.editingThresholds = false; |
||||
this.panelCtrl.render(); |
||||
unbindDestroy(); |
||||
}); |
||||
|
||||
this.panelCtrl.editingThresholds = true; |
||||
} |
||||
|
||||
addThreshold() { |
||||
this.panel.thresholds.push({ |
||||
value: undefined, |
||||
colorMode: 'critical', |
||||
op: 'gt', |
||||
fill: true, |
||||
line: true, |
||||
}); |
||||
this.panelCtrl.render(); |
||||
} |
||||
|
||||
removeThreshold(index) { |
||||
this.panel.thresholds.splice(index, 1); |
||||
this.panelCtrl.render(); |
||||
} |
||||
|
||||
render() { |
||||
this.panelCtrl.render(); |
||||
} |
||||
|
||||
onFillColorChange(index) { |
||||
return newColor => { |
||||
this.panel.thresholds[index].fillColor = newColor; |
||||
this.render(); |
||||
}; |
||||
} |
||||
|
||||
onLineColorChange(index) { |
||||
return newColor => { |
||||
this.panel.thresholds[index].lineColor = newColor; |
||||
this.render(); |
||||
}; |
||||
} |
||||
} |
||||
|
||||
var template = ` |
||||
<div class="gf-form-group"> |
||||
<h5>Thresholds</h5> |
||||
<p class="muted" ng-show="ctrl.disabled"> |
||||
Visual thresholds options <strong>disabled.</strong> |
||||
Visit the Alert tab update your thresholds. <br> |
||||
To re-enable thresholds, the alert rule must be deleted from this panel. |
||||
</p> |
||||
<div ng-class="{'thresholds-form-disabled': ctrl.disabled}"> |
||||
<div class="gf-form-inline" ng-repeat="threshold in ctrl.panel.thresholds"> |
||||
<div class="gf-form"> |
||||
<label class="gf-form-label">T{{$index+1}}</label> |
||||
</div> |
||||
|
||||
<div class="gf-form"> |
||||
<div class="gf-form-select-wrapper"> |
||||
<select class="gf-form-input" ng-model="threshold.op" |
||||
ng-options="f for f in ['gt', 'lt']" ng-change="ctrl.render()" ng-disabled="ctrl.disabled"></select> |
||||
</div> |
||||
<input type="number" ng-model="threshold.value" class="gf-form-input width-8" |
||||
ng-change="ctrl.render()" placeholder="value" ng-disabled="ctrl.disabled"> |
||||
</div> |
||||
|
||||
<div class="gf-form"> |
||||
<label class="gf-form-label">Color</label> |
||||
<div class="gf-form-select-wrapper"> |
||||
<select class="gf-form-input" ng-model="threshold.colorMode" |
||||
ng-options="f for f in ['custom', 'critical', 'warning', 'ok']" ng-change="ctrl.render()" ng-disabled="ctrl.disabled"> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
|
||||
<gf-form-switch class="gf-form" label="Fill" checked="threshold.fill" |
||||
on-change="ctrl.render()" ng-disabled="ctrl.disabled"></gf-form-switch> |
||||
|
||||
<div class="gf-form" ng-if="threshold.fill && threshold.colorMode === 'custom'"> |
||||
<label class="gf-form-label">Fill color</label> |
||||
<span class="gf-form-label"> |
||||
<color-picker color="threshold.fillColor" onChange="ctrl.onFillColorChange($index)"></color-picker> |
||||
</span> |
||||
</div> |
||||
|
||||
<gf-form-switch class="gf-form" label="Line" checked="threshold.line" |
||||
on-change="ctrl.render()" ng-disabled="ctrl.disabled"></gf-form-switch> |
||||
|
||||
<div class="gf-form" ng-if="threshold.line && threshold.colorMode === 'custom'"> |
||||
<label class="gf-form-label">Line color</label> |
||||
<span class="gf-form-label"> |
||||
<color-picker color="threshold.lineColor" onChange="ctrl.onLineColorChange($index)"></color-picker> |
||||
</span> |
||||
</div> |
||||
|
||||
<div class="gf-form"> |
||||
<label class="gf-form-label"> |
||||
<a class="pointer" ng-click="ctrl.removeThreshold($index)" ng-disabled="ctrl.disabled"> |
||||
<i class="fa fa-trash"></i> |
||||
</a> |
||||
</label> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="gf-form-button-row"> |
||||
<button class="btn btn-inverse" ng-click="ctrl.addThreshold()" ng-disabled="ctrl.disabled"> |
||||
<i class="fa fa-plus"></i> Add Threshold |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
`;
|
||||
|
||||
coreModule.directive('hasticGraphThresholdForm', function() { |
||||
return { |
||||
restrict: 'E', |
||||
template: template, |
||||
controller: ThresholdFormCtrl, |
||||
bindToController: true, |
||||
controllerAs: 'ctrl', |
||||
scope: { |
||||
panelCtrl: '=', |
||||
}, |
||||
}; |
||||
}); |
Loading…
Reference in new issue