mirror of https://github.com/grafana/grafana
parent
ef9dd014c7
commit
55b24be115
@ -0,0 +1,136 @@ |
||||
///<reference path="../../../headers/common.d.ts" />
|
||||
import angular from 'angular'; |
||||
import _ from 'lodash'; |
||||
import $ from 'jquery'; |
||||
import d3 from 'd3'; |
||||
import {contextSrv} from 'app/core/core'; |
||||
|
||||
let module = angular.module('grafana.directives'); |
||||
module.directive('colorLegend', function() { |
||||
return { |
||||
restrict: 'E', |
||||
template: '<div class="heatmap-color-legend"><svg width="19em" height="2em"></svg></div>', |
||||
link: function(scope, elem, attrs) { |
||||
let ctrl = scope.ctrl; |
||||
let panel = scope.ctrl.panel; |
||||
|
||||
render(); |
||||
|
||||
ctrl.events.on('render', function() { |
||||
render(); |
||||
}); |
||||
|
||||
function render() { |
||||
let legendElem = $(elem).find('svg'); |
||||
let legendWidth = Math.floor(legendElem.outerWidth()); |
||||
|
||||
if (panel.color.mode === 'spectrum') { |
||||
let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme}); |
||||
let colorScale = getColorScale(colorScheme, legendWidth); |
||||
drawColorLegend(elem, colorScale); |
||||
} else if (panel.color.mode === 'opacity') { |
||||
let colorOptions = panel.color; |
||||
drawOpacityLegend(elem, colorOptions); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
}); |
||||
|
||||
module.directive('heatmapLegend', function() { |
||||
return { |
||||
restrict: 'E', |
||||
template: '<div class="heatmap-color-legend"><svg width="19em" height="2em"></svg></div>', |
||||
link: function(scope, elem, attrs) { |
||||
let ctrl = scope.ctrl; |
||||
let panel = scope.ctrl.panel; |
||||
|
||||
ctrl.events.on('render', function() { |
||||
if (!_.isEmpty(ctrl.data)) { |
||||
let legendElem = $(elem).find('svg'); |
||||
let legendWidth = Math.floor(legendElem.outerWidth()); |
||||
|
||||
if (panel.color.mode === 'spectrum') { |
||||
let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme}); |
||||
let colorScale = getColorScale(colorScheme, legendWidth); |
||||
drawColorLegend(elem, colorScale); |
||||
} else if (panel.color.mode === 'opacity') { |
||||
let colorOptions = panel.color; |
||||
drawOpacityLegend(elem, colorOptions); |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
}; |
||||
}); |
||||
|
||||
function drawColorLegend(elem, colorScale) { |
||||
let legendElem = $(elem).find('svg'); |
||||
legendElem.find("rect").remove(); |
||||
|
||||
let legendWidth = Math.floor(legendElem.outerWidth()); |
||||
let legendHeight = legendElem.attr("height"); |
||||
|
||||
let rangeStep = 2; |
||||
let valuesRange = d3.range(0, legendWidth, rangeStep); |
||||
|
||||
let legend = d3.select(legendElem.get(0)); |
||||
var legendRects = legend.selectAll(".heatmap-color-legend-rect").data(valuesRange); |
||||
|
||||
legendRects.enter().append("rect") |
||||
.attr("x", d => d) |
||||
.attr("y", 0) |
||||
.attr("width", rangeStep + 1) // Overlap rectangles to prevent gaps
|
||||
.attr("height", legendHeight) |
||||
.attr("stroke-width", 0) |
||||
.attr("fill", d => colorScale(d)); |
||||
} |
||||
|
||||
function clearLegend(elem) { |
||||
let legendElem = $(elem).find('svg'); |
||||
legendElem.find("rect").remove(); |
||||
} |
||||
|
||||
function drawOpacityLegend(elem, options) { |
||||
let legendElem = $(elem).find('svg'); |
||||
clearLegend(elem); |
||||
|
||||
let legend = d3.select(legendElem.get(0)); |
||||
let legendWidth = Math.floor(legendElem.outerWidth()); |
||||
let legendHeight = legendElem.attr("height"); |
||||
|
||||
let legendOpacityScale; |
||||
if (options.colorScale === 'linear') { |
||||
legendOpacityScale = d3.scaleLinear() |
||||
.domain([0, legendWidth]) |
||||
.range([0, 1]); |
||||
} else if (options.colorScale === 'sqrt') { |
||||
legendOpacityScale = d3.scalePow().exponent(options.exponent) |
||||
.domain([0, legendWidth]) |
||||
.range([0, 1]); |
||||
} |
||||
|
||||
let rangeStep = 1; |
||||
let valuesRange = d3.range(0, legendWidth, rangeStep); |
||||
var legendRects = legend.selectAll(".heatmap-opacity-legend-rect").data(valuesRange); |
||||
|
||||
legendRects.enter().append("rect") |
||||
.attr("x", d => d) |
||||
.attr("y", 0) |
||||
.attr("width", rangeStep) |
||||
.attr("height", legendHeight) |
||||
.attr("stroke-width", 0) |
||||
.attr("fill", options.cardColor) |
||||
.style("opacity", d => legendOpacityScale(d)); |
||||
} |
||||
|
||||
function getColorScale(colorScheme, maxValue, minValue = 0) { |
||||
let colorInterpolator = d3[colorScheme.value]; |
||||
let colorScaleInverted = colorScheme.invert === 'always' || |
||||
(colorScheme.invert === 'dark' && !contextSrv.user.lightTheme); |
||||
|
||||
let start = colorScaleInverted ? maxValue : minValue; |
||||
let end = colorScaleInverted ? minValue : maxValue; |
||||
|
||||
return d3.scaleSequential(colorInterpolator).domain([start, end]); |
||||
} |
Loading…
Reference in new issue