"use strict"; System.register(["lodash", "jquery", "d3", "./libs/d3-scale-chromatic/index", "app/core/core", "app/core/utils/ticks", "app/core/core_module"], function (_export, _context) { "use strict"; var _, $, d3, d3ScaleChromatic, contextSrv, tickStep, coreModule, LEGEND_STEP_WIDTH; function drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minValue) { var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); clearLegend(elem); var legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values var legendHeight = legendElem.attr("height"); var rangeStep = (rangeTo - rangeFrom) / (legendWidth / LEGEND_STEP_WIDTH); // width in pixels in legend space of unit segment in range space // rangeStep * witdhFactor == width in pixels of one rangeStep var widthFactor = legendWidth / (rangeTo - rangeFrom); var valuesRange = d3.range(rangeFrom, rangeTo, rangeStep); var colorScale = getColorScale(colorScheme, maxValue, minValue); legend.selectAll(".status-heatmap-color-legend-rect").data(valuesRange).enter().append("rect") // translate from range space into pixels // and shift all rectangles to the right by 10 .attr("x", function (d) { return (d - rangeFrom) * widthFactor + 10; }).attr("y", 0) // rectangles are slightly overlaped to prevent gaps .attr("width", LEGEND_STEP_WIDTH + 1).attr("height", legendHeight).attr("stroke-width", 0).attr("fill", function (d) { return colorScale(d); }); drawLegendValues(elem, colorScale, rangeFrom, rangeTo, maxValue, minValue, legendWidth); } function drawOpacityLegend(elem, options, rangeFrom, rangeTo, maxValue, minValue) { var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); clearLegend(elem); var legendWidth = Math.floor(legendElem.outerWidth()) - 30; // narrow legendWidth by 30px to get space for first and last tick values var legendHeight = legendElem.attr("height"); var rangeStep = (rangeTo - rangeFrom) / (legendWidth / LEGEND_STEP_WIDTH); // width in pixels in legend space of unit segment in range space // rangeStep * witdhFactor == width in pixels of one rangeStep var widthFactor = legendWidth / (rangeTo - rangeFrom); var valuesRange = d3.range(rangeFrom, rangeTo, rangeStep); var opacityScale = getOpacityScale(options, maxValue, minValue); legend.selectAll(".status-heatmap-opacity-legend-rect").data(valuesRange).enter().append("rect") // translate from range space into pixels // and shift all rectangles to the right by 10 .attr("x", function (d) { return d * widthFactor + 10; }).attr("y", 0) // rectangles are slightly overlaped to prevent gaps .attr("width", LEGEND_STEP_WIDTH + 1).attr("height", legendHeight).attr("stroke-width", 0).attr("fill", options.cardColor).style("opacity", function (d) { return opacityScale(d); }); drawLegendValues(elem, opacityScale, rangeFrom, rangeTo, maxValue, minValue, legendWidth); } function drawDiscreteColorLegend(elem, colorOptions, discreteExtraSeries) { var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); clearLegend(elem); var thresholds = colorOptions.thresholds; var tooltips = _.map(thresholds, function (tr) { return tr.tooltip; }); var valuesNumber = thresholds.length; // graph width as a fallback var $heatmap = $(elem).parent().parent().parent().find('.statusmap-panel'); var graphWidthAttr = $heatmap.find('svg').attr("width"); var graphWidth = parseInt(graphWidthAttr); // calculate max width of tooltip and use it as width for each item var textWidth = []; legend.selectAll(".hidden-texts").data(tooltips).enter().append("text").attr("class", "axis tick hidden-texts").attr("font-family", "sans-serif").text(function (d) { return d; }).each(function (d, i) { var thisWidth = this.getBBox().width; textWidth.push(thisWidth); }); legend.selectAll(".hidden-texts").remove(); var legendWidth = Math.floor(_.min([graphWidth - 30, (_.max(textWidth) + 3) * valuesNumber])); legendElem.attr("width", legendWidth); var legendHeight = legendElem.attr("height"); var itemWidth = Math.floor(legendWidth / valuesNumber); var valuesRange = d3.range(valuesNumber); // from 0 to valuesNumber-1 legend.selectAll(".status-heatmap-color-legend-rect").data(valuesRange).enter().append("rect").attr("x", function (d) { return d * itemWidth; }).attr("y", 0).attr("width", itemWidth + 1) // Overlap rectangles to prevent gaps .attr("height", legendHeight).attr("stroke-width", 0).attr("fill", function (d) { return discreteExtraSeries.getDiscreteColor(d); }); drawDiscreteLegendValues(elem, colorOptions, legendWidth); } function drawLegendValues(elem, colorScale, rangeFrom, rangeTo, maxValue, minValue, legendWidth) { var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); if (legendWidth <= 0 || legendElem.get(0).childNodes.length === 0) { return; } var legendValueScale = d3.scaleLinear().domain([rangeFrom, rangeTo]).range([0, legendWidth]); var ticks = buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue); var xAxis = d3.axisBottom(legendValueScale).tickValues(ticks).tickSize(2); var colorRect = legendElem.find(":first-child"); var posY = getSvgElemHeight(legendElem) + 2; var posX = getSvgElemX(colorRect); d3.select(legendElem.get(0)).append("g").attr("class", "axis").attr("transform", "translate(" + posX + "," + posY + ")").call(xAxis); legend.select(".axis").select(".domain").remove(); } function drawDiscreteLegendValues(elem, colorOptions, legendWidth) { var thresholds = colorOptions.thresholds; var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); if (legendWidth <= 0 || legendElem.get(0).childNodes.length === 0) { return; } var valuesNumber = thresholds.length; var rangeStep = Math.floor(legendWidth / valuesNumber); var valuesRange = d3.range(0, legendWidth, rangeStep); var legendValueScale = d3.scaleLinear().domain([0, valuesNumber]).range([0, legendWidth]); var thresholdValues = []; var thresholdTooltips = []; for (var i = 0; i < thresholds.length; i++) { thresholdValues.push(thresholds[i].value); thresholdTooltips.push(thresholds[i].tooltip); } var xAxis = d3.axisBottom(legendValueScale).tickValues(d3.range(0, valuesNumber, 1)) //thresholdValues) .tickSize(2).tickFormat(function (t) { var i = Math.floor(t); var v = thresholdTooltips[i]; if (v != undefined) { return "" + v; } else { v = thresholdValues[i]; if (v != undefined) { return "" + v; } else { return "n/a"; } } }); var colorRect = legendElem.find(":first-child"); var posY = getSvgElemHeight(legendElem) + 2; var posX = getSvgElemX(colorRect) + Math.floor(rangeStep / 2); d3.select(legendElem.get(0)).append("g").attr("class", "axis").attr("transform", "translate(" + posX + "," + posY + ")").call(xAxis); legend.select(".axis").select(".domain").remove(); } function drawSimpleColorLegend(elem, colorScale) { var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); clearLegend(elem); var legendWidth = Math.floor(legendElem.outerWidth()); var legendHeight = legendElem.attr("height"); if (legendWidth) { var valuesRange = d3.range(0, legendWidth, LEGEND_STEP_WIDTH); legend.selectAll(".status-heatmap-color-legend-rect").data(valuesRange).enter().append("rect").attr("x", function (d) { return d; }).attr("y", 0).attr("width", LEGEND_STEP_WIDTH + 1) // Overlap rectangles to prevent gaps .attr("height", legendHeight).attr("stroke-width", 0).attr("fill", function (d) { return colorScale(d); }); } } function drawSimpleOpacityLegend(elem, options) { var legendElem = $(elem).find('svg'); var legend = d3.select(legendElem.get(0)); clearLegend(elem); var legendWidth = Math.floor(legendElem.outerWidth()); var legendHeight = legendElem.attr("height"); if (legendWidth) { var 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]); } var valuesRange = d3.range(0, legendWidth, LEGEND_STEP_WIDTH); legend.selectAll(".status-heatmap-opacity-legend-rect").data(valuesRange).enter().append("rect").attr("x", function (d) { return d; }).attr("y", 0).attr("width", LEGEND_STEP_WIDTH + 1).attr("height", legendHeight).attr("stroke-width", 0).attr("fill", options.cardColor).style("opacity", function (d) { return legendOpacityScale(d); }); } } function clearLegend(elem) { var legendElem = $(elem).find('svg'); legendElem.empty(); } function getColorScale(colorScheme, maxValue) { var minValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var colorInterpolator = d3ScaleChromatic[colorScheme.value]; var colorScaleInverted = colorScheme.invert === 'always' || colorScheme.invert === 'dark' && !contextSrv.user.lightTheme; var start = colorScaleInverted ? maxValue : minValue; var end = colorScaleInverted ? minValue : maxValue; return d3.scaleSequential(colorInterpolator).domain([start, end]); } function getOpacityScale(options, maxValue) { var minValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; var legendOpacityScale; if (options.colorScale === 'linear') { legendOpacityScale = d3.scaleLinear().domain([minValue, maxValue]).range([0, 1]); } else if (options.colorScale === 'sqrt') { legendOpacityScale = d3.scalePow().exponent(options.exponent).domain([minValue, maxValue]).range([0, 1]); } return legendOpacityScale; } function getSvgElemX(elem) { var svgElem = elem.get(0); if (svgElem && svgElem.x && svgElem.x.baseVal) { return svgElem.x.baseVal.value; } else { return 0; } } function getSvgElemHeight(elem) { var svgElem = elem.get(0); if (svgElem && svgElem.height && svgElem.height.baseVal) { return svgElem.height.baseVal.value; } else { return 0; } } function buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) { var range = rangeTo - rangeFrom; var tickStepSize = tickStep(rangeFrom, rangeTo, 3); var ticksNum = Math.round(range / tickStepSize); var ticks = []; for (var i = 0; i < ticksNum; i++) { var current = tickStepSize * i + rangeFrom; // Add user-defined min and max if it had been set if (isValueCloseTo(minValue, current, tickStepSize)) { ticks.push(minValue); continue; } else if (minValue < current) { ticks.push(minValue); } if (isValueCloseTo(maxValue, current, tickStepSize)) { ticks.push(maxValue); continue; } else if (maxValue < current) { ticks.push(maxValue); } ticks.push(current); } if (!isValueCloseTo(maxValue, rangeTo, tickStepSize)) { ticks.push(maxValue); } ticks.push(rangeTo); ticks = _.sortBy(_.uniq(ticks)); return ticks; } function isValueCloseTo(val, valueTo, step) { var diff = Math.abs(val - valueTo); return diff < step * 0.3; } return { setters: [function (_lodash) { _ = _lodash.default; }, function (_jquery) { $ = _jquery.default; }, function (_d) { d3 = _d.default; }, function (_libsD3ScaleChromaticIndex) { d3ScaleChromatic = _libsD3ScaleChromaticIndex; }, function (_appCoreCore) { contextSrv = _appCoreCore.contextSrv; }, function (_appCoreUtilsTicks) { tickStep = _appCoreUtilsTicks.tickStep; }, function (_appCoreCore_module) { coreModule = _appCoreCore_module.default; }], execute: function () { LEGEND_STEP_WIDTH = 2; /** * Bigger color legend for opacity and spectrum modes editor. */ coreModule.directive('optionsColorLegend', function () { return { restrict: 'E', template: '
', link: function link(scope, elem, attrs) { var ctrl = scope.ctrl; var panel = scope.ctrl.panel; render(); ctrl.events.on('render', function () { render(); }); function render() { var legendElem = $(elem).find('svg'); var legendWidth = Math.floor(legendElem.outerWidth()); if (panel.color.mode === 'spectrum') { var colorScheme = _.find(ctrl.colorSchemes, { value: panel.color.colorScheme }); var colorScale = getColorScale(colorScheme, legendWidth); drawSimpleColorLegend(elem, colorScale); } else if (panel.color.mode === 'opacity') { var colorOptions = panel.color; drawSimpleOpacityLegend(elem, colorOptions); } } } }; }); /** * Graph legend with values. */ coreModule.directive('statusHeatmapLegend', function () { return { restrict: 'E', template: '
', link: function link(scope, elem, attrs) { var ctrl = scope.ctrl; var panel = scope.ctrl.panel; render(); ctrl.events.on('render', function () { render(); }); function render() { clearLegend(elem); if (!ctrl.panel.legend.show) { return; } if (ctrl.bucketMatrix) { var rangeFrom = ctrl.bucketMatrix.minValue; var rangeTo = ctrl.bucketMatrix.maxValue; var maxValue = panel.color.max || rangeTo; var minValue = panel.color.min || rangeFrom; if (ctrl.bucketMatrix.noDatapoints) { if (!panel.color.max) { rangeTo = maxValue = 100; } else { rangeTo = 100; } if (!panel.color.min) { rangeFrom = minValue = 0; } else { rangeFrom = 0; } } // console.log("legend state:", { // rangeFrom: rangeFrom, // rangeTo: rangeTo, // maxValue: maxValue, // minValue: minValue, // colorMode: panel.color.mode // }); if (panel.color.mode === 'spectrum') { var colorScheme = _.find(ctrl.colorSchemes, { value: panel.color.colorScheme }); drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minValue); } else if (panel.color.mode === 'opacity') { var colorOptions = panel.color; drawOpacityLegend(elem, colorOptions, rangeFrom, rangeTo, maxValue, minValue); } else if (panel.color.mode === 'discrete') { var _colorOptions = panel.color; drawDiscreteColorLegend(elem, _colorOptions, ctrl.discreteExtraSeries); } } } } }; }); } }; }); //# sourceMappingURL=color_legend.js.map