Commit fb3ea93f by Alexander Zobnin

heatmap: fix for negative values

parent 54f92514
...@@ -69,10 +69,11 @@ coreModule.directive('heatmapLegend', () => { ...@@ -69,10 +69,11 @@ coreModule.directive('heatmapLegend', () => {
function render() { function render() {
clearLegend(elem); clearLegend(elem);
if (!_.isEmpty(ctrl.data) && !_.isEmpty(ctrl.data.cards)) { if (!_.isEmpty(ctrl.data) && !_.isEmpty(ctrl.data.cards)) {
const rangeFrom = 0; const cardStats = ctrl.data.cardStats;
const rangeTo = ctrl.data.cardStats.max; const rangeFrom = _.isNil(panel.color.min) ? Math.min(cardStats.min, 0) : panel.color.min;
const maxValue = panel.color.max || rangeTo; const rangeTo = _.isNil(panel.color.max) ? cardStats.max : panel.color.max;
const minValue = panel.color.min || 0; const maxValue = cardStats.max;
const minValue = cardStats.min;
if (panel.color.mode === 'spectrum') { if (panel.color.mode === 'spectrum') {
const colorScheme = _.find(ctrl.colorSchemes, { const colorScheme = _.find(ctrl.colorSchemes, {
...@@ -110,7 +111,7 @@ function drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minVal ...@@ -110,7 +111,7 @@ function drawColorLegend(elem, colorScheme, rangeFrom, rangeTo, maxValue, minVal
.data(valuesRange) .data(valuesRange)
.enter() .enter()
.append('rect') .append('rect')
.attr('x', d => Math.round(d * widthFactor)) .attr('x', d => Math.round((d - rangeFrom) * widthFactor))
.attr('y', 0) .attr('y', 0)
.attr('width', Math.round(rangeStep * widthFactor + 1)) // Overlap rectangles to prevent gaps .attr('width', Math.round(rangeStep * widthFactor + 1)) // Overlap rectangles to prevent gaps
.attr('height', legendHeight) .attr('height', legendHeight)
...@@ -141,7 +142,7 @@ function drawOpacityLegend(elem, options, rangeFrom, rangeTo, maxValue, minValue ...@@ -141,7 +142,7 @@ function drawOpacityLegend(elem, options, rangeFrom, rangeTo, maxValue, minValue
.data(valuesRange) .data(valuesRange)
.enter() .enter()
.append('rect') .append('rect')
.attr('x', d => Math.round(d * widthFactor)) .attr('x', d => Math.round((d - rangeFrom) * widthFactor))
.attr('y', 0) .attr('y', 0)
.attr('width', Math.round(rangeStep * widthFactor)) .attr('width', Math.round(rangeStep * widthFactor))
.attr('height', legendHeight) .attr('height', legendHeight)
...@@ -162,10 +163,10 @@ function drawLegendValues(elem, rangeFrom, rangeTo, maxValue, minValue, legendWi ...@@ -162,10 +163,10 @@ function drawLegendValues(elem, rangeFrom, rangeTo, maxValue, minValue, legendWi
const legendValueScale = d3 const legendValueScale = d3
.scaleLinear() .scaleLinear()
.domain([0, rangeTo]) .domain([rangeFrom, rangeTo])
.range([0, legendWidth]); .range([0, legendWidth]);
const ticks = buildLegendTicks(0, rangeTo, maxValue, minValue); const ticks = buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue);
const xAxis = d3 const xAxis = d3
.axisBottom(legendValueScale) .axisBottom(legendValueScale)
.tickValues(ticks) .tickValues(ticks)
...@@ -286,11 +287,12 @@ function getSvgElemHeight(elem) { ...@@ -286,11 +287,12 @@ function getSvgElemHeight(elem) {
function buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) { function buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) {
const range = rangeTo - rangeFrom; const range = rangeTo - rangeFrom;
const tickStepSize = tickStep(rangeFrom, rangeTo, 3); const tickStepSize = tickStep(rangeFrom, rangeTo, 3);
const ticksNum = Math.round(range / tickStepSize); const ticksNum = Math.ceil(range / tickStepSize);
const firstTick = getFirstCloseTick(rangeFrom, tickStepSize);
let ticks = []; let ticks = [];
for (let i = 0; i < ticksNum; i++) { for (let i = 0; i < ticksNum; i++) {
const current = tickStepSize * i; const current = firstTick + tickStepSize * i;
// Add user-defined min and max if it had been set // Add user-defined min and max if it had been set
if (isValueCloseTo(minValue, current, tickStepSize)) { if (isValueCloseTo(minValue, current, tickStepSize)) {
ticks.push(minValue); ticks.push(minValue);
...@@ -304,7 +306,7 @@ function buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) { ...@@ -304,7 +306,7 @@ function buildLegendTicks(rangeFrom, rangeTo, maxValue, minValue) {
} else if (maxValue < current) { } else if (maxValue < current) {
ticks.push(maxValue); ticks.push(maxValue);
} }
ticks.push(tickStepSize * i); ticks.push(current);
} }
if (!isValueCloseTo(maxValue, rangeTo, tickStepSize)) { if (!isValueCloseTo(maxValue, rangeTo, tickStepSize)) {
ticks.push(maxValue); ticks.push(maxValue);
...@@ -318,3 +320,10 @@ function isValueCloseTo(val, valueTo, step) { ...@@ -318,3 +320,10 @@ function isValueCloseTo(val, valueTo, step) {
const diff = Math.abs(val - valueTo); const diff = Math.abs(val - valueTo);
return diff < step * 0.3; return diff < step * 0.3;
} }
function getFirstCloseTick(minValue, step) {
if (minValue < 0) {
return Math.floor(minValue / step) * step;
}
return 0;
}
...@@ -524,14 +524,16 @@ export class HeatmapRenderer { ...@@ -524,14 +524,16 @@ export class HeatmapRenderer {
} }
const cardsData = this.data.cards; const cardsData = this.data.cards;
const maxValueAuto = this.data.cardStats.max; const cardStats = this.data.cardStats;
const maxValue = this.panel.color.max || maxValueAuto; const maxValueAuto = cardStats.max;
const minValue = this.panel.color.min || 0; const minValueAuto = Math.min(cardStats.min, 0);
const maxValue = _.isNil(this.panel.color.max) ? maxValueAuto : this.panel.color.max;
const minValue = _.isNil(this.panel.color.min) ? minValueAuto : this.panel.color.min;
const colorScheme = _.find(this.ctrl.colorSchemes, { const colorScheme = _.find(this.ctrl.colorSchemes, {
value: this.panel.color.colorScheme, value: this.panel.color.colorScheme,
}); });
this.colorScale = getColorScale(colorScheme, contextSrv.user.lightTheme, maxValue, minValue); this.colorScale = getColorScale(colorScheme, contextSrv.user.lightTheme, maxValue, minValue);
this.opacityScale = getOpacityScale(this.panel.color, maxValue); this.opacityScale = getOpacityScale(this.panel.color, maxValue, minValue);
this.setCardSize(); this.setCardSize();
let cards = this.heatmap.selectAll('.heatmap-card').data(cardsData); let cards = this.heatmap.selectAll('.heatmap-card').data(cardsData);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment