Browse Source

Merge pull request #1940 from cgrandfield/master

Improvements for graph3d legend support
codeClimate
Alexander Wunschik 8 years ago
committed by GitHub
parent
commit
9e4c42e25b
5 changed files with 105 additions and 59 deletions
  1. +9
    -1
      docs/graph3d/index.html
  2. +1
    -0
      examples/graph3d/11_tooltips.html
  3. +4
    -0
      examples/graph3d/playground/index.html
  4. +1
    -0
      examples/graph3d/playground/playground.js
  5. +90
    -58
      lib/graph3d/Graph3d.js

+ 9
- 1
docs/graph3d/index.html View File

@ -435,6 +435,14 @@ var options = {
when drawn in perspective. when drawn in perspective.
</td> </td>
</tr> </tr>
<tr>
<td>showLegend</td>
<td>boolean</td>
<td>none</td>
<td>If true, a legend is drawn for the graph (if the graph type supports it).
By default a legend is drawn for dot and dot-color style graphs.
</td>
</tr>
<tr> <tr>
<td>showShadow</td> <td>showShadow</td>
<td>boolean</td> <td>boolean</td>
@ -796,4 +804,4 @@ graph3d.on('cameraPositionChange', onCameraPositionChange);
<script src="../js/tipuesearch.config.js"></script> <script src="../js/tipuesearch.config.js"></script>
<script src="../js/tipuesearch.js"></script> <script src="../js/tipuesearch.js"></script>
<!-- controller --> <!-- controller -->
<script src="../js/main.js"></script>
<script src="../js/main.js"></script>

+ 1
- 0
examples/graph3d/11_tooltips.html View File

@ -48,6 +48,7 @@
height: '600px', height: '600px',
style: style, style: style,
showPerspective: true, showPerspective: true,
showLegend: true,
showGrid: true, showGrid: true,
showShadow: false, showShadow: false,

+ 4
- 0
examples/graph3d/playground/index.html View File

@ -116,6 +116,10 @@
<td>showPerspective</td> <td>showPerspective</td>
<td><input type="checkbox" id="showPerspective" checked /></td> <td><input type="checkbox" id="showPerspective" checked /></td>
</tr> </tr>
<tr>
<td>showLegend</td>
<td><input type="checkbox" id="showLegend" checked /></td>
</tr>
<tr> <tr>
<td>showShadow</td> <td>showShadow</td>
<td><input type="checkbox" id="showShadow" /></td> <td><input type="checkbox" id="showShadow" /></td>

+ 1
- 0
examples/graph3d/playground/playground.js View File

@ -407,6 +407,7 @@ function getOptions() {
showAnimationControls: (document.getElementById("showAnimationControls").checked != false), showAnimationControls: (document.getElementById("showAnimationControls").checked != false),
showGrid: (document.getElementById("showGrid").checked != false), showGrid: (document.getElementById("showGrid").checked != false),
showPerspective: (document.getElementById("showPerspective").checked != false), showPerspective: (document.getElementById("showPerspective").checked != false),
showLegend: (document.getElementById("showLegend").checked != false),
showShadow: (document.getElementById("showShadow").checked != false), showShadow: (document.getElementById("showShadow").checked != false),
keepAspectRatio: (document.getElementById("keepAspectRatio").checked != false), keepAspectRatio: (document.getElementById("keepAspectRatio").checked != false),
verticalRatio: document.getElementById("verticalRatio").value, verticalRatio: document.getElementById("verticalRatio").value,

+ 90
- 58
lib/graph3d/Graph3d.js View File

@ -44,6 +44,7 @@ function Graph3d(container, data, options) {
this.filterLabel = 'time'; this.filterLabel = 'time';
this.legendLabel = 'value'; this.legendLabel = 'value';
this.showLegend = undefined; // auto by default (based on graph style)
this.style = Graph3d.STYLE.DOT; this.style = Graph3d.STYLE.DOT;
this.showPerspective = true; this.showPerspective = true;
@ -494,7 +495,11 @@ Graph3d.prototype._dataInitialize = function (rawData, style) {
this.valueMax = (this.defaultValueMax !== undefined) ? this.defaultValueMax : valueRange.max; this.valueMax = (this.defaultValueMax !== undefined) ? this.defaultValueMax : valueRange.max;
if (this.valueMax <= this.valueMin) this.valueMax = this.valueMin + 1; if (this.valueMax <= this.valueMin) this.valueMax = this.valueMin + 1;
} }
// these styles default to having legends
var isLegendGraphStyle = this.style === Graph3d.STYLE.DOTCOLOR || this.style === Graph3d.STYLE.DOTSIZE;
this.showLegend = (this.defaultShowLegend !== undefined) ? this.defaultShowLegend : isLegendGraphStyle;
// set the scale dependent on the ranges. // set the scale dependent on the ranges.
this._setScale(); this._setScale();
}; };
@ -838,6 +843,7 @@ Graph3d.prototype.setOptions = function (options) {
if (options.filterLabel !== undefined) this.filterLabel = options.filterLabel; if (options.filterLabel !== undefined) this.filterLabel = options.filterLabel;
if (options.legendLabel !== undefined) this.legendLabel = options.legendLabel; if (options.legendLabel !== undefined) this.legendLabel = options.legendLabel;
if (options.showLegend !== undefined) this.defaultShowLegend = options.showLegend;
if (options.xLabel !== undefined) this.xLabel = options.xLabel; if (options.xLabel !== undefined) this.xLabel = options.xLabel;
if (options.yLabel !== undefined) this.yLabel = options.yLabel; if (options.yLabel !== undefined) this.yLabel = options.yLabel;
if (options.zLabel !== undefined) this.zLabel = options.zLabel; if (options.zLabel !== undefined) this.zLabel = options.zLabel;
@ -972,46 +978,64 @@ Graph3d.prototype._redrawClear = function() {
/** /**
* Redraw the legend showing the colors
* Get legend width
*/ */
Graph3d.prototype._redrawLegend = function() {
var y;
if (this.style === Graph3d.STYLE.DOTCOLOR ||
this.style === Graph3d.STYLE.DOTSIZE) {
Graph3d.prototype._getLegendWidth = function() {
var width;
if (this.style === Graph3d.STYLE.DOTSIZE) {
var dotSize = this.frame.clientWidth * this.dotSizeRatio; var dotSize = this.frame.clientWidth * this.dotSizeRatio;
width = dotSize / 2 + dotSize * 2;
} else if (this.style === Graph3d.STYLE.BARSIZE) {
width = this.xBarWidth ;
} else {
width = 20;
}
return width;
}
var widthMin, widthMax;
if (this.style === Graph3d.STYLE.DOTSIZE) {
widthMin = dotSize / 2; // px
widthMax = dotSize / 2 + dotSize * 2; // Todo: put this in one function
}
else {
widthMin = 20; // px
widthMax = 20; // px
}
var height = Math.max(this.frame.clientHeight * 0.25, 100);
var top = this.margin;
var right = this.frame.clientWidth - this.margin;
var left = right - widthMax;
var bottom = top + height;
}
/**
* Redraw the legend based on size, dot color, or surface height
*/
Graph3d.prototype._redrawLegend = function() {
//Return without drawing anything, if no legend is specified
if (this.showLegend !== true) {return;}
// Do not draw legend when graph style does not support
if (this.style === Graph3d.STYLE.LINE
|| this.style === Graph3d.STYLE.BARSIZE //TODO add legend support for BARSIZE
){return;}
// Legend types - size and color. Determine if size legend.
var isSizeLegend = (this.style === Graph3d.STYLE.BARSIZE
|| this.style === Graph3d.STYLE.DOTSIZE) ;
// Legend is either tracking z values or style values. This flag if false means use z values.
var isValueLegend = (this.style === Graph3d.STYLE.DOTSIZE
|| this.style === Graph3d.STYLE.DOTCOLOR
|| this.style === Graph3d.STYLE.BARCOLOR);
var height = Math.max(this.frame.clientHeight * 0.25, 100);
var top = this.margin;
var width = this._getLegendWidth() ; // px - overwritten by size legend
var right = this.frame.clientWidth - this.margin;
var left = right - width;
var bottom = top + height;
var canvas = this.frame.canvas; var canvas = this.frame.canvas;
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.font = '14px arial'; // TODO: put in options ctx.font = '14px arial'; // TODO: put in options
if (this.style === Graph3d.STYLE.DOTCOLOR) {
if (isSizeLegend === false) {
// draw the color bar // draw the color bar
var ymin = 0; var ymin = 0;
var ymax = height; // Todo: make height customizable var ymax = height; // Todo: make height customizable
var y;
for (y = ymin; y < ymax; y++) { for (y = ymin; y < ymax; y++) {
var f = (y - ymin) / (ymax - ymin); var f = (y - ymin) / (ymax - ymin);
//var width = (dotSize / 2 + (1-f) * dotSize * 2); // Todo: put this in one function
var hue = f * 240; var hue = f * 240;
var color = this._hsv2rgb(hue, 1, 1); var color = this._hsv2rgb(hue, 1, 1);
@ -1021,55 +1045,63 @@ Graph3d.prototype._redrawLegend = function() {
ctx.lineTo(right, top + y); ctx.lineTo(right, top + y);
ctx.stroke(); ctx.stroke();
} }
ctx.strokeStyle = this.axisColor; ctx.strokeStyle = this.axisColor;
ctx.strokeRect(left, top, widthMax, height);
}
ctx.strokeRect(left, top, width, height);
if (this.style === Graph3d.STYLE.DOTSIZE) {
// draw border around color bar
} else {
// draw the size legend box
var widthMin;
if (this.style === Graph3d.STYLE.DOTSIZE) {
var dotSize = this.frame.clientWidth * this.dotSizeRatio;
widthMin = dotSize / 2; // px
} else if (this.style === Graph3d.STYLE.BARSIZE) {
//widthMin = this.xBarWidth * 0.2 this is wrong - barwidth measures in terms of xvalues
}
ctx.strokeStyle = this.axisColor; ctx.strokeStyle = this.axisColor;
ctx.fillStyle = this.dataColor.fill; ctx.fillStyle = this.dataColor.fill;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(left, top); ctx.moveTo(left, top);
ctx.lineTo(right, top); ctx.lineTo(right, top);
ctx.lineTo(right - widthMax + widthMin, bottom);
ctx.lineTo(right - width + widthMin, bottom);
ctx.lineTo(left, bottom); ctx.lineTo(left, bottom);
ctx.closePath(); ctx.closePath();
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
} }
if (this.style === Graph3d.STYLE.DOTCOLOR ||
this.style === Graph3d.STYLE.DOTSIZE) {
// print values along the color bar
var gridLineLen = 5; // px
var step = new StepNumber(this.valueMin, this.valueMax, (this.valueMax-this.valueMin)/5, true);
step.start();
if (step.getCurrent() < this.valueMin) {
step.next();
}
while (!step.end()) {
y = bottom - (step.getCurrent() - this.valueMin) / (this.valueMax - this.valueMin) * height;
ctx.beginPath();
ctx.moveTo(left - gridLineLen, y);
ctx.lineTo(left, y);
ctx.stroke();
ctx.textAlign = 'right';
ctx.textBaseline = 'middle';
ctx.fillStyle = this.axisColor;
ctx.fillText(step.getCurrent(), left - 2 * gridLineLen, y);
// print value text along the legend edge
var gridLineLen = 5; // px
var legendMin = isValueLegend ? this.valueMin : this.zMin;
var legendMax = isValueLegend ? this.valueMax : this.zMax;
var step = new StepNumber(legendMin, legendMax, (legendMax-legendMin)/5, true);
step.start();
if (step.getCurrent() < legendMin) {
step.next();
}
var y;
while (!step.end()) {
y = bottom - (step.getCurrent() - legendMin) / (legendMax - legendMin) * height;
step.next();
}
ctx.beginPath();
ctx.moveTo(left - gridLineLen, y);
ctx.lineTo(left, y);
ctx.stroke();
ctx.textAlign = 'right'; ctx.textAlign = 'right';
ctx.textBaseline = 'top';
var label = this.legendLabel;
ctx.fillText(label, right, bottom + this.margin);
ctx.textBaseline = 'middle';
ctx.fillStyle = this.axisColor;
ctx.fillText(step.getCurrent(), left - 2 * gridLineLen, y);
step.next();
} }
ctx.textAlign = 'right';
ctx.textBaseline = 'top';
var label = this.legendLabel;
ctx.fillText(label, right, bottom + this.margin);
}; };
/** /**

Loading…
Cancel
Save