Skip to content

Commit

Permalink
Add: Heatmap chart visualization by Plotly (#2080)
Browse files Browse the repository at this point in the history
  • Loading branch information
deecay authored and arikfr committed Oct 21, 2018
1 parent 38a89b9 commit 34c118c
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 9 deletions.
10 changes: 10 additions & 0 deletions client/app/services/query-result.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ function QueryResultService($resource, $timeout, $q, QueryResultError) {
const yValues = {};
let eValue = null;
let sizeValue = null;
let zValue = null;

forOwn(row, (v, definition) => {
definition = '' + definition;
Expand Down Expand Up @@ -320,6 +321,11 @@ function QueryResultService($resource, $timeout, $q, QueryResultError) {
sizeValue = value;
}

if (type === 'zVal') {
point[type] = value;
zValue = value;
}

if (type === 'multiFilter' || type === 'multi-filter') {
seriesName = String(value);
}
Expand All @@ -335,6 +341,10 @@ function QueryResultService($resource, $timeout, $q, QueryResultError) {
if (sizeValue !== null) {
point.size = sizeValue;
}

if (zValue !== null) {
point.zVal = zValue;
}
addPointToSeries(point, series, ySeriesName);
});
} else {
Expand Down
90 changes: 84 additions & 6 deletions client/app/visualizations/chart/chart-editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

</div>

<div class="form-group" ng-if="options.globalSeriesType != 'custom'">
<div class="form-group" ng-if="['custom', 'heatmap'].indexOf(options.globalSeriesType) == -1">
<label class="control-label">Group by</label>
<ui-select name="groupby" ng-model="form.groupby" class="clearable">
<ui-select-match allow-clear="true" placeholder="Choose column...">
Expand All @@ -97,7 +97,19 @@
</ui-select>
</div>

<div class="form-group" ng-if="options.globalSeriesType != 'custom'">
<div class="form-group" ng-if="showZColumnPicker()">
<label class="control-label">Color Column</label>

<ui-select name="zValColumn" ng-model="form.zValColumn">
<ui-select-match allow-clear="true" placeholder="Choose column...">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="column in columnNames | remove:form.yAxisColumns | remove:form.groupby">
<span ng-bind-html="column | highlight: $select.search"></span><span> </span>
<small class="text-muted" ng-bind="columns[column].type"></small>
</ui-select-choices>
</ui-select>
</div>

<div class="form-group" ng-if="['custom', 'heatmap'].indexOf(options.globalSeriesType) == -1">
<label class="control-label">Errors column</label>

<ui-select name="errorColumn" ng-model="form.errorColumn">
Expand All @@ -110,7 +122,7 @@
</ui-select>
</div>

<div class="checkbox" ng-if="options.globalSeriesType != 'custom'">
<div class="checkbox" ng-if="['custom', 'heatmap'].indexOf(options.globalSeriesType) == -1">
<label>
<input type="checkbox" ng-model="options.legend.enabled">
<i class="input-helper"></i> Show Legend
Expand All @@ -124,7 +136,7 @@
</label>
</div>

<div class="form-group" ng-if="options.globalSeriesType != 'custom'">
<div class="form-group" ng-if="['custom', 'heatmap'].indexOf(options.globalSeriesType) == -1">
<label class="control-label">Stacking</label>

<div ng-if="stackingOptions">
Expand Down Expand Up @@ -190,6 +202,13 @@
</label>
</div>

<div class="checkbox">
<label>
<input type="checkbox" ng-model="options.reverseX">
<i class="input-helper"></i> Reverse Order
</label>
</div>

<div class="checkbox">
<label>
<input type="checkbox" ng-model="options.xAxis.labels.enabled">
Expand Down Expand Up @@ -223,6 +242,21 @@ <h4>{{$index == 0 ? 'Left' : 'Right'}} Y Axis</h4>
<label class="control-label">Max Value</label>
<input ng-model="yAxis.rangeMax" type="number" step="any" placeholder="Auto" class="form-control">
</div>

<div class="checkbox">
<label>
<input type="checkbox" ng-model="options.sortY">
<i class="input-helper"></i> Sort Values
</label>
</div>

<div class="checkbox">
<label>
<input type="checkbox" ng-model="options.reverseY">
<i class="input-helper"></i> Reverse Order
</label>
</div>

</div>
</div>

Expand Down Expand Up @@ -272,7 +306,7 @@ <h4>{{$index == 0 ? 'Left' : 'Right'}} Y Axis</h4>
</table>
</div>

<div ng-if="(currentTab == 'colors') && (options.globalSeriesType != 'pie')" class="m-t-10 m-b-10">
<div ng-if="(currentTab == 'colors') && (['pie', 'heatmap'].indexOf(options.globalSeriesType) == -1)" class="m-t-10 m-b-10">
<table class="table table-condensed col-table">
<tbody>
<tr ng-repeat="name in form.seriesList">
Expand All @@ -295,6 +329,50 @@ <h4>{{$index == 0 ? 'Left' : 'Right'}} Y Axis</h4>
</table>
</div>

<div ng-if="(currentTab == 'colors') && (options.globalSeriesType == 'heatmap')" class="m-t-10 m-b-10">
<div class="form-group" ng-if="options.globalSeriesType == 'heatmap'">
<label class="control-label">Color Scheme</label>

<ui-select ng-model="options.colorScheme">
<ui-select-match allow-clear="true" placeholder="Choose Color Scheme...">{{$select.selected | capitalize}}</ui-select-match>
<ui-select-choices repeat="value in colorScheme">
<div ng-bind-html="value | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
</div>

<div class="row">
<div class="col-xs-6">
<div class="form-group" ng-if="options.colorScheme == 'Custom...'">
<label class="control-label">Min Color</label>
<ui-select ng-model="options.heatMinColor">
<ui-select-match>
<color-box color="$select.selected.value"></color-box>
</ui-select-match>
<ui-select-choices repeat="color.value as (key, color) in colors">
<color-box color="color.value"></color-box>
<span ng-bind-html="color.key | capitalize | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>
<div class="col-xs-6">
<div class="form-group" ng-if="options.colorScheme == 'Custom...'">
<label class="control-label">Max Color</label>
<ui-select ng-model="options.heatMaxColor">
<ui-select-match>
<color-box color="$select.selected.value"></color-box>
</ui-select-match>
<ui-select-choices repeat="color.value as (key, color) in colors">
<color-box color="color.value"></color-box>
<span ng-bind-html="color.key | capitalize | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>
</div>
</div>

<div ng-if="(currentTab == 'colors') && (options.globalSeriesType == 'pie')" class="m-t-10 m-b-10">
<table class="table table-condensed col-table">
<tbody>
Expand All @@ -319,7 +397,7 @@ <h4>{{$index == 0 ? 'Left' : 'Right'}} Y Axis</h4>
</div>

<div ng-if="currentTab == 'dataLabels'" class="m-t-10 m-b-10">
<div ng-if="['line', 'area', 'column', 'scatter', 'pie'].indexOf(options.globalSeriesType) >= 0" class="checkbox">
<div ng-if="['line', 'area', 'column', 'scatter', 'pie', 'heatmap'].indexOf(options.globalSeriesType) >= 0" class="checkbox">
<label>
<input type="checkbox" ng-model="options.showDataLabels"> Show Data Labels</label>
</div>
Expand Down
16 changes: 16 additions & 0 deletions client/app/visualizations/chart/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function ChartEditor(ColorPalette, clientConfig) {
pie: { name: 'Pie', icon: 'pie-chart' },
scatter: { name: 'Scatter', icon: 'circle-o' },
bubble: { name: 'Bubble', icon: 'circle-o' },
heatmap: { name: 'Heatmap', icon: 'th' },
box: { name: 'Box', icon: 'square-o' },
};

Expand All @@ -121,7 +122,12 @@ function ChartEditor(ColorPalette, clientConfig) {
scope.$applyAsync();
};

scope.colorScheme = ['Blackbody', 'Bluered', 'Blues', 'Earth', 'Electric',
'Greens', 'Greys', 'Hot', 'Jet', 'Picnic', 'Portland',
'Rainbow', 'RdBu', 'Reds', 'Viridis', 'YlGnBu', 'YlOrRd', 'Custom...'];

scope.showSizeColumnPicker = () => some(scope.options.seriesOptions, options => options.type === 'bubble');
scope.showZColumnPicker = () => some(scope.options.seriesOptions, options => options.type === 'heatmap');

if (scope.options.customCode === undefined) {
scope.options.customCode = `// Available variables are x, ys, element, and Plotly
Expand Down Expand Up @@ -268,6 +274,14 @@ function ChartEditor(ColorPalette, clientConfig) {
}
});

scope.$watch('form.zValColumn', (value, old) => {
if (old !== undefined) {
unsetColumn(old);
}
if (value !== undefined) {
setColumnRole('zVal', value);
}
});

scope.$watch('form.groupby', (value, old) => {
if (old !== undefined) {
Expand Down Expand Up @@ -297,6 +311,8 @@ function ChartEditor(ColorPalette, clientConfig) {
scope.form.errorColumn = key;
} else if (value === 'size') {
scope.form.sizeColumn = key;
} else if (value === 'zVal') {
scope.form.zValColumn = key;
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion client/app/visualizations/chart/plotly/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import bar from 'plotly.js/lib/bar';
import pie from 'plotly.js/lib/pie';
import histogram from 'plotly.js/lib/histogram';
import box from 'plotly.js/lib/box';
import heatmap from 'plotly.js/lib/heatmap';

import {
ColorPalette,
Expand All @@ -15,7 +16,7 @@ import {
normalizeValue,
} from './utils';

Plotly.register([bar, pie, histogram, box]);
Plotly.register([bar, pie, histogram, box, heatmap]);
Plotly.setPlotConfig({
modeBarButtonsToRemove: ['sendDataToCloud'],
});
Expand Down
Loading

0 comments on commit 34c118c

Please sign in to comment.