mirror of
https://github.com/timberjoegithub/grafana-statusmap.git
synced 2026-07-21 23:42:03 +00:00
bucket spacing, fix 1px last card.
This commit is contained in:
@@ -137,13 +137,17 @@
|
|||||||
<select class="gf-form-input max-width-9" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['as empty', 'as zero']" ng-change="ctrl.render()"></select>
|
<select class="gf-form-input max-width-9" ng-model="ctrl.panel.nullPointMode" ng-options="f for f in ['as empty', 'as zero']" ng-change="ctrl.render()"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="gf-form">
|
||||||
|
<label class="gf-form-label width-9">Min width for 1/1</label>
|
||||||
|
<input type="number" class="gf-form-input width-5" placeholder="5" data-placement="right" bs-tooltip="'Minimal card width for 1/1 resolution in pixels'" ng-model="ctrl.panel.cards.cardMinWidth" ng-change="ctrl.refresh()" ng-model-onblur>
|
||||||
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label width-9">Spacing</label>
|
<label class="gf-form-label width-9">Spacing</label>
|
||||||
<input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right" bs-tooltip="''" ng-model="ctrl.panel.cards.cardPadding" ng-change="ctrl.refresh()" ng-model-onblur>
|
<input type="number" class="gf-form-input width-5" placeholder="2" data-placement="right" bs-tooltip="'Card spacing in pixels'" ng-model="ctrl.panel.cards.cardSpacing" ng-change="ctrl.refresh()" ng-model-onblur>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label width-9">Rounding</label>
|
<label class="gf-form-label width-9">Rounding</label>
|
||||||
<input type="number" class="gf-form-input width-5" placeholder="auto" data-placement="right" bs-tooltip="''" ng-model="ctrl.panel.cards.cardRound" ng-change="ctrl.refresh()" ng-model-onblur>
|
<input type="number" class="gf-form-input width-5" placeholder="0" data-placement="right" bs-tooltip="'Angles rounding in percent'" ng-model="ctrl.panel.cards.cardRound" ng-change="ctrl.refresh()" ng-model-onblur>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+37
-26
@@ -8,8 +8,8 @@ import d3 from 'd3';
|
|||||||
import * as d3ScaleChromatic from './libs/d3-scale-chromatic/index';
|
import * as d3ScaleChromatic from './libs/d3-scale-chromatic/index';
|
||||||
import {StatusHeatmapTooltip} from './tooltip';
|
import {StatusHeatmapTooltip} from './tooltip';
|
||||||
|
|
||||||
let MIN_CARD_SIZE = 1,
|
let MIN_CARD_SIZE = 5,
|
||||||
CARD_PADDING = 1,
|
CARD_SPACING = 2,
|
||||||
CARD_ROUND = 0,
|
CARD_ROUND = 0,
|
||||||
DATA_RANGE_WIDING_FACTOR = 1.2,
|
DATA_RANGE_WIDING_FACTOR = 1.2,
|
||||||
DEFAULT_X_TICK_SIZE_PX = 100,
|
DEFAULT_X_TICK_SIZE_PX = 100,
|
||||||
@@ -30,10 +30,11 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
chartWidth, chartHeight,
|
chartWidth, chartHeight,
|
||||||
chartTop, chartBottom,
|
chartTop, chartBottom,
|
||||||
yAxisWidth, xAxisHeight,
|
yAxisWidth, xAxisHeight,
|
||||||
cardPadding, cardRound,
|
cardSpacing, cardRound,
|
||||||
cardWidth, cardHeight,
|
cardWidth, cardHeight,
|
||||||
colorScale, opacityScale,
|
colorScale, opacityScale,
|
||||||
mouseUpHandler;
|
mouseUpHandler,
|
||||||
|
xGridSize, yGridSize;
|
||||||
|
|
||||||
let yOffset = 0;
|
let yOffset = 0;
|
||||||
|
|
||||||
@@ -91,9 +92,10 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addXAxis() {
|
function addXAxis() {
|
||||||
|
// Scale timestamps to cards centers
|
||||||
scope.xScale = xScale = d3.scaleTime()
|
scope.xScale = xScale = d3.scaleTime()
|
||||||
.domain([timeRange.from, timeRange.to])
|
.domain([timeRange.from, timeRange.to])
|
||||||
.range([0, chartWidth]);
|
.range([xGridSize/2, chartWidth-xGridSize/2]);
|
||||||
|
|
||||||
let ticks = chartWidth / DEFAULT_X_TICK_SIZE_PX;
|
let ticks = chartWidth / DEFAULT_X_TICK_SIZE_PX;
|
||||||
let grafanaTimeFormatter = grafanaTimeFormat(ticks, timeRange.from, timeRange.to);
|
let grafanaTimeFormatter = grafanaTimeFormat(ticks, timeRange.from, timeRange.to);
|
||||||
@@ -229,12 +231,12 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
chartTop = margin.top;
|
chartTop = margin.top;
|
||||||
chartBottom = chartTop + chartHeight;
|
chartBottom = chartTop + chartHeight;
|
||||||
|
|
||||||
cardPadding = panel.cards.cardPadding !== null ? panel.cards.cardPadding : CARD_PADDING;
|
cardSpacing = panel.cards.cardSpacing !== null ? panel.cards.cardSpacing : CARD_SPACING;
|
||||||
cardRound = panel.cards.cardRound !== null ? panel.cards.cardRound : CARD_ROUND;
|
cardRound = panel.cards.cardRound !== null ? panel.cards.cardRound : CARD_ROUND;
|
||||||
|
|
||||||
// calculate yOffset for YAxis
|
// calculate yOffset for YAxis
|
||||||
let yGridSize = Math.floor(chartHeight / cardsData.yBucketSize);
|
yGridSize = Math.floor(chartHeight / cardsData.yBucketSize);
|
||||||
cardHeight = yGridSize ? yGridSize - cardPadding * 2 : 0;
|
cardHeight = yGridSize ? yGridSize - cardSpacing : 0;
|
||||||
yOffset = cardHeight / 2;
|
yOffset = cardHeight / 2;
|
||||||
|
|
||||||
addYAxis();
|
addYAxis();
|
||||||
@@ -242,8 +244,9 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
yAxisWidth = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING;
|
yAxisWidth = getYAxisWidth(heatmap) + Y_AXIS_TICK_PADDING;
|
||||||
chartWidth = width - yAxisWidth - margin.right;
|
chartWidth = width - yAxisWidth - margin.right;
|
||||||
|
|
||||||
let xGridSize = Math.floor(chartWidth / cardsData.xBucketSize);
|
// we need to fill chartWidth with xBucketSize cards.
|
||||||
cardWidth = xGridSize - cardPadding * 2;
|
xGridSize = chartWidth / (cardsData.xBucketSize+1);
|
||||||
|
cardWidth = xGridSize - cardSpacing;
|
||||||
|
|
||||||
addXAxis();
|
addXAxis();
|
||||||
xAxisHeight = getXAxisHeight(heatmap);
|
xAxisHeight = getXAxisHeight(heatmap);
|
||||||
@@ -351,46 +354,53 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
|
|
||||||
function getCardX(d) {
|
function getCardX(d) {
|
||||||
let x;
|
let x;
|
||||||
if (xScale(d.x) < 0) {
|
// cx is the center of the card. Card should be placed to the left.
|
||||||
// Cut card left to prevent overlay
|
let cx = xScale(d.x);
|
||||||
x = yAxisWidth + cardPadding;
|
|
||||||
|
if (cx - cardWidth/2 < 0) {
|
||||||
|
x = yAxisWidth + cardSpacing/2;
|
||||||
} else {
|
} else {
|
||||||
x = xScale(d.x) + yAxisWidth + cardPadding;
|
x = yAxisWidth + cx - cardWidth/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// xScale returns card center. Adjust cardWidth in case of overlaping.
|
||||||
function getCardWidth(d) {
|
function getCardWidth(d) {
|
||||||
let w;
|
let w;
|
||||||
if (xScale(d.x) < 0) {
|
let cx = xScale(d.x);
|
||||||
// Cut card left to prevent overlay
|
|
||||||
let cutted_width = xScale(d.x) + cardWidth;
|
if (cx < cardWidth/2) {
|
||||||
|
// Center should not exceed half of card.
|
||||||
|
// Cut card to the left to prevent overlay of y axis.
|
||||||
|
let cutted_width = (cx - cardSpacing/2) + cardWidth/2;
|
||||||
w = cutted_width > 0 ? cutted_width : 0;
|
w = cutted_width > 0 ? cutted_width : 0;
|
||||||
} else if (xScale(d.x) + cardWidth > chartWidth) {
|
} else if (chartWidth - cx < cardWidth/2) {
|
||||||
// Cut card right to prevent overlay
|
// Cut card to the right to prevent overlay of right graph edge.
|
||||||
w = chartWidth - xScale(d.x) - cardPadding;
|
w = cardWidth/2 + (chartWidth - cx - cardSpacing/2);
|
||||||
} else {
|
} else {
|
||||||
w = cardWidth;
|
w = cardWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Card width should be MIN_CARD_SIZE at least
|
// Card width should be MIN_CARD_SIZE at least
|
||||||
w = Math.max(w, MIN_CARD_SIZE);
|
w = Math.max(w, MIN_CARD_SIZE);
|
||||||
|
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCardY(d) {
|
function getCardY(d) {
|
||||||
return yScale(d.y) + chartTop - cardHeight - cardPadding;
|
return yScale(d.y) + chartTop - cardHeight - cardSpacing/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCardHeight(d) {
|
function getCardHeight(d) {
|
||||||
let ys = yScale(d.y);
|
let ys = yScale(d.y);
|
||||||
let y = ys + chartTop - cardHeight - cardPadding;
|
let y = ys + chartTop - cardHeight - cardSpacing/2;
|
||||||
let h = cardHeight;
|
let h = cardHeight;
|
||||||
|
|
||||||
// Cut card height to prevent overlay
|
// Cut card height to prevent overlay
|
||||||
if (y < chartTop) {
|
if (y < chartTop) {
|
||||||
h = ys - cardPadding;
|
h = ys - cardSpacing/2;
|
||||||
} else if (ys > chartBottom) {
|
} else if (ys > chartBottom) {
|
||||||
h = chartBottom - y;
|
h = chartBottom - y;
|
||||||
} else if (y + cardHeight > chartBottom) {
|
} else if (y + cardHeight > chartBottom) {
|
||||||
@@ -464,8 +474,8 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
|
|
||||||
let selectionRange = Math.abs(selection.x2 - selection.x1);
|
let selectionRange = Math.abs(selection.x2 - selection.x1);
|
||||||
if (selection.x2 >= 0 && selectionRange > MIN_SELECTION_WIDTH) {
|
if (selection.x2 >= 0 && selectionRange > MIN_SELECTION_WIDTH) {
|
||||||
let timeFrom = xScale.invert(Math.min(selection.x1, selection.x2) - yAxisWidth);
|
let timeFrom = xScale.invert(Math.min(selection.x1, selection.x2) - yAxisWidth - xGridSize/2);
|
||||||
let timeTo = xScale.invert(Math.max(selection.x1, selection.x2) - yAxisWidth);
|
let timeTo = xScale.invert(Math.max(selection.x1, selection.x2) - yAxisWidth - xGridSize/2);
|
||||||
|
|
||||||
ctrl.timeSrv.setTime({
|
ctrl.timeSrv.setTime({
|
||||||
from: moment.utc(timeFrom),
|
from: moment.utc(timeFrom),
|
||||||
@@ -499,7 +509,7 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function emitGraphHoverEvet(event) {
|
function emitGraphHoverEvet(event) {
|
||||||
let x = xScale.invert(event.offsetX - yAxisWidth).valueOf();
|
let x = xScale.invert(event.offsetX - yAxisWidth - xGridSize/2).valueOf();
|
||||||
let y = yScale(event.offsetY);
|
let y = yScale(event.offsetY);
|
||||||
let pos = {
|
let pos = {
|
||||||
pageX: event.pageX,
|
pageX: event.pageX,
|
||||||
@@ -568,6 +578,7 @@ export default function link(scope, elem, attrs, ctrl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// map time to X
|
||||||
function drawSharedCrosshair(pos) {
|
function drawSharedCrosshair(pos) {
|
||||||
if (heatmap && ctrl.dashboard.graphTooltip !== 0) {
|
if (heatmap && ctrl.dashboard.graphTooltip !== 0) {
|
||||||
let posX = xScale(pos.x) + yAxisWidth;
|
let posX = xScale(pos.x) + yAxisWidth;
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ const panelDefaults = {
|
|||||||
thresholds: [] // manual colors
|
thresholds: [] // manual colors
|
||||||
},
|
},
|
||||||
cards: {
|
cards: {
|
||||||
cardPadding: null,
|
cardMinWidth: 5,
|
||||||
|
cardSpacing: 2,
|
||||||
cardRound: null
|
cardRound: null
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@@ -148,9 +149,9 @@ export class StatusHeatmapCtrl extends MetricsPanelCtrl {
|
|||||||
chartWidth = Math.ceil($(window).width() * (this.panel.gridPos.w / 24));
|
chartWidth = Math.ceil($(window).width() * (this.panel.gridPos.w / 24));
|
||||||
}
|
}
|
||||||
|
|
||||||
let minCardWidth = 5;
|
let minCardWidth = this.panel.cards.cardMinWidth;
|
||||||
let minSpacing = 2;
|
let minSpacing = this.panel.cards.cardSpacing;
|
||||||
let maxCardsCount = Math.ceil(chartWidth / (minCardWidth + minSpacing));
|
let maxCardsCount = Math.ceil((chartWidth-minCardWidth) / (minCardWidth + minSpacing));
|
||||||
|
|
||||||
let intervalMs;
|
let intervalMs;
|
||||||
let rangeMs = this.range.to.valueOf() - this.range.from.valueOf();
|
let rangeMs = this.range.to.valueOf() - this.range.from.valueOf();
|
||||||
|
|||||||
Reference in New Issue
Block a user