adding more options

This commit is contained in:
ppisljar 2016-12-08 11:00:10 +01:00
parent 6e80819140
commit 56569c4db6
8 changed files with 185 additions and 115 deletions

View file

@ -14,6 +14,56 @@
<div class="text-info text-center" ng-show="customColors" ng-click="resetColors()">reset colors</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="invertColors">
Invert Color Schema
</label>
<div class="kuiSideBarFormRow__control">
<input class="kuiCheckBox" id="invertColors" type="checkbox" ng-model="vis.params.invertColors">
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="axisScale">
Color Scale
</label>
<div class="kuiSideBarFormRow__control">
<select
id="axisScale"
class="kuiSelect kuiSideBarSelect"
ng-model="vis.params.scale"
ng-options="mode for mode in vis.type.params.scales"
></select>
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="defaultYExtents">
Scale to Data Bounds
</label>
<div class="kuiSideBarFormRow__control">
<input class="kuiCheckBox" id="defaultYExtents" type="checkbox" ng-model="vis.params.defaultYExtents">
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="percentageMode">
Percentage Mode
</label>
<div class="kuiSideBarFormRow__control">
<input class="kuiCheckBox" id="percentageMode" type="checkbox" ng-model="vis.params.percentageMode">
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="cellLabels">
Show Cell Labels
</label>
<div class="kuiSideBarFormRow__control">
<input class="kuiCheckBox" id="cellLabels" type="checkbox" ng-model="vis.params.cellLabels">
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="colorsNumber">
Number of colors

View file

@ -9,7 +9,7 @@ module.directive('heatmapOptions', function ($parse, $compile, getAppState) {
template: heatmapOptionsTemplate,
replace: true,
link: function ($scope) {
$scope.isColorRangeOpen = false;
$scope.isColorRangeOpen = true;
$scope.customColors = false;
$scope.resetColors = () => {
@ -43,11 +43,6 @@ module.directive('heatmapOptions', function ($parse, $compile, getAppState) {
$scope.uiState.on('colorChanged', () => {
$scope.customColors = true;
/*const appState = getAppState();
$scope.realVis.params.colorSchema = 'custom';
$scope.vis.params.colorSchema = 'custom';
appState.vis.params.colorSchema = 'custom';
appState.save();*/
});
}
};

View file

@ -37,29 +37,6 @@
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="axisScale">
Z Axis Scale
</label>
<div class="kuiSideBarFormRow__control">
<select
id="axisScale"
class="kuiSelect kuiSideBarSelect"
ng-model="vis.params.scale"
ng-options="mode for mode in vis.type.params.scales"
></select>
</div>
</div>
<div class="kuiSideBarFormRow">
<label class="kuiSideBarFormRow__label" for="defaultYExtents">
Scale to Data Bounds
</label>
<div class="kuiSideBarFormRow__control">
<input class="kuiCheckBox" id="defaultYExtents" type="checkbox" ng-model="vis.params.defaultYExtents">
</div>
</div>
<div class="kuiSideBarSectionTitle">
<div class="kuiSideBarSectionTitle__text">
Heatmap Settings

View file

@ -24,9 +24,12 @@ export default function HeatmapVisType(Private) {
defaultYExtents: false,
setYExtents: false,
colorsNumber: 4,
colorSchema: 'yellow to red',
colorSchema: 'Greens',
setColorRange: false,
colorsRange: [],
invertColors: false,
percentageMode: true,
cellLabels: false,
},
legendPositions: [{
value: 'left',
@ -42,7 +45,8 @@ export default function HeatmapVisType(Private) {
text: 'bottom',
}],
scales: ['linear', 'log', 'square root'],
colorSchemas: ['yellow to red', 'reds', 'greens', 'blues', 'custom'],
colorSchemas: ['Blues', 'Greens', 'Greys', 'Reds', 'YlOrRd', 'autumn', 'bone',
'hot', 'coolwarm', 'Spectral', 'gist_earth', 'terrain', 'gnuplot', 'jet'],
editor: heatmapTemplate
},
schemas: new Schemas([

View file

@ -1,36 +1,69 @@
import _ from 'lodash';
import colormaps from './colormaps';
const reds = [
'#99000E', '#A41926', '#AF333E', '#BB4C56', '#C6666E', '#D17F86', '#DD999E', '#E8B2B6', '#F3CCCE', '#FFE6E6'
];
const greens = [
'#E5F5F9', '#CBE1E0', '#B2CDC7', '#98BAAF', '#7FA696', '#65927D', '#4C7F65', '#326B4C', '#195733', '#00441B'
];
const blues = [
'#DEEBF7', '#C6D6E7', '#AEC1D7', '#96ACC8', '#7E97B8', '#6783A9', '#4F6E99', '#37598A', '#1F447A', '#08306B'
];
const yellowtored = [
'#F8F840', '#EEDA35', '#E4BC2A', '#DB9F1F', '#D18114', '#C8640A', '#D05415', '#D84520', '#E0362B', '#E82736'
];
export default function (value, colorSchema) {
if (!_.isNumber(value) || value < 0 || value > 9) {
throw new Error('heatmap_color expects a number from 0 to 9 as first parameter');
function enforceBounds(x) {
if (x < 0) {
return 0;
} else if (x > 1) {
return 1;
} else {
return x;
}
switch (colorSchema) {
case 'reds':
return reds[9 - value];
case 'greens':
return greens[value];
case 'blues':
return blues[value];
case 'yellow to red':
return yellowtored[value];
default:
const start = 120;
const end = 360;
const c = start + (end - start) * (value * 10);
}
return `hsl(${c},60%,50%)`;
function interpolateLinearly(x, values) {
// Split values into four lists
const xValues = [];
const rValues = [];
const gValues = [];
const bValues = [];
values.forEach(value => {
xValues.push(value[0]);
rValues.push(value[1][0]);
gValues.push(value[1][1]);
bValues.push(value[1][2]);
});
let i = 1;
while (xValues[i] < x) i++;
const width = Math.abs(xValues[i - 1] - xValues[i]);
const scalingFactor = (x - xValues[i - 1]) / width;
// Get the new color values though interpolation
const r = rValues[i - 1] + scalingFactor * (rValues[i] - rValues[i - 1]);
const g = gValues[i - 1] + scalingFactor * (gValues[i] - gValues[i - 1]);
const b = bValues[i - 1] + scalingFactor * (bValues[i] - bValues[i - 1]);
return [enforceBounds(r), enforceBounds(g), enforceBounds(b)];
}
function getColor(value, colorSchemaName) {
if (!_.isNumber(value) || value < 0 || value > 1) {
throw new Error('heatmap_color expects a number from 0 to 1 as first parameter');
}
};
const colorSchema = colormaps[colorSchemaName];
if (!colorSchema) {
throw new Error('invalid colorSchemaName provided');
}
const color = interpolateLinearly(value, colorSchema);
const r = Math.round(255 * color[0]);
const g = Math.round(255 * color[1]);
const b = Math.round(255 * color[2]);
return `rgb(${r},${g},${b})`;
}
function drawColormap(colorSchema, width = 100, height = 10) {
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
for (let i = 0; i <= width; i++) {
ctx.fillStyle = getColor(i / width, colorSchema);
ctx.fillRect(i, 0, 1, height);
}
return canvas;
}
getColor.prototype.drawColormap = drawColormap;
export default getColor;

View file

@ -1,39 +1,8 @@
import _ from 'lodash';
import errors from 'ui/errors';
import heatmapColorFunc from 'ui/vislib/components/color/heatmap_color';
export default function ColumnHandler(Private) {
const getHeatmapLabels = (cfg) => {
const colorsNumber = cfg.colorsNumber;
const labels = [];
for (let i = 0; i < colorsNumber; i++) {
let label;
const val = Math.ceil(i * (100 / colorsNumber));
if (cfg.setColorRange) {
const greaterThan = cfg.colorsRange[i].value;
label = `> ${greaterThan}`;
} else {
const nextVal = Math.ceil((i + 1) * (100 / colorsNumber));
label = `${val}% - ${nextVal}%`;
}
labels.push(label);
}
return labels;
};
const getHeatmapColors = (cfg) => {
const colorsNumber = cfg.colorsNumber;
const labels = getHeatmapLabels(cfg);
const colors = {};
for (let i in labels) {
if (labels[i]) {
colors[labels[i]] = heatmapColorFunc(Math.ceil(i * 10 / colorsNumber), cfg.colorSchema);
}
}
return colors;
};
const createSeries = (cfg, series) => {
const stacked = ['stacked', 'percentage', 'wiggle', 'silhouette'].includes(cfg.mode);
let interpolate = cfg.interpolate;
@ -195,10 +164,6 @@ export default function ColumnHandler(Private) {
text: data.get('yAxisLabel')
}
});
defaults.legend = {
labels: getHeatmapLabels(cfg),
colors: getHeatmapColors(cfg)
};
return defaults;
}
};

View file

@ -68,12 +68,6 @@ export default function VisFactory(Private) {
this.visConfig = new VisConfig(this.visConfigArgs, this.data, this.uiState, this.el);
const colors = this.getLegendColors();
if (colors) {
this.uiState.setSilent('vis.defaultColors', null);
this.uiState.setSilent('vis.defaultColors', colors);
}
this.handler = new Handler(this, this.visConfig);
this._runWithoutResizeChecker('render');
}

View file

@ -1,7 +1,7 @@
import _ from 'lodash';
import moment from 'moment';
import VislibVisualizationsPointSeriesProvider from './_point_series';
import colorFunc from 'ui/vislib/components/color/heatmap_color';
import heatmapColorFunc from 'ui/vislib/components/color/heatmap_color';
export default function HeatmapChartFactory(Private) {
@ -25,8 +25,69 @@ export default function HeatmapChartFactory(Private) {
constructor(handler, chartEl, chartData, seriesConfigArgs) {
super(handler, chartEl, chartData, seriesConfigArgs);
this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults);
this.handler.visConfig.set('legend', {
labels: this.getHeatmapLabels(this.handler.visConfig),
colors: this.getHeatmapColors(this.handler.visConfig)
});
const colors = this.handler.visConfig.get('legend.colors', null);
if (colors) {
this.handler.vis.uiState.setSilent('vis.defaultColors', null);
this.handler.vis.uiState.setSilent('vis.defaultColors', colors);
}
}
getHeatmapLabels(cfg) {
const percentageMode = cfg.get('percentageMode');
const colorsNumber = cfg.get('colorsNumber');
const colorsRange = cfg.get('colorsRange');
const zScale = this.getValueAxis().getScale();
const [min, max] = zScale.domain();
const labels = [];
for (let i = 0; i < colorsNumber; i++) {
let label;
if (cfg.get('setColorRange')) {
const greaterThan = colorsRange[i].value;
label = `> ${greaterThan}`;
} else {
let val = i / colorsNumber;
let nextVal = (i + 1) / colorsNumber;
if (percentageMode) {
val = Math.ceil(val * 100);
nextVal = Math.ceil(nextVal * 100);
label = `${val}% - ${nextVal}%`;
} else {
val = val * (max - min) + min;
nextVal = nextVal * (max - min) + min;
if (max > 1) {
val = Math.ceil(val);
nextVal = Math.ceil(nextVal);
}
label = `${val} - ${nextVal}`;
}
}
labels.push(label);
}
return labels;
};
getHeatmapColors(cfg) {
const colorsNumber = cfg.get('colorsNumber');
const invertColors = cfg.get('invertColors');
const colorSchema = cfg.get('colorSchema');
const labels = this.getHeatmapLabels(cfg);
const colors = {};
for (let i in labels) {
if (labels[i]) {
const val = invertColors ? 1 - i / colorsNumber : i / colorsNumber;
colors[labels[i]] = heatmapColorFunc(val, colorSchema);
}
}
return colors;
};
addSquares(svg, data) {
const xScale = this.getCategoryAxis().getScale();
const yScale = this.handler.valueAxes[1].getScale();
@ -39,6 +100,7 @@ export default function HeatmapChartFactory(Private) {
const setColorRange = this.handler.visConfig.get('setColorRange');
const colorsRange = this.handler.visConfig.get('colorsRange');
const color = this.handler.data.getColorFunc();
const labels = this.handler.visConfig.get('legend.labels');
const layer = svg.append('g')
.attr('class', 'series');
@ -89,17 +151,7 @@ export default function HeatmapChartFactory(Private) {
function label(d) {
const colorBucket = getColorBucket(d);
let label;
if (colorBucket < 0) return '';
const val = Math.ceil(colorBucket * (100 / colorsNumber));
if (setColorRange) {
const greaterThan = colorsRange[colorBucket].value;
label = `> ${greaterThan}`;
} else {
const nextVal = Math.ceil((colorBucket + 1) * (100 / colorsNumber));
label = `${val}% - ${nextVal}%`;
}
return label;
return labels[colorBucket];
}
function z(d) {