diff --git a/dist/annotations.js b/dist/annotations.js new file mode 100644 index 0000000..e3c901c --- /dev/null +++ b/dist/annotations.js @@ -0,0 +1,183 @@ +'use strict'; + +System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_export, _context) { + "use strict"; + + var d3, $, _, kbn, _createClass, TOOLTIP_PADDING_X, TOOLTIP_PADDING_Y, AnnotationTooltip; + + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + return { + setters: [function (_d) { + d3 = _d.default; + }, function (_jquery) { + $ = _jquery.default; + }, function (_lodash) { + _ = _lodash.default; + }, function (_appCoreUtilsKbn) { + kbn = _appCoreUtilsKbn.default; + }], + execute: function () { + _createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + TOOLTIP_PADDING_X = 30; + TOOLTIP_PADDING_Y = 10; + + _export('AnnotationTooltip', AnnotationTooltip = function () { + function AnnotationTooltip(elem, scope) { + _classCallCheck(this, AnnotationTooltip); + + this.scope = scope; + this.dashboard = scope.ctrl.dashboard; + this.panelCtrl = scope.ctrl; + this.panel = scope.ctrl.panel; + this.mouseOverAnnotationTick = false; + + elem.on("mouseover", this.onMouseOver.bind(this)); + elem.on("mouseleave", this.onMouseLeave.bind(this)); + } + + _createClass(AnnotationTooltip, [{ + key: 'onMouseOver', + value: function onMouseOver(e) { + if (!this.panel.tooltip.show || !this.scope.ctrl.data || _.isEmpty(this.scope.ctrl.data)) { + return; + } + + if (!this.tooltip) { + this.add(); + this.move(e); + } + } + }, { + key: 'onMouseLeave', + value: function onMouseLeave() { + this.destroy(); + } + }, { + key: 'onMouseMove', + value: function onMouseMove(e) { + if (!this.panel.tooltip.show) { + return; + } + + this.move(e); + } + }, { + key: 'add', + value: function add() { + this.tooltipBase = d3.select("body").append("div").attr("class", "statusmap-annotation-tooltip drop drop-popover drop-popover--annotation drop-element drop-enabled drop-target-attached-center drop-open drop-open-transitionend drop-after-open").style("position", "absolute"); + this.tooltip = this.tooltipBase.append("div").attr("class", "drop-content").append("div").append("annotation-tooltip").append("div").attr("class", "graph-annotation"); + } + }, { + key: 'destroy', + value: function destroy() { + if (this.tooltip) { + this.tooltip.remove(); + } + + this.tooltip = null; + + if (this.tooltipBase) { + this.tooltipBase.remove(); + } + + this.tooltipBase = null; + } + }, { + key: 'show', + value: function show(pos) { + if (!this.panel.tooltip.show || !this.tooltip) { + return; + } + // shared tooltip mode + //if (pos.panelRelY) { + // return; + //} + + var annoId = d3.select(pos.target).attr('annoId'); + if (!annoId) { + this.destroy(); + return; + } + + var anno = this.panelCtrl.annotations[annoId]; + if (!anno) { + this.destroy(); + return; + } + + var annoTitle = ""; + + var tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss'; + var annoTime = this.dashboard.formatDate(anno.time, tooltipTimeFormat); + var annoText = anno.text; + var annoTags = []; + if (anno.tags) { + annoTags = _.map(anno.tags, function (t) { + return { "text": t, "backColor": "rgb(63, 43, 91)", "borderColor": "rgb(101, 81, 129)" }; + }); + } + + var tooltipHtml = '
\n ' + annoTitle + '\n ' + annoTime + '
\n
\n
' + annoText + '
\n ' + _.join(_.map(annoTags, function (t) { + return '' + t.text + ''; + }), "") + '\n
\n
'; + + this.tooltip.html(tooltipHtml); + + this.move(pos); + } + }, { + key: 'move', + value: function move(pos) { + if (!this.tooltipBase) { + return; + } + + var elem = $(this.tooltipBase.node())[0]; + var tooltipWidth = elem.clientWidth; + var tooltipHeight = elem.clientHeight; + + var left = pos.pageX - tooltipWidth / 2; + var top = pos.pageY + TOOLTIP_PADDING_Y; + + if (pos.pageX + tooltipWidth / 2 + 10 > window.innerWidth) { + left = pos.pageX - tooltipWidth - TOOLTIP_PADDING_X; + } + + if (pos.pageY - window.pageYOffset + tooltipHeight + 20 > window.innerHeight) { + top = pos.pageY - tooltipHeight - TOOLTIP_PADDING_Y; + } + + return this.tooltipBase.style("left", left + "px").style("top", top + "px"); + } + }]); + + return AnnotationTooltip; + }()); + + _export('AnnotationTooltip', AnnotationTooltip); + } + }; +}); +//# sourceMappingURL=annotations.js.map diff --git a/dist/annotations.js.map b/dist/annotations.js.map new file mode 100644 index 0000000..5c1d106 --- /dev/null +++ b/dist/annotations.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/annotations.js"],"names":["d3","$","_","kbn","TOOLTIP_PADDING_X","TOOLTIP_PADDING_Y","AnnotationTooltip","elem","scope","dashboard","ctrl","panelCtrl","panel","mouseOverAnnotationTick","on","onMouseOver","bind","onMouseLeave","e","tooltip","show","data","isEmpty","add","move","destroy","tooltipBase","select","append","attr","style","remove","pos","annoId","target","anno","annotations","annoTitle","tooltipTimeFormat","annoTime","formatDate","time","annoText","text","annoTags","tags","map","t","tooltipHtml","join","backColor","borderColor","html","node","tooltipWidth","clientWidth","tooltipHeight","clientHeight","left","pageX","top","pageY","window","innerWidth","pageYOffset","innerHeight"],"mappings":"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","file":"annotations.js","sourcesContent":["import d3 from 'd3';\nimport $ from 'jquery';\nimport _ from 'lodash';\nimport kbn from 'app/core/utils/kbn';\n\nlet TOOLTIP_PADDING_X = 30;\nlet TOOLTIP_PADDING_Y = 10;\n\nexport class AnnotationTooltip {\n constructor(elem, scope) {\n this.scope = scope;\n this.dashboard = scope.ctrl.dashboard;\n this.panelCtrl = scope.ctrl;\n this.panel = scope.ctrl.panel;\n this.mouseOverAnnotationTick = false;\n\n elem.on(\"mouseover\", this.onMouseOver.bind(this));\n elem.on(\"mouseleave\", this.onMouseLeave.bind(this));\n }\n\n onMouseOver(e) {\n if (!this.panel.tooltip.show || !this.scope.ctrl.data || _.isEmpty(this.scope.ctrl.data)) { return; }\n\n if (!this.tooltip) {\n this.add();\n this.move(e);\n }\n }\n\n onMouseLeave() {\n this.destroy();\n }\n\n onMouseMove(e) {\n if (!this.panel.tooltip.show) { return; }\n\n this.move(e);\n }\n\n add() {\n this.tooltipBase = d3.select(\"body\")\n .append(\"div\")\n .attr(\"class\", \"statusmap-annotation-tooltip drop drop-popover drop-popover--annotation drop-element drop-enabled drop-target-attached-center drop-open drop-open-transitionend drop-after-open\")\n .style(\"position\", \"absolute\")\n this.tooltip = this.tooltipBase\n .append(\"div\")\n .attr(\"class\", \"drop-content\")\n .append(\"div\")\n .append(\"annotation-tooltip\")\n .append(\"div\")\n .attr(\"class\", \"graph-annotation\");\n }\n\n destroy() {\n if (this.tooltip) {\n this.tooltip.remove();\n }\n\n this.tooltip = null;\n\n if (this.tooltipBase) {\n this.tooltipBase.remove();\n }\n\n this.tooltipBase = null;\n\n }\n\n show(pos) {\n if (!this.panel.tooltip.show || !this.tooltip) { return; }\n // shared tooltip mode\n //if (pos.panelRelY) {\n // return;\n //}\n\n let annoId = d3.select(pos.target).attr('annoId');\n if (!annoId) {\n this.destroy();\n return;\n }\n\n let anno = this.panelCtrl.annotations[annoId];\n if (!anno) {\n this.destroy();\n return;\n }\n\n let annoTitle = \"\";\n\n let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss';\n let annoTime = this.dashboard.formatDate(anno.time, tooltipTimeFormat);\n let annoText = anno.text;\n let annoTags = [];\n if (anno.tags) {\n annoTags = _.map(anno.tags, t => ({\"text\": t, \"backColor\": \"rgb(63, 43, 91)\", \"borderColor\":\"rgb(101, 81, 129)\"}))\n }\n\n let tooltipHtml = `
\n ${annoTitle}\n ${annoTime}
\n
\n
${annoText}
\n ${_.join(_.map(annoTags, t => `${t.text}`), \"\")}\n
\n
`;\n\n this.tooltip.html(tooltipHtml);\n\n this.move(pos);\n }\n\n move(pos) {\n if (!this.tooltipBase) { return; }\n\n let elem = $(this.tooltipBase.node())[0];\n let tooltipWidth = elem.clientWidth;\n let tooltipHeight = elem.clientHeight;\n\n let left = pos.pageX - tooltipWidth/2;\n let top = pos.pageY + TOOLTIP_PADDING_Y;\n\n if (pos.pageX + tooltipWidth/2 + 10 > window.innerWidth) {\n left = pos.pageX - tooltipWidth - TOOLTIP_PADDING_X;\n }\n\n if (pos.pageY - window.pageYOffset + tooltipHeight + 20 > window.innerHeight) {\n top = pos.pageY - tooltipHeight - TOOLTIP_PADDING_Y;\n }\n\n return this.tooltipBase\n .style(\"left\", left + \"px\")\n .style(\"top\", top + \"px\");\n }\n}\n"]} \ No newline at end of file diff --git a/dist/rendering.js b/dist/rendering.js index 193d049..882b57c 100644 --- a/dist/rendering.js +++ b/dist/rendering.js @@ -1,9 +1,9 @@ 'use strict'; -System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/core', 'app/core/utils/ticks', 'd3', './libs/d3-scale-chromatic/index', './tooltip'], function (_export, _context) { +System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/core', 'app/core/utils/ticks', 'd3', './libs/d3-scale-chromatic/index', './tooltip', './annotations'], function (_export, _context) { "use strict"; - var _, $, moment, kbn, appEvents, contextSrv, tickStep, getScaledDecimals, getFlotTickSize, d3, d3ScaleChromatic, StatusHeatmapTooltip, MIN_CARD_SIZE, CARD_H_SPACING, CARD_V_SPACING, CARD_ROUND, DATA_RANGE_WIDING_FACTOR, DEFAULT_X_TICK_SIZE_PX, DEFAULT_Y_TICK_SIZE_PX, X_AXIS_TICK_PADDING, Y_AXIS_TICK_PADDING, MIN_SELECTION_WIDTH; + var _, $, moment, kbn, appEvents, contextSrv, tickStep, getScaledDecimals, getFlotTickSize, d3, d3ScaleChromatic, StatusHeatmapTooltip, AnnotationTooltip, MIN_CARD_SIZE, CARD_H_SPACING, CARD_V_SPACING, CARD_ROUND, DATA_RANGE_WIDING_FACTOR, DEFAULT_X_TICK_SIZE_PX, DEFAULT_Y_TICK_SIZE_PX, X_AXIS_TICK_PADDING, Y_AXIS_TICK_PADDING, MIN_SELECTION_WIDTH; function link(scope, elem, attrs, ctrl) { var data = void 0, @@ -15,6 +15,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c // $heatmap is JQuery object, but heatmap is D3 var $heatmap = elem.find('.status-heatmap-panel'); var tooltip = new StatusHeatmapTooltip($heatmap, scope); + var annotationTooltip = new AnnotationTooltip($heatmap, scope); var width = void 0, height = void 0, @@ -78,7 +79,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c return text.getBBox().width; })); - return max_text_width; + return Math.ceil(max_text_width); } function getXAxisHeight(elem) { @@ -289,6 +290,8 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c resetCardHighLight(event); }); + _renderAnnotations(); + ctrl.events.emit('render-complete', { "chartWidth": chartWidth }); @@ -475,6 +478,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c function onMouseLeave() { appEvents.emit('graph-hover-clear'); clearCrosshair(); + //annotationTooltip.destroy(); } function onMouseMove(event) { @@ -486,6 +490,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c // Clear crosshair and tooltip clearCrosshair(); tooltip.destroy(); + annotationTooltip.destroy(); selection.x2 = limitSelection(event.offsetX); drawSelection(selection.x1, selection.x2); @@ -493,6 +498,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c emitGraphHoverEvet(event); drawCrosshair(event.offsetX); tooltip.show(event); //, data); + annotationTooltip.show(event); } } @@ -595,6 +601,49 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c $heatmap.on("mousedown", onMouseDown); $heatmap.on("mousemove", onMouseMove); $heatmap.on("mouseleave", onMouseLeave); + + function _renderAnnotations() { + if (!ctrl.annotations || ctrl.annotations.length == 0) { + return; + } + + if (!heatmap) { + return; + } + + var annoData = _.map(ctrl.annotations, function (d, i) { + return { "x": Math.floor(yAxisWidth + xScale(d.time)), "id": i, "anno": d.source }; + }); + + var anno = heatmap.append("g").attr("class", "statusmap-annotations").attr("transform", "translate(0.5,0)").selectAll(".statusmap-annotations").data(annoData).enter().append("g"); + anno.append("line") + //.attr("class", "statusmap-annotation-tick") + .attr("x1", function (d) { + return d.x; + }).attr("y1", chartTop).attr("x2", function (d) { + return d.x; + }).attr("y2", chartBottom).style("stroke", function (d) { + return d.anno.iconColor; + }).style("stroke-width", 1).style("stroke-dasharray", "3,3"); + anno.append("polygon").attr("points", function (d) { + return [[d.x, chartBottom + 1], [d.x - 5, chartBottom + 6], [d.x + 5, chartBottom + 6]].join(" "); + }).style("stroke-width", 0).style("fill", function (d) { + return d.anno.iconColor; + }); + // Polygons didn't fire mouseevents + anno.append("rect").attr("x", function (d) { + return d.x - 5; + }).attr("width", 10).attr("y", chartBottom + 1).attr("height", 5).attr("class", "statusmap-annotation-tick").attr("annoId", function (d) { + return d.id; + }).style("opacity", 0); + + var $ticks = $heatmap.find(".statusmap-annotation-tick"); + $ticks.on("mouseenter", function (event) { + annotationTooltip.mouseOverAnnotationTick = true; + }).on("mouseleave", function (event) { + annotationTooltip.mouseOverAnnotationTick = false; + }); + } } _export('default', link); @@ -645,6 +694,8 @@ System.register(['lodash', 'jquery', 'moment', 'app/core/utils/kbn', 'app/core/c d3ScaleChromatic = _libsD3ScaleChromaticIndex; }, function (_tooltip) { StatusHeatmapTooltip = _tooltip.StatusHeatmapTooltip; + }, function (_annotations) { + AnnotationTooltip = _annotations.AnnotationTooltip; }], execute: function () { MIN_CARD_SIZE = 5; diff --git a/dist/rendering.js.map b/dist/rendering.js.map index 77341f3..4b57532 100644 --- a/dist/rendering.js.map +++ b/dist/rendering.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/rendering.js"],"names":["link","scope","elem","attrs","ctrl","data","cardsData","timeRange","panel","heatmap","$heatmap","find","tooltip","StatusHeatmapTooltip","width","height","yScale","xScale","chartWidth","chartHeight","chartTop","chartBottom","yAxisWidth","xAxisHeight","cardVSpacing","cardHSpacing","cardRound","cardWidth","cardHeight","colorScale","opacityScale","mouseUpHandler","xGridSize","yGridSize","yOffset","selection","active","x1","x2","padding","left","right","top","bottom","margin","dataRangeWidingFactor","DATA_RANGE_WIDING_FACTOR","events","on","render","setElementHeight","row","_","isString","parseInt","replace","legend","show","css","e","getYAxisWidth","axis_text","selectAll","nodes","max_text_width","max","map","text","getBBox","getXAxisHeight","axis_line","select","empty","axis_line_position","parseFloat","attr","canvas_width","addXAxis","d3","scaleTime","domain","from","to","range","ticks","DEFAULT_X_TICK_SIZE_PX","grafanaTimeFormatter","grafanaTimeFormat","timeFormat","dashboardTimeZone","dashboard","getTimezone","utcFormat","xAxis","axisBottom","tickFormat","tickPadding","X_AXIS_TICK_PADDING","tickSize","posY","posX","append","call","remove","getYScale","step","length","push","i","scaleOrdinal","getYAxisScale","addYAxis","uniq","d","target","isEmpty","yAxisSort","sort","a","b","localeCompare","ignorePunctuation","numeric","yAxisScale","yAxis","axisLeft","tickValues","tickSizeInner","Y_AXIS_TICK_PADDING","wideYAxisRange","min","tickInterval","y_widing","y_min","y_max","Math","ceil","floor","tickValueFormatter","decimals","scaledDecimals","format","value","kbn","valueFormats","addHeatmapCanvas","heatmap_elem","cards","CARD_H_SPACING","CARD_V_SPACING","CARD_ROUND","yBucketSize","xBucketSize","style","addHeatmap","maxValue","color","minValue","mode","getColorScale","setOpacityScale","enter","c","id","getCardX","getCardWidth","getCardY","getCardHeight","getCardColor","getCardOpacity","$cards","event","mouseOverBucket","highlightCard","resetCardHighLight","emit","highlightColor","darker","strokeColor","brighter","current_card","originalFillColor","colorScheme","colorSchemes","colorInterpolator","d3ScaleChromatic","colorScaleInverted","invert","contextSrv","user","lightTheme","start","end","scaleSequential","scaleLinear","scalePow","exponent","x","cx","w","cutted_width","MIN_CARD_SIZE","y","ys","h","cardColor","discreteHelper","getBucketColor","values","nullPointMode","getCardStrokeWidth","appEvents","drawSharedCrosshair","pos","clearCrosshair","onMouseDown","offsetX","onMouseUp","$","document","one","unbind","selectionRange","abs","MIN_SELECTION_WIDTH","timeFrom","timeTo","timeSrv","setTime","moment","utc","clearSelection","onMouseLeave","onMouseMove","destroy","limitSelection","drawSelection","emitGraphHoverEvet","drawCrosshair","valueOf","offsetY","pageX","pageY","y1","panelRelY","posX1","posX2","selectionX","selectionWidth","position","graphTooltip","secPerTick","oneDay","oneYear","tickStep","getScaledDecimals","getFlotTickSize","DEFAULT_Y_TICK_SIZE_PX"],"mappings":"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","file":"rendering.js","sourcesContent":["import _ from 'lodash';\nimport $ from 'jquery';\nimport moment from 'moment';\nimport kbn from 'app/core/utils/kbn';\nimport {appEvents, contextSrv} from 'app/core/core';\nimport {tickStep, getScaledDecimals, getFlotTickSize} from 'app/core/utils/ticks';\nimport d3 from 'd3';\nimport * as d3ScaleChromatic from './libs/d3-scale-chromatic/index';\nimport {StatusHeatmapTooltip} from './tooltip';\n\nlet MIN_CARD_SIZE = 5,\n CARD_H_SPACING = 2,\n CARD_V_SPACING = 2,\n CARD_ROUND = 0,\n DATA_RANGE_WIDING_FACTOR = 1.2,\n DEFAULT_X_TICK_SIZE_PX = 100,\n DEFAULT_Y_TICK_SIZE_PX = 50,\n X_AXIS_TICK_PADDING = 10,\n Y_AXIS_TICK_PADDING = 5,\n MIN_SELECTION_WIDTH = 2;\n\nexport default function link(scope, elem, attrs, ctrl) {\n let data, cardsData, timeRange, panel, heatmap;\n\n // $heatmap is JQuery object, but heatmap is D3\n let $heatmap = elem.find('.status-heatmap-panel');\n let tooltip = new StatusHeatmapTooltip($heatmap, scope);\n\n let width, height,\n yScale, xScale,\n chartWidth, chartHeight,\n chartTop, chartBottom,\n yAxisWidth, xAxisHeight,\n cardVSpacing, cardHSpacing, cardRound,\n cardWidth, cardHeight,\n colorScale, opacityScale,\n mouseUpHandler,\n xGridSize, yGridSize;\n\n let yOffset = 0;\n\n let selection = {\n active: false,\n x1: -1,\n x2: -1\n };\n\n let padding = {left: 0, right: 0, top: 0, bottom: 0},\n margin = {left: 25, right: 15, top: 10, bottom: 20},\n dataRangeWidingFactor = DATA_RANGE_WIDING_FACTOR;\n\n ctrl.events.on('render', () => {\n render();\n });\n\n function setElementHeight() {\n try {\n var height = ctrl.height || panel.height || ctrl.row.height;\n if (_.isString(height)) {\n height = parseInt(height.replace('px', ''), 10);\n }\n\n height -= panel.legend.show ? 32 : 10; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend !\n\n $heatmap.css('height', height + 'px');\n\n return true;\n } catch (e) { // IE throws errors sometimes\n return false;\n }\n }\n\n function getYAxisWidth(elem) {\n let axis_text = elem.selectAll(\".axis-y text\").nodes();\n let max_text_width = _.max(_.map(axis_text, text => {\n // Use SVG getBBox method\n return text.getBBox().width;\n }));\n\n return max_text_width;\n }\n\n function getXAxisHeight(elem) {\n let axis_line = elem.select(\".axis-x line\");\n if (!axis_line.empty()) {\n let axis_line_position = parseFloat(elem.select(\".axis-x line\").attr(\"y2\"));\n let canvas_width = parseFloat(elem.attr(\"height\"));\n return canvas_width - axis_line_position;\n } else {\n // Default height\n return 30;\n }\n }\n\n function addXAxis() {\n // Scale timestamps to cards centers\n scope.xScale = xScale = d3.scaleTime()\n .domain([timeRange.from, timeRange.to])\n .range([xGridSize/2, chartWidth-xGridSize/2]);\n\n let ticks = chartWidth / DEFAULT_X_TICK_SIZE_PX;\n let grafanaTimeFormatter = grafanaTimeFormat(ticks, timeRange.from, timeRange.to);\n let timeFormat;\n let dashboardTimeZone = ctrl.dashboard.getTimezone();\n if (dashboardTimeZone === 'utc') {\n timeFormat = d3.utcFormat(grafanaTimeFormatter);\n } else {\n timeFormat = d3.timeFormat(grafanaTimeFormatter);\n }\n\n let xAxis = d3.axisBottom(xScale)\n .ticks(ticks)\n .tickFormat(timeFormat)\n .tickPadding(X_AXIS_TICK_PADDING)\n .tickSize(chartHeight);\n\n let posY = chartTop;\n let posX = yAxisWidth;\n\n heatmap.append(\"g\")\n .attr(\"class\", \"axis axis-x\")\n .attr(\"transform\", \"translate(\" + posX + \",\" + posY + \")\")\n .call(xAxis);\n\n // Remove horizontal line in the top of axis labels (called domain in d3)\n heatmap.select(\".axis-x\").select(\".domain\").remove();\n }\n\n // divide chart height by ticks for cards drawing\n function getYScale(ticks) {\n let range = [];\n let step = chartHeight / ticks.length;\n // svg has y=0 on the top, so top card should have a minimal value in range\n range.push(step);\n for (let i = 1; i < ticks.length; i++) {\n range.push(step * (i+1));\n }\n return d3.scaleOrdinal()\n .domain(ticks)\n .range(range);\n }\n\n // divide chart height by ticks with offset for ticks drawing\n function getYAxisScale(ticks) {\n let range = [];\n let step = chartHeight / ticks.length;\n // svg has y=0 on the top, so top tick should have a minimal value in range\n range.push(yOffset);\n for (let i = 1; i < ticks.length; i++) {\n range.push(step * i + yOffset);\n }\n return d3.scaleOrdinal()\n .domain(ticks)\n .range(range);\n }\n\n function addYAxis() {\n let ticks = _.uniq(_.map(data, d => d.target));\n\n // Set default Y min and max if no data\n if (_.isEmpty(data)) {\n ticks = [''];\n }\n\n if (panel.yAxisSort == 'a → z') {\n ticks.sort((a, b) => a.localeCompare(b, 'en', {ignorePunctuation: false, numeric: true}));\n } else if (panel.yAxisSort == 'z → a') {\n ticks.sort((b, a) => a.localeCompare(b, 'en', {ignorePunctuation: false, numeric: true}));\n }\n\n let yAxisScale = getYAxisScale(ticks);\n scope.yScale = yScale = getYScale(ticks);\n\n let yAxis = d3.axisLeft(yAxisScale)\n .tickValues(ticks)\n .tickSizeInner(0 - width)\n .tickPadding(Y_AXIS_TICK_PADDING);\n\n heatmap.append(\"g\")\n .attr(\"class\", \"axis axis-y\")\n .call(yAxis);\n\n // Calculate Y axis width first, then move axis into visible area\n let posY = margin.top;\n let posX = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING;\n heatmap.select(\".axis-y\").attr(\"transform\", \"translate(\" + posX + \",\" + posY + \")\");\n\n // Remove vertical line in the right of axis labels (called domain in d3)\n heatmap.select(\".axis-y\").select(\".domain\").remove();\n heatmap.select(\".axis-y\").selectAll(\".tick line\").remove();\n }\n\n // Wide Y values range and adjust to bucket size\n function wideYAxisRange(min, max, tickInterval) {\n let y_widing = (max * (dataRangeWidingFactor - 1) - min * (dataRangeWidingFactor - 1)) / 2;\n let y_min, y_max;\n\n if (tickInterval === 0) {\n y_max = max * dataRangeWidingFactor;\n y_min = min - min * (dataRangeWidingFactor - 1);\n tickInterval = (y_max - y_min) / 2;\n } else {\n y_max = Math.ceil((max + y_widing) / tickInterval) * tickInterval;\n y_min = Math.floor((min - y_widing) / tickInterval) * tickInterval;\n }\n\n // Don't wide axis below 0 if all values are positive\n if (min >= 0 && y_min < 0) {\n y_min = 0;\n }\n\n return {y_min, y_max};\n }\n\n function tickValueFormatter(decimals, scaledDecimals = null) {\n let format = panel.yAxis.format;\n return function(value) {\n return kbn.valueFormats[format](value, decimals, scaledDecimals);\n };\n }\n\n // Create svg element, add axes and\n // calculate sizes for cards drawing\n function addHeatmapCanvas() {\n let heatmap_elem = $heatmap[0];\n\n width = Math.floor($heatmap.width()) - padding.right;\n height = Math.floor($heatmap.height()) - padding.bottom;\n\n if (heatmap) {\n heatmap.remove();\n }\n\n heatmap = d3.select(heatmap_elem)\n .append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height);\n\n chartHeight = height - margin.top - margin.bottom;\n chartTop = margin.top;\n chartBottom = chartTop + chartHeight;\n\n cardHSpacing = panel.cards.cardHSpacing !== null ? panel.cards.cardHSpacing : CARD_H_SPACING;\n cardVSpacing = panel.cards.cardVSpacing !== null ? panel.cards.cardVSpacing : CARD_V_SPACING;\n cardRound = panel.cards.cardRound !== null ? panel.cards.cardRound : CARD_ROUND;\n\n // calculate yOffset for YAxis\n yGridSize = Math.floor(chartHeight / cardsData.yBucketSize);\n cardHeight = yGridSize ? yGridSize - cardVSpacing : 0;\n yOffset = cardHeight / 2;\n\n addYAxis();\n\n yAxisWidth = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING;\n chartWidth = width - yAxisWidth - margin.right;\n\n // TODO allow per-y cardWidth!\n // we need to fill chartWidth with xBucketSize cards.\n xGridSize = chartWidth / (cardsData.xBucketSize+1);\n cardWidth = xGridSize - cardHSpacing;\n\n addXAxis();\n xAxisHeight = getXAxisHeight(heatmap);\n\n if (!panel.yAxis.show) {\n heatmap.select(\".axis-y\").selectAll(\"line\").style(\"opacity\", 0);\n }\n\n if (!panel.xAxis.show) {\n heatmap.select(\".axis-x\").selectAll(\"line\").style(\"opacity\", 0);\n }\n }\n\n function addHeatmap() {\n addHeatmapCanvas();\n\n let maxValue = panel.color.max || cardsData.maxValue;\n let minValue = panel.color.min || cardsData.minValue;\n\n if (panel.color.mode !== 'discrete') {\n colorScale = getColorScale(maxValue, minValue);\n }\n setOpacityScale(maxValue);\n\n let cards = heatmap.selectAll(\".status-heatmap-card\").data(cardsData.cards);\n cards.append(\"title\");\n cards = cards.enter().append(\"rect\")\n .attr(\"cardId\", c => c.id)\n .attr(\"x\", getCardX)\n .attr(\"width\", getCardWidth)\n .attr(\"y\", getCardY)\n .attr(\"height\", getCardHeight)\n .attr(\"rx\", cardRound)\n .attr(\"ry\", cardRound)\n .attr(\"class\", \"bordered status-heatmap-card\")\n .style(\"fill\", getCardColor)\n .style(\"stroke\", getCardColor)\n .style(\"stroke-width\", 0)\n //.style(\"stroke-width\", getCardStrokeWidth)\n //.style(\"stroke-dasharray\", \"3,3\")\n .style(\"opacity\", getCardOpacity);\n\n let $cards = $heatmap.find(\".status-heatmap-card\");\n $cards.on(\"mouseenter\", (event) => {\n tooltip.mouseOverBucket = true;\n highlightCard(event);\n })\n .on(\"mouseleave\", (event) => {\n tooltip.mouseOverBucket = false;\n resetCardHighLight(event);\n });\n\n ctrl.events.emit('render-complete', {\n \"chartWidth\": chartWidth\n });\n }\n\n function highlightCard(event) {\n let color = d3.select(event.target).style(\"fill\");\n let highlightColor = d3.color(color).darker(2);\n let strokeColor = d3.color(color).brighter(4);\n let current_card = d3.select(event.target);\n tooltip.originalFillColor = color;\n current_card.style(\"fill\", highlightColor)\n .style(\"stroke\", strokeColor)\n .style(\"stroke-width\", 1);\n }\n\n function resetCardHighLight(event) {\n d3\n .select(event.target)\n .style(\"fill\", tooltip.originalFillColor)\n .style(\"stroke\", tooltip.originalFillColor)\n .style(\"stroke-width\", 0);\n }\n\n function getColorScale(maxValue, minValue = 0) {\n let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme});\n let colorInterpolator = d3ScaleChromatic[colorScheme.value];\n let colorScaleInverted = colorScheme.invert === 'always' ||\n (colorScheme.invert === 'dark' && !contextSrv.user.lightTheme);\n\n if (maxValue == minValue)\n maxValue = minValue + 1;\n\n let start = colorScaleInverted ? maxValue : minValue;\n let end = colorScaleInverted ? minValue : maxValue;\n\n return d3.scaleSequential(colorInterpolator).domain([start, end]);\n }\n\n function setOpacityScale(maxValue) {\n if (panel.color.colorScale === 'linear') {\n opacityScale = d3.scaleLinear()\n .domain([0, maxValue])\n .range([0, 1]);\n } else if (panel.color.colorScale === 'sqrt') {\n opacityScale = d3.scalePow().exponent(panel.color.exponent)\n .domain([0, maxValue])\n .range([0, 1]);\n }\n }\n\n function getCardX(d) {\n let x;\n // cx is the center of the card. Card should be placed to the left.\n let cx = xScale(d.x);\n\n if (cx - cardWidth/2 < 0) {\n x = yAxisWidth + cardHSpacing/2;\n } else {\n x = yAxisWidth + cx - cardWidth/2;\n }\n\n return x;\n }\n\n // xScale returns card center. Adjust cardWidth in case of overlaping.\n function getCardWidth(d) {\n let w;\n let cx = xScale(d.x);\n\n if (cx < cardWidth/2) {\n // Center should not exceed half of card.\n // Cut card to the left to prevent overlay of y axis.\n let cutted_width = (cx - cardHSpacing/2) + cardWidth/2;\n w = cutted_width > 0 ? cutted_width : 0;\n } else if (chartWidth - cx < cardWidth/2) {\n // Cut card to the right to prevent overlay of right graph edge.\n w = cardWidth/2 + (chartWidth - cx - cardHSpacing/2);\n } else {\n w = cardWidth;\n }\n\n // Card width should be MIN_CARD_SIZE at least\n w = Math.max(w, MIN_CARD_SIZE);\n\n if (cardHSpacing == 0) {\n w = w+1;\n }\n\n return w;\n }\n\n function getCardY(d) {\n return yScale(d.y) + chartTop - cardHeight - cardVSpacing/2;\n }\n\n function getCardHeight(d) {\n let ys = yScale(d.y);\n let y = ys + chartTop - cardHeight - cardVSpacing/2;\n let h = cardHeight;\n\n // Cut card height to prevent overlay\n if (y < chartTop) {\n h = ys - cardVSpacing/2;\n } else if (ys > chartBottom) {\n h = chartBottom - y;\n } else if (y + cardHeight > chartBottom) {\n h = chartBottom - y;\n }\n\n // Height can't be more than chart height\n h = Math.min(h, chartHeight);\n // Card height should be MIN_CARD_SIZE at least\n h = Math.max(h, MIN_CARD_SIZE);\n\n if (cardVSpacing == 0) {\n h = h+1\n }\n\n return h;\n }\n\n function getCardColor(d) {\n if (panel.color.mode === 'opacity') {\n return panel.color.cardColor;\n } else if (panel.color.mode === 'spectrum') {\n return colorScale(d.value);\n } else if (panel.color.mode === 'discrete') {\n return ctrl.discreteHelper.getBucketColor(d.values);\n }\n }\n\n function getCardOpacity(d) {\n if (panel.nullPointMode === 'as empty' && d.value == null ) {\n return 0;\n }\n if (panel.color.mode === 'opacity') {\n return opacityScale(d.value);\n } else {\n return 1;\n }\n }\n\n function getCardStrokeWidth(d) {\n if (panel.color.mode === 'discrete') {\n return '1';\n }\n return '0';\n }\n\n /////////////////////////////\n // Selection and crosshair //\n /////////////////////////////\n\n // Shared crosshair and tooltip\n appEvents.on('graph-hover', event => {\n drawSharedCrosshair(event.pos);\n }, scope);\n\n appEvents.on('graph-hover-clear', () => {\n clearCrosshair();\n }, scope);\n\n function onMouseDown(event) {\n selection.active = true;\n selection.x1 = event.offsetX;\n\n mouseUpHandler = function() {\n onMouseUp();\n };\n\n $(document).one(\"mouseup\", mouseUpHandler);\n }\n\n function onMouseUp() {\n $(document).unbind(\"mouseup\", mouseUpHandler);\n mouseUpHandler = null;\n selection.active = false;\n\n let selectionRange = Math.abs(selection.x2 - selection.x1);\n if (selection.x2 >= 0 && selectionRange > MIN_SELECTION_WIDTH) {\n let timeFrom = xScale.invert(Math.min(selection.x1, selection.x2) - yAxisWidth - xGridSize/2);\n let timeTo = xScale.invert(Math.max(selection.x1, selection.x2) - yAxisWidth - xGridSize/2);\n\n ctrl.timeSrv.setTime({\n from: moment.utc(timeFrom),\n to: moment.utc(timeTo)\n });\n }\n\n clearSelection();\n }\n\n function onMouseLeave() {\n appEvents.emit('graph-hover-clear');\n clearCrosshair();\n }\n\n function onMouseMove(event) {\n if (!heatmap) { return; }\n\n if (selection.active) {\n // Clear crosshair and tooltip\n clearCrosshair();\n tooltip.destroy();\n\n selection.x2 = limitSelection(event.offsetX);\n drawSelection(selection.x1, selection.x2);\n } else {\n emitGraphHoverEvet(event);\n drawCrosshair(event.offsetX);\n tooltip.show(event); //, data);\n }\n }\n\n function emitGraphHoverEvet(event) {\n let x = xScale.invert(event.offsetX - yAxisWidth - xGridSize/2).valueOf();\n let y = yScale(event.offsetY);\n let pos = {\n pageX: event.pageX,\n pageY: event.pageY,\n x: x, x1: x,\n y: y, y1: y,\n panelRelY: null\n };\n\n // Set minimum offset to prevent showing legend from another panel\n pos.panelRelY = Math.max(event.offsetY / height, 0.001);\n\n // broadcast to other graph panels that we are hovering\n appEvents.emit('graph-hover', {pos: pos, panel: panel});\n }\n\n function limitSelection(x2) {\n x2 = Math.max(x2, yAxisWidth);\n x2 = Math.min(x2, chartWidth + yAxisWidth);\n return x2;\n }\n\n function drawSelection(posX1, posX2) {\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-selection\").remove();\n let selectionX = Math.min(posX1, posX2);\n let selectionWidth = Math.abs(posX1 - posX2);\n\n if (selectionWidth > MIN_SELECTION_WIDTH) {\n heatmap.append(\"rect\")\n .attr(\"class\", \"status-heatmap-selection\")\n .attr(\"x\", selectionX)\n .attr(\"width\", selectionWidth)\n .attr(\"y\", chartTop)\n .attr(\"height\", chartHeight);\n }\n }\n }\n\n function clearSelection() {\n selection.x1 = -1;\n selection.x2 = -1;\n\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-selection\").remove();\n }\n }\n\n function drawCrosshair(position) {\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-crosshair\").remove();\n\n let posX = position;\n posX = Math.max(posX, yAxisWidth);\n posX = Math.min(posX, chartWidth + yAxisWidth);\n\n heatmap.append(\"g\")\n .attr(\"class\", \"status-heatmap-crosshair\")\n .attr(\"transform\", \"translate(\" + posX + \",0)\")\n .append(\"line\")\n .attr(\"x1\", 1)\n .attr(\"y1\", chartTop)\n .attr(\"x2\", 1)\n .attr(\"y2\", chartBottom)\n .attr(\"stroke-width\", 1);\n }\n }\n\n // map time to X\n function drawSharedCrosshair(pos) {\n if (heatmap && ctrl.dashboard.graphTooltip !== 0) {\n let posX = xScale(pos.x) + yAxisWidth;\n drawCrosshair(posX);\n }\n }\n\n function clearCrosshair() {\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-crosshair\").remove();\n }\n }\n\n function render() {\n data = ctrl.data;\n panel = ctrl.panel;\n timeRange = ctrl.range;\n cardsData = ctrl.cardsData;\n\n if (!data || !cardsData || !setElementHeight()) {\n return;\n }\n\n // Draw default axes and return if no data\n if (_.isEmpty(cardsData.cards)) {\n addHeatmapCanvas();\n return;\n }\n\n addHeatmap();\n scope.yAxisWidth = yAxisWidth;\n scope.xAxisHeight = xAxisHeight;\n scope.chartHeight = chartHeight;\n scope.chartWidth = chartWidth;\n scope.chartTop = chartTop;\n }\n\n // Register selection listeners\n $heatmap.on(\"mousedown\", onMouseDown);\n $heatmap.on(\"mousemove\", onMouseMove);\n $heatmap.on(\"mouseleave\", onMouseLeave);\n}\n\nfunction grafanaTimeFormat(ticks, min, max) {\n if (min && max && ticks) {\n let range = max - min;\n let secPerTick = (range/ticks) / 1000;\n let oneDay = 86400000;\n let oneYear = 31536000000;\n\n if (secPerTick <= 45) {\n return \"%H:%M:%S\";\n }\n if (secPerTick <= 7200 || range <= oneDay) {\n return \"%H:%M\";\n }\n if (secPerTick <= 80000) {\n return \"%m/%d %H:%M\";\n }\n if (secPerTick <= 2419200 || range <= oneYear) {\n return \"%m/%d\";\n }\n return \"%Y-%m\";\n }\n\n return \"%H:%M\";\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/rendering.js"],"names":["link","scope","elem","attrs","ctrl","data","cardsData","timeRange","panel","heatmap","$heatmap","find","tooltip","StatusHeatmapTooltip","annotationTooltip","AnnotationTooltip","width","height","yScale","xScale","chartWidth","chartHeight","chartTop","chartBottom","yAxisWidth","xAxisHeight","cardVSpacing","cardHSpacing","cardRound","cardWidth","cardHeight","colorScale","opacityScale","mouseUpHandler","xGridSize","yGridSize","yOffset","selection","active","x1","x2","padding","left","right","top","bottom","margin","dataRangeWidingFactor","DATA_RANGE_WIDING_FACTOR","events","on","render","setElementHeight","row","_","isString","parseInt","replace","legend","show","css","e","getYAxisWidth","axis_text","selectAll","nodes","max_text_width","max","map","text","getBBox","Math","ceil","getXAxisHeight","axis_line","select","empty","axis_line_position","parseFloat","attr","canvas_width","addXAxis","d3","scaleTime","domain","from","to","range","ticks","DEFAULT_X_TICK_SIZE_PX","grafanaTimeFormatter","grafanaTimeFormat","timeFormat","dashboardTimeZone","dashboard","getTimezone","utcFormat","xAxis","axisBottom","tickFormat","tickPadding","X_AXIS_TICK_PADDING","tickSize","posY","posX","append","call","remove","getYScale","step","length","push","i","scaleOrdinal","getYAxisScale","addYAxis","uniq","d","target","isEmpty","yAxisSort","sort","a","b","localeCompare","ignorePunctuation","numeric","yAxisScale","yAxis","axisLeft","tickValues","tickSizeInner","Y_AXIS_TICK_PADDING","wideYAxisRange","min","tickInterval","y_widing","y_min","y_max","floor","tickValueFormatter","decimals","scaledDecimals","format","value","kbn","valueFormats","addHeatmapCanvas","heatmap_elem","cards","CARD_H_SPACING","CARD_V_SPACING","CARD_ROUND","yBucketSize","xBucketSize","style","addHeatmap","maxValue","color","minValue","mode","getColorScale","setOpacityScale","enter","c","id","getCardX","getCardWidth","getCardY","getCardHeight","getCardColor","getCardOpacity","$cards","event","mouseOverBucket","highlightCard","resetCardHighLight","_renderAnnotations","emit","highlightColor","darker","strokeColor","brighter","current_card","originalFillColor","colorScheme","colorSchemes","colorInterpolator","d3ScaleChromatic","colorScaleInverted","invert","contextSrv","user","lightTheme","start","end","scaleSequential","scaleLinear","scalePow","exponent","x","cx","w","cutted_width","MIN_CARD_SIZE","y","ys","h","cardColor","discreteHelper","getBucketColor","values","nullPointMode","getCardStrokeWidth","appEvents","drawSharedCrosshair","pos","clearCrosshair","onMouseDown","offsetX","onMouseUp","$","document","one","unbind","selectionRange","abs","MIN_SELECTION_WIDTH","timeFrom","timeTo","timeSrv","setTime","moment","utc","clearSelection","onMouseLeave","onMouseMove","destroy","limitSelection","drawSelection","emitGraphHoverEvet","drawCrosshair","valueOf","offsetY","pageX","pageY","y1","panelRelY","posX1","posX2","selectionX","selectionWidth","position","graphTooltip","annotations","annoData","time","source","anno","iconColor","join","$ticks","mouseOverAnnotationTick","secPerTick","oneDay","oneYear","tickStep","getScaledDecimals","getFlotTickSize","DEFAULT_Y_TICK_SIZE_PX"],"mappings":"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","file":"rendering.js","sourcesContent":["import _ from 'lodash';\nimport $ from 'jquery';\nimport moment from 'moment';\nimport kbn from 'app/core/utils/kbn';\nimport {appEvents, contextSrv} from 'app/core/core';\nimport {tickStep, getScaledDecimals, getFlotTickSize} from 'app/core/utils/ticks';\nimport d3 from 'd3';\nimport * as d3ScaleChromatic from './libs/d3-scale-chromatic/index';\nimport {StatusHeatmapTooltip} from './tooltip';\nimport {AnnotationTooltip} from './annotations';\n\nlet MIN_CARD_SIZE = 5,\n CARD_H_SPACING = 2,\n CARD_V_SPACING = 2,\n CARD_ROUND = 0,\n DATA_RANGE_WIDING_FACTOR = 1.2,\n DEFAULT_X_TICK_SIZE_PX = 100,\n DEFAULT_Y_TICK_SIZE_PX = 50,\n X_AXIS_TICK_PADDING = 10,\n Y_AXIS_TICK_PADDING = 5,\n MIN_SELECTION_WIDTH = 2;\n\nexport default function link(scope, elem, attrs, ctrl) {\n let data, cardsData, timeRange, panel, heatmap;\n\n // $heatmap is JQuery object, but heatmap is D3\n let $heatmap = elem.find('.status-heatmap-panel');\n let tooltip = new StatusHeatmapTooltip($heatmap, scope);\n let annotationTooltip = new AnnotationTooltip($heatmap, scope);\n\n let width, height,\n yScale, xScale,\n chartWidth, chartHeight,\n chartTop, chartBottom,\n yAxisWidth, xAxisHeight,\n cardVSpacing, cardHSpacing, cardRound,\n cardWidth, cardHeight,\n colorScale, opacityScale,\n mouseUpHandler,\n xGridSize, yGridSize;\n\n let yOffset = 0;\n\n let selection = {\n active: false,\n x1: -1,\n x2: -1\n };\n\n let padding = {left: 0, right: 0, top: 0, bottom: 0},\n margin = {left: 25, right: 15, top: 10, bottom: 20},\n dataRangeWidingFactor = DATA_RANGE_WIDING_FACTOR;\n\n ctrl.events.on('render', () => {\n render();\n });\n\n function setElementHeight() {\n try {\n var height = ctrl.height || panel.height || ctrl.row.height;\n if (_.isString(height)) {\n height = parseInt(height.replace('px', ''), 10);\n }\n\n height -= panel.legend.show ? 32 : 10; // bottom padding and space for legend. Change margin in .status-heatmap-color-legend !\n\n $heatmap.css('height', height + 'px');\n\n return true;\n } catch (e) { // IE throws errors sometimes\n return false;\n }\n }\n\n function getYAxisWidth(elem) {\n let axis_text = elem.selectAll(\".axis-y text\").nodes();\n let max_text_width = _.max(_.map(axis_text, text => {\n // Use SVG getBBox method\n return text.getBBox().width;\n }));\n\n return Math.ceil(max_text_width);\n }\n\n function getXAxisHeight(elem) {\n let axis_line = elem.select(\".axis-x line\");\n if (!axis_line.empty()) {\n let axis_line_position = parseFloat(elem.select(\".axis-x line\").attr(\"y2\"));\n let canvas_width = parseFloat(elem.attr(\"height\"));\n return canvas_width - axis_line_position;\n } else {\n // Default height\n return 30;\n }\n }\n\n function addXAxis() {\n // Scale timestamps to cards centers\n scope.xScale = xScale = d3.scaleTime()\n .domain([timeRange.from, timeRange.to])\n .range([xGridSize/2, chartWidth-xGridSize/2]);\n\n let ticks = chartWidth / DEFAULT_X_TICK_SIZE_PX;\n let grafanaTimeFormatter = grafanaTimeFormat(ticks, timeRange.from, timeRange.to);\n let timeFormat;\n let dashboardTimeZone = ctrl.dashboard.getTimezone();\n if (dashboardTimeZone === 'utc') {\n timeFormat = d3.utcFormat(grafanaTimeFormatter);\n } else {\n timeFormat = d3.timeFormat(grafanaTimeFormatter);\n }\n\n let xAxis = d3.axisBottom(xScale)\n .ticks(ticks)\n .tickFormat(timeFormat)\n .tickPadding(X_AXIS_TICK_PADDING)\n .tickSize(chartHeight);\n\n let posY = chartTop;\n let posX = yAxisWidth;\n\n heatmap.append(\"g\")\n .attr(\"class\", \"axis axis-x\")\n .attr(\"transform\", \"translate(\" + posX + \",\" + posY + \")\")\n .call(xAxis);\n\n // Remove horizontal line in the top of axis labels (called domain in d3)\n heatmap.select(\".axis-x\").select(\".domain\").remove();\n }\n\n // divide chart height by ticks for cards drawing\n function getYScale(ticks) {\n let range = [];\n let step = chartHeight / ticks.length;\n // svg has y=0 on the top, so top card should have a minimal value in range\n range.push(step);\n for (let i = 1; i < ticks.length; i++) {\n range.push(step * (i+1));\n }\n return d3.scaleOrdinal()\n .domain(ticks)\n .range(range);\n }\n\n // divide chart height by ticks with offset for ticks drawing\n function getYAxisScale(ticks) {\n let range = [];\n let step = chartHeight / ticks.length;\n // svg has y=0 on the top, so top tick should have a minimal value in range\n range.push(yOffset);\n for (let i = 1; i < ticks.length; i++) {\n range.push(step * i + yOffset);\n }\n return d3.scaleOrdinal()\n .domain(ticks)\n .range(range);\n }\n\n function addYAxis() {\n let ticks = _.uniq(_.map(data, d => d.target));\n\n // Set default Y min and max if no data\n if (_.isEmpty(data)) {\n ticks = [''];\n }\n\n if (panel.yAxisSort == 'a → z') {\n ticks.sort((a, b) => a.localeCompare(b, 'en', {ignorePunctuation: false, numeric: true}));\n } else if (panel.yAxisSort == 'z → a') {\n ticks.sort((b, a) => a.localeCompare(b, 'en', {ignorePunctuation: false, numeric: true}));\n }\n\n let yAxisScale = getYAxisScale(ticks);\n scope.yScale = yScale = getYScale(ticks);\n\n let yAxis = d3.axisLeft(yAxisScale)\n .tickValues(ticks)\n .tickSizeInner(0 - width)\n .tickPadding(Y_AXIS_TICK_PADDING);\n\n heatmap.append(\"g\")\n .attr(\"class\", \"axis axis-y\")\n .call(yAxis);\n\n // Calculate Y axis width first, then move axis into visible area\n let posY = margin.top;\n let posX = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING;\n heatmap.select(\".axis-y\").attr(\"transform\", \"translate(\" + posX + \",\" + posY + \")\");\n\n // Remove vertical line in the right of axis labels (called domain in d3)\n heatmap.select(\".axis-y\").select(\".domain\").remove();\n heatmap.select(\".axis-y\").selectAll(\".tick line\").remove();\n }\n\n // Wide Y values range and adjust to bucket size\n function wideYAxisRange(min, max, tickInterval) {\n let y_widing = (max * (dataRangeWidingFactor - 1) - min * (dataRangeWidingFactor - 1)) / 2;\n let y_min, y_max;\n\n if (tickInterval === 0) {\n y_max = max * dataRangeWidingFactor;\n y_min = min - min * (dataRangeWidingFactor - 1);\n tickInterval = (y_max - y_min) / 2;\n } else {\n y_max = Math.ceil((max + y_widing) / tickInterval) * tickInterval;\n y_min = Math.floor((min - y_widing) / tickInterval) * tickInterval;\n }\n\n // Don't wide axis below 0 if all values are positive\n if (min >= 0 && y_min < 0) {\n y_min = 0;\n }\n\n return {y_min, y_max};\n }\n\n function tickValueFormatter(decimals, scaledDecimals = null) {\n let format = panel.yAxis.format;\n return function(value) {\n return kbn.valueFormats[format](value, decimals, scaledDecimals);\n };\n }\n\n // Create svg element, add axes and\n // calculate sizes for cards drawing\n function addHeatmapCanvas() {\n let heatmap_elem = $heatmap[0];\n\n width = Math.floor($heatmap.width()) - padding.right;\n height = Math.floor($heatmap.height()) - padding.bottom;\n\n if (heatmap) {\n heatmap.remove();\n }\n\n heatmap = d3.select(heatmap_elem)\n .append(\"svg\")\n .attr(\"width\", width)\n .attr(\"height\", height);\n\n chartHeight = height - margin.top - margin.bottom;\n chartTop = margin.top;\n chartBottom = chartTop + chartHeight;\n\n cardHSpacing = panel.cards.cardHSpacing !== null ? panel.cards.cardHSpacing : CARD_H_SPACING;\n cardVSpacing = panel.cards.cardVSpacing !== null ? panel.cards.cardVSpacing : CARD_V_SPACING;\n cardRound = panel.cards.cardRound !== null ? panel.cards.cardRound : CARD_ROUND;\n\n // calculate yOffset for YAxis\n yGridSize = Math.floor(chartHeight / cardsData.yBucketSize);\n cardHeight = yGridSize ? yGridSize - cardVSpacing : 0;\n yOffset = cardHeight / 2;\n\n addYAxis();\n\n yAxisWidth = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING;\n chartWidth = width - yAxisWidth - margin.right;\n\n // TODO allow per-y cardWidth!\n // we need to fill chartWidth with xBucketSize cards.\n xGridSize = chartWidth / (cardsData.xBucketSize+1);\n cardWidth = xGridSize - cardHSpacing;\n\n addXAxis();\n xAxisHeight = getXAxisHeight(heatmap);\n\n if (!panel.yAxis.show) {\n heatmap.select(\".axis-y\").selectAll(\"line\").style(\"opacity\", 0);\n }\n\n if (!panel.xAxis.show) {\n heatmap.select(\".axis-x\").selectAll(\"line\").style(\"opacity\", 0);\n }\n }\n\n function addHeatmap() {\n addHeatmapCanvas();\n\n let maxValue = panel.color.max || cardsData.maxValue;\n let minValue = panel.color.min || cardsData.minValue;\n\n if (panel.color.mode !== 'discrete') {\n colorScale = getColorScale(maxValue, minValue);\n }\n setOpacityScale(maxValue);\n\n let cards = heatmap.selectAll(\".status-heatmap-card\").data(cardsData.cards);\n cards.append(\"title\");\n cards = cards.enter().append(\"rect\")\n .attr(\"cardId\", c => c.id)\n .attr(\"x\", getCardX)\n .attr(\"width\", getCardWidth)\n .attr(\"y\", getCardY)\n .attr(\"height\", getCardHeight)\n .attr(\"rx\", cardRound)\n .attr(\"ry\", cardRound)\n .attr(\"class\", \"bordered status-heatmap-card\")\n .style(\"fill\", getCardColor)\n .style(\"stroke\", getCardColor)\n .style(\"stroke-width\", 0)\n //.style(\"stroke-width\", getCardStrokeWidth)\n //.style(\"stroke-dasharray\", \"3,3\")\n .style(\"opacity\", getCardOpacity);\n\n let $cards = $heatmap.find(\".status-heatmap-card\");\n $cards.on(\"mouseenter\", (event) => {\n tooltip.mouseOverBucket = true;\n highlightCard(event);\n })\n .on(\"mouseleave\", (event) => {\n tooltip.mouseOverBucket = false;\n resetCardHighLight(event);\n });\n\n _renderAnnotations();\n\n ctrl.events.emit('render-complete', {\n \"chartWidth\": chartWidth\n });\n }\n\n function highlightCard(event) {\n let color = d3.select(event.target).style(\"fill\");\n let highlightColor = d3.color(color).darker(2);\n let strokeColor = d3.color(color).brighter(4);\n let current_card = d3.select(event.target);\n tooltip.originalFillColor = color;\n current_card.style(\"fill\", highlightColor)\n .style(\"stroke\", strokeColor)\n .style(\"stroke-width\", 1);\n }\n\n function resetCardHighLight(event) {\n d3\n .select(event.target)\n .style(\"fill\", tooltip.originalFillColor)\n .style(\"stroke\", tooltip.originalFillColor)\n .style(\"stroke-width\", 0);\n }\n\n function getColorScale(maxValue, minValue = 0) {\n let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme});\n let colorInterpolator = d3ScaleChromatic[colorScheme.value];\n let colorScaleInverted = colorScheme.invert === 'always' ||\n (colorScheme.invert === 'dark' && !contextSrv.user.lightTheme);\n\n if (maxValue == minValue)\n maxValue = minValue + 1;\n\n let start = colorScaleInverted ? maxValue : minValue;\n let end = colorScaleInverted ? minValue : maxValue;\n\n return d3.scaleSequential(colorInterpolator).domain([start, end]);\n }\n\n function setOpacityScale(maxValue) {\n if (panel.color.colorScale === 'linear') {\n opacityScale = d3.scaleLinear()\n .domain([0, maxValue])\n .range([0, 1]);\n } else if (panel.color.colorScale === 'sqrt') {\n opacityScale = d3.scalePow().exponent(panel.color.exponent)\n .domain([0, maxValue])\n .range([0, 1]);\n }\n }\n\n function getCardX(d) {\n let x;\n // cx is the center of the card. Card should be placed to the left.\n let cx = xScale(d.x);\n\n if (cx - cardWidth/2 < 0) {\n x = yAxisWidth + cardHSpacing/2;\n } else {\n x = yAxisWidth + cx - cardWidth/2;\n }\n\n return x;\n }\n\n // xScale returns card center. Adjust cardWidth in case of overlaping.\n function getCardWidth(d) {\n let w;\n let cx = xScale(d.x);\n\n if (cx < cardWidth/2) {\n // Center should not exceed half of card.\n // Cut card to the left to prevent overlay of y axis.\n let cutted_width = (cx - cardHSpacing/2) + cardWidth/2;\n w = cutted_width > 0 ? cutted_width : 0;\n } else if (chartWidth - cx < cardWidth/2) {\n // Cut card to the right to prevent overlay of right graph edge.\n w = cardWidth/2 + (chartWidth - cx - cardHSpacing/2);\n } else {\n w = cardWidth;\n }\n\n // Card width should be MIN_CARD_SIZE at least\n w = Math.max(w, MIN_CARD_SIZE);\n\n if (cardHSpacing == 0) {\n w = w+1;\n }\n\n return w;\n }\n\n function getCardY(d) {\n return yScale(d.y) + chartTop - cardHeight - cardVSpacing/2;\n }\n\n function getCardHeight(d) {\n let ys = yScale(d.y);\n let y = ys + chartTop - cardHeight - cardVSpacing/2;\n let h = cardHeight;\n\n // Cut card height to prevent overlay\n if (y < chartTop) {\n h = ys - cardVSpacing/2;\n } else if (ys > chartBottom) {\n h = chartBottom - y;\n } else if (y + cardHeight > chartBottom) {\n h = chartBottom - y;\n }\n\n // Height can't be more than chart height\n h = Math.min(h, chartHeight);\n // Card height should be MIN_CARD_SIZE at least\n h = Math.max(h, MIN_CARD_SIZE);\n\n if (cardVSpacing == 0) {\n h = h+1\n }\n\n return h;\n }\n\n function getCardColor(d) {\n if (panel.color.mode === 'opacity') {\n return panel.color.cardColor;\n } else if (panel.color.mode === 'spectrum') {\n return colorScale(d.value);\n } else if (panel.color.mode === 'discrete') {\n return ctrl.discreteHelper.getBucketColor(d.values);\n }\n }\n\n function getCardOpacity(d) {\n if (panel.nullPointMode === 'as empty' && d.value == null ) {\n return 0;\n }\n if (panel.color.mode === 'opacity') {\n return opacityScale(d.value);\n } else {\n return 1;\n }\n }\n\n function getCardStrokeWidth(d) {\n if (panel.color.mode === 'discrete') {\n return '1';\n }\n return '0';\n }\n\n /////////////////////////////\n // Selection and crosshair //\n /////////////////////////////\n\n // Shared crosshair and tooltip\n appEvents.on('graph-hover', event => {\n drawSharedCrosshair(event.pos);\n }, scope);\n\n appEvents.on('graph-hover-clear', () => {\n clearCrosshair();\n }, scope);\n\n function onMouseDown(event) {\n selection.active = true;\n selection.x1 = event.offsetX;\n\n mouseUpHandler = function() {\n onMouseUp();\n };\n\n $(document).one(\"mouseup\", mouseUpHandler);\n }\n\n function onMouseUp() {\n $(document).unbind(\"mouseup\", mouseUpHandler);\n mouseUpHandler = null;\n selection.active = false;\n\n let selectionRange = Math.abs(selection.x2 - selection.x1);\n if (selection.x2 >= 0 && selectionRange > MIN_SELECTION_WIDTH) {\n let timeFrom = xScale.invert(Math.min(selection.x1, selection.x2) - yAxisWidth - xGridSize/2);\n let timeTo = xScale.invert(Math.max(selection.x1, selection.x2) - yAxisWidth - xGridSize/2);\n\n ctrl.timeSrv.setTime({\n from: moment.utc(timeFrom),\n to: moment.utc(timeTo)\n });\n }\n\n clearSelection();\n }\n\n function onMouseLeave() {\n appEvents.emit('graph-hover-clear');\n clearCrosshair();\n //annotationTooltip.destroy();\n }\n\n function onMouseMove(event) {\n if (!heatmap) { return; }\n\n if (selection.active) {\n // Clear crosshair and tooltip\n clearCrosshair();\n tooltip.destroy();\n annotationTooltip.destroy();\n\n selection.x2 = limitSelection(event.offsetX);\n drawSelection(selection.x1, selection.x2);\n } else {\n emitGraphHoverEvet(event);\n drawCrosshair(event.offsetX);\n tooltip.show(event); //, data);\n annotationTooltip.show(event);\n }\n }\n\n function emitGraphHoverEvet(event) {\n let x = xScale.invert(event.offsetX - yAxisWidth - xGridSize/2).valueOf();\n let y = yScale(event.offsetY);\n let pos = {\n pageX: event.pageX,\n pageY: event.pageY,\n x: x, x1: x,\n y: y, y1: y,\n panelRelY: null\n };\n\n // Set minimum offset to prevent showing legend from another panel\n pos.panelRelY = Math.max(event.offsetY / height, 0.001);\n\n // broadcast to other graph panels that we are hovering\n appEvents.emit('graph-hover', {pos: pos, panel: panel});\n }\n\n function limitSelection(x2) {\n x2 = Math.max(x2, yAxisWidth);\n x2 = Math.min(x2, chartWidth + yAxisWidth);\n return x2;\n }\n\n function drawSelection(posX1, posX2) {\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-selection\").remove();\n let selectionX = Math.min(posX1, posX2);\n let selectionWidth = Math.abs(posX1 - posX2);\n\n if (selectionWidth > MIN_SELECTION_WIDTH) {\n heatmap.append(\"rect\")\n .attr(\"class\", \"status-heatmap-selection\")\n .attr(\"x\", selectionX)\n .attr(\"width\", selectionWidth)\n .attr(\"y\", chartTop)\n .attr(\"height\", chartHeight);\n }\n }\n }\n\n function clearSelection() {\n selection.x1 = -1;\n selection.x2 = -1;\n\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-selection\").remove();\n }\n }\n\n function drawCrosshair(position) {\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-crosshair\").remove();\n\n let posX = position;\n posX = Math.max(posX, yAxisWidth);\n posX = Math.min(posX, chartWidth + yAxisWidth);\n\n heatmap.append(\"g\")\n .attr(\"class\", \"status-heatmap-crosshair\")\n .attr(\"transform\", \"translate(\" + posX + \",0)\")\n .append(\"line\")\n .attr(\"x1\", 1)\n .attr(\"y1\", chartTop)\n .attr(\"x2\", 1)\n .attr(\"y2\", chartBottom)\n .attr(\"stroke-width\", 1);\n }\n }\n\n // map time to X\n function drawSharedCrosshair(pos) {\n if (heatmap && ctrl.dashboard.graphTooltip !== 0) {\n let posX = xScale(pos.x) + yAxisWidth;\n drawCrosshair(posX);\n }\n }\n\n function clearCrosshair() {\n if (heatmap) {\n heatmap.selectAll(\".status-heatmap-crosshair\").remove();\n }\n }\n\n function render() {\n data = ctrl.data;\n panel = ctrl.panel;\n timeRange = ctrl.range;\n cardsData = ctrl.cardsData;\n\n if (!data || !cardsData || !setElementHeight()) {\n return;\n }\n\n // Draw default axes and return if no data\n if (_.isEmpty(cardsData.cards)) {\n addHeatmapCanvas();\n return;\n }\n\n addHeatmap();\n scope.yAxisWidth = yAxisWidth;\n scope.xAxisHeight = xAxisHeight;\n scope.chartHeight = chartHeight;\n scope.chartWidth = chartWidth;\n scope.chartTop = chartTop;\n }\n\n // Register selection listeners\n $heatmap.on(\"mousedown\", onMouseDown);\n $heatmap.on(\"mousemove\", onMouseMove);\n $heatmap.on(\"mouseleave\", onMouseLeave);\n\n function _renderAnnotations() {\n if (!ctrl.annotations || ctrl.annotations.length == 0) {\n return;\n }\n \n if (!heatmap) {\n return;\n }\n\n let annoData = _.map(ctrl.annotations, (d,i) => ({\"x\": Math.floor(yAxisWidth + xScale(d.time)), \"id\":i, \"anno\": d.source}));\n\n\n let anno = heatmap\n .append(\"g\")\n .attr(\"class\", \"statusmap-annotations\")\n .attr(\"transform\", \"translate(0.5,0)\")\n .selectAll(\".statusmap-annotations\")\n .data(annoData)\n .enter().append(\"g\")\n ;\n anno.append(\"line\")\n //.attr(\"class\", \"statusmap-annotation-tick\")\n .attr(\"x1\", d => d.x)\n .attr(\"y1\", chartTop)\n .attr(\"x2\", d => d.x)\n .attr(\"y2\", chartBottom)\n .style(\"stroke\", d => d.anno.iconColor)\n .style(\"stroke-width\", 1)\n .style(\"stroke-dasharray\", \"3,3\")\n ;\n anno.append(\"polygon\")\n .attr(\"points\", d => [[d.x, chartBottom+1], [d.x-5, chartBottom+6], [d.x+5, chartBottom+6]].join(\" \"))\n .style(\"stroke-width\", 0)\n .style(\"fill\", d => d.anno.iconColor)\n ;\n // Polygons didn't fire mouseevents\n anno.append(\"rect\") \n .attr(\"x\", d => d.x-5)\n .attr(\"width\", 10)\n .attr(\"y\", chartBottom+1)\n .attr(\"height\", 5)\n .attr(\"class\", \"statusmap-annotation-tick\")\n .attr(\"annoId\", d => d.id)\n .style(\"opacity\", 0)\n ;\n\n let $ticks = $heatmap.find(\".statusmap-annotation-tick\");\n $ticks.on(\"mouseenter\", (event) => {\n annotationTooltip.mouseOverAnnotationTick = true;\n })\n .on(\"mouseleave\", (event) => {\n annotationTooltip.mouseOverAnnotationTick = false;\n });\n \n }\n}\n\nfunction grafanaTimeFormat(ticks, min, max) {\n if (min && max && ticks) {\n let range = max - min;\n let secPerTick = (range/ticks) / 1000;\n let oneDay = 86400000;\n let oneYear = 31536000000;\n\n if (secPerTick <= 45) {\n return \"%H:%M:%S\";\n }\n if (secPerTick <= 7200 || range <= oneDay) {\n return \"%H:%M\";\n }\n if (secPerTick <= 80000) {\n return \"%m/%d %H:%M\";\n }\n if (secPerTick <= 2419200 || range <= oneYear) {\n return \"%m/%d\";\n }\n return \"%Y-%m\";\n }\n\n return \"%H:%M\";\n}\n"]} \ No newline at end of file diff --git a/dist/status_heatmap_ctrl.js b/dist/status_heatmap_ctrl.js index 294dcf9..066f355 100644 --- a/dist/status_heatmap_ctrl.js +++ b/dist/status_heatmap_ctrl.js @@ -3,7 +3,7 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/kbn', './color_legend', './rendering', './options_editor', './color_mode_discrete'], function (_export, _context) { "use strict"; - var MetricsPanelCtrl, _, contextSrv, kbn, rendering, statusHeatmapOptionsEditor, ColorModeDiscrete, CANVAS, SVG, VALUE_INDEX, TIME_INDEX, panelDefaults, renderer, colorSchemes, colorModes, opacityScales, StatusHeatmapCtrl; + var MetricsPanelCtrl, _, contextSrv, kbn, rendering, statusHeatmapOptionsEditor, ColorModeDiscrete, _get, CANVAS, SVG, VALUE_INDEX, TIME_INDEX, panelDefaults, renderer, colorSchemes, colorModes, opacityScales, StatusHeatmapCtrl; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -52,6 +52,31 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k ColorModeDiscrete = _color_mode_discrete.ColorModeDiscrete; }], execute: function () { + _get = function get(object, property, receiver) { + if (object === null) object = Function.prototype; + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === undefined) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return undefined; + } else { + return get(parent, property, receiver); + } + } else if ("value" in desc) { + return desc.value; + } else { + var getter = desc.get; + + if (getter === undefined) { + return undefined; + } + + return getter.call(receiver); + } + }; + CANVAS = 'CANVAS'; SVG = 'SVG'; VALUE_INDEX = 0; @@ -118,7 +143,8 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k _export('StatusHeatmapCtrl', StatusHeatmapCtrl = function (_MetricsPanelCtrl) { _inherits(StatusHeatmapCtrl, _MetricsPanelCtrl); - function StatusHeatmapCtrl($scope, $injector, $rootScope, timeSrv) { + /** @ngInject */ + function StatusHeatmapCtrl($scope, $injector, $rootScope, timeSrv, annotationsSrv) { _classCallCheck(this, StatusHeatmapCtrl); var _this = _possibleConstructorReturn(this, (StatusHeatmapCtrl.__proto__ || Object.getPrototypeOf(StatusHeatmapCtrl)).call(this, $scope, $injector)); @@ -169,11 +195,44 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k _this.interval = kbn.secondsToHms(intervalMs / 1000); }; + _this.issueQueries = function (datasource) { + _this.annotationsPromise = _this.annotationsSrv.getAnnotations({ + dashboard: _this.dashboard, + panel: _this.panel, + range: _this.range + }); + + /* Wait for annotationSrv requests to get datasources to + * resolve before issuing queries. This allows the annotations + * service to fire annotations queries before graph queries + * (but not wait for completion). This resolves + * issue 11806. + */ + return _this.annotationsSrv.datasourcePromises.then(function (r) { + return _get(StatusHeatmapCtrl.prototype.__proto__ || Object.getPrototypeOf(StatusHeatmapCtrl.prototype), 'issueQueries', _this).call(_this, datasource); + }); + }; + _this.onDataReceived = function (dataList) { _this.data = dataList; _this.cardsData = _this.convertToCards(_this.data); - _this.render(); + _this.annotationsPromise.then(function (result) { + _this.loading = false; + //this.alertState = result.alertState; + if (result.annotations && result.annotations.length > 0) { + _this.annotations = result.annotations; + } else { + _this.annotations = null; + } + _this.render(); + }, function () { + _this.loading = false; + _this.annotations = null; + _this.render(); + }); + + //this.render(); }; _this.onInitEditMode = function () { @@ -209,6 +268,7 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k _this.onDataError = function () { _this.data = []; + _this.annotations = []; _this.render(); }; @@ -296,7 +356,9 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k id: i * cardsData.xBucketSize + j, values: [], multipleValues: false, - noColorDefined: false + noColorDefined: false, + y: target, + x: -1 }; // collect values from all timeseries with target @@ -308,7 +370,6 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k var datapoint = s.datapoints[j]; if (card.values.length === 0) { card.x = datapoint[TIME_INDEX]; - card.y = s.target; } card.values.push(datapoint[VALUE_INDEX]); } @@ -326,7 +387,9 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k if (cardsData.minValue > card.minValue) cardsData.minValue = card.minValue; - cardsData.cards.push(card); + if (card.x != -1) { + cardsData.cards.push(card); + } } } @@ -360,6 +423,9 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k } }; + _this.annotations = []; + _this.annotationsSrv = annotationsSrv; + _this.events.on('data-received', _this.onDataReceived); _this.events.on('data-snapshot-load', _this.onDataReceived); _this.events.on('data-error', _this.onDataError); diff --git a/dist/status_heatmap_ctrl.js.map b/dist/status_heatmap_ctrl.js.map index 2ae4371..2b04b8a 100644 --- a/dist/status_heatmap_ctrl.js.map +++ b/dist/status_heatmap_ctrl.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/status_heatmap_ctrl.js"],"names":["MetricsPanelCtrl","_","contextSrv","kbn","rendering","statusHeatmapOptionsEditor","ColorModeDiscrete","CANVAS","SVG","VALUE_INDEX","TIME_INDEX","panelDefaults","color","mode","cardColor","colorScale","exponent","colorScheme","defaultColor","thresholds","cards","cardMinWidth","cardVSpacing","cardHSpacing","cardRound","xAxis","show","showWeekends","minBucketWidthToShowWeekends","showCrosshair","labelFormat","yAxis","tooltip","legend","data","unitFormat","decimals","nullPointMode","yAxisSort","highlightCards","useMax","renderer","colorSchemes","name","value","invert","colorModes","opacityScales","StatusHeatmapCtrl","$scope","$injector","$rootScope","timeSrv","onRenderComplete","graph","chartWidth","renderingCompleted","calculateInterval","panelWidth","Math","ceil","$","window","width","panel","gridPos","w","max","minCardWidth","minSpacing","maxCardsCount","intervalMs","rangeMs","range","to","valueOf","from","discreteHelper","roundIntervalCeil","lowLimitMs","intervalOverride","interval","templateSrv","replace","scopedVars","datasource","slice","interval_to_ms","secondsToHms","onDataReceived","dataList","cardsData","convertToCards","render","onInitEditMode","addEditorTab","unitFormats","getUnitFormats","onRender","multipleValues","noColorDefined","updateCardsValuesHasColorInfo","onCardColorChange","newColor","onDataError","postRefresh","onEditorAddThreshold","push","onEditorRemoveThreshold","index","splice","onEditorRemoveThresholds","onEditorAddThreeLights","onEditorAddSolarized","link","scope","elem","attrs","ctrl","xBucketSize","yBucketSize","maxValue","minValue","targets","targetIndex","length","map","d","i","target","concat","toArray","keys","datapoints","j","card","id","values","si","s","datapoint","x","y","min","defaultsDeep","dataWarnings","title","tip","events","on","templateUrl"],"mappings":"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","file":"status_heatmap_ctrl.js","sourcesContent":["import { MetricsPanelCtrl } from 'app/plugins/sdk';\nimport _ from 'lodash';\nimport { contextSrv } from 'app/core/core';\nimport kbn from 'app/core/utils/kbn';\n\nimport './color_legend';\nimport rendering from './rendering';\n// import aggregates, { aggregatesMap } from './aggregates';\n// import fragments, { fragmentsMap } from './fragments';\n// import { labelFormats } from './xAxisLabelFormats';\nimport {statusHeatmapOptionsEditor} from './options_editor';\nimport {ColorModeDiscrete} from \"./color_mode_discrete\";\n\nconst CANVAS = 'CANVAS';\nconst SVG = 'SVG';\nconst VALUE_INDEX = 0,\n TIME_INDEX = 1;\n\nconst panelDefaults = {\n // aggregate: aggregates.AVG,\n // fragment: fragments.HOUR,\n color: {\n mode: 'spectrum',\n cardColor: '#b4ff00',\n colorScale: 'sqrt',\n exponent: 0.5,\n colorScheme: 'interpolateGnYlRd',\n // discrete mode settings\n defaultColor: '#757575',\n thresholds: [] // manual colors\n },\n cards: {\n cardMinWidth: 5,\n cardVSpacing: 2,\n cardHSpacing: 2,\n cardRound: null\n },\n xAxis: {\n show: true,\n showWeekends: true,\n minBucketWidthToShowWeekends: 4,\n showCrosshair: true,\n labelFormat: '%a %m/%d'\n },\n yAxis: {\n show: true,\n showCrosshair: false\n },\n tooltip: {\n show: true\n },\n legend: {\n show: true\n },\n data: {\n unitFormat: 'short',\n decimals: null\n },\n // how null points should be handled\n nullPointMode: 'as empty',\n yAxisSort: 'metrics',\n highlightCards: true,\n useMax: true\n};\n\nconst renderer = CANVAS;\n\nconst colorSchemes = [\n // Diverging\n { name: 'Spectral', value: 'interpolateSpectral', invert: 'always' },\n { name: 'RdYlGn', value: 'interpolateRdYlGn', invert: 'always' },\n { name: 'GnYlRd', value: 'interpolateGnYlRd', invert: 'always' },\n\n // Sequential (Single Hue)\n { name: 'Blues', value: 'interpolateBlues', invert: 'dark' },\n { name: 'Greens', value: 'interpolateGreens', invert: 'dark' },\n { name: 'Greys', value: 'interpolateGreys', invert: 'dark' },\n { name: 'Oranges', value: 'interpolateOranges', invert: 'dark' },\n { name: 'Purples', value: 'interpolatePurples', invert: 'dark' },\n { name: 'Reds', value: 'interpolateReds', invert: 'dark' },\n\n // Sequential (Multi-Hue)\n { name: 'BuGn', value: 'interpolateBuGn', invert: 'dark' },\n { name: 'BuPu', value: 'interpolateBuPu', invert: 'dark' },\n { name: 'GnBu', value: 'interpolateGnBu', invert: 'dark' },\n { name: 'OrRd', value: 'interpolateOrRd', invert: 'dark' },\n { name: 'PuBuGn', value: 'interpolatePuBuGn', invert: 'dark' },\n { name: 'PuBu', value: 'interpolatePuBu', invert: 'dark' },\n { name: 'PuRd', value: 'interpolatePuRd', invert: 'dark' },\n { name: 'RdPu', value: 'interpolateRdPu', invert: 'dark' },\n { name: 'YlGnBu', value: 'interpolateYlGnBu', invert: 'dark' },\n { name: 'YlGn', value: 'interpolateYlGn', invert: 'dark' },\n { name: 'YlOrBr', value: 'interpolateYlOrBr', invert: 'dark' },\n { name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'dark' }\n];\n\nlet colorModes = ['opacity', 'spectrum', 'discrete'];\nlet opacityScales = ['linear', 'sqrt'];\n\nexport class StatusHeatmapCtrl extends MetricsPanelCtrl {\n static templateUrl = 'module.html';\n\n constructor($scope, $injector, $rootScope, timeSrv) {\n super($scope, $injector);\n _.defaultsDeep(this.panel, panelDefaults);\n\n this.opacityScales = opacityScales;\n this.colorModes = colorModes;\n this.colorSchemes = colorSchemes;\n\n // default graph width for discrete card width calculation\n this.graph = {\n \"chartWidth\" : -1\n };\n\n this.multipleValues = false;\n this.noColorDefined = false;\n\n this.discreteHelper = new ColorModeDiscrete($scope);\n\n this.dataWarnings = {\n \"noColorDefined\": {\n title: 'Data has value with undefined color',\n tip: 'Check metric values, color values or define a new color',\n },\n \"multipleValues\": {\n title: 'Data has multiple values for one target',\n tip: 'Change targets definitions or set \"use max value\"',\n }\n };\n\n this.events.on('data-received', this.onDataReceived);\n this.events.on('data-snapshot-load', this.onDataReceived);\n this.events.on('data-error', this.onDataError);\n this.events.on('init-edit-mode', this.onInitEditMode);\n this.events.on('render', this.onRender);\n this.events.on('refresh', this.postRefresh);\n // custom event from rendering.js\n this.events.on('render-complete', this.onRenderComplete);\n }\n\n onRenderComplete = (data) => {\n this.graph.chartWidth = data.chartWidth;\n this.renderingCompleted();\n };\n\n // override calculateInterval for discrete color mode\n calculateInterval = () => {\n let panelWidth = Math.ceil($(window).width() * (this.panel.gridPos.w / 24));\n // approximate chartWidth because y axis ticks not rendered yet on first data receive.\n let chartWidth = _.max([\n panelWidth - 200,\n panelWidth/2\n ]);\n\n let minCardWidth = this.panel.cards.cardMinWidth;\n let minSpacing = this.panel.cards.cardHSpacing;\n let maxCardsCount = Math.ceil((chartWidth-minCardWidth) / (minCardWidth + minSpacing));\n\n let intervalMs;\n let rangeMs = this.range.to.valueOf() - this.range.from.valueOf();\n\n // this is minimal interval! kbn.round_interval will lower it.\n intervalMs = this.discreteHelper.roundIntervalCeil(rangeMs / maxCardsCount);\n\n // Calculate low limit of interval\n let lowLimitMs = 1; // 1 millisecond default low limit\n let intervalOverride = this.panel.interval;\n\n // if no panel interval check datasource\n if (intervalOverride) {\n intervalOverride = this.templateSrv.replace(intervalOverride, this.panel.scopedVars);\n } else if (this.datasource && this.datasource.interval) {\n intervalOverride = this.datasource.interval;\n }\n\n if (intervalOverride) {\n if (intervalOverride[0] === '>') {\n intervalOverride = intervalOverride.slice(1);\n }\n lowLimitMs = kbn.interval_to_ms(intervalOverride);\n }\n\n if (lowLimitMs > intervalMs) {\n intervalMs = lowLimitMs;\n }\n\n this.intervalMs = intervalMs;\n this.interval = kbn.secondsToHms(intervalMs / 1000);\n };\n\n onDataReceived = (dataList) => {\n this.data = dataList;\n this.cardsData = this.convertToCards(this.data);\n\n this.render();\n };\n\n onInitEditMode = () => {\n this.addEditorTab('Options', statusHeatmapOptionsEditor, 2);\n this.unitFormats = kbn.getUnitFormats();\n };\n\n onRender = () => {\n if (!this.data) { return; }\n\n this.multipleValues = false;\n if (!this.panel.useMax) {\n if (this.cardsData) {\n this.multipleValues = this.cardsData.multipleValues;\n }\n }\n\n this.noColorDefined = false;\n if (this.panel.color.mode === 'discrete') {\n this.discreteHelper.updateCardsValuesHasColorInfo();\n if (this.cardsData) {\n this.noColorDefined = this.cardsData.noColorDefined;\n }\n }\n };\n\n onCardColorChange = (newColor) => {\n this.panel.color.cardColor = newColor;\n this.render();\n };\n\n onDataError = () => {\n this.data = [];\n this.render();\n };\n\n postRefresh = () => {\n this.noColorDefined = false;\n };\n\n onEditorAddThreshold = () => {\n this.panel.color.thresholds.push({ color: this.panel.defaultColor });\n this.render();\n };\n\n onEditorRemoveThreshold = (index) => {\n this.panel.color.thresholds.splice(index, 1);\n this.render();\n };\n\n onEditorRemoveThresholds = () => {\n this.panel.color.thresholds = [];\n this.render();\n };\n\n onEditorAddThreeLights = () => {\n this.panel.color.thresholds.push({color: \"red\", value: 2, tooltip: \"error\" });\n this.panel.color.thresholds.push({color: \"yellow\", value: 1, tooltip: \"warning\" });\n this.panel.color.thresholds.push({color: \"green\", value: 0, tooltip: \"ok\" });\n this.render();\n };\n \n /* https://ethanschoonover.com/solarized/ */\n onEditorAddSolarized = () => {\n this.panel.color.thresholds.push({color: \"#b58900\", value: 0, tooltip: \"yellow\" });\n this.panel.color.thresholds.push({color: \"#cb4b16\", value: 1, tooltip: \"orange\" });\n this.panel.color.thresholds.push({color: \"#dc322f\", value: 2, tooltip: \"red\" });\n this.panel.color.thresholds.push({color: \"#d33682\", value: 3, tooltip: \"magenta\" });\n this.panel.color.thresholds.push({color: \"#6c71c4\", value: 4, tooltip: \"violet\" });\n this.panel.color.thresholds.push({color: \"#268bd2\", value: 5, tooltip: \"blue\" });\n this.panel.color.thresholds.push({color: \"#2aa198\", value: 6, tooltip: \"cyan\" });\n this.panel.color.thresholds.push({color: \"#859900\", value: 7, tooltip: \"green\" });\n this.render();\n }\n\n link = (scope, elem, attrs, ctrl) => {\n rendering(scope, elem, attrs, ctrl);\n };\n\n // group values into buckets by target\n convertToCards = (data) => {\n let cardsData = {\n cards: [],\n xBucketSize: 0,\n yBucketSize: 0,\n maxValue: 0,\n minValue: 0,\n multipleValues: false,\n noColorDefined: false,\n targets: [], // array of available unique targets\n targetIndex: {} // indices in data array for each of available unique targets\n };\n\n if (!data || data.length == 0) { return cardsData;}\n\n // Collect uniq timestamps from data and spread over targets and timestamps\n\n // collect uniq targets and their indices\n _.map(data, (d, i) => {\n cardsData.targetIndex[d.target] = _.concat(_.toArray(cardsData.targetIndex[d.target]), i)\n });\n\n // TODO add some logic for targets heirarchy\n cardsData.targets = _.keys(cardsData.targetIndex);\n cardsData.yBucketSize = cardsData.targets.length;\n // Maximum number of buckets over x axis\n cardsData.xBucketSize = _.max(_.map(data, d => d.datapoints.length));\n\n // Collect all values for each bucket from datapoints with similar target.\n // TODO aggregate values into buckets over datapoint[TIME_INDEX] not over datapoint index (j).\n for(let i = 0; i < cardsData.targets.length; i++) {\n let target = cardsData.targets[i];\n\n for (let j = 0; j < cardsData.xBucketSize; j++) {\n let card = {\n id: i*cardsData.xBucketSize + j,\n values: [],\n multipleValues: false,\n noColorDefined: false,\n };\n\n // collect values from all timeseries with target\n for (let si = 0; si < cardsData.targetIndex[target].length; si++) {\n let s = data[cardsData.targetIndex[target][si]];\n if (s.datapoints.length <= j) {\n continue;\n }\n let datapoint = s.datapoints[j];\n if (card.values.length === 0) {\n card.x = datapoint[TIME_INDEX];\n card.y = s.target;\n }\n card.values.push(datapoint[VALUE_INDEX]);\n }\n card.minValue = _.min(card.values);\n card.maxValue = _.max(card.values);\n if (card.values.length > 1) {\n cardsData.multipleValues = true;\n card.multipleValues = true;\n card.value = card.maxValue; // max value by default\n } else {\n card.value = card.maxValue; // max value by default\n }\n\n if (cardsData.maxValue < card.maxValue)\n cardsData.maxValue = card.maxValue;\n\n if (cardsData.minValue > card.minValue)\n cardsData.minValue = card.minValue;\n\n cardsData.cards.push(card);\n }\n }\n\n return cardsData;\n };\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/status_heatmap_ctrl.js"],"names":["MetricsPanelCtrl","_","contextSrv","kbn","rendering","statusHeatmapOptionsEditor","ColorModeDiscrete","CANVAS","SVG","VALUE_INDEX","TIME_INDEX","panelDefaults","color","mode","cardColor","colorScale","exponent","colorScheme","defaultColor","thresholds","cards","cardMinWidth","cardVSpacing","cardHSpacing","cardRound","xAxis","show","showWeekends","minBucketWidthToShowWeekends","showCrosshair","labelFormat","yAxis","tooltip","legend","data","unitFormat","decimals","nullPointMode","yAxisSort","highlightCards","useMax","renderer","colorSchemes","name","value","invert","colorModes","opacityScales","StatusHeatmapCtrl","$scope","$injector","$rootScope","timeSrv","annotationsSrv","onRenderComplete","graph","chartWidth","renderingCompleted","calculateInterval","panelWidth","Math","ceil","$","window","width","panel","gridPos","w","max","minCardWidth","minSpacing","maxCardsCount","intervalMs","rangeMs","range","to","valueOf","from","discreteHelper","roundIntervalCeil","lowLimitMs","intervalOverride","interval","templateSrv","replace","scopedVars","datasource","slice","interval_to_ms","secondsToHms","issueQueries","annotationsPromise","getAnnotations","dashboard","datasourcePromises","then","onDataReceived","dataList","cardsData","convertToCards","loading","result","annotations","length","render","onInitEditMode","addEditorTab","unitFormats","getUnitFormats","onRender","multipleValues","noColorDefined","updateCardsValuesHasColorInfo","onCardColorChange","newColor","onDataError","postRefresh","onEditorAddThreshold","push","onEditorRemoveThreshold","index","splice","onEditorRemoveThresholds","onEditorAddThreeLights","onEditorAddSolarized","link","scope","elem","attrs","ctrl","xBucketSize","yBucketSize","maxValue","minValue","targets","targetIndex","map","d","i","target","concat","toArray","keys","datapoints","j","card","id","values","y","x","si","s","datapoint","min","defaultsDeep","dataWarnings","title","tip","events","on","templateUrl"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAASA,sB,kBAAAA,gB;;AACFC,O;;AACEC,gB,gBAAAA,U;;AACFC,S;;AAGAC,e;;AAICC,gC,mBAAAA,0B;;AACAC,uB,wBAAAA,iB;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEFC,Y,GAAS,Q;AACTC,S,GAAM,K;AACNC,iB,GAAc,C;AACdC,gB,GAAa,C;AAEbC,mB,GAAgB;AACpB;AACA;AACAC,eAAO;AACLC,gBAAM,UADD;AAELC,qBAAW,SAFN;AAGLC,sBAAY,MAHP;AAILC,oBAAU,GAJL;AAKLC,uBAAa,mBALR;AAML;AACAC,wBAAc,SAPT;AAQLC,sBAAY,EARP,CAQU;AARV,SAHa;AAapBC,eAAO;AACLC,wBAAc,CADT;AAELC,wBAAc,CAFT;AAGLC,wBAAc,CAHT;AAILC,qBAAW;AAJN,SAba;AAmBpBC,eAAO;AACLC,gBAAM,IADD;AAELC,wBAAc,IAFT;AAGLC,wCAA8B,CAHzB;AAILC,yBAAe,IAJV;AAKLC,uBAAa;AALR,SAnBa;AA0BpBC,eAAO;AACLL,gBAAM,IADD;AAELG,yBAAe;AAFV,SA1Ba;AA8BpBG,iBAAS;AACPN,gBAAM;AADC,SA9BW;AAiCpBO,gBAAQ;AACNP,gBAAM;AADA,SAjCY;AAoCpBQ,cAAM;AACJC,sBAAY,OADR;AAEJC,oBAAU;AAFN,SApCc;AAwCpB;AACAC,uBAAe,UAzCK;AA0CpBC,mBAAW,SA1CS;AA2CpBC,wBAAgB,IA3CI;AA4CpBC,gBAAQ;AA5CY,O;AA+ChBC,c,GAAWlC,M;AAEXmC,kB,GAAe;AACnB;AACA,QAAEC,MAAM,UAAR,EAAoBC,OAAO,qBAA3B,EAAkDC,QAAQ,QAA1D,EAFmB,EAGnB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,QAAtD,EAHmB,EAInB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,QAAtD,EAJmB;;AAMnB;AACA,QAAEF,MAAM,OAAR,EAAiBC,OAAO,kBAAxB,EAA4CC,QAAQ,MAApD,EAPmB,EAQnB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,MAAtD,EARmB,EASnB,EAAEF,MAAM,OAAR,EAAiBC,OAAO,kBAAxB,EAA4CC,QAAQ,MAApD,EATmB,EAUnB,EAAEF,MAAM,SAAR,EAAmBC,OAAO,oBAA1B,EAAgDC,QAAQ,MAAxD,EAVmB,EAWnB,EAAEF,MAAM,SAAR,EAAmBC,OAAO,oBAA1B,EAAgDC,QAAQ,MAAxD,EAXmB,EAYnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAZmB;;AAcnB;AACA,QAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAfmB,EAgBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAhBmB,EAiBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAjBmB,EAkBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAlBmB,EAmBnB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,MAAtD,EAnBmB,EAoBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EApBmB,EAqBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EArBmB,EAsBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAtBmB,EAuBnB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,MAAtD,EAvBmB,EAwBnB,EAAEF,MAAM,MAAR,EAAgBC,OAAO,iBAAvB,EAA0CC,QAAQ,MAAlD,EAxBmB,EAyBnB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,MAAtD,EAzBmB,EA0BnB,EAAEF,MAAM,QAAR,EAAkBC,OAAO,mBAAzB,EAA8CC,QAAQ,MAAtD,EA1BmB,C;AA6BjBC,gB,GAAa,CAAC,SAAD,EAAY,UAAZ,EAAwB,UAAxB,C;AACbC,mB,GAAgB,CAAC,QAAD,EAAW,MAAX,C;;mCAEPC,iB;;;AAGX;AACA,mCAAYC,MAAZ,EAAoBC,SAApB,EAA+BC,UAA/B,EAA2CC,OAA3C,EAAoDC,cAApD,EAAoE;AAAA;;AAAA,4IAC5DJ,MAD4D,EACpDC,SADoD;;AAAA,gBA0CpEI,gBA1CoE,GA0CjD,UAACpB,IAAD,EAAU;AAC3B,kBAAKqB,KAAL,CAAWC,UAAX,GAAwBtB,KAAKsB,UAA7B;AACA,kBAAKC,kBAAL;AACD,WA7CmE;;AAAA,gBAgDpEC,iBAhDoE,GAgDhD,YAAM;AACxB,gBAAIC,aAAaC,KAAKC,IAAL,CAAUC,EAAEC,MAAF,EAAUC,KAAV,MAAqB,MAAKC,KAAL,CAAWC,OAAX,CAAmBC,CAAnB,GAAuB,EAA5C,CAAV,CAAjB;AACA;AACA,gBAAIX,aAAavD,EAAEmE,GAAF,CAAM,CACnBT,aAAa,GADM,EAEnBA,aAAW,CAFQ,CAAN,CAAjB;;AAKA,gBAAIU,eAAe,MAAKJ,KAAL,CAAW7C,KAAX,CAAiBC,YAApC;AACA,gBAAIiD,aAAa,MAAKL,KAAL,CAAW7C,KAAX,CAAiBG,YAAlC;AACA,gBAAIgD,gBAAgBX,KAAKC,IAAL,CAAU,CAACL,aAAWa,YAAZ,KAA6BA,eAAeC,UAA5C,CAAV,CAApB;;AAEA,gBAAIE,mBAAJ;AACA,gBAAIC,UAAU,MAAKC,KAAL,CAAWC,EAAX,CAAcC,OAAd,KAA0B,MAAKF,KAAL,CAAWG,IAAX,CAAgBD,OAAhB,EAAxC;;AAEA;AACAJ,yBAAa,MAAKM,cAAL,CAAoBC,iBAApB,CAAsCN,UAAUF,aAAhD,CAAb;;AAEA;AACA,gBAAIS,aAAa,CAAjB,CAnBwB,CAmBJ;AACpB,gBAAIC,mBAAmB,MAAKhB,KAAL,CAAWiB,QAAlC;;AAEA;AACA,gBAAID,gBAAJ,EAAsB;AACpBA,iCAAmB,MAAKE,WAAL,CAAiBC,OAAjB,CAAyBH,gBAAzB,EAA2C,MAAKhB,KAAL,CAAWoB,UAAtD,CAAnB;AACD,aAFD,MAEO,IAAI,MAAKC,UAAL,IAAmB,MAAKA,UAAL,CAAgBJ,QAAvC,EAAiD;AACtDD,iCAAmB,MAAKK,UAAL,CAAgBJ,QAAnC;AACD;;AAED,gBAAID,gBAAJ,EAAsB;AACpB,kBAAIA,iBAAiB,CAAjB,MAAwB,GAA5B,EAAiC;AAC/BA,mCAAmBA,iBAAiBM,KAAjB,CAAuB,CAAvB,CAAnB;AACD;AACDP,2BAAa7E,IAAIqF,cAAJ,CAAmBP,gBAAnB,CAAb;AACD;;AAED,gBAAID,aAAaR,UAAjB,EAA6B;AAC3BA,2BAAaQ,UAAb;AACD;;AAED,kBAAKR,UAAL,GAAkBA,UAAlB;AACA,kBAAKU,QAAL,GAAgB/E,IAAIsF,YAAJ,CAAiBjB,aAAa,IAA9B,CAAhB;AACD,WA1FmE;;AAAA,gBA4FpEkB,YA5FoE,GA4FrD,UAACJ,UAAD,EAAgB;AAC7B,kBAAKK,kBAAL,GAA0B,MAAKtC,cAAL,CAAoBuC,cAApB,CAAmC;AAC3DC,yBAAW,MAAKA,SAD2C;AAE3D5B,qBAAO,MAAKA,KAF+C;AAG3DS,qBAAO,MAAKA;AAH+C,aAAnC,CAA1B;;AAMA;;;;;;AAMA,mBAAO,MAAKrB,cAAL,CAAoByC,kBAApB,CAAuCC,IAAvC,CAA4C,aAAK;AACtD,0JAA0BT,UAA1B;AACD,aAFM,CAAP;AAGD,WA5GmE;;AAAA,gBA+GpEU,cA/GoE,GA+GnD,UAACC,QAAD,EAAc;AAC7B,kBAAK/D,IAAL,GAAiB+D,QAAjB;AACA,kBAAKC,SAAL,GAAiB,MAAKC,cAAL,CAAoB,MAAKjE,IAAzB,CAAjB;;AAEA,kBAAKyD,kBAAL,CAAwBI,IAAxB,CACE,kBAAU;AACR,oBAAKK,OAAL,GAAe,KAAf;AACA;AACA,kBAAIC,OAAOC,WAAP,IAAsBD,OAAOC,WAAP,CAAmBC,MAAnB,GAA4B,CAAtD,EAAyD;AACvD,sBAAKD,WAAL,GAAmBD,OAAOC,WAA1B;AACD,eAFD,MAEO;AACL,sBAAKA,WAAL,GAAmB,IAAnB;AACD;AACD,oBAAKE,MAAL;AACD,aAVH,EAWE,YAAM;AACJ,oBAAKJ,OAAL,GAAe,KAAf;AACA,oBAAKE,WAAL,GAAmB,IAAnB;AACA,oBAAKE,MAAL;AACD,aAfH;;AAkBA;AACD,WAtImE;;AAAA,gBAwIpEC,cAxIoE,GAwInD,YAAM;AACrB,kBAAKC,YAAL,CAAkB,SAAlB,EAA6BrG,0BAA7B,EAAyD,CAAzD;AACA,kBAAKsG,WAAL,GAAmBxG,IAAIyG,cAAJ,EAAnB;AACD,WA3ImE;;AAAA,gBA6IpEC,QA7IoE,GA6IzD,YAAM;AACf,gBAAI,CAAC,MAAK3E,IAAV,EAAgB;AAAE;AAAS;;AAE3B,kBAAK4E,cAAL,GAAsB,KAAtB;AACA,gBAAI,CAAC,MAAK7C,KAAL,CAAWzB,MAAhB,EAAwB;AACtB,kBAAI,MAAK0D,SAAT,EAAoB;AAClB,sBAAKY,cAAL,GAAsB,MAAKZ,SAAL,CAAeY,cAArC;AACD;AACF;;AAED,kBAAKC,cAAL,GAAsB,KAAtB;AACA,gBAAI,MAAK9C,KAAL,CAAWrD,KAAX,CAAiBC,IAAjB,KAA0B,UAA9B,EAA0C;AACxC,oBAAKiE,cAAL,CAAoBkC,6BAApB;AACA,kBAAI,MAAKd,SAAT,EAAoB;AAClB,sBAAKa,cAAL,GAAsB,MAAKb,SAAL,CAAea,cAArC;AACD;AACF;AACF,WA9JmE;;AAAA,gBAgKpEE,iBAhKoE,GAgKhD,UAACC,QAAD,EAAc;AAChC,kBAAKjD,KAAL,CAAWrD,KAAX,CAAiBE,SAAjB,GAA6BoG,QAA7B;AACA,kBAAKV,MAAL;AACD,WAnKmE;;AAAA,gBAqKpEW,WArKoE,GAqKtD,YAAM;AAClB,kBAAKjF,IAAL,GAAY,EAAZ;AACA,kBAAKoE,WAAL,GAAmB,EAAnB;AACA,kBAAKE,MAAL;AACD,WAzKmE;;AAAA,gBA2KpEY,WA3KoE,GA2KtD,YAAM;AAClB,kBAAKL,cAAL,GAAsB,KAAtB;AACD,WA7KmE;;AAAA,gBA+KpEM,oBA/KoE,GA+K7C,YAAM;AAC3B,kBAAKpD,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAE1G,OAAO,MAAKqD,KAAL,CAAW/C,YAApB,EAAjC;AACA,kBAAKsF,MAAL;AACD,WAlLmE;;AAAA,gBAoLpEe,uBApLoE,GAoL1C,UAACC,KAAD,EAAW;AACnC,kBAAKvD,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BsG,MAA5B,CAAmCD,KAAnC,EAA0C,CAA1C;AACA,kBAAKhB,MAAL;AACD,WAvLmE;;AAAA,gBAyLpEkB,wBAzLoE,GAyLzC,YAAM;AAC/B,kBAAKzD,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,GAA8B,EAA9B;AACA,kBAAKqF,MAAL;AACD,WA5LmE;;AAAA,gBA8LpEmB,sBA9LoE,GA8L3C,YAAM;AAC7B,kBAAK1D,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,KAAR,EAAegC,OAAO,CAAtB,EAAyBZ,SAAS,OAAlC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,QAAR,EAAkBgC,OAAO,CAAzB,EAA4BZ,SAAS,SAArC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,OAAR,EAAiBgC,OAAO,CAAxB,EAA2BZ,SAAS,IAApC,EAAjC;AACA,kBAAKwE,MAAL;AACD,WAnMmE;;AAAA,gBAsMpEoB,oBAtMoE,GAsM7C,YAAM;AAC3B,kBAAK3D,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,QAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,QAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,KAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,SAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,QAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,MAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,MAAtC,EAAjC;AACA,kBAAKiC,KAAL,CAAWrD,KAAX,CAAiBO,UAAjB,CAA4BmG,IAA5B,CAAiC,EAAC1G,OAAO,SAAR,EAAmBgC,OAAO,CAA1B,EAA6BZ,SAAS,OAAtC,EAAjC;AACA,kBAAKwE,MAAL;AACD,WAhNmE;;AAAA,gBAkNpEqB,IAlNoE,GAkN7D,UAACC,KAAD,EAAQC,IAAR,EAAcC,KAAd,EAAqBC,IAArB,EAA8B;AACnC7H,sBAAU0H,KAAV,EAAiBC,IAAjB,EAAuBC,KAAvB,EAA8BC,IAA9B;AACD,WApNmE;;AAAA,gBAuNpE9B,cAvNoE,GAuNnD,UAACjE,IAAD,EAAU;AACzB,gBAAIgE,YAAY;AACd9E,qBAAO,EADO;AAEd8G,2BAAa,CAFC;AAGdC,2BAAa,CAHC;AAIdC,wBAAU,CAJI;AAKdC,wBAAU,CALI;AAMdvB,8BAAgB,KANF;AAOdC,8BAAgB,KAPF;AAQduB,uBAAS,EARK,EAQD;AACbC,2BAAa,EATC,CASE;AATF,aAAhB;;AAYA,gBAAI,CAACrG,IAAD,IAASA,KAAKqE,MAAL,IAAe,CAA5B,EAA+B;AAAE,qBAAOL,SAAP;AAAkB;;AAEnD;;AAEA;AACAjG,cAAEuI,GAAF,CAAMtG,IAAN,EAAY,UAACuG,CAAD,EAAIC,CAAJ,EAAU;AACpBxC,wBAAUqC,WAAV,CAAsBE,EAAEE,MAAxB,IAAkC1I,EAAE2I,MAAF,CAAS3I,EAAE4I,OAAF,CAAU3C,UAAUqC,WAAV,CAAsBE,EAAEE,MAAxB,CAAV,CAAT,EAAqDD,CAArD,CAAlC;AACD,aAFD;;AAIA;AACAxC,sBAAUoC,OAAV,GAAoBrI,EAAE6I,IAAF,CAAO5C,UAAUqC,WAAjB,CAApB;AACArC,sBAAUiC,WAAV,GAAwBjC,UAAUoC,OAAV,CAAkB/B,MAA1C;AACA;AACAL,sBAAUgC,WAAV,GAAwBjI,EAAEmE,GAAF,CAAMnE,EAAEuI,GAAF,CAAMtG,IAAN,EAAY;AAAA,qBAAKuG,EAAEM,UAAF,CAAaxC,MAAlB;AAAA,aAAZ,CAAN,CAAxB;;AAEA;AACA;AACA,iBAAI,IAAImC,IAAI,CAAZ,EAAeA,IAAIxC,UAAUoC,OAAV,CAAkB/B,MAArC,EAA6CmC,GAA7C,EAAkD;AAChD,kBAAIC,SAASzC,UAAUoC,OAAV,CAAkBI,CAAlB,CAAb;;AAEA,mBAAK,IAAIM,IAAI,CAAb,EAAgBA,IAAI9C,UAAUgC,WAA9B,EAA2Cc,GAA3C,EAAgD;AAC9C,oBAAIC,OAAO;AACTC,sBAAIR,IAAExC,UAAUgC,WAAZ,GAA0Bc,CADrB;AAETG,0BAAQ,EAFC;AAGTrC,kCAAgB,KAHP;AAITC,kCAAgB,KAJP;AAKTqC,qBAAGT,MALM;AAMTU,qBAAG,CAAC;AANK,iBAAX;;AASA;AACA,qBAAK,IAAIC,KAAK,CAAd,EAAiBA,KAAKpD,UAAUqC,WAAV,CAAsBI,MAAtB,EAA8BpC,MAApD,EAA4D+C,IAA5D,EAAkE;AAChE,sBAAIC,IAAIrH,KAAKgE,UAAUqC,WAAV,CAAsBI,MAAtB,EAA8BW,EAA9B,CAAL,CAAR;AACA,sBAAIC,EAAER,UAAF,CAAaxC,MAAb,IAAuByC,CAA3B,EAA8B;AAC5B;AACD;AACD,sBAAIQ,YAAYD,EAAER,UAAF,CAAaC,CAAb,CAAhB;AACA,sBAAIC,KAAKE,MAAL,CAAY5C,MAAZ,KAAuB,CAA3B,EAA8B;AAC5B0C,yBAAKI,CAAL,GAASG,UAAU9I,UAAV,CAAT;AACD;AACDuI,uBAAKE,MAAL,CAAY7B,IAAZ,CAAiBkC,UAAU/I,WAAV,CAAjB;AACD;AACDwI,qBAAKZ,QAAL,GAAgBpI,EAAEwJ,GAAF,CAAMR,KAAKE,MAAX,CAAhB;AACAF,qBAAKb,QAAL,GAAgBnI,EAAEmE,GAAF,CAAM6E,KAAKE,MAAX,CAAhB;AACA,oBAAIF,KAAKE,MAAL,CAAY5C,MAAZ,GAAqB,CAAzB,EAA4B;AAC1BL,4BAAUY,cAAV,GAA2B,IAA3B;AACAmC,uBAAKnC,cAAL,GAAsB,IAAtB;AACAmC,uBAAKrG,KAAL,GAAaqG,KAAKb,QAAlB,CAH0B,CAGE;AAC7B,iBAJD,MAIO;AACLa,uBAAKrG,KAAL,GAAaqG,KAAKb,QAAlB,CADK,CACuB;AAC7B;;AAED,oBAAIlC,UAAUkC,QAAV,GAAqBa,KAAKb,QAA9B,EACElC,UAAUkC,QAAV,GAAqBa,KAAKb,QAA1B;;AAEF,oBAAIlC,UAAUmC,QAAV,GAAqBY,KAAKZ,QAA9B,EACEnC,UAAUmC,QAAV,GAAqBY,KAAKZ,QAA1B;;AAEF,oBAAIY,KAAKI,CAAL,IAAU,CAAC,CAAf,EAAkB;AAClBnD,4BAAU9E,KAAV,CAAgBkG,IAAhB,CAAqB2B,IAArB;AACC;AACF;AACF;;AAED,mBAAO/C,SAAP;AACD,WArSmE;;AAElEjG,YAAEyJ,YAAF,CAAe,MAAKzF,KAApB,EAA2BtD,aAA3B;;AAEA,gBAAKoC,aAAL,GAAqBA,aAArB;AACA,gBAAKD,UAAL,GAAkBA,UAAlB;AACA,gBAAKJ,YAAL,GAAoBA,YAApB;;AAEA;AACA,gBAAKa,KAAL,GAAa;AACX,0BAAe,CAAC;AADL,WAAb;;AAIA,gBAAKuD,cAAL,GAAsB,KAAtB;AACA,gBAAKC,cAAL,GAAsB,KAAtB;;AAEA,gBAAKjC,cAAL,GAAsB,IAAIxE,iBAAJ,CAAsB2C,MAAtB,CAAtB;;AAEA,gBAAK0G,YAAL,GAAoB;AAClB,8BAAkB;AAChBC,qBAAO,qCADS;AAEhBC,mBAAK;AAFW,aADA;AAKlB,8BAAkB;AAChBD,qBAAO,yCADS;AAEhBC,mBAAK;AAFW;AALA,WAApB;;AAWA,gBAAKvD,WAAL,GAAmB,EAAnB;AACA,gBAAKjD,cAAL,GAAsBA,cAAtB;;AAEA,gBAAKyG,MAAL,CAAYC,EAAZ,CAAe,eAAf,EAAgC,MAAK/D,cAArC;AACA,gBAAK8D,MAAL,CAAYC,EAAZ,CAAe,oBAAf,EAAqC,MAAK/D,cAA1C;AACA,gBAAK8D,MAAL,CAAYC,EAAZ,CAAe,YAAf,EAA6B,MAAK5C,WAAlC;AACA,gBAAK2C,MAAL,CAAYC,EAAZ,CAAe,gBAAf,EAAiC,MAAKtD,cAAtC;AACA,gBAAKqD,MAAL,CAAYC,EAAZ,CAAe,QAAf,EAAyB,MAAKlD,QAA9B;AACA,gBAAKiD,MAAL,CAAYC,EAAZ,CAAe,SAAf,EAA0B,MAAK3C,WAA/B;AACA;AACA,gBAAK0C,MAAL,CAAYC,EAAZ,CAAe,iBAAf,EAAkC,MAAKzG,gBAAvC;AAvCkE;AAwCnE;;AAOD;;;AAsJA;;;AAiBA;;;;QA1NqCtD,gB;;;;AAA1BgD,uB,CACJgH,W,GAAc,a","file":"status_heatmap_ctrl.js","sourcesContent":["import { MetricsPanelCtrl } from 'app/plugins/sdk';\nimport _ from 'lodash';\nimport { contextSrv } from 'app/core/core';\nimport kbn from 'app/core/utils/kbn';\n\nimport './color_legend';\nimport rendering from './rendering';\n// import aggregates, { aggregatesMap } from './aggregates';\n// import fragments, { fragmentsMap } from './fragments';\n// import { labelFormats } from './xAxisLabelFormats';\nimport {statusHeatmapOptionsEditor} from './options_editor';\nimport {ColorModeDiscrete} from \"./color_mode_discrete\";\n\nconst CANVAS = 'CANVAS';\nconst SVG = 'SVG';\nconst VALUE_INDEX = 0,\n TIME_INDEX = 1;\n\nconst panelDefaults = {\n // aggregate: aggregates.AVG,\n // fragment: fragments.HOUR,\n color: {\n mode: 'spectrum',\n cardColor: '#b4ff00',\n colorScale: 'sqrt',\n exponent: 0.5,\n colorScheme: 'interpolateGnYlRd',\n // discrete mode settings\n defaultColor: '#757575',\n thresholds: [] // manual colors\n },\n cards: {\n cardMinWidth: 5,\n cardVSpacing: 2,\n cardHSpacing: 2,\n cardRound: null\n },\n xAxis: {\n show: true,\n showWeekends: true,\n minBucketWidthToShowWeekends: 4,\n showCrosshair: true,\n labelFormat: '%a %m/%d'\n },\n yAxis: {\n show: true,\n showCrosshair: false\n },\n tooltip: {\n show: true\n },\n legend: {\n show: true\n },\n data: {\n unitFormat: 'short',\n decimals: null\n },\n // how null points should be handled\n nullPointMode: 'as empty',\n yAxisSort: 'metrics',\n highlightCards: true,\n useMax: true\n};\n\nconst renderer = CANVAS;\n\nconst colorSchemes = [\n // Diverging\n { name: 'Spectral', value: 'interpolateSpectral', invert: 'always' },\n { name: 'RdYlGn', value: 'interpolateRdYlGn', invert: 'always' },\n { name: 'GnYlRd', value: 'interpolateGnYlRd', invert: 'always' },\n\n // Sequential (Single Hue)\n { name: 'Blues', value: 'interpolateBlues', invert: 'dark' },\n { name: 'Greens', value: 'interpolateGreens', invert: 'dark' },\n { name: 'Greys', value: 'interpolateGreys', invert: 'dark' },\n { name: 'Oranges', value: 'interpolateOranges', invert: 'dark' },\n { name: 'Purples', value: 'interpolatePurples', invert: 'dark' },\n { name: 'Reds', value: 'interpolateReds', invert: 'dark' },\n\n // Sequential (Multi-Hue)\n { name: 'BuGn', value: 'interpolateBuGn', invert: 'dark' },\n { name: 'BuPu', value: 'interpolateBuPu', invert: 'dark' },\n { name: 'GnBu', value: 'interpolateGnBu', invert: 'dark' },\n { name: 'OrRd', value: 'interpolateOrRd', invert: 'dark' },\n { name: 'PuBuGn', value: 'interpolatePuBuGn', invert: 'dark' },\n { name: 'PuBu', value: 'interpolatePuBu', invert: 'dark' },\n { name: 'PuRd', value: 'interpolatePuRd', invert: 'dark' },\n { name: 'RdPu', value: 'interpolateRdPu', invert: 'dark' },\n { name: 'YlGnBu', value: 'interpolateYlGnBu', invert: 'dark' },\n { name: 'YlGn', value: 'interpolateYlGn', invert: 'dark' },\n { name: 'YlOrBr', value: 'interpolateYlOrBr', invert: 'dark' },\n { name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'dark' }\n];\n\nlet colorModes = ['opacity', 'spectrum', 'discrete'];\nlet opacityScales = ['linear', 'sqrt'];\n\nexport class StatusHeatmapCtrl extends MetricsPanelCtrl {\n static templateUrl = 'module.html';\n\n /** @ngInject */\n constructor($scope, $injector, $rootScope, timeSrv, annotationsSrv) {\n super($scope, $injector);\n _.defaultsDeep(this.panel, panelDefaults);\n\n this.opacityScales = opacityScales;\n this.colorModes = colorModes;\n this.colorSchemes = colorSchemes;\n\n // default graph width for discrete card width calculation\n this.graph = {\n \"chartWidth\" : -1\n };\n\n this.multipleValues = false;\n this.noColorDefined = false;\n\n this.discreteHelper = new ColorModeDiscrete($scope);\n\n this.dataWarnings = {\n \"noColorDefined\": {\n title: 'Data has value with undefined color',\n tip: 'Check metric values, color values or define a new color',\n },\n \"multipleValues\": {\n title: 'Data has multiple values for one target',\n tip: 'Change targets definitions or set \"use max value\"',\n }\n };\n\n this.annotations = [];\n this.annotationsSrv = annotationsSrv;\n\n this.events.on('data-received', this.onDataReceived);\n this.events.on('data-snapshot-load', this.onDataReceived);\n this.events.on('data-error', this.onDataError);\n this.events.on('init-edit-mode', this.onInitEditMode);\n this.events.on('render', this.onRender);\n this.events.on('refresh', this.postRefresh);\n // custom event from rendering.js\n this.events.on('render-complete', this.onRenderComplete);\n }\n\n onRenderComplete = (data) => {\n this.graph.chartWidth = data.chartWidth;\n this.renderingCompleted();\n };\n\n // override calculateInterval for discrete color mode\n calculateInterval = () => {\n let panelWidth = Math.ceil($(window).width() * (this.panel.gridPos.w / 24));\n // approximate chartWidth because y axis ticks not rendered yet on first data receive.\n let chartWidth = _.max([\n panelWidth - 200,\n panelWidth/2\n ]);\n\n let minCardWidth = this.panel.cards.cardMinWidth;\n let minSpacing = this.panel.cards.cardHSpacing;\n let maxCardsCount = Math.ceil((chartWidth-minCardWidth) / (minCardWidth + minSpacing));\n\n let intervalMs;\n let rangeMs = this.range.to.valueOf() - this.range.from.valueOf();\n\n // this is minimal interval! kbn.round_interval will lower it.\n intervalMs = this.discreteHelper.roundIntervalCeil(rangeMs / maxCardsCount);\n\n // Calculate low limit of interval\n let lowLimitMs = 1; // 1 millisecond default low limit\n let intervalOverride = this.panel.interval;\n\n // if no panel interval check datasource\n if (intervalOverride) {\n intervalOverride = this.templateSrv.replace(intervalOverride, this.panel.scopedVars);\n } else if (this.datasource && this.datasource.interval) {\n intervalOverride = this.datasource.interval;\n }\n\n if (intervalOverride) {\n if (intervalOverride[0] === '>') {\n intervalOverride = intervalOverride.slice(1);\n }\n lowLimitMs = kbn.interval_to_ms(intervalOverride);\n }\n\n if (lowLimitMs > intervalMs) {\n intervalMs = lowLimitMs;\n }\n\n this.intervalMs = intervalMs;\n this.interval = kbn.secondsToHms(intervalMs / 1000);\n };\n\n issueQueries = (datasource) => {\n this.annotationsPromise = this.annotationsSrv.getAnnotations({\n dashboard: this.dashboard,\n panel: this.panel,\n range: this.range,\n });\n\n /* Wait for annotationSrv requests to get datasources to\n * resolve before issuing queries. This allows the annotations\n * service to fire annotations queries before graph queries\n * (but not wait for completion). This resolves\n * issue 11806.\n */\n return this.annotationsSrv.datasourcePromises.then(r => {\n return super.issueQueries(datasource);\n });\n }\n\n\n onDataReceived = (dataList) => {\n this.data = dataList;\n this.cardsData = this.convertToCards(this.data);\n\n this.annotationsPromise.then(\n result => {\n this.loading = false;\n //this.alertState = result.alertState;\n if (result.annotations && result.annotations.length > 0) {\n this.annotations = result.annotations;\n } else {\n this.annotations = null;\n }\n this.render();\n },\n () => {\n this.loading = false;\n this.annotations = null;\n this.render();\n }\n );\n\n //this.render();\n };\n\n onInitEditMode = () => {\n this.addEditorTab('Options', statusHeatmapOptionsEditor, 2);\n this.unitFormats = kbn.getUnitFormats();\n };\n\n onRender = () => {\n if (!this.data) { return; }\n\n this.multipleValues = false;\n if (!this.panel.useMax) {\n if (this.cardsData) {\n this.multipleValues = this.cardsData.multipleValues;\n }\n }\n\n this.noColorDefined = false;\n if (this.panel.color.mode === 'discrete') {\n this.discreteHelper.updateCardsValuesHasColorInfo();\n if (this.cardsData) {\n this.noColorDefined = this.cardsData.noColorDefined;\n }\n }\n };\n\n onCardColorChange = (newColor) => {\n this.panel.color.cardColor = newColor;\n this.render();\n };\n\n onDataError = () => {\n this.data = [];\n this.annotations = [];\n this.render();\n };\n\n postRefresh = () => {\n this.noColorDefined = false;\n };\n\n onEditorAddThreshold = () => {\n this.panel.color.thresholds.push({ color: this.panel.defaultColor });\n this.render();\n };\n\n onEditorRemoveThreshold = (index) => {\n this.panel.color.thresholds.splice(index, 1);\n this.render();\n };\n\n onEditorRemoveThresholds = () => {\n this.panel.color.thresholds = [];\n this.render();\n };\n\n onEditorAddThreeLights = () => {\n this.panel.color.thresholds.push({color: \"red\", value: 2, tooltip: \"error\" });\n this.panel.color.thresholds.push({color: \"yellow\", value: 1, tooltip: \"warning\" });\n this.panel.color.thresholds.push({color: \"green\", value: 0, tooltip: \"ok\" });\n this.render();\n };\n \n /* https://ethanschoonover.com/solarized/ */\n onEditorAddSolarized = () => {\n this.panel.color.thresholds.push({color: \"#b58900\", value: 0, tooltip: \"yellow\" });\n this.panel.color.thresholds.push({color: \"#cb4b16\", value: 1, tooltip: \"orange\" });\n this.panel.color.thresholds.push({color: \"#dc322f\", value: 2, tooltip: \"red\" });\n this.panel.color.thresholds.push({color: \"#d33682\", value: 3, tooltip: \"magenta\" });\n this.panel.color.thresholds.push({color: \"#6c71c4\", value: 4, tooltip: \"violet\" });\n this.panel.color.thresholds.push({color: \"#268bd2\", value: 5, tooltip: \"blue\" });\n this.panel.color.thresholds.push({color: \"#2aa198\", value: 6, tooltip: \"cyan\" });\n this.panel.color.thresholds.push({color: \"#859900\", value: 7, tooltip: \"green\" });\n this.render();\n }\n\n link = (scope, elem, attrs, ctrl) => {\n rendering(scope, elem, attrs, ctrl);\n };\n\n // group values into buckets by target\n convertToCards = (data) => {\n let cardsData = {\n cards: [],\n xBucketSize: 0,\n yBucketSize: 0,\n maxValue: 0,\n minValue: 0,\n multipleValues: false,\n noColorDefined: false,\n targets: [], // array of available unique targets\n targetIndex: {} // indices in data array for each of available unique targets\n };\n\n if (!data || data.length == 0) { return cardsData;}\n\n // Collect uniq timestamps from data and spread over targets and timestamps\n\n // collect uniq targets and their indices\n _.map(data, (d, i) => {\n cardsData.targetIndex[d.target] = _.concat(_.toArray(cardsData.targetIndex[d.target]), i)\n });\n\n // TODO add some logic for targets heirarchy\n cardsData.targets = _.keys(cardsData.targetIndex);\n cardsData.yBucketSize = cardsData.targets.length;\n // Maximum number of buckets over x axis\n cardsData.xBucketSize = _.max(_.map(data, d => d.datapoints.length));\n\n // Collect all values for each bucket from datapoints with similar target.\n // TODO aggregate values into buckets over datapoint[TIME_INDEX] not over datapoint index (j).\n for(let i = 0; i < cardsData.targets.length; i++) {\n let target = cardsData.targets[i];\n\n for (let j = 0; j < cardsData.xBucketSize; j++) {\n let card = {\n id: i*cardsData.xBucketSize + j,\n values: [],\n multipleValues: false,\n noColorDefined: false,\n y: target,\n x: -1,\n };\n\n // collect values from all timeseries with target\n for (let si = 0; si < cardsData.targetIndex[target].length; si++) {\n let s = data[cardsData.targetIndex[target][si]];\n if (s.datapoints.length <= j) {\n continue;\n }\n let datapoint = s.datapoints[j];\n if (card.values.length === 0) {\n card.x = datapoint[TIME_INDEX];\n }\n card.values.push(datapoint[VALUE_INDEX]);\n }\n card.minValue = _.min(card.values);\n card.maxValue = _.max(card.values);\n if (card.values.length > 1) {\n cardsData.multipleValues = true;\n card.multipleValues = true;\n card.value = card.maxValue; // max value by default\n } else {\n card.value = card.maxValue; // max value by default\n }\n\n if (cardsData.maxValue < card.maxValue)\n cardsData.maxValue = card.maxValue;\n\n if (cardsData.minValue > card.minValue)\n cardsData.minValue = card.minValue;\n\n if (card.x != -1) {\n cardsData.cards.push(card);\n }\n }\n }\n\n return cardsData;\n };\n}\n"]} \ No newline at end of file diff --git a/src/annotations.js b/src/annotations.js new file mode 100644 index 0000000..044faa3 --- /dev/null +++ b/src/annotations.js @@ -0,0 +1,134 @@ +import d3 from 'd3'; +import $ from 'jquery'; +import _ from 'lodash'; +import kbn from 'app/core/utils/kbn'; + +let TOOLTIP_PADDING_X = 30; +let TOOLTIP_PADDING_Y = 10; + +export class AnnotationTooltip { + constructor(elem, scope) { + this.scope = scope; + this.dashboard = scope.ctrl.dashboard; + this.panelCtrl = scope.ctrl; + this.panel = scope.ctrl.panel; + this.mouseOverAnnotationTick = false; + + elem.on("mouseover", this.onMouseOver.bind(this)); + elem.on("mouseleave", this.onMouseLeave.bind(this)); + } + + onMouseOver(e) { + if (!this.panel.tooltip.show || !this.scope.ctrl.data || _.isEmpty(this.scope.ctrl.data)) { return; } + + if (!this.tooltip) { + this.add(); + this.move(e); + } + } + + onMouseLeave() { + this.destroy(); + } + + onMouseMove(e) { + if (!this.panel.tooltip.show) { return; } + + this.move(e); + } + + add() { + this.tooltipBase = d3.select("body") + .append("div") + .attr("class", "statusmap-annotation-tooltip drop drop-popover drop-popover--annotation drop-element drop-enabled drop-target-attached-center drop-open drop-open-transitionend drop-after-open") + .style("position", "absolute") + this.tooltip = this.tooltipBase + .append("div") + .attr("class", "drop-content") + .append("div") + .append("annotation-tooltip") + .append("div") + .attr("class", "graph-annotation"); + } + + destroy() { + if (this.tooltip) { + this.tooltip.remove(); + } + + this.tooltip = null; + + if (this.tooltipBase) { + this.tooltipBase.remove(); + } + + this.tooltipBase = null; + + } + + show(pos) { + if (!this.panel.tooltip.show || !this.tooltip) { return; } + // shared tooltip mode + //if (pos.panelRelY) { + // return; + //} + + let annoId = d3.select(pos.target).attr('annoId'); + if (!annoId) { + this.destroy(); + return; + } + + let anno = this.panelCtrl.annotations[annoId]; + if (!anno) { + this.destroy(); + return; + } + + let annoTitle = ""; + + let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss'; + let annoTime = this.dashboard.formatDate(anno.time, tooltipTimeFormat); + let annoText = anno.text; + let annoTags = []; + if (anno.tags) { + annoTags = _.map(anno.tags, t => ({"text": t, "backColor": "rgb(63, 43, 91)", "borderColor":"rgb(101, 81, 129)"})) + } + + let tooltipHtml = `
+ ${annoTitle} + ${annoTime}
+
+
${annoText}
+ ${_.join(_.map(annoTags, t => `${t.text}`), "")} +
+
`; + + this.tooltip.html(tooltipHtml); + + this.move(pos); + } + + move(pos) { + if (!this.tooltipBase) { return; } + + let elem = $(this.tooltipBase.node())[0]; + let tooltipWidth = elem.clientWidth; + let tooltipHeight = elem.clientHeight; + + let left = pos.pageX - tooltipWidth/2; + let top = pos.pageY + TOOLTIP_PADDING_Y; + + if (pos.pageX + tooltipWidth/2 + 10 > window.innerWidth) { + left = pos.pageX - tooltipWidth - TOOLTIP_PADDING_X; + } + + if (pos.pageY - window.pageYOffset + tooltipHeight + 20 > window.innerHeight) { + top = pos.pageY - tooltipHeight - TOOLTIP_PADDING_Y; + } + + return this.tooltipBase + .style("left", left + "px") + .style("top", top + "px"); + } +} diff --git a/src/rendering.js b/src/rendering.js index 8ddc5f7..bb69b2f 100644 --- a/src/rendering.js +++ b/src/rendering.js @@ -7,6 +7,7 @@ import {tickStep, getScaledDecimals, getFlotTickSize} from 'app/core/utils/ticks import d3 from 'd3'; import * as d3ScaleChromatic from './libs/d3-scale-chromatic/index'; import {StatusHeatmapTooltip} from './tooltip'; +import {AnnotationTooltip} from './annotations'; let MIN_CARD_SIZE = 5, CARD_H_SPACING = 2, @@ -25,6 +26,7 @@ export default function link(scope, elem, attrs, ctrl) { // $heatmap is JQuery object, but heatmap is D3 let $heatmap = elem.find('.status-heatmap-panel'); let tooltip = new StatusHeatmapTooltip($heatmap, scope); + let annotationTooltip = new AnnotationTooltip($heatmap, scope); let width, height, yScale, xScale, @@ -77,7 +79,7 @@ export default function link(scope, elem, attrs, ctrl) { return text.getBBox().width; })); - return max_text_width; + return Math.ceil(max_text_width); } function getXAxisHeight(elem) { @@ -310,6 +312,8 @@ export default function link(scope, elem, attrs, ctrl) { resetCardHighLight(event); }); + _renderAnnotations(); + ctrl.events.emit('render-complete', { "chartWidth": chartWidth }); @@ -506,6 +510,7 @@ export default function link(scope, elem, attrs, ctrl) { function onMouseLeave() { appEvents.emit('graph-hover-clear'); clearCrosshair(); + //annotationTooltip.destroy(); } function onMouseMove(event) { @@ -515,6 +520,7 @@ export default function link(scope, elem, attrs, ctrl) { // Clear crosshair and tooltip clearCrosshair(); tooltip.destroy(); + annotationTooltip.destroy(); selection.x2 = limitSelection(event.offsetX); drawSelection(selection.x1, selection.x2); @@ -522,6 +528,7 @@ export default function link(scope, elem, attrs, ctrl) { emitGraphHoverEvet(event); drawCrosshair(event.offsetX); tooltip.show(event); //, data); + annotationTooltip.show(event); } } @@ -637,6 +644,62 @@ export default function link(scope, elem, attrs, ctrl) { $heatmap.on("mousedown", onMouseDown); $heatmap.on("mousemove", onMouseMove); $heatmap.on("mouseleave", onMouseLeave); + + function _renderAnnotations() { + if (!ctrl.annotations || ctrl.annotations.length == 0) { + return; + } + + if (!heatmap) { + return; + } + + let annoData = _.map(ctrl.annotations, (d,i) => ({"x": Math.floor(yAxisWidth + xScale(d.time)), "id":i, "anno": d.source})); + + + let anno = heatmap + .append("g") + .attr("class", "statusmap-annotations") + .attr("transform", "translate(0.5,0)") + .selectAll(".statusmap-annotations") + .data(annoData) + .enter().append("g") + ; + anno.append("line") + //.attr("class", "statusmap-annotation-tick") + .attr("x1", d => d.x) + .attr("y1", chartTop) + .attr("x2", d => d.x) + .attr("y2", chartBottom) + .style("stroke", d => d.anno.iconColor) + .style("stroke-width", 1) + .style("stroke-dasharray", "3,3") + ; + anno.append("polygon") + .attr("points", d => [[d.x, chartBottom+1], [d.x-5, chartBottom+6], [d.x+5, chartBottom+6]].join(" ")) + .style("stroke-width", 0) + .style("fill", d => d.anno.iconColor) + ; + // Polygons didn't fire mouseevents + anno.append("rect") + .attr("x", d => d.x-5) + .attr("width", 10) + .attr("y", chartBottom+1) + .attr("height", 5) + .attr("class", "statusmap-annotation-tick") + .attr("annoId", d => d.id) + .style("opacity", 0) + ; + + let $ticks = $heatmap.find(".statusmap-annotation-tick"); + $ticks.on("mouseenter", (event) => { + annotationTooltip.mouseOverAnnotationTick = true; + }) + .on("mouseleave", (event) => { + annotationTooltip.mouseOverAnnotationTick = false; + }); + + } } function grafanaTimeFormat(ticks, min, max) { diff --git a/src/status_heatmap_ctrl.js b/src/status_heatmap_ctrl.js index fe286fa..6ceb266 100644 --- a/src/status_heatmap_ctrl.js +++ b/src/status_heatmap_ctrl.js @@ -100,7 +100,8 @@ let opacityScales = ['linear', 'sqrt']; export class StatusHeatmapCtrl extends MetricsPanelCtrl { static templateUrl = 'module.html'; - constructor($scope, $injector, $rootScope, timeSrv) { + /** @ngInject */ + constructor($scope, $injector, $rootScope, timeSrv, annotationsSrv) { super($scope, $injector); _.defaultsDeep(this.panel, panelDefaults); @@ -129,6 +130,9 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl { } }; + this.annotations = []; + this.annotationsSrv = annotationsSrv; + this.events.on('data-received', this.onDataReceived); this.events.on('data-snapshot-load', this.onDataReceived); this.events.on('data-error', this.onDataError); @@ -189,11 +193,48 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl { this.interval = kbn.secondsToHms(intervalMs / 1000); }; + issueQueries = (datasource) => { + this.annotationsPromise = this.annotationsSrv.getAnnotations({ + dashboard: this.dashboard, + panel: this.panel, + range: this.range, + }); + + /* Wait for annotationSrv requests to get datasources to + * resolve before issuing queries. This allows the annotations + * service to fire annotations queries before graph queries + * (but not wait for completion). This resolves + * issue 11806. + */ + return this.annotationsSrv.datasourcePromises.then(r => { + return super.issueQueries(datasource); + }); + } + + onDataReceived = (dataList) => { this.data = dataList; this.cardsData = this.convertToCards(this.data); - this.render(); + this.annotationsPromise.then( + result => { + this.loading = false; + //this.alertState = result.alertState; + if (result.annotations && result.annotations.length > 0) { + this.annotations = result.annotations; + } else { + this.annotations = null; + } + this.render(); + }, + () => { + this.loading = false; + this.annotations = null; + this.render(); + } + ); + + //this.render(); }; onInitEditMode = () => { @@ -227,6 +268,7 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl { onDataError = () => { this.data = []; + this.annotations = []; this.render(); }; @@ -313,6 +355,8 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl { values: [], multipleValues: false, noColorDefined: false, + y: target, + x: -1, }; // collect values from all timeseries with target @@ -324,7 +368,6 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl { let datapoint = s.datapoints[j]; if (card.values.length === 0) { card.x = datapoint[TIME_INDEX]; - card.y = s.target; } card.values.push(datapoint[VALUE_INDEX]); } @@ -344,7 +387,9 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl { if (cardsData.minValue > card.minValue) cardsData.minValue = card.minValue; + if (card.x != -1) { cardsData.cards.push(card); + } } }