|
|
@ -12,6 +12,21 @@ var StepNumber = require('./StepNumber'); |
|
|
|
// Definitions private to module
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/// enumerate the available styles
|
|
|
|
var STYLE = { |
|
|
|
BAR : 0, |
|
|
|
BARCOLOR: 1, |
|
|
|
BARSIZE : 2, |
|
|
|
DOT : 3, |
|
|
|
DOTLINE : 4, |
|
|
|
DOTCOLOR: 5, |
|
|
|
DOTSIZE : 6, |
|
|
|
GRID : 7, |
|
|
|
LINE : 8, |
|
|
|
SURFACE : 9 |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Field names in the options hash which are of relevance to the user. |
|
|
|
* |
|
|
@ -32,9 +47,9 @@ var OPTIONKEYS = [ |
|
|
|
'showGrid', |
|
|
|
'showPerspective', |
|
|
|
'showShadow', |
|
|
|
'showAnimationControls', |
|
|
|
'keepAspectRatio', |
|
|
|
'verticalRatio', |
|
|
|
'showAnimationControls', |
|
|
|
'animationInterval', |
|
|
|
'animationPreload', |
|
|
|
'animationAutoStart', |
|
|
@ -76,28 +91,28 @@ var DEFAULTS = { |
|
|
|
showPerspective : true, |
|
|
|
showShadow : false, |
|
|
|
keepAspectRatio : true, |
|
|
|
verticalRatio : 0.5, // 0.1 to 1.0, where 1.0 results in a 'cube'
|
|
|
|
animationInterval: 1000, // milliseconds
|
|
|
|
animationPreload : false, |
|
|
|
verticalRatio : 0.5, // 0.1 to 1.0, where 1.0 results in a 'cube'
|
|
|
|
|
|
|
|
showAnimationControls: undefined, // auto by default
|
|
|
|
animationInterval : 1000, // milliseconds
|
|
|
|
animationPreload : false, |
|
|
|
animationAutoStart : undefined, // auto by default
|
|
|
|
|
|
|
|
axisColor : '#4D4D4D', |
|
|
|
gridColor : '#D3D3D3', |
|
|
|
xCenter : '55%', |
|
|
|
yCenter : '50%', |
|
|
|
|
|
|
|
|
|
|
|
// Following not in defaults (yet) but present in user settings
|
|
|
|
// These will be initialized as 'undefined'
|
|
|
|
//'showAnimationControls',
|
|
|
|
//'animationAutoStart'
|
|
|
|
|
|
|
|
// Following not in OPTIONKEYS because they require special handling,
|
|
|
|
|
|
|
|
style : STYLE.DOT, // Can't use Graph3d.STYLE here, not defined yet
|
|
|
|
backgroundColor : undefined, |
|
|
|
|
|
|
|
dataColor : { |
|
|
|
fill : '#7DC1FF', |
|
|
|
stroke : '#3267D2', |
|
|
|
strokeWidth: 1 // px
|
|
|
|
strokeWidth: 1 // px
|
|
|
|
}, |
|
|
|
|
|
|
|
cameraPosition : { |
|
|
@ -154,6 +169,15 @@ function safeCopy(src, dst, fields) { |
|
|
|
// Class Graph3d
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/** |
|
|
|
* Enumerate the available styles. |
|
|
|
* |
|
|
|
* This definition retained for external compatibility |
|
|
|
* (It should be internal, but you never know) |
|
|
|
*/ |
|
|
|
Graph3d.STYLE = STYLE; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @constructor Graph3d |
|
|
|
* Graph3d displays data in 3d. |
|
|
@ -201,8 +225,6 @@ function Graph3d(container, data, options) { |
|
|
|
|
|
|
|
this.showLegend = undefined; // auto by default (based on graph style)
|
|
|
|
|
|
|
|
this.style = Graph3d.STYLE.DOT; |
|
|
|
|
|
|
|
this.eye = new Point3d(0, 0, -1); // TODO: set eye.z about 3/4 of the width of the window?
|
|
|
|
|
|
|
|
// the column indexes
|
|
|
@ -403,10 +425,10 @@ Graph3d.prototype._setSpecialSettings = function(src, dst) { |
|
|
|
} |
|
|
|
|
|
|
|
this._setDataColor(src.dataColor, dst); |
|
|
|
this._setStyle(src.style, dst); |
|
|
|
this._setCameraPosition(src.cameraPosition, dst); |
|
|
|
|
|
|
|
/* TODO |
|
|
|
setStyle(src.style, dst); |
|
|
|
|
|
|
|
if (src.tooltip !== undefined) { |
|
|
|
dst.showTooltip = src.tooltip; |
|
|
@ -416,6 +438,39 @@ End TODO */ |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Graph3d.prototype._setStyle = function(style, dst) { |
|
|
|
if (style === undefined) { |
|
|
|
return; // Nothing to do
|
|
|
|
} |
|
|
|
|
|
|
|
var styleNumber; |
|
|
|
|
|
|
|
if (typeof style === 'string') { |
|
|
|
styleNumber = this._getStyleNumber(style); |
|
|
|
|
|
|
|
if (styleNumber === -1 ) { |
|
|
|
throw new Error('Style \'' + style + '\' is invalid'); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Do a pedantic check on style number value
|
|
|
|
var valid = false; |
|
|
|
for (var n in STYLE) { |
|
|
|
if (STYLE[n] === style) { |
|
|
|
valid = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!valid) { |
|
|
|
throw new Error('Style \'' + style + '\' is invalid'); |
|
|
|
} |
|
|
|
|
|
|
|
styleNumber = style; |
|
|
|
} |
|
|
|
|
|
|
|
dst.style = styleNumber; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
@ -521,19 +576,7 @@ Graph3d.prototype.setCameraPosition = function(pos) { |
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/// enumerate the available styles
|
|
|
|
Graph3d.STYLE = { |
|
|
|
BAR: 0, |
|
|
|
BARCOLOR: 1, |
|
|
|
BARSIZE: 2, |
|
|
|
DOT : 3, |
|
|
|
DOTLINE : 4, |
|
|
|
DOTCOLOR: 5, |
|
|
|
DOTSIZE: 6, |
|
|
|
GRID : 7, |
|
|
|
LINE: 8, |
|
|
|
SURFACE : 9 |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Retrieve the style index from given styleName |
|
|
@ -686,13 +729,11 @@ Graph3d.prototype._dataInitialize = function (rawData, style) { |
|
|
|
this.colX = 'x'; |
|
|
|
this.colY = 'y'; |
|
|
|
this.colZ = 'z'; |
|
|
|
this.colValue = 'style'; |
|
|
|
this.colFilter = 'filter'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check if a filter column is provided
|
|
|
|
if (data[0].hasOwnProperty('filter')) { |
|
|
|
this.colFilter = 'filter'; // Bugfix: only set this field if it's actually present!
|
|
|
|
|
|
|
|
if (this.dataFilter === undefined) { |
|
|
|
this.dataFilter = new Filter(rawData, this.colFilter, this); |
|
|
|
this.dataFilter.setOnLoadCallback(function() {me.redraw();}); |
|
|
@ -750,7 +791,9 @@ Graph3d.prototype._dataInitialize = function (rawData, style) { |
|
|
|
if (this.zMax <= this.zMin) this.zMax = this.zMin + 1; |
|
|
|
this.zStep = (this.defaultZStep !== undefined) ? this.defaultZStep : (this.zMax-this.zMin)/5; |
|
|
|
|
|
|
|
if (this.colValue !== undefined) { |
|
|
|
// Bugfix: Only handle field 'style' if it's actually present
|
|
|
|
if (data[0].hasOwnProperty('style')) { |
|
|
|
this.colValue = 'style'; |
|
|
|
var valueRange = this.getColumnRange(data,this.colValue); |
|
|
|
this.valueMin = (this.defaultValueMin !== undefined) ? this.defaultValueMin : valueRange.min; |
|
|
|
this.valueMax = (this.defaultValueMax !== undefined) ? this.defaultValueMax : valueRange.max; |
|
|
@ -850,6 +893,30 @@ Graph3d.prototype._getDataPoints = function (data) { |
|
|
|
} |
|
|
|
} |
|
|
|
else { // 'dot', 'dot-line', etc.
|
|
|
|
|
|
|
|
// Bugfix: ensure value field is present in data if expected
|
|
|
|
var hasValueField = this.style === Graph3d.STYLE.BARCOLOR |
|
|
|
|| this.style === Graph3d.STYLE.BARSIZE |
|
|
|
|| this.style === Graph3d.STYLE.DOTCOLOR |
|
|
|
|| this.style === Graph3d.STYLE.DOTSIZE; |
|
|
|
|
|
|
|
if (hasValueField) { |
|
|
|
if (this.colValue === undefined) { |
|
|
|
throw new Error('Expected data to have ' |
|
|
|
+ ' field \'style\' ' |
|
|
|
+ ' for graph style \'' + this.style + '\'' |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
if (data[0][this.colValue] === undefined) { |
|
|
|
throw new Error('Expected data to have ' |
|
|
|
+ ' field \'' + this.colValue + '\' ' |
|
|
|
+ ' for graph style \'' + this.style + '\'' |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// copy all values from the google data table to a list with Point3d objects
|
|
|
|
for (i = 0; i < data.length; i++) { |
|
|
|
point = new Point3d(); |
|
|
@ -1077,12 +1144,6 @@ Graph3d.prototype.setOptions = function (options) { |
|
|
|
// Handle the rest of the parameters
|
|
|
|
if (options.showLegend !== undefined) this.defaultShowLegend = options.showLegend; |
|
|
|
|
|
|
|
if (options.style !== undefined) { |
|
|
|
var styleNumber = this._getStyleNumber(options.style); |
|
|
|
if (styleNumber !== -1) { |
|
|
|
this.style = styleNumber; |
|
|
|
} |
|
|
|
} |
|
|
|
if (options.tooltip !== undefined) this.showTooltip = options.tooltip; |
|
|
|
|
|
|
|
if (options.xBarWidth !== undefined) this.defaultXBarWidth = options.xBarWidth; |
|
|
|