From 0a8463e2ed7e7f1aa015f55a8e8730752206311b Mon Sep 17 00:00:00 2001 From: Ivan Mikheykin Date: Wed, 17 Oct 2018 22:33:27 +0300 Subject: [PATCH] Support for dark theme - dark theme colors - dark theme screenshot --- .gitignore | 2 + Gruntfile.js | 3 +- README.md | 2 + dist/README.md | 2 + dist/color_legend.js.map | 1 + dist/color_mode_discrete.js.map | 1 + dist/css/status-heatmap.css.map | 7 -- dist/css/statusmap.dark.css | 66 ++++++++++++++++++ dist/css/statusmap.dark.css.map | 7 ++ ...status-heatmap.css => statusmap.light.css} | 16 +++-- dist/css/statusmap.light.css.map | 7 ++ dist/img/flant-statusmap-panel-dark.png | Bin 0 -> 30692 bytes dist/module.js | 14 +++- dist/module.js.map | 1 + dist/options_editor.js.map | 1 + dist/plugin.json | 5 +- dist/rendering.js.map | 1 + dist/status_heatmap_ctrl.js | 4 +- dist/status_heatmap_ctrl.js.map | 1 + dist/tooltip.js | 6 +- dist/tooltip.js.map | 1 + .../{status-heatmap.scss => _statusmap.scss} | 48 +++++++------ src/css/_variables.dark.scss | 9 +++ src/css/_variables.light.scss | 10 +++ src/css/_variables.scss | 3 + src/css/statusmap.dark.scss | 3 + src/css/statusmap.light.scss | 3 + src/img/flant-statusmap-panel-dark.png | Bin 0 -> 30692 bytes src/module.js | 7 ++ src/plugin.json | 5 +- src/status_heatmap_ctrl.js | 1 - src/tooltip.js | 6 +- 32 files changed, 191 insertions(+), 52 deletions(-) create mode 100644 dist/color_legend.js.map create mode 100644 dist/color_mode_discrete.js.map delete mode 100644 dist/css/status-heatmap.css.map create mode 100644 dist/css/statusmap.dark.css create mode 100644 dist/css/statusmap.dark.css.map rename dist/css/{status-heatmap.css => statusmap.light.css} (81%) create mode 100644 dist/css/statusmap.light.css.map create mode 100644 dist/img/flant-statusmap-panel-dark.png create mode 100644 dist/module.js.map create mode 100644 dist/options_editor.js.map create mode 100644 dist/rendering.js.map create mode 100644 dist/status_heatmap_ctrl.js.map create mode 100644 dist/tooltip.js.map rename src/css/{status-heatmap.scss => _statusmap.scss} (63%) create mode 100644 src/css/_variables.dark.scss create mode 100644 src/css/_variables.light.scss create mode 100644 src/css/_variables.scss create mode 100644 src/css/statusmap.dark.scss create mode 100644 src/css/statusmap.light.scss create mode 100644 src/img/flant-statusmap-panel-dark.png diff --git a/.gitignore b/.gitignore index de81777..af23741 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules .jshintrc +.idea +.sass-cache diff --git a/Gruntfile.js b/Gruntfile.js index 59e95b4..6758b13 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -53,7 +53,8 @@ module.exports = (grunt) => { sass: { dist: { files: { - 'dist/css/status-heatmap.css': 'src/css/status-heatmap.scss' + 'dist/css/statusmap.dark.css': 'src/css/statusmap.dark.scss', + 'dist/css/statusmap.light.css': 'src/css/statusmap.light.scss' } } } diff --git a/README.md b/README.md index 4faab62..55ba3c4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Statusmap panel for Grafana ![Statusmap sample panel](https://raw.githubusercontent.com/flant/grafana-statusmap/master/src/img/flant-statusmap-panel.png) +(https://raw.githubusercontent.com/flant/grafana-statusmap/master/src/img/flant-statusmap-panel-dark.png) + ## Features diff --git a/dist/README.md b/dist/README.md index 4faab62..55ba3c4 100644 --- a/dist/README.md +++ b/dist/README.md @@ -1,6 +1,8 @@ # Statusmap panel for Grafana ![Statusmap sample panel](https://raw.githubusercontent.com/flant/grafana-statusmap/master/src/img/flant-statusmap-panel.png) +(https://raw.githubusercontent.com/flant/grafana-statusmap/master/src/img/flant-statusmap-panel-dark.png) + ## Features diff --git a/dist/color_legend.js.map b/dist/color_legend.js.map new file mode 100644 index 0000000..a5b06ac --- /dev/null +++ b/dist/color_legend.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/color_legend.js"],"names":["drawColorLegend","elem","colorScheme","rangeFrom","rangeTo","maxValue","minValue","legendElem","$","find","legend","d3","select","get","clearLegend","legendWidth","Math","floor","outerWidth","legendHeight","attr","rangeStep","MIN_LEGEND_STEPS","widthFactor","valuesRange","range","colorScale","getColorScale","selectAll","data","enter","append","d","drawLegendValues","drawOpacityLegend","options","opacityScale","getOpacityScale","cardColor","style","drawDiscreteColorLegend","colorOptions","discreteHelper","thresholds","tooltips","_","map","tr","tooltip","valuesNumber","length","$heatmap","parent","graphWidth","textWidth","text","each","i","thisWidth","getBBox","width","push","remove","min","max","itemWidth","getDiscreteColor","drawDiscreteLegendValues","childNodes","legendValueScale","scaleLinear","domain","ticks","buildLegendTicks","xAxis","axisBottom","tickValues","tickSize","colorRect","posY","getSvgElemHeight","posX","getSvgElemX","call","thresholdValues","thresholdTooltips","value","tickFormat","t","v","undefined","drawSimpleColorLegend","legendRects","drawSimpleOpacityLegend","graphElem","legendOpacityScale","scalePow","exponent","empty","colorInterpolator","d3ScaleChromatic","colorScaleInverted","invert","contextSrv","user","lightTheme","start","end","scaleSequential","svgElem","x","baseVal","height","tickStepSize","tickStep","ticksNum","round","current","isValueCloseTo","sortBy","uniq","val","valueTo","step","diff","abs","angular","mod","module","directive","restrict","template","link","scope","attrs","ctrl","panel","render","events","on","color","mode","colorSchemes","isEmpty","cardsData","cards"],"mappings":"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","file":"color_legend.js","sourcesContent":["import angular from 'angular';\nimport _ from 'lodash';\nimport $ from 'jquery';\nimport d3 from 'd3';\nimport * as d3ScaleChromatic from './libs/d3-scale-chromatic/index';\nimport {contextSrv} from 'app/core/core';\nimport {tickStep} from 'app/core/utils/ticks';\n\nlet mod = angular.module('grafana.directives');\n\nconst MIN_LEGEND_STEPS = 10;\n\n/**\n * Color legend for heatmap editor.\n */\nmod.directive('optionsColorLegend', function() {\n return {\n restrict: 'E',\n template: '
',\n link: function(scope, elem, attrs) {\n let ctrl = scope.ctrl;\n let panel = scope.ctrl.panel;\n\n render();\n\n ctrl.events.on('render', function() {\n render();\n });\n\n function render() {\n let legendElem = $(elem).find('svg');\n let legendWidth = Math.floor(legendElem.outerWidth());\n\n if (panel.color.mode === 'spectrum') {\n let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme});\n let colorScale = getColorScale(colorScheme, legendWidth);\n drawSimpleColorLegend(elem, colorScale);\n } else if (panel.color.mode === 'opacity') {\n let colorOptions = panel.color;\n drawSimpleOpacityLegend(elem, colorOptions);\n }\n }\n }\n };\n});\n\n/**\n * Heatmap legend with scale values.\n */\nmod.directive('statusHeatmapLegend', function() {\n return {\n restrict: 'E',\n template: '
',\n link: function(scope, elem, attrs) {\n let ctrl = scope.ctrl;\n let panel = scope.ctrl.panel;\n\n render();\n ctrl.events.on('render', function() {\n render();\n });\n\n function render() {\n clearLegend(elem);\n if (!_.isEmpty(ctrl.cardsData) && !_.isEmpty(ctrl.cardsData.cards)) {\n let rangeFrom = ctrl.cardsData.minValue;\n let rangeTo = ctrl.cardsData.maxValue;\n let maxValue = panel.color.max || rangeTo;\n let minValue = panel.color.min || rangeFrom;\n\n if (panel.color.mode === 'spectrum') {\n let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme});\n drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minValue);\n } else if (panel.color.mode === 'opacity') {\n let colorOptions = panel.color;\n drawOpacityLegend(elem, colorOptions, rangeFrom, rangeTo, maxValue, minValue);\n } else if (panel.color.mode === 'discrete') {\n let colorOptions = panel.color;\n drawDiscreteColorLegend(elem, colorOptions, ctrl.discreteHelper);\n }\n }\n }\n }\n };\n});\n\nfunction drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minValue) {\n let legendElem = $(elem).find('svg');\n let legend = d3.select(legendElem.get(0));\n clearLegend(elem);\n\n let legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values\n let legendHeight = legendElem.attr(\"height\");\n\n let rangeStep = 1;\n if (rangeTo - rangeFrom > legendWidth) {\n rangeStep = Math.floor((rangeTo - rangeFrom) / legendWidth);\n }\n\n if (rangeStep * MIN_LEGEND_STEPS > rangeTo) {\n rangeStep = rangeTo / MIN_LEGEND_STEPS;\n }\n\n let widthFactor = legendWidth / (rangeTo - rangeFrom);\n let valuesRange = d3.range(rangeFrom, rangeTo, rangeStep);\n\n let colorScale = getColorScale(colorScheme, maxValue, minValue);\n legend.selectAll(\".status-heatmap-color-legend-rect\")\n .data(valuesRange)\n .enter().append(\"rect\")\n .attr(\"x\", d => d * widthFactor + 10) // shift all color rectangles to the right\n .attr(\"y\", 0)\n .attr(\"width\", rangeStep * widthFactor + 1) // Overlap rectangles to prevent gaps\n .attr(\"height\", legendHeight)\n .attr(\"stroke-width\", 0)\n .attr(\"fill\", d => colorScale(d));\n\n drawLegendValues(elem, colorScale, rangeFrom, rangeTo, maxValue, minValue, legendWidth);\n}\n\nfunction drawOpacityLegend(elem, options, rangeFrom, rangeTo, maxValue, minValue) {\n let legendElem = $(elem).find('svg');\n let legend = d3.select(legendElem.get(0));\n clearLegend(elem);\n\n let legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values\n let legendHeight = legendElem.attr(\"height\");\n\n let rangeStep = 10;\n let widthFactor = legendWidth / (rangeTo - rangeFrom);\n\n if (rangeStep * MIN_LEGEND_STEPS > rangeTo) {\n rangeStep = rangeTo / MIN_LEGEND_STEPS;\n }\n\n let valuesRange = d3.range(rangeFrom, rangeTo, rangeStep);\n\n let opacityScale = getOpacityScale(options, maxValue, minValue);\n legend.selectAll(\".status-heatmap-opacity-legend-rect\")\n .data(valuesRange)\n .enter().append(\"rect\")\n .attr(\"x\", d => d * widthFactor + 10) // shift all opacity rectangles to the right\n .attr(\"y\", 0)\n .attr(\"width\", rangeStep * widthFactor)\n .attr(\"height\", legendHeight)\n .attr(\"stroke-width\", 0)\n .attr(\"fill\", options.cardColor)\n .style(\"opacity\", d => opacityScale(d));\n\n drawLegendValues(elem, opacityScale, rangeFrom, rangeTo, maxValue, minValue, legendWidth);\n}\n\nfunction drawDiscreteColorLegend(elem, colorOptions, discreteHelper) {\n let legendElem = $(elem).find('svg');\n let legend = d3.select(legendElem.get(0));\n clearLegend(elem);\n\n let thresholds = colorOptions.thresholds;\n let tooltips = _.map(thresholds, tr => tr.tooltip);\n let valuesNumber = thresholds.length;\n\n // graph width as a fallback\n let $heatmap = $(elem).parent().parent().parent().find('.status-heatmap-panel');\n let graphWidth = $heatmap.find('svg').attr(\"width\");\n\n // calculate max width of tooltip and use it as width for each item\n let textWidth = [];\n legend.selectAll(\".hidden-texts\")\n .data(tooltips)\n .enter().append(\"text\")\n .attr(\"class\", \"axis tick\")\n .attr(\"font-family\", \"sans-serif\")\n .text(d => d)\n .each(function(d,i) {\n let thisWidth = this.getBBox().width;\n textWidth.push(thisWidth);\n this.remove(); // remove them just after displaying them\n });\n\n let legendWidth = Math.floor(_.min([\n graphWidth - 30,\n (_.max(textWidth) + 3) * valuesNumber,\n ]));\n legendElem.attr(\"width\", legendWidth);\n\n let legendHeight = legendElem.attr(\"height\");\n\n let itemWidth = Math.floor(legendWidth / valuesNumber);\n let valuesRange = d3.range(valuesNumber); // from 0 to valuesNumber-1\n\n legend.selectAll(\".status-heatmap-color-legend-rect\")\n .data(valuesRange)\n .enter().append(\"rect\")\n .attr(\"x\", d => d*itemWidth)\n .attr(\"y\", 0)\n .attr(\"width\", itemWidth + 1) // Overlap rectangles to prevent gaps\n .attr(\"height\", legendHeight)\n .attr(\"stroke-width\", 0)\n .attr(\"fill\", d => discreteHelper.getDiscreteColor(d));\n\n drawDiscreteLegendValues(elem, colorOptions, legendWidth);\n}\n\n\nfunction drawLegendValues(elem, colorScale, rangeFrom, rangeTo, maxValue, minValue, legendWidth) {\n let legendElem = $(elem).find('svg');\n let legend = d3.select(legendElem.get(0));\n\n if (legendWidth <= 0 || legendElem.get(0).childNodes.length === 0) {\n return;\n }\n\n let legendValueScale = d3.scaleLinear()\n .domain([0, rangeTo])\n .range([0, legendWidth]);\n\n let ticks = buildLegendTicks(0, rangeTo, maxValue, minValue);\n let xAxis = d3.axisBottom(legendValueScale)\n .tickValues(ticks)\n .tickSize(2);\n\n let colorRect = legendElem.find(\":first-child\");\n let posY = getSvgElemHeight(legendElem) + 2;\n let posX = getSvgElemX(colorRect);\n\n d3.select(legendElem.get(0)).append(\"g\")\n .attr(\"class\", \"axis\")\n .attr(\"transform\", \"translate(\" + posX + \",\" + posY + \")\")\n .call(xAxis);\n\n legend.select(\".axis\").select(\".domain\").remove();\n}\n\nfunction drawDiscreteLegendValues(elem, colorOptions, legendWidth) {\n let thresholds = colorOptions.thresholds;\n\n let legendElem = $(elem).find('svg');\n let legend = d3.select(legendElem.get(0));\n\n if (legendWidth <= 0 || legendElem.get(0).childNodes.length === 0) {\n return;\n }\n\n let valuesNumber = thresholds.length;\n let rangeStep = Math.floor(legendWidth / valuesNumber);\n let valuesRange = d3.range(0, legendWidth, rangeStep);\n\n\n let legendValueScale = d3.scaleLinear()\n .domain([0, valuesNumber])\n .range([0, legendWidth]);\n\n let thresholdValues = [];\n let thresholdTooltips = [];\n for (let i = 0; i < thresholds.length; i++) {\n thresholdValues.push(thresholds[i].value);\n thresholdTooltips.push(thresholds[i].tooltip);\n }\n\n let xAxis = d3.axisBottom(legendValueScale)\n .tickValues(d3.range(0, valuesNumber, 1)) //thresholdValues)\n .tickSize(2)\n .tickFormat((t) => {\n let i = Math.floor(t);\n let v = thresholdTooltips[i];\n if (v != undefined) {\n return \"\"+v;\n } else {\n v = thresholdValues[i];\n if (v != undefined) {\n return \"\"+v;\n } else {\n return \"n/a\";\n }\n }\n });\n\n let colorRect = legendElem.find(\":first-child\");\n let posY = getSvgElemHeight(legendElem) + 2;\n let posX = getSvgElemX(colorRect) + Math.floor(rangeStep/2);\n\n d3.select(legendElem.get(0)).append(\"g\")\n .attr(\"class\", \"axis\")\n .attr(\"transform\", \"translate(\" + posX + \",\" + posY + \")\")\n .call(xAxis);\n\n legend.select(\".axis\").select(\".domain\").remove();\n}\n\nfunction drawSimpleColorLegend(elem, colorScale) {\n let legendElem = $(elem).find('svg');\n clearLegend(elem);\n\n let legendWidth = Math.floor(legendElem.outerWidth());\n let legendHeight = legendElem.attr(\"height\");\n\n if (legendWidth) {\n let valuesNumber = Math.floor(legendWidth / 2);\n let rangeStep = Math.floor(legendWidth / valuesNumber);\n let valuesRange = d3.range(0, legendWidth, rangeStep);\n\n let legend = d3.select(legendElem.get(0));\n var legendRects = legend.selectAll(\".status-heatmap-color-legend-rect\").data(valuesRange);\n\n legendRects.enter().append(\"rect\")\n .attr(\"x\", d => d)\n .attr(\"y\", 0)\n .attr(\"width\", rangeStep + 1) // Overlap rectangles to prevent gaps\n .attr(\"height\", legendHeight)\n .attr(\"stroke-width\", 0)\n .attr(\"fill\", d => colorScale(d));\n }\n}\n\nfunction drawSimpleOpacityLegend(elem, options) {\n let legendElem = $(elem).find('svg');\n let graphElem = $(elem);\n clearLegend(elem);\n\n let legend = d3.select(legendElem.get(0));\n let legendWidth = Math.floor(legendElem.outerWidth());\n let legendHeight = legendElem.attr(\"height\");\n\n if (legendWidth) {\n let legendOpacityScale;\n if (options.colorScale === 'linear') {\n legendOpacityScale = d3.scaleLinear()\n .domain([0, legendWidth])\n .range([0, 1]);\n } else if (options.colorScale === 'sqrt') {\n legendOpacityScale = d3.scalePow().exponent(options.exponent)\n .domain([0, legendWidth])\n .range([0, 1]);\n }\n\n let rangeStep = 10;\n let valuesRange = d3.range(0, legendWidth, rangeStep);\n var legendRects = legend.selectAll(\".status-heatmap-opacity-legend-rect\").data(valuesRange);\n\n legendRects.enter().append(\"rect\")\n .attr(\"x\", d => d)\n .attr(\"y\", 0)\n .attr(\"width\", rangeStep)\n .attr(\"height\", legendHeight)\n .attr(\"stroke-width\", 0)\n .attr(\"fill\", options.cardColor)\n .style(\"opacity\", d => legendOpacityScale(d));\n }\n}\n\n\nfunction clearLegend(elem) {\n let legendElem = $(elem).find('svg');\n legendElem.empty();\n}\n\nfunction getColorScale(colorScheme, maxValue, minValue = 0) {\n let colorInterpolator = d3ScaleChromatic[colorScheme.value];\n let colorScaleInverted = colorScheme.invert === 'always' ||\n (colorScheme.invert === 'dark' && !contextSrv.user.lightTheme);\n\n let start = colorScaleInverted ? maxValue : minValue;\n let end = colorScaleInverted ? minValue : maxValue;\n\n return d3.scaleSequential(colorInterpolator).domain([start, end]);\n}\n\nfunction getOpacityScale(options, maxValue, minValue = 0) {\n let legendOpacityScale;\n if (options.colorScale === 'linear') {\n legendOpacityScale = d3.scaleLinear()\n .domain([minValue, maxValue])\n .range([0, 1]);\n } else if (options.colorScale === 'sqrt') {\n legendOpacityScale = d3.scalePow().exponent(options.exponent)\n .domain([minValue, maxValue])\n .range([0, 1]);\n }\n return legendOpacityScale;\n}\n\nfunction getSvgElemX(elem) {\n let svgElem = elem.get(0);\n if (svgElem && svgElem.x && svgElem.x.baseVal) {\n return svgElem.x.baseVal.value;\n } else {\n return 0;\n }\n}\n\nfunction getSvgElemHeight(elem) {\n let svgElem = elem.get(0);\n if (svgElem && svgElem.height && svgElem.height.baseVal) {\n return svgElem.height.baseVal.value;\n } else {\n return 0;\n }\n}\n\nfunction buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) {\n let range = rangeTo - rangeFrom;\n let tickStepSize = tickStep(rangeFrom, rangeTo, 3);\n let ticksNum = Math.round(range / tickStepSize);\n let ticks = [];\n\n for (let i = 0; i < ticksNum; i++) {\n let current = tickStepSize * i;\n // Add user-defined min and max if it had been set\n if (isValueCloseTo(minValue, current, tickStepSize)) {\n ticks.push(minValue);\n continue;\n } else if (minValue < current) {\n ticks.push(minValue);\n }\n if (isValueCloseTo(maxValue, current, tickStepSize)) {\n ticks.push(maxValue);\n continue;\n } else if (maxValue < current) {\n ticks.push(maxValue);\n }\n ticks.push(tickStepSize * i);\n }\n if (!isValueCloseTo(maxValue, rangeTo, tickStepSize)) {\n ticks.push(maxValue);\n }\n ticks.push(rangeTo);\n ticks = _.sortBy(_.uniq(ticks));\n return ticks;\n}\n\nfunction isValueCloseTo(val, valueTo, step) {\n let diff = Math.abs(val - valueTo);\n return diff < step * 0.3;\n}\n"]} \ No newline at end of file diff --git a/dist/color_mode_discrete.js.map b/dist/color_mode_discrete.js.map new file mode 100644 index 0000000..d9e3ee3 --- /dev/null +++ b/dist/color_mode_discrete.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/color_mode_discrete.js"],"names":["_","ColorModeDiscrete","scope","panelCtrl","ctrl","panel","values","thresholds","color","tooltips","i","length","j","value","push","tooltip","notMatched","getMatchedThreshold","threshold","index","getThreshold","getDiscreteColor","cardsData","noColorDefined","cards","nullPointMode","k","interval"],"mappings":"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","file":"color_mode_discrete.js","sourcesContent":["import _ from 'lodash';\n\n// Helper methods to handle discrete color mode\nexport class ColorModeDiscrete {\n constructor(scope) {\n this.scope = scope;\n this.panelCtrl = scope.ctrl;\n this.panel = scope.ctrl.panel;\n }\n\n // get tooltip for each value ordered by thresholds priority\n convertValuesToTooltips(values) {\n let thresholds = this.panel.color.thresholds;\n let tooltips = [];\n\n for (let i = 0; i < thresholds.length; i++) {\n for (let j = 0; j < values.length; j++) {\n if (values[j] == thresholds[i].value) {\n tooltips.push({\n \"tooltip\": thresholds[i].tooltip?thresholds[i].tooltip:values[j],\n \"color\": thresholds[i].color\n });\n }\n }\n }\n return tooltips;\n }\n\n\n getNotMatchedValues(values) {\n let notMatched = [];\n for (let j = 0; j < values.length; j++) {\n if (!this.getMatchedThreshold(values[j])) {\n notMatched.push(values[j]);\n }\n }\n return notMatched;\n }\n\n getNotColoredValues(values) {\n let notMatched = [];\n for (let j = 0; j < values.length; j++) {\n let threshold = this.getMatchedThreshold(values[j]);\n if (!threshold || !threshold.color || threshold.color == \"\") {\n notMatched.push(values[j]);\n }\n }\n return notMatched;\n }\n\n\n getDiscreteColor(index) {\n let color = this.getThreshold(index).color;\n if (!color || color == \"\") {\n return 'rgba(0,0,0,1)';\n }\n return color;\n }\n\n // returns color from first matched thresold in order from 0 to thresholds.length\n getBucketColor(values) {\n let thresholds = this.panel.color.thresholds;\n\n for (let i = 0; i < thresholds.length; i++) {\n for (let j = 0; j < values.length; j++) {\n if (values[j] == thresholds[i].value) {\n return this.getDiscreteColor(i);\n }\n }\n }\n return 'rgba(0,0,0,1)';\n }\n\n updateCardsValuesHasColorInfo() {\n if (!this.panelCtrl.cardsData) {\n return\n }\n this.panelCtrl.cardsData.noColorDefined = false;\n let cards = this.panelCtrl.cardsData.cards;\n for (let i=0; i= thresholds.length == null) {\n return {\n \"color\": \"rgba(0,0,0,0)\",\n \"value\": \"null\",\n \"tooltip\": \"null\",\n }\n }\n return thresholds[index];\n }\n\n roundIntervalCeil(interval) {\n switch (true) {\n case interval <= 10:\n return 10; // 0.01s\n case interval <= 20:\n return 20; // 0.02s\n case interval <= 50:\n return 50; // 0.05s\n case interval <= 100:\n return 100; // 0.1s\n case interval <= 200:\n return 200; // 0.2s\n case interval <= 500:\n return 500; // 0.5s\n case interval <= 1000:\n return 1000; // 1s\n case interval <= 2000:\n return 2000; // 2s\n case interval <= 5000:\n return 5000; // 5s\n case interval <= 10000:\n return 10000; // 10s\n case interval <= 15000:\n return 15000; // 15s\n case interval <= 20000:\n return 20000; // 20s\n case interval <= 30000:\n return 30000; // 30s\n case interval <= 60000:\n return 60000; // 1m\n case interval <= 120000:\n return 120000; // 2m\n case interval <= 300000:\n return 300000; // 5m\n case interval <= 600000:\n return 600000; // 10m\n case interval <= 900000:\n return 900000; // 15m\n case interval <= 1200000:\n return 1200000; // 20m\n case interval <= 1800000:\n return 1800000; // 30m\n case interval <= 3600000:\n return 3600000; // 1h\n case interval <= 7200000:\n return 7200000; // 2h\n case interval <= 10800000:\n return 10800000; // 3h\n case interval <= 21600000:\n return 21600000; // 6h\n case interval <= 43200000:\n return 43200000; // 12h\n case interval <= 86400000:\n return 86400000; // 1d\n case interval <= 604800000:\n return 604800000; // 1w\n case interval <= 2592000000:\n return 2592000000; // 30d\n default:\n return 31536000000; // 1y\n }\n }\n}\n"]} \ No newline at end of file diff --git a/dist/css/status-heatmap.css.map b/dist/css/status-heatmap.css.map deleted file mode 100644 index 793b717..0000000 --- a/dist/css/status-heatmap.css.map +++ /dev/null @@ -1,7 +0,0 @@ -{ -"version": 3, -"mappings": "AAGA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAEjB,uDAAyB;IACzB,gBAAgB,EAAE,KAAK;IACvB,OAAO,EAAE,GAAG;;AAId,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAGhB,sCAAK;IACH,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,IAAI;EAGjB,sCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,OAAO;EAKnB,yBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,8BAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,uBAAwB;EACtB,WAAW,EAAE,MAAM;EACnB,SAAS,EAzCI,IAAI;EA0CjB,gBAAgB,EAAE,OAAO;EACzB,KAAK,EAAE,OAAO;;AAGhB,8BAA+B;EAC7B,IAAI,EAAE,OAAO;;AAIb,8BAAK;EACH,MAAM,EAAE,OAAe;EACvB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAGlC,8BAA+B;EAE7B,MAAM,EAAE,MAAM;EAGd,kCAAI;IAGF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,IAAI;EAGjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,OAAO;EAGjB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,EAAE,OAAO", -"sources": ["../../src/css/status-heatmap.scss"], -"names": [], -"file": "status-heatmap.css" -} diff --git a/dist/css/statusmap.dark.css b/dist/css/statusmap.dark.css new file mode 100644 index 0000000..8775d43 --- /dev/null +++ b/dist/css/statusmap.dark.css @@ -0,0 +1,66 @@ +.status-heatmap-canvas-wrapper { + cursor: crosshair; } + .status-heatmap-canvas-wrapper .datapoints-warning span { + background-color: #333333; + color: #d8d9da; + padding: 1px; } + +.status-heatmap-panel { + position: relative; } + .status-heatmap-panel .axis .tick text { + fill: #d8d9da; + color: #d8d9da; + font-size: 11px; } + .status-heatmap-panel .axis .tick line { + opacity: 0.4; + stroke: #8e8e8e; } + .status-heatmap-panel svg { + pointer-events: none; } + .status-heatmap-panel svg rect { + pointer-events: visiblePainted; } + +.statusmap-tooltip { + white-space: nowrap; + font-size: 12px; + background-color: #141414; + color: #d8d9da; } + .statusmap-tooltip .discrete-item { + color: #52545c; + padding: 1px; + font-weight: bold; + text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF; } + +.statusmap-histogram rect { + fill: #8e8e8e; } + +.status-heatmap-crosshair line { + stroke: #9f3023; + stroke-width: 1; } + +.status-heatmap-selection { + stroke-width: 1; + fill: rgba(102, 102, 102, 0.4); + stroke: rgba(102, 102, 102, 0.8); } + +.status-heatmap-legend-wrapper { + margin: 0 10px; } + .status-heatmap-legend-wrapper svg { + height: 24px; + float: left; + white-space: nowrap; } + .status-heatmap-legend-wrapper .status-heatmap-color-legend { + margin-top: 4px; } + .status-heatmap-legend-wrapper .status-heatmap-legend-values { + display: inline-block; } + .status-heatmap-legend-wrapper .axis .tick text { + fill: #d8d9da; + color: #d8d9da; + font-size: 11px; } + .status-heatmap-legend-wrapper .axis .tick line { + opacity: 0.4; + stroke: #8e8e8e; } + .status-heatmap-legend-wrapper .axis .tick .domain { + opacity: 0.4; + stroke: #8e8e8e; } + +/*# sourceMappingURL=statusmap.dark.css.map */ diff --git a/dist/css/statusmap.dark.css.map b/dist/css/statusmap.dark.css.map new file mode 100644 index 0000000..d00f583 --- /dev/null +++ b/dist/css/statusmap.dark.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAEjB,uDAAyB;IACzB,gBAAgB,ECDL,OAAO;IDElB,KAAK,ECLM,OAAO;IDMlB,OAAO,EAAE,GAAG;;AAId,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAGhB,sCAAK;IACH,IAAI,ECfG,OAAO;IDgBd,KAAK,EChBE,OAAO;IDiBd,SAAS,EEjBE,IAAI;EFoBjB,sCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECrBM,OAAO;ED0BvB,yBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,8BAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EACjB,WAAW,EAAE,MAAM;EACnB,SAAS,EEvCI,IAAI;EFwCjB,gBAAgB,ECrCC,OAAO;EDsCxB,KAAK,ECxCM,OAAO;ED0ClB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,8CAA8C;;AAI/D,yBAA0B;EACxB,IAAI,EClDY,OAAO;;ADsDvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAIlC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,ECxFG,OAAO;IDyFd,KAAK,ECzFE,OAAO;ID0Fd,SAAS,EE1FE,IAAI;EF6FjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC9FM,OAAO;EDiGrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECnGM,OAAO", +"sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.dark.scss","../../src/css/_variables.scss"], +"names": [], +"file": "statusmap.dark.css" +} diff --git a/dist/css/status-heatmap.css b/dist/css/statusmap.light.css similarity index 81% rename from dist/css/status-heatmap.css rename to dist/css/statusmap.light.css index 0c339ec..84067e5 100644 --- a/dist/css/status-heatmap.css +++ b/dist/css/statusmap.light.css @@ -1,7 +1,8 @@ .status-heatmap-canvas-wrapper { cursor: crosshair; } .status-heatmap-canvas-wrapper .datapoints-warning span { - background-color: white; + background-color: #e9edf2; + color: #52545c; padding: 1px; } .status-heatmap-panel { @@ -18,17 +19,22 @@ .status-heatmap-panel svg rect { pointer-events: visiblePainted; } -.status-heatmap-tooltip { +.statusmap-tooltip { white-space: nowrap; font-size: 12px; background-color: #dde4ed; color: #52545c; } + .statusmap-tooltip .discrete-item { + color: #52545c; + padding: 1px; + font-weight: bold; + text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF; } -.status-heatmap-histogram rect { +.statusmap-histogram rect { fill: #767980; } .status-heatmap-crosshair line { - stroke: #b30000; + stroke: #9e2f22; stroke-width: 1; } .status-heatmap-selection { @@ -57,4 +63,4 @@ opacity: 0.4; stroke: #767980; } -/*# sourceMappingURL=status-heatmap.css.map */ +/*# sourceMappingURL=statusmap.light.css.map */ diff --git a/dist/css/statusmap.light.css.map b/dist/css/statusmap.light.css.map new file mode 100644 index 0000000..5bd8ab4 --- /dev/null +++ b/dist/css/statusmap.light.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "AAAA,8BAA+B;EAE7B,MAAM,EAAE,SAAS;EAEjB,uDAAyB;IACzB,gBAAgB,ECDL,OAAO;IDElB,KAAK,ECLM,OAAO;IDMlB,OAAO,EAAE,GAAG;;AAId,qBAAsB;EACpB,QAAQ,EAAE,QAAQ;EAGhB,sCAAK;IACH,IAAI,ECfG,OAAO;IDgBd,KAAK,EChBE,OAAO;IDiBd,SAAS,EEjBE,IAAI;EFoBjB,sCAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,ECrBM,OAAO;ED0BvB,yBAAI;IACF,cAAc,EAAE,IAAI;IAEpB,8BAAK;MACH,cAAc,EAAE,cAAc;;AAKpC,kBAAmB;EACjB,WAAW,EAAE,MAAM;EACnB,SAAS,EEvCI,IAAI;EFwCjB,gBAAgB,ECrCC,OAAO;EDsCxB,KAAK,ECxCM,OAAO;ED0ClB,iCAAe;IACb,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,GAAG;IACZ,WAAW,EAAE,IAAI;IACjB,WAAW,EAAE,8CAA8C;;AAI/D,yBAA0B;EACxB,IAAI,EClDY,OAAO;;ADsDvB,8BAAK;EACH,MAAM,EAAE,OAAgB;EACxB,YAAY,EAAE,CAAC;;AAInB,yBAA0B;EACxB,YAAY,EAAE,CAAC;EACf,IAAI,EAAE,wBAAwB;EAC9B,MAAM,EAAE,wBAAwB;;AAIlC,8BAA+B;EAC7B,MAAM,EAAE,MAAM;EAEd,kCAAI;IACF,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,MAAM;EAIrB,2DAA6B;IAC3B,UAAU,EAAE,GAAG;EAGjB,4DAA8B;IAC5B,OAAO,EAAE,YAAY;EAIrB,+CAAK;IACH,IAAI,ECxFG,OAAO;IDyFd,KAAK,ECzFE,OAAO;ID0Fd,SAAS,EE1FE,IAAI;EF6FjB,+CAAK;IACH,OAAO,EAAE,GAAG;IACZ,MAAM,EC9FM,OAAO;EDiGrB,kDAAQ;IACN,OAAO,EAAE,GAAG;IACZ,MAAM,ECnGM,OAAO", +"sources": ["../../src/css/_statusmap.scss","../../src/css/_variables.light.scss","../../src/css/_variables.scss"], +"names": [], +"file": "statusmap.light.css" +} diff --git a/dist/img/flant-statusmap-panel-dark.png b/dist/img/flant-statusmap-panel-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..242eaae75f201b9b5a3aac74e652d02d08ca3d56 GIT binary patch literal 30692 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

t)6$P$WBA>f*f;lO6Ic!9&~VTpy<| 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 a-@!Muu0|E7_Wm5w3nn275UCK-_4_}!ECeF} literal 0 HcmV?d00001 diff --git a/dist/module.js b/dist/module.js index cf94993..deff0e9 100644 --- a/dist/module.js +++ b/dist/module.js @@ -1,14 +1,22 @@ 'use strict'; -System.register(['./color_legend', './status_heatmap_ctrl'], function (_export, _context) { +System.register(['app/plugins/sdk', './color_legend', './status_heatmap_ctrl'], function (_export, _context) { "use strict"; - var StatusHeatmapCtrl; + var loadPluginCss, StatusHeatmapCtrl; return { - setters: [function (_color_legend) {}, function (_status_heatmap_ctrl) { + setters: [function (_appPluginsSdk) { + loadPluginCss = _appPluginsSdk.loadPluginCss; + }, function (_color_legend) {}, function (_status_heatmap_ctrl) { StatusHeatmapCtrl = _status_heatmap_ctrl.StatusHeatmapCtrl; }], execute: function () { + + loadPluginCss({ + dark: 'plugins/flant-statusmap-panel/css/statusmap.dark.css', + light: 'plugins/flant-statusmap-panel/css/statusmap.light.css' + }); + _export('PanelCtrl', StatusHeatmapCtrl); } }; diff --git a/dist/module.js.map b/dist/module.js.map new file mode 100644 index 0000000..e9d3212 --- /dev/null +++ b/dist/module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/module.js"],"names":["loadPluginCss","StatusHeatmapCtrl","dark","light"],"mappings":";;;;;;;;AAAQA,mB,kBAAAA,a;;AAECC,uB,wBAAAA,iB;;;;AAETD,oBAAc;AACZE,cAAM,sDADM;AAEZC,eAAO;AAFK,OAAd;;2BAOEF,iB","file":"module.js","sourcesContent":["import {loadPluginCss} from 'app/plugins/sdk';\nimport './color_legend';\nimport { StatusHeatmapCtrl } from './status_heatmap_ctrl';\n\nloadPluginCss({\n dark: 'plugins/flant-statusmap-panel/css/statusmap.dark.css',\n light: 'plugins/flant-statusmap-panel/css/statusmap.light.css'\n});\n\n\nexport {\n StatusHeatmapCtrl as PanelCtrl\n};\n"]} \ No newline at end of file diff --git a/dist/options_editor.js.map b/dist/options_editor.js.map new file mode 100644 index 0000000..105e78a --- /dev/null +++ b/dist/options_editor.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/options_editor.js"],"names":["statusHeatmapOptionsEditor","restrict","scope","templateUrl","controller","StatusHeatmapOptionsEditorCtrl","kbn","$scope","editor","panelCtrl","ctrl","panel","unitFormats","getUnitFormats","render","subItem","data","unitFormat","value"],"mappings":";;;;;;;;;;;;;AAkBO,WAASA,0BAAT,GAAsC;AAC3C;;AACA,WAAO;AACLC,gBAAU,GADL;AAELC,aAAO,IAFF;AAGLC,mBAAa,mEAHR;AAILC,kBAAYC;AAJP,KAAP;AAMD;;wCAReL,0B;;;;AAlBTM,S;;;;;;;;;;;;;;;;;;;;;gDAEMD,8B;AACX,gDAAYE,MAAZ,EAAoB;AAAA;;AAClBA,iBAAOC,MAAP,GAAgB,IAAhB;AACA,eAAKC,SAAL,GAAiBF,OAAOG,IAAxB;AACA,eAAKC,KAAL,GAAa,KAAKF,SAAL,CAAeE,KAA5B;AACA,eAAKC,WAAL,GAAmBN,IAAIO,cAAJ,EAAnB;;AAEA,eAAKJ,SAAL,CAAeK,MAAf;AACD;;;;wCAEaC,O,EAAS;AACrB,iBAAKJ,KAAL,CAAWK,IAAX,CAAgBC,UAAhB,GAA6BF,QAAQG,KAArC;AACA,iBAAKT,SAAL,CAAeK,MAAf;AACD","file":"options_editor.js","sourcesContent":["import kbn from 'app/core/utils/kbn';\n\nexport class StatusHeatmapOptionsEditorCtrl {\n constructor($scope) {\n $scope.editor = this;\n this.panelCtrl = $scope.ctrl;\n this.panel = this.panelCtrl.panel;\n this.unitFormats = kbn.getUnitFormats();\n\n this.panelCtrl.render();\n }\n\n setUnitFormat(subItem) {\n this.panel.data.unitFormat = subItem.value;\n this.panelCtrl.render();\n }\n}\n\nexport function statusHeatmapOptionsEditor() {\n 'use strict';\n return {\n restrict: 'E',\n scope: true,\n templateUrl: 'public/plugins/flant-statusmap-panel/partials/options_editor.html',\n controller: StatusHeatmapOptionsEditorCtrl,\n };\n}\n"]} \ No newline at end of file diff --git a/dist/plugin.json b/dist/plugin.json index 0d9e6a7..46588a7 100644 --- a/dist/plugin.json +++ b/dist/plugin.json @@ -20,12 +20,13 @@ ], "screenshots": [ - {"name": "Panel", "path": "img/flant-statusmap-panel.png"}, + {"name": "Panel with light theme", "path": "img/flant-statusmap-panel.png"}, + {"name": "Panel with dark theme", "path": "img/flant-statusmap-panel-dark.png"}, {"name": "Color mapping", "path": "img/color-mapping.png"}, {"name": "Queries example", "path": "img/queries-example.png"} ], "version": "0.0.2", - "updated": "2018-10-05" + "updated": "2018-10-17" }, "dependencies": { diff --git a/dist/rendering.js.map b/dist/rendering.js.map new file mode 100644 index 0000000..453e2f0 --- /dev/null +++ b/dist/rendering.js.map @@ -0,0 +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","cardSpacing","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","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_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_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 cardSpacing, 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 range.push(chartHeight);\n for (let i = 1; i < ticks.length; i++) {\n range.push(chartHeight - step * i);\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 range.push(chartHeight - yOffset);\n for (let i = 1; i < ticks.length; i++) {\n range.push(chartHeight - 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 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 cardSpacing = panel.cards.cardSpacing !== null ? panel.cards.cardSpacing : CARD_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 - cardSpacing : 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 // we need to fill chartWidth with xBucketSize cards.\n xGridSize = chartWidth / (cardsData.xBucketSize+1);\n cardWidth = xGridSize - cardSpacing;\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 + cardSpacing/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 - cardSpacing/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 - cardSpacing/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 return w;\n }\n\n function getCardY(d) {\n return yScale(d.y) + chartTop - cardHeight - cardSpacing/2;\n }\n\n function getCardHeight(d) {\n let ys = yScale(d.y);\n let y = ys + chartTop - cardHeight - cardSpacing/2;\n let h = cardHeight;\n\n // Cut card height to prevent overlay\n if (y < chartTop) {\n h = ys - cardSpacing/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 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 diff --git a/dist/status_heatmap_ctrl.js b/dist/status_heatmap_ctrl.js index b0c8953..96aba20 100644 --- a/dist/status_heatmap_ctrl.js +++ b/dist/status_heatmap_ctrl.js @@ -1,6 +1,6 @@ 'use strict'; -System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/kbn', './rendering', './options_editor', './color_mode_discrete', './css/status-heatmap.css!'], function (_export, _context) { +System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/kbn', './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; @@ -50,7 +50,7 @@ System.register(['app/plugins/sdk', 'lodash', 'app/core/core', 'app/core/utils/k statusHeatmapOptionsEditor = _options_editor.statusHeatmapOptionsEditor; }, function (_color_mode_discrete) { ColorModeDiscrete = _color_mode_discrete.ColorModeDiscrete; - }, function (_cssStatusHeatmapCss) {}], + }], execute: function () { CANVAS = 'CANVAS'; SVG = 'SVG'; diff --git a/dist/status_heatmap_ctrl.js.map b/dist/status_heatmap_ctrl.js.map new file mode 100644 index 0000000..7636779 --- /dev/null +++ b/dist/status_heatmap_ctrl.js.map @@ -0,0 +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","cardSpacing","cardRound","xAxis","show","showWeekends","minBucketWidthToShowWeekends","showCrosshair","labelFormat","yAxis","tooltip","legend","data","unitFormat","decimals","nullPointMode","highlightCards","useMax","renderer","colorSchemes","name","value","invert","colorModes","opacityScales","StatusHeatmapCtrl","$scope","$injector","$rootScope","timeSrv","onRenderComplete","graph","chartWidth","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","onEditorAddThreeLights","link","scope","elem","attrs","ctrl","xBucketSize","yBucketSize","maxValue","minValue","length","targetIndex","i","ts","target","undefined","targets","keys","sort","min","map","d","datapoints","j","card","id","values","si","s","datapoint","x","y","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 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 cardSpacing: 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 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: 'darm' }\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 this.events.on('render-complete', this.onRenderComplete);\n }\n\n onRenderComplete = (data) => {\n this.graph.chartWidth = data.chartWidth;\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.cardSpacing;\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 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 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 };\n\n if (!data || data.length == 0) { return cardsData;}\n\n // collect uniq targets and their indexes in data array\n cardsData.targetIndex = {};\n for (let i = 0; i < data.length; i++) {\n let ts = data[i];\n let target = ts.target;\n if (cardsData.targetIndex[target] == undefined) {\n cardsData.targetIndex[target] = []\n }\n cardsData.targetIndex[target].push(i);\n }\n\n // TODO add some logic for targets heirarchy\n cardsData.targets = _.keys(cardsData.targetIndex);\n cardsData.targets.sort();\n cardsData.yBucketSize = cardsData.targets.length;\n cardsData.xBucketSize = _.min(_.map(data, d => d.datapoints.length));\n\n // Collect all values for each bucket from datapoints with similar target.\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 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 diff --git a/dist/tooltip.js b/dist/tooltip.js index 15e5633..3869451 100644 --- a/dist/tooltip.js +++ b/dist/tooltip.js @@ -88,7 +88,7 @@ System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_exp }, { key: 'add', value: function add() { - this.tooltip = d3.select("body").append("div").attr("class", "heatmap-tooltip graph-tooltip grafana-tooltip"); + this.tooltip = d3.select("body").append("div").attr("class", "statusmap-tooltip graph-tooltip grafana-tooltip"); } }, { key: 'destroy', @@ -128,7 +128,7 @@ System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_exp var tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss'; var time = this.dashboard.formatDate(+x, tooltipTimeFormat); - var tooltipHtml = '

' + time + '
\n
'; + var tooltipHtml = '
' + time + '
\n
'; if (this.panel.color.mode === 'discrete') { var statuses = this.panelCtrl.discreteHelper.convertValuesToTooltips(values); @@ -139,7 +139,7 @@ System.register(['d3', 'jquery', 'lodash', 'app/core/utils/kbn'], function (_exp statusesHtml = "statuses:"; } tooltipHtml += '\n
\n name: ' + y + '
\n ' + statusesHtml + '\n
    \n ' + _.join(_.map(statuses, function (v) { - return '
  • ' + v.tooltip + '
  • '; + return '
  • ' + v.tooltip + '
  • '; }), "") + '\n
\n
'; } else { if (values.length === 1) { diff --git a/dist/tooltip.js.map b/dist/tooltip.js.map new file mode 100644 index 0000000..37484dd --- /dev/null +++ b/dist/tooltip.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/tooltip.js"],"names":["d3","$","_","kbn","TOOLTIP_PADDING_X","TOOLTIP_PADDING_Y","StatusHeatmapTooltip","elem","scope","dashboard","ctrl","panelCtrl","panel","heatmapPanel","mouseOverBucket","originalFillColor","on","onMouseOver","bind","onMouseLeave","e","tooltip","show","data","isEmpty","add","move","destroy","select","append","attr","remove","pos","panelRelY","cardId","target","card","cardsData","cards","x","y","value","values","tooltipTimeFormat","time","formatDate","tooltipHtml","color","mode","statuses","discreteHelper","convertValuesToTooltips","statusesHtml","length","join","map","v","useMax","multipleValues","dataWarnings","title","noColorDefined","badValues","getNotColoredValues","html","node","tooltipWidth","clientWidth","tooltipHeight","clientHeight","left","pageX","top","pageY","window","innerWidth","pageYOffset","innerHeight","style"],"mappings":"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","file":"tooltip.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 = 5;\n\nexport class StatusHeatmapTooltip {\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.heatmapPanel = elem;\n this.mouseOverBucket = false;\n this.originalFillColor = null;\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.tooltip = d3.select(\"body\")\n .append(\"div\")\n .attr(\"class\", \"statusmap-tooltip graph-tooltip grafana-tooltip\");\n }\n\n destroy() {\n if (this.tooltip) {\n this.tooltip.remove();\n }\n\n this.tooltip = null;\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 let cardId = d3.select(pos.target).attr('cardId');\n if (!cardId) {\n this.destroy();\n return;\n }\n\n let card = this.panelCtrl.cardsData.cards[cardId];\n if (!card) {\n this.destroy();\n return;\n }\n\n let x = card.x;\n let y = card.y;\n let value = card.value;\n let values = card.values;\n let tooltipTimeFormat = 'YYYY-MM-DD HH:mm:ss';\n let time = this.dashboard.formatDate(+x, tooltipTimeFormat);\n\n let tooltipHtml = `
${time}
\n
`;\n\n if (this.panel.color.mode === 'discrete') {\n let statuses = this.panelCtrl.discreteHelper.convertValuesToTooltips(values);\n let statusesHtml = '';\n if (statuses.length === 1) {\n statusesHtml = \"status:\";\n } else if (statuses.length > 1) {\n statusesHtml = \"statuses:\";\n }\n tooltipHtml += `\n
\n name: ${y}
\n ${statusesHtml}\n
    \n ${_.join(_.map(statuses, v => `
  • ${v.tooltip}
  • `), \"\")}\n
\n
`;\n } else {\n if (values.length === 1) {\n tooltipHtml += `
\n name: ${y}
\n value: ${value}
\n
`;\n } else {\n tooltipHtml += `
\n name: ${y}
\n values:\n
    \n ${_.join(_.map(values, v => `
  • ${v}
  • `), \"\")}\n
\n
`;\n }\n }\n\n // \"Ambiguous bucket state: Multiple values!\";\n if (!this.panel.useMax && card.multipleValues) {\n tooltipHtml += `
Error: ${this.panelCtrl.dataWarnings.multipleValues.title}
`;\n }\n\n // Discrete mode errors\n if (this.panel.color.mode === 'discrete') {\n if (card.noColorDefined) {\n let badValues = this.panelCtrl.discreteHelper.getNotColoredValues(values);\n tooltipHtml += `
Error: ${this.panelCtrl.dataWarnings.noColorDefined.title}\n
not colored values:\n
    \n ${_.join(_.map(badValues, v => `
  • ${v}
  • `), \"\")}\n
\n
`;\n\n }\n }\n\n this.tooltip.html(tooltipHtml);\n\n this.move(pos);\n }\n\n move(pos) {\n if (!this.tooltip) { return; }\n\n let elem = $(this.tooltip.node())[0];\n let tooltipWidth = elem.clientWidth;\n let tooltipHeight = elem.clientHeight;\n\n let left = pos.pageX + TOOLTIP_PADDING_X;\n let top = pos.pageY + TOOLTIP_PADDING_Y;\n\n if (pos.pageX + tooltipWidth + 40 > 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.tooltip\n .style(\"left\", left + \"px\")\n .style(\"top\", top + \"px\");\n }\n}\n"]} \ No newline at end of file diff --git a/src/css/status-heatmap.scss b/src/css/_statusmap.scss similarity index 63% rename from src/css/status-heatmap.scss rename to src/css/_statusmap.scss index 5e3ee6f..2382457 100644 --- a/src/css/status-heatmap.scss +++ b/src/css/_statusmap.scss @@ -1,12 +1,10 @@ -$font-size-sm: 12px !default; - - .status-heatmap-canvas-wrapper { // position: relative; cursor: crosshair; .datapoints-warning span { - background-color: white; + background-color: $warning-bg; + color: $text-color; padding: 1px; } } @@ -16,14 +14,14 @@ $font-size-sm: 12px !default; .axis .tick { text { - fill: #52545c; - color: #52545c; - font-size: 11px; + fill: $text-color; + color: $text-color; + font-size: $font-size-tick; } line { opacity: 0.4; - stroke: #767980; + stroke: $text-color-weak; } } @@ -37,20 +35,27 @@ $font-size-sm: 12px !default; } } -.status-heatmap-tooltip { +.statusmap-tooltip { white-space: nowrap; font-size: $font-size-sm; - background-color: #dde4ed; - color: #52545c; + background-color: $graph-tooltip-bg; + color: $text-color; + + .discrete-item { + color: #52545c; + padding: 1px; + font-weight: bold; + text-shadow: 0 0 0.2em #FFF, 0 0 0.2em #FFF, 0 0 0.2em #FFF; + } } -.status-heatmap-histogram rect { - fill: #767980; +.statusmap-histogram rect { + fill: $text-color-weak; } .status-heatmap-crosshair { line { - stroke: darken(red,15%); + stroke: darken($red,15%); stroke-width: 1; } } @@ -61,14 +66,11 @@ $font-size-sm: 12px !default; stroke: rgba(102, 102, 102, 0.8); } + .status-heatmap-legend-wrapper { - // @include clearfix(); margin: 0 10px; - //padding-top: 10px; svg { - //width: 100%; - //max-width: 1300px; height: 24px; float: left; white-space: nowrap; @@ -85,19 +87,19 @@ $font-size-sm: 12px !default; .axis .tick { text { - fill: #52545c; - color: #52545c; - font-size: 11px; + fill: $text-color; + color: $text-color; + font-size: $font-size-tick; } line { opacity: 0.4; - stroke: #767980; + stroke: $text-color-weak; } .domain { opacity: 0.4; - stroke: #767980; + stroke: $text-color-weak; } } } diff --git a/src/css/_variables.dark.scss b/src/css/_variables.dark.scss new file mode 100644 index 0000000..6d0b610 --- /dev/null +++ b/src/css/_variables.dark.scss @@ -0,0 +1,9 @@ +// Dark variables +$text-color: #d8d9da; // $gray-4 +$text-color-weak: #8e8e8e; // $gray-2 +$graph-tooltip-bg: #141414; // $dark-1 +$warning-bg: #333333; // $dark-4 + +$theme-name: dark; +$white: #fff; +$red: #d44a3a; diff --git a/src/css/_variables.light.scss b/src/css/_variables.light.scss new file mode 100644 index 0000000..46df305 --- /dev/null +++ b/src/css/_variables.light.scss @@ -0,0 +1,10 @@ +// Light variables +$text-color: #52545c; // $gray-1 +$text-color-weak: #767980; // $gray-2 +$graph-tooltip-bg: #dde4ed; // $gray-5 +$warning-bg: #e9edf2; // $gray-6 + +$theme-name: light; +$white: #fff; +$red: #d44939; + diff --git a/src/css/_variables.scss b/src/css/_variables.scss new file mode 100644 index 0000000..6fb4540 --- /dev/null +++ b/src/css/_variables.scss @@ -0,0 +1,3 @@ +$font-size-sm: 12px !default; +$font-size-tick: 11px; + diff --git a/src/css/statusmap.dark.scss b/src/css/statusmap.dark.scss new file mode 100644 index 0000000..2f58744 --- /dev/null +++ b/src/css/statusmap.dark.scss @@ -0,0 +1,3 @@ +@import "variables"; +@import "variables.dark"; +@import "statusmap" diff --git a/src/css/statusmap.light.scss b/src/css/statusmap.light.scss new file mode 100644 index 0000000..b359a74 --- /dev/null +++ b/src/css/statusmap.light.scss @@ -0,0 +1,3 @@ +@import "variables"; +@import "variables.light"; +@import "statusmap" diff --git a/src/img/flant-statusmap-panel-dark.png b/src/img/flant-statusmap-panel-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..242eaae75f201b9b5a3aac74e652d02d08ca3d56 GIT binary patch literal 30692 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

t)6$P$WBA>f*f;lO6Ic!9&~VTpy<| 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 a-@!Muu0|E7_Wm5w3nn275UCK-_4_}!ECeF} literal 0 HcmV?d00001 diff --git a/src/module.js b/src/module.js index 9b47ac0..f31cc18 100644 --- a/src/module.js +++ b/src/module.js @@ -1,6 +1,13 @@ +import {loadPluginCss} from 'app/plugins/sdk'; import './color_legend'; import { StatusHeatmapCtrl } from './status_heatmap_ctrl'; +loadPluginCss({ + dark: 'plugins/flant-statusmap-panel/css/statusmap.dark.css', + light: 'plugins/flant-statusmap-panel/css/statusmap.light.css' +}); + + export { StatusHeatmapCtrl as PanelCtrl }; diff --git a/src/plugin.json b/src/plugin.json index 0d9e6a7..46588a7 100644 --- a/src/plugin.json +++ b/src/plugin.json @@ -20,12 +20,13 @@ ], "screenshots": [ - {"name": "Panel", "path": "img/flant-statusmap-panel.png"}, + {"name": "Panel with light theme", "path": "img/flant-statusmap-panel.png"}, + {"name": "Panel with dark theme", "path": "img/flant-statusmap-panel-dark.png"}, {"name": "Color mapping", "path": "img/color-mapping.png"}, {"name": "Queries example", "path": "img/queries-example.png"} ], "version": "0.0.2", - "updated": "2018-10-05" + "updated": "2018-10-17" }, "dependencies": { diff --git a/src/status_heatmap_ctrl.js b/src/status_heatmap_ctrl.js index 27d6b92..91f276b 100644 --- a/src/status_heatmap_ctrl.js +++ b/src/status_heatmap_ctrl.js @@ -9,7 +9,6 @@ import rendering from './rendering'; // import { labelFormats } from './xAxisLabelFormats'; import {statusHeatmapOptionsEditor} from './options_editor'; import {ColorModeDiscrete} from "./color_mode_discrete"; -import './css/status-heatmap.css!'; const CANVAS = 'CANVAS'; const SVG = 'SVG'; diff --git a/src/tooltip.js b/src/tooltip.js index 571c8b0..fa13883 100644 --- a/src/tooltip.js +++ b/src/tooltip.js @@ -42,7 +42,7 @@ export class StatusHeatmapTooltip { add() { this.tooltip = d3.select("body") .append("div") - .attr("class", "heatmap-tooltip graph-tooltip grafana-tooltip"); + .attr("class", "statusmap-tooltip graph-tooltip grafana-tooltip"); } destroy() { @@ -79,7 +79,7 @@ export class StatusHeatmapTooltip { let time = this.dashboard.formatDate(+x, tooltipTimeFormat); let tooltipHtml = `

${time}
-
`; +
`; if (this.panel.color.mode === 'discrete') { let statuses = this.panelCtrl.discreteHelper.convertValuesToTooltips(values); @@ -94,7 +94,7 @@ export class StatusHeatmapTooltip { name: ${y}
${statusesHtml}
    - ${_.join(_.map(statuses, v => `
  • ${v.tooltip}
  • `), "")} + ${_.join(_.map(statuses, v => `
  • ${v.tooltip}
  • `), "")}
`; } else {