Commit f77f8ebf by Torkel Ödegaard

heatmap: changes to color spectrum, inverted some on dark theme

parent 3ed1600b
......@@ -11,6 +11,7 @@ export class User {
orgRole: any;
timezone: string;
helpFlags1: number;
lightTheme: boolean;
constructor() {
if (config.bootData.user) {
......
......@@ -20,11 +20,11 @@ let panelDefaults = {
cardRound: null
},
color: {
mode: 'color',
mode: 'spectrum',
cardColor: '#b4ff00',
colorScale: 'linear',
colorScale: 'sqrt',
exponent: 0.5,
colorScheme: 'interpolateSpectral',
colorScheme: 'interpolateOranges',
fillBackground: false
},
dataFormat: 'timeseries',
......@@ -53,44 +53,37 @@ let panelDefaults = {
highlightCards: true
};
let colorModes = ['opacity', 'color'];
let colorModes = ['opacity', 'spectrum'];
let opacityScales = ['linear', 'sqrt'];
// Schemes from d3-scale-chromatic
// https://github.com/d3/d3-scale-chromatic
let colorSchemes = [
// Diverging
{name: 'Spectral', value: 'interpolateSpectral'},
{name: 'BrBG', value: 'interpolateBrBG'},
{name: 'PRGn', value: 'interpolatePRGn'},
{name: 'PiYG', value: 'interpolatePiYG'},
{name: 'PuOr', value: 'interpolatePuOr'},
{name: 'RdBu', value: 'interpolateRdBu'},
{name: 'RdGy', value: 'interpolateRdGy'},
{name: 'RdYlBu', value: 'interpolateRdYlBu'},
{name: 'RdYlGn', value: 'interpolateRdYlGn'},
{name: 'Spectral', value: 'interpolateSpectral', invert: 'always'},
{name: 'RdYlGn', value: 'interpolateRdYlGn', invert: 'always'},
// Sequential (Single Hue)
{name: 'Blues', value: 'interpolateBlues'},
{name: 'Greens', value: 'interpolateGreens'},
{name: 'Greys', value: 'interpolateGreys'},
{name: 'Oranges', value: 'interpolateOranges'},
{name: 'Purples', value: 'interpolatePurples'},
{name: 'Reds', value: 'interpolateReds'},
{name: 'Blues', value: 'interpolateBlues', invert: 'dark'},
{name: 'Greens', value: 'interpolateGreens', invert: 'dark'},
{name: 'Greys', value: 'interpolateGreys', invert: 'dark'},
{name: 'Oranges', value: 'interpolateOranges', invert: 'dark'},
{name: 'Purples', value: 'interpolatePurples', invert: 'dark'},
{name: 'Reds', value: 'interpolateReds', invert: 'dark'},
// Sequential (Multi-Hue)
{name: 'BuGn', value: 'interpolateBuGn'},
{name: 'BuPu', value: 'interpolateBuPu'},
{name: 'GnBu', value: 'interpolateGnBu'},
{name: 'OrRd', value: 'interpolateOrRd'},
{name: 'PuBuGn', value: 'interpolatePuBuGn'},
{name: 'PuBu', value: 'interpolatePuBu'},
{name: 'PuRd', value: 'interpolatePuRd'},
{name: 'RdPu', value: 'interpolateRdPu'},
{name: 'YlGnBu', value: 'interpolateYlGnBu'},
{name: 'YlGn', value: 'interpolateYlGn'},
{name: 'YlOrBr', value: 'interpolateYlOrBr'},
{name: 'YlOrRd', value: 'interpolateYlOrRd'}
{name: 'BuGn', value: 'interpolateBuGn', invert: 'dark'},
{name: 'BuPu', value: 'interpolateBuPu', invert: 'dark'},
{name: 'GnBu', value: 'interpolateGnBu', invert: 'dark'},
{name: 'OrRd', value: 'interpolateOrRd', invert: 'dark'},
{name: 'PuBuGn', value: 'interpolatePuBuGn', invert: 'dark'},
{name: 'PuBu', value: 'interpolatePuBu', invert: 'dark'},
{name: 'PuRd', value: 'interpolatePuRd', invert: 'dark'},
{name: 'RdPu', value: 'interpolateRdPu', invert: 'dark'},
{name: 'YlGnBu', value: 'interpolateYlGnBu', invert: 'dark'},
{name: 'YlGn', value: 'interpolateYlGn', invert: 'dark'},
{name: 'YlOrBr', value: 'interpolateYlOrBr', invert: 'dark'},
{name: 'YlOrRd', value: 'interpolateYlOrRd', invert: 'darm'}
];
export class HeatmapCtrl extends MetricsPanelCtrl {
......
......@@ -2,7 +2,7 @@
<div class="section gf-form-group">
<h5 class="section-heading">Colors</h5>
<div class="gf-form">
<label class="gf-form-label width-8">Color mode</label>
<label class="gf-form-label width-7">Mode</label>
<div class="gf-form-select-wrapper width-12">
<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>
......@@ -10,44 +10,38 @@
<div ng-show="ctrl.panel.color.mode === 'opacity'">
<div class="gf-form">
<label class="gf-form-label width-8">Card Color</label>
<label class="gf-form-label width-7">Color</label>
<span class="gf-form-label">
<spectrum-picker ng-model="ctrl.panel.color.cardColor" ng-change="ctrl.render()" ></spectrum-picker>
</span>
</div>
<div class="gf-form">
<label class="gf-form-label width-8">Opacity scale</label>
<div class="gf-form-select-wrapper width-12">
<label class="gf-form-label width-7">Scale</label>
<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>
</div>
</div>
<div class="gf-form" ng-if="ctrl.panel.color.colorScale === 'sqrt'">
<label class="gf-form-label width-8">Exponent</label>
<label class="gf-form-label width-7">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>
</div>
<div class="gf-form">
<svg id="heatmap-opacity-legend"
width="22.7em" height="2em">
</svg>
<svg id="heatmap-opacity-legend" width="22.7em" height="2em"></svg>
</div>
</div>
<div ng-show="ctrl.panel.color.mode === 'color'">
<div ng-show="ctrl.panel.color.mode === 'spectrum'">
<div class="gf-form">
<label class="gf-form-label width-8">Color scheme</label>
<label class="gf-form-label width-7">Scheme</label>
<div class="gf-form-select-wrapper width-12">
<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 class="gf-form">
<svg id="heatmap-color-legend"
width="22.7em" height="2em">
</svg>
<svg id="heatmap-color-legend" width="22.7em" height="2em"></svg>
</div>
<gf-form-switch class="gf-form" label-class="width-10"
label="Fill background"
checked="ctrl.panel.color.fillBackground" on-change="ctrl.render()">
</gf-form-switch>
<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>
......
......@@ -4,7 +4,7 @@ import _ from 'lodash';
import $ from 'jquery';
import moment from 'moment';
import kbn from 'app/core/utils/kbn';
import {appEvents} from 'app/core/core';
import {appEvents, contextSrv} from 'app/core/core';
import d3 from 'd3';
import {HeatmapTooltip} from './heatmap_tooltip';
import {convertToCards, mergeZeroBuckets, removeZeroBuckets} from './heatmap_data_converter';
......@@ -371,11 +371,11 @@ export default function link(scope, elem, attrs, ctrl) {
return card.values.length;
});
setColorScale(max_value);
colorScale = getColorScale(max_value);
setOpacityScale(max_value);
setCardSize();
if (panel.color.fillBackground && panel.color.mode === 'color') {
if (panel.color.fillBackground && panel.color.mode === 'spectrum') {
fillBackground(heatmap, colorScale(0));
}
......@@ -426,9 +426,16 @@ export default function link(scope, elem, attrs, ctrl) {
}
}
function setColorScale(max_value) {
let colorInterpolator = d3[panel.color.colorScheme];
colorScale = d3.scaleSequential(colorInterpolator).domain([max_value, 0]);
function getColorScale(maxValue) {
let colorScheme = _.find(ctrl.colorSchemes, {value: panel.color.colorScheme});
let colorInterpolator = d3[colorScheme.value];
let colorScaleInverted = colorScheme.invert === 'always' ||
(colorScheme.invert === 'dark' && !contextSrv.user.lightTheme);
let start = colorScaleInverted ? maxValue : 0;
let end = colorScaleInverted ? 0 : maxValue;
return d3.scaleSequential(colorInterpolator).domain([start, end]);
}
function setOpacityScale(max_value) {
......@@ -710,8 +717,7 @@ export default function link(scope, elem, attrs, ctrl) {
let legendWidth = Math.floor($(d3.select("#heatmap-color-legend").node()).outerWidth());
let legendHeight = d3.select("#heatmap-color-legend").attr("height");
let colorInterpolator = d3[panel.color.colorScheme];
let legendColorScale = d3.scaleSequential(colorInterpolator).domain([legendWidth, 0]);
let legendColorScale = getColorScale(legendWidth);
let rangeStep = 2;
let valuesRange = d3.range(0, legendWidth, rangeStep);
......
......@@ -30,6 +30,10 @@ describe('grafanaHeatmap', function () {
beforeEach(angularMocks.inject(function ($rootScope, $compile) {
var ctrl: any = {
colorSchemes: [
{name: 'Oranges', value: 'interpolateOranges', invert: 'dark'},
{name: 'Reds', value: 'interpolateReds', invert: 'dark'},
],
events: new Emitter(),
height: 200,
panel: {
......@@ -40,11 +44,11 @@ describe('grafanaHeatmap', function () {
cardRound: null
},
color: {
mode: 'color',
mode: 'spectrum',
cardColor: '#b4ff00',
colorScale: 'linear',
exponent: 0.5,
colorScheme: 'interpolateSpectral',
colorScheme: 'interpolateOranges',
fillBackground: false
},
xBucketSize: 1000,
......
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