Commit 43c6f749 by Torkel Ödegaard

heatmap: removed fill background, and highlight card options

parent 4412e417
...@@ -25,7 +25,6 @@ let panelDefaults = { ...@@ -25,7 +25,6 @@ let panelDefaults = {
colorScale: 'sqrt', colorScale: 'sqrt',
exponent: 0.5, exponent: 0.5,
colorScheme: 'interpolateOranges', colorScheme: 'interpolateOranges',
fillBackground: false
}, },
dataFormat: 'timeseries', dataFormat: 'timeseries',
xAxis: { xAxis: {
......
...@@ -87,7 +87,7 @@ export class HeatmapTooltip { ...@@ -87,7 +87,7 @@ export class HeatmapTooltip {
let tooltipHtml = `<div class="graph-tooltip-time">${time}</div> let tooltipHtml = `<div class="graph-tooltip-time">${time}</div>
<div class="heatmap-histogram"></div>`; <div class="heatmap-histogram"></div>`;
if (yData) { if (yData && yData.bounds) {
boundBottom = valueFormatter(yData.bounds.bottom); boundBottom = valueFormatter(yData.bounds.bottom);
boundTop = valueFormatter(yData.bounds.top); boundTop = valueFormatter(yData.bounds.top);
valuesNumber = yData.values.length; valuesNumber = yData.values.length;
......
...@@ -2,51 +2,49 @@ ...@@ -2,51 +2,49 @@
<div class="section gf-form-group"> <div class="section gf-form-group">
<h5 class="section-heading">Colors</h5> <h5 class="section-heading">Colors</h5>
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label width-7">Mode</label> <label class="gf-form-label width-9">Mode</label>
<div class="gf-form-select-wrapper width-12"> <div class="gf-form-select-wrapper width-8">
<select class="input-small gf-form-input" ng-model="ctrl.panel.color.mode" ng-options="s for s in ctrl.colorModes" ng-change="ctrl.render()"></select> <select class="input-small gf-form-input" ng-model="ctrl.panel.color.mode" ng-options="s for s in ctrl.colorModes" ng-change="ctrl.render()"></select>
</div> </div>
</div> </div>
<div ng-show="ctrl.panel.color.mode === 'opacity'"> <div ng-show="ctrl.panel.color.mode === 'opacity'">
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label width-7">Color</label> <label class="gf-form-label width-9">Color</label>
<span class="gf-form-label"> <span class="gf-form-label">
<spectrum-picker ng-model="ctrl.panel.color.cardColor" ng-change="ctrl.render()" ></spectrum-picker> <spectrum-picker ng-model="ctrl.panel.color.cardColor" ng-change="ctrl.render()" ></spectrum-picker>
</span> </span>
</div> </div>
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label width-7">Scale</label> <label class="gf-form-label width-9">Scale</label>
<div class="gf-form-select-wrapper width-8"> <div class="gf-form-select-wrapper width-8">
<select class="input-small gf-form-input" ng-model="ctrl.panel.color.colorScale" ng-options="s for s in ctrl.opacityScales" ng-change="ctrl.render()"></select> <select class="input-small gf-form-input" ng-model="ctrl.panel.color.colorScale" ng-options="s for s in ctrl.opacityScales" ng-change="ctrl.render()"></select>
</div> </div>
</div> </div>
<div class="gf-form" ng-if="ctrl.panel.color.colorScale === 'sqrt'"> <div class="gf-form" ng-if="ctrl.panel.color.colorScale === 'sqrt'">
<label class="gf-form-label width-7">Exponent</label> <label class="gf-form-label width-9">Exponent</label>
<input type="number" class="gf-form-input width-8" placeholder="auto" data-placement="right" bs-tooltip="''" ng-model="ctrl.panel.color.exponent" ng-change="ctrl.refresh()" ng-model-onblur> <input type="number" class="gf-form-input width-8" placeholder="auto" data-placement="right" bs-tooltip="''" ng-model="ctrl.panel.color.exponent" ng-change="ctrl.refresh()" ng-model-onblur>
</div> </div>
<div class="gf-form"> <div class="gf-form">
<svg id="heatmap-opacity-legend" width="22.7em" height="2em"></svg> <svg id="heatmap-opacity-legend" width="19em" height="2em"></svg>
</div> </div>
</div> </div>
<div ng-show="ctrl.panel.color.mode === 'spectrum'"> <div ng-show="ctrl.panel.color.mode === 'spectrum'">
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label width-7">Scheme</label> <label class="gf-form-label width-9">Scheme</label>
<div class="gf-form-select-wrapper width-12"> <div class="gf-form-select-wrapper width-8">
<select class="input-small gf-form-input" ng-model="ctrl.panel.color.colorScheme" ng-options="s.value as s.name for s in ctrl.colorSchemes" ng-change="ctrl.render()"></select> <select class="input-small gf-form-input" ng-model="ctrl.panel.color.colorScheme" ng-options="s.value as s.name for s in ctrl.colorSchemes" ng-change="ctrl.render()"></select>
</div> </div>
</div> </div>
<div class="gf-form"> <div class="gf-form">
<svg id="heatmap-color-legend" width="22.7em" height="2em"></svg> <svg id="heatmap-color-legend" width="19em" height="2em"></svg>
</div> </div>
<gf-form-switch class="gf-form" label-class="width-9" label="Fill background" checked="ctrl.panel.color.fillBackground" on-change="ctrl.render()">
</gf-form-switch>
</div> </div>
</div> </div>
<div class="section gf-form-group"> <div class="section gf-form-group">
<h5 class="section-heading">Cards</h5> <h5 class="section-heading">Buckets</h5>
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label width-8">Space</label> <label class="gf-form-label width-8">Space</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="auto" data-placement="right" bs-tooltip="''" ng-model="ctrl.panel.cards.cardPadding" ng-change="ctrl.refresh()" ng-model-onblur>
...@@ -65,10 +63,6 @@ ...@@ -65,10 +63,6 @@
</gf-form-switch> </gf-form-switch>
<div ng-if="ctrl.panel.tooltip.show"> <div ng-if="ctrl.panel.tooltip.show">
<gf-form-switch class="gf-form" label-class="width-8" <gf-form-switch class="gf-form" label-class="width-8"
label="Highlight cards"
checked="ctrl.panel.highlightCards" on-change="ctrl.render()">
</gf-form-switch>
<gf-form-switch class="gf-form" label-class="width-8"
label="Series stats" label="Series stats"
checked="ctrl.panel.tooltip.seriesStat" on-change="ctrl.render()"> checked="ctrl.panel.tooltip.seriesStat" on-change="ctrl.render()">
</gf-form-switch> </gf-form-switch>
......
...@@ -376,10 +376,6 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -376,10 +376,6 @@ export default function link(scope, elem, attrs, ctrl) {
setOpacityScale(max_value); setOpacityScale(max_value);
setCardSize(); setCardSize();
if (panel.color.fillBackground && panel.color.mode === 'spectrum') {
fillBackground(heatmap, colorScale(0));
}
let cards = heatmap.selectAll(".heatmap-card").data(cardsData); let cards = heatmap.selectAll(".heatmap-card").data(cardsData);
cards.append("title"); cards.append("title");
cards = cards.enter().append("rect") cards = cards.enter().append("rect")
...@@ -407,24 +403,20 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -407,24 +403,20 @@ export default function link(scope, elem, attrs, ctrl) {
} }
function highlightCard(event) { function highlightCard(event) {
if (panel.highlightCards) { let color = d3.select(event.target).style("fill");
let color = d3.select(event.target).style("fill"); let highlightColor = d3.color(color).darker(2);
let highlightColor = d3.color(color).darker(2); let strokeColor = d3.color(color).brighter(4);
let strokeColor = d3.color(color).brighter(4); let current_card = d3.select(event.target);
let current_card = d3.select(event.target); tooltip.originalFillColor = color;
tooltip.originalFillColor = color; current_card.style("fill", highlightColor)
current_card.style("fill", highlightColor) .style("stroke", strokeColor)
.style("stroke", strokeColor) .style("stroke-width", 1);
.style("stroke-width", 1);
}
} }
function resetCardHighLight(event) { function resetCardHighLight(event) {
if (panel.highlightCards) { d3.select(event.target).style("fill", tooltip.originalFillColor)
d3.select(event.target).style("fill", tooltip.originalFillColor) .style("stroke", tooltip.originalFillColor)
.style("stroke", tooltip.originalFillColor) .style("stroke-width", 0);
.style("stroke-width", 0);
}
} }
function getColorScale(maxValue) { function getColorScale(maxValue) {
...@@ -442,12 +434,12 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -442,12 +434,12 @@ export default function link(scope, elem, attrs, ctrl) {
function setOpacityScale(max_value) { function setOpacityScale(max_value) {
if (panel.color.colorScale === 'linear') { if (panel.color.colorScale === 'linear') {
opacityScale = d3.scaleLinear() opacityScale = d3.scaleLinear()
.domain([0, max_value]) .domain([0, max_value])
.range([0, 1]); .range([0, 1]);
} else if (panel.color.colorScale === 'sqrt') { } else if (panel.color.colorScale === 'sqrt') {
opacityScale = d3.scalePow().exponent(panel.color.exponent) opacityScale = d3.scalePow().exponent(panel.color.exponent)
.domain([0, max_value]) .domain([0, max_value])
.range([0, 1]); .range([0, 1]);
} }
} }
...@@ -549,15 +541,6 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -549,15 +541,6 @@ export default function link(scope, elem, attrs, ctrl) {
} }
} }
function fillBackground(heatmap, color) {
heatmap.insert("rect", "g")
.attr("x", yAxisWidth)
.attr("y", margin.top)
.attr("width", chartWidth)
.attr("height", chartHeight)
.attr("fill", color);
}
///////////////////////////// /////////////////////////////
// Selection and crosshair // // Selection and crosshair //
///////////////////////////// /////////////////////////////
...@@ -570,12 +553,12 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -570,12 +553,12 @@ export default function link(scope, elem, attrs, ctrl) {
if (ctrl.dashboard.graphTooltip === 2) { if (ctrl.dashboard.graphTooltip === 2) {
tooltip.show(event.pos, data); tooltip.show(event.pos, data);
} }
}); }, scope);
appEvents.on('graph-hover-clear', () => { appEvents.on('graph-hover-clear', () => {
clearCrosshair(); clearCrosshair();
tooltip.destroy(); tooltip.destroy();
}); }, scope);
function onMouseDown(event) { function onMouseDown(event) {
selection.active = true; selection.active = true;
...@@ -584,6 +567,7 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -584,6 +567,7 @@ export default function link(scope, elem, attrs, ctrl) {
mouseUpHandler = function() { mouseUpHandler = function() {
onMouseUp(); onMouseUp();
}; };
$(document).one("mouseup", mouseUpHandler); $(document).one("mouseup", mouseUpHandler);
} }
...@@ -660,11 +644,11 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -660,11 +644,11 @@ export default function link(scope, elem, attrs, ctrl) {
if (selectionWidth > MIN_SELECTION_WIDTH) { if (selectionWidth > MIN_SELECTION_WIDTH) {
heatmap.append("rect") heatmap.append("rect")
.attr("class", "heatmap-selection") .attr("class", "heatmap-selection")
.attr("x", selectionX) .attr("x", selectionX)
.attr("width", selectionWidth) .attr("width", selectionWidth)
.attr("y", chartTop) .attr("y", chartTop)
.attr("height", chartHeight); .attr("height", chartHeight);
} }
} }
} }
...@@ -687,14 +671,14 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -687,14 +671,14 @@ export default function link(scope, elem, attrs, ctrl) {
posX = Math.min(posX, chartWidth + yAxisWidth); posX = Math.min(posX, chartWidth + yAxisWidth);
heatmap.append("g") heatmap.append("g")
.attr("class", "heatmap-crosshair") .attr("class", "heatmap-crosshair")
.attr("transform", "translate(" + posX + ",0)") .attr("transform", "translate(" + posX + ",0)")
.append("line") .append("line")
.attr("x1", 1) .attr("x1", 1)
.attr("y1", chartTop) .attr("y1", chartTop)
.attr("x2", 1) .attr("x2", 1)
.attr("y2", chartBottom) .attr("y2", chartBottom)
.attr("stroke-width", 1); .attr("stroke-width", 1);
} }
} }
...@@ -725,14 +709,14 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -725,14 +709,14 @@ export default function link(scope, elem, attrs, ctrl) {
var legendRects = legend.selectAll(".heatmap-color-legend-rect").data(valuesRange); var legendRects = legend.selectAll(".heatmap-color-legend-rect").data(valuesRange);
legendRects.enter().append("rect") legendRects.enter().append("rect")
.attr("x", d => d) .attr("x", d => d)
.attr("y", 0) .attr("y", 0)
.attr("width", rangeStep + 1) // Overlap rectangles to prevent gaps .attr("width", rangeStep + 1) // Overlap rectangles to prevent gaps
.attr("height", legendHeight) .attr("height", legendHeight)
.attr("stroke-width", 0) .attr("stroke-width", 0)
.attr("fill", d => { .attr("fill", d => {
return legendColorScale(d); return legendColorScale(d);
}); });
} }
function drawOpacityLegend() { function drawOpacityLegend() {
...@@ -745,12 +729,12 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -745,12 +729,12 @@ export default function link(scope, elem, attrs, ctrl) {
let legendOpacityScale; let legendOpacityScale;
if (panel.color.colorScale === 'linear') { if (panel.color.colorScale === 'linear') {
legendOpacityScale = d3.scaleLinear() legendOpacityScale = d3.scaleLinear()
.domain([0, legendWidth]) .domain([0, legendWidth])
.range([0, 1]); .range([0, 1]);
} else if (panel.color.colorScale === 'sqrt') { } else if (panel.color.colorScale === 'sqrt') {
legendOpacityScale = d3.scalePow().exponent(panel.color.exponent) legendOpacityScale = d3.scalePow().exponent(panel.color.exponent)
.domain([0, legendWidth]) .domain([0, legendWidth])
.range([0, 1]); .range([0, 1]);
} }
let rangeStep = 1; let rangeStep = 1;
...@@ -758,15 +742,15 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -758,15 +742,15 @@ export default function link(scope, elem, attrs, ctrl) {
var legendRects = legend.selectAll(".heatmap-opacity-legend-rect").data(valuesRange); var legendRects = legend.selectAll(".heatmap-opacity-legend-rect").data(valuesRange);
legendRects.enter().append("rect") legendRects.enter().append("rect")
.attr("x", d => d) .attr("x", d => d)
.attr("y", 0) .attr("y", 0)
.attr("width", rangeStep) .attr("width", rangeStep)
.attr("height", legendHeight) .attr("height", legendHeight)
.attr("stroke-width", 0) .attr("stroke-width", 0)
.attr("fill", panel.color.cardColor) .attr("fill", panel.color.cardColor)
.style("opacity", d => { .style("opacity", d => {
return legendOpacityScale(d); return legendOpacityScale(d);
}); });
} }
function render() { function render() {
...@@ -774,34 +758,26 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -774,34 +758,26 @@ export default function link(scope, elem, attrs, ctrl) {
panel = ctrl.panel; panel = ctrl.panel;
timeRange = ctrl.range; timeRange = ctrl.range;
if (setElementHeight()) { if (!setElementHeight() || !data) {
return;
if (data) {
// Draw default axes and return if no data
if (_.isEmpty(data.buckets)) {
addHeatmapCanvas();
addAxes();
return;
}
addHeatmap();
scope.yScale = yScale;
scope.xScale = xScale;
scope.yAxisWidth = yAxisWidth;
scope.xAxisHeight = xAxisHeight;
scope.chartHeight = chartHeight;
scope.chartWidth = chartWidth;
scope.chartTop = chartTop;
// Register selection listeners
$heatmap.on("mousedown", onMouseDown);
$heatmap.on("mousemove", onMouseMove);
$heatmap.on("mouseleave", onMouseLeave);
} else {
return;
}
} }
// Draw default axes and return if no data
if (_.isEmpty(data.buckets)) {
addHeatmapCanvas();
addAxes();
return;
}
addHeatmap();
scope.yScale = yScale;
scope.xScale = xScale;
scope.yAxisWidth = yAxisWidth;
scope.xAxisHeight = xAxisHeight;
scope.chartHeight = chartHeight;
scope.chartWidth = chartWidth;
scope.chartTop = chartTop;
// Draw only if color editor is opened // Draw only if color editor is opened
if (!d3.select("#heatmap-color-legend").empty()) { if (!d3.select("#heatmap-color-legend").empty()) {
drawColorLegend(); drawColorLegend();
...@@ -810,6 +786,11 @@ export default function link(scope, elem, attrs, ctrl) { ...@@ -810,6 +786,11 @@ export default function link(scope, elem, attrs, ctrl) {
drawOpacityLegend(); drawOpacityLegend();
} }
} }
// Register selection listeners
$heatmap.on("mousedown", onMouseDown);
$heatmap.on("mousemove", onMouseMove);
$heatmap.on("mouseleave", onMouseLeave);
} }
function grafanaTimeFormat(ticks, min, max) { function grafanaTimeFormat(ticks, min, max) {
......
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