diff --git a/docs/graph3d/index.html b/docs/graph3d/index.html
index c0e604a7..16467484 100644
--- a/docs/graph3d/index.html
+++ b/docs/graph3d/index.html
@@ -435,6 +435,14 @@ var options = {
when drawn in perspective.
+
+ showLegend |
+ boolean |
+ none |
+ 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.
+ |
+
showShadow |
boolean |
@@ -796,4 +804,4 @@ graph3d.on('cameraPositionChange', onCameraPositionChange);
-
\ No newline at end of file
+
diff --git a/examples/graph3d/11_tooltips.html b/examples/graph3d/11_tooltips.html
index 6ae32a39..508e7e0a 100644
--- a/examples/graph3d/11_tooltips.html
+++ b/examples/graph3d/11_tooltips.html
@@ -48,6 +48,7 @@
height: '600px',
style: style,
showPerspective: true,
+ showLegend: true,
showGrid: true,
showShadow: false,
diff --git a/examples/graph3d/playground/index.html b/examples/graph3d/playground/index.html
index 4f42260e..134bb264 100644
--- a/examples/graph3d/playground/index.html
+++ b/examples/graph3d/playground/index.html
@@ -116,6 +116,10 @@
showPerspective |
|
+
+ showLegend |
+ |
+
showShadow |
|
diff --git a/examples/graph3d/playground/playground.js b/examples/graph3d/playground/playground.js
index 5b93dddb..a2e28728 100644
--- a/examples/graph3d/playground/playground.js
+++ b/examples/graph3d/playground/playground.js
@@ -407,6 +407,7 @@ function getOptions() {
showAnimationControls: (document.getElementById("showAnimationControls").checked != false),
showGrid: (document.getElementById("showGrid").checked != false),
showPerspective: (document.getElementById("showPerspective").checked != false),
+ showLegend: (document.getElementById("showLegend").checked != false),
showShadow: (document.getElementById("showShadow").checked != false),
keepAspectRatio: (document.getElementById("keepAspectRatio").checked != false),
verticalRatio: document.getElementById("verticalRatio").value,
diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js
index 9db4fbeb..f2c17507 100644
--- a/lib/graph3d/Graph3d.js
+++ b/lib/graph3d/Graph3d.js
@@ -44,6 +44,7 @@ function Graph3d(container, data, options) {
this.filterLabel = 'time';
this.legendLabel = 'value';
+ this.showLegend = undefined; // auto by default (based on graph style)
this.style = Graph3d.STYLE.DOT;
this.showPerspective = true;
@@ -494,7 +495,11 @@ Graph3d.prototype._dataInitialize = function (rawData, style) {
this.valueMax = (this.defaultValueMax !== undefined) ? this.defaultValueMax : valueRange.max;
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.
this._setScale();
};
@@ -838,6 +843,7 @@ Graph3d.prototype.setOptions = function (options) {
if (options.filterLabel !== undefined) this.filterLabel = options.filterLabel;
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.yLabel !== undefined) this.yLabel = options.yLabel;
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;
+ 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 ctx = canvas.getContext('2d');
ctx.lineWidth = 1;
ctx.font = '14px arial'; // TODO: put in options
- if (this.style === Graph3d.STYLE.DOTCOLOR) {
+ if (isSizeLegend === false) {
// draw the color bar
var ymin = 0;
var ymax = height; // Todo: make height customizable
+ var y;
+
for (y = ymin; y < ymax; y++) {
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 color = this._hsv2rgb(hue, 1, 1);
@@ -1021,55 +1045,63 @@ Graph3d.prototype._redrawLegend = function() {
ctx.lineTo(right, top + y);
ctx.stroke();
}
-
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.fillStyle = this.dataColor.fill;
ctx.beginPath();
ctx.moveTo(left, top);
ctx.lineTo(right, top);
- ctx.lineTo(right - widthMax + widthMin, bottom);
+ ctx.lineTo(right - width + widthMin, bottom);
ctx.lineTo(left, bottom);
ctx.closePath();
ctx.fill();
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.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);
+
};
/**