|
|
@ -135,11 +135,11 @@ Graph3d.DEFAULTS = { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @constructor Graph3d |
|
|
|
* Graph3d displays data in 3d. |
|
|
|
* |
|
|
|
* Graph3d is developed in javascript as a Google Visualization Chart. |
|
|
|
* |
|
|
|
* @constructor Graph3d |
|
|
|
* @param {Element} container The DOM element in which the Graph3d will |
|
|
|
* be created. Normally a div element. |
|
|
|
* @param {DataSet | DataView | Array} [data] |
|
|
@ -304,6 +304,9 @@ Graph3d.prototype._convertTranslationToScreen = function(translation) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Calculate the translations and screen positions of all points |
|
|
|
* |
|
|
|
* @param {Array<Point3d>} points |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._calcTranslations = function(points) { |
|
|
|
for (var i = 0; i < points.length; i++) { |
|
|
@ -355,6 +358,9 @@ Graph3d.prototype._initializeRanges = function() { |
|
|
|
|
|
|
|
/** |
|
|
|
* Return all data values as a list of Point3d objects |
|
|
|
* |
|
|
|
* @param {vis.DataSet} data |
|
|
|
* @returns {Array<Object>} |
|
|
|
*/ |
|
|
|
Graph3d.prototype.getDataPoints = function(data) { |
|
|
|
var dataPoints = []; |
|
|
@ -516,6 +522,10 @@ Graph3d.prototype.create = function () { |
|
|
|
|
|
|
|
/** |
|
|
|
* Set a new size for the graph |
|
|
|
* |
|
|
|
* @param {number} width |
|
|
|
* @param {number} height |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._setSize = function(width, height) { |
|
|
|
this.frame.style.width = width; |
|
|
@ -608,6 +618,9 @@ Graph3d.prototype.getCameraPosition = function() { |
|
|
|
|
|
|
|
/** |
|
|
|
* Load data into the 3D Graph |
|
|
|
* |
|
|
|
* @param {vis.DataSet} data |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._readData = function(data) { |
|
|
|
// read the data
|
|
|
@ -723,6 +736,9 @@ Graph3d.prototype.redraw = function() { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get drawing context without exposing canvas |
|
|
|
* |
|
|
|
* @returns {CanvasRenderingContext2D} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._getContext = function() { |
|
|
|
var canvas = this.frame.canvas; |
|
|
@ -753,6 +769,9 @@ Graph3d.prototype._dotSize = function() { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get legend width |
|
|
|
* |
|
|
|
* @returns {*} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._getLegendWidth = function() { |
|
|
|
var width; |
|
|
@ -767,7 +786,7 @@ Graph3d.prototype._getLegendWidth = function() { |
|
|
|
width = 20; |
|
|
|
} |
|
|
|
return width; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
@ -957,6 +976,12 @@ Graph3d.prototype._redrawInfo = function() { |
|
|
|
* Draw a line between 2d points 'from' and 'to'. |
|
|
|
* |
|
|
|
* If stroke style specified, set that as well. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {vis.Point2d} from |
|
|
|
* @param {vis.Point2d} to |
|
|
|
* @param {string} [strokeStyle] |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._line = function(ctx, from, to, strokeStyle) { |
|
|
|
if (strokeStyle !== undefined) { |
|
|
@ -967,9 +992,16 @@ Graph3d.prototype._line = function(ctx, from, to, strokeStyle) { |
|
|
|
ctx.moveTo(from.x, from.y); |
|
|
|
ctx.lineTo(to.x , to.y ); |
|
|
|
ctx.stroke(); |
|
|
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {vis.Point3d} point3d |
|
|
|
* @param {string} text |
|
|
|
* @param {number} armAngle |
|
|
|
* @param {number} [yMargin=0] |
|
|
|
*/ |
|
|
|
Graph3d.prototype.drawAxisLabelX = function(ctx, point3d, text, armAngle, yMargin) { |
|
|
|
if (yMargin === undefined) { |
|
|
|
yMargin = 0; |
|
|
@ -993,9 +1025,17 @@ Graph3d.prototype.drawAxisLabelX = function(ctx, point3d, text, armAngle, yMargi |
|
|
|
|
|
|
|
ctx.fillStyle = this.axisColor; |
|
|
|
ctx.fillText(text, point2d.x, point2d.y); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {vis.Point3d} point3d |
|
|
|
* @param {string} text |
|
|
|
* @param {number} armAngle |
|
|
|
* @param {number} [yMargin=0] |
|
|
|
*/ |
|
|
|
Graph3d.prototype.drawAxisLabelY = function(ctx, point3d, text, armAngle, yMargin) { |
|
|
|
if (yMargin === undefined) { |
|
|
|
yMargin = 0; |
|
|
@ -1019,9 +1059,16 @@ Graph3d.prototype.drawAxisLabelY = function(ctx, point3d, text, armAngle, yMargi |
|
|
|
|
|
|
|
ctx.fillStyle = this.axisColor; |
|
|
|
ctx.fillText(text, point2d.x, point2d.y); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {vis.Point3d} point3d |
|
|
|
* @param {string} text |
|
|
|
* @param {number} [offset=0] |
|
|
|
*/ |
|
|
|
Graph3d.prototype.drawAxisLabelZ = function(ctx, point3d, text, offset) { |
|
|
|
if (offset === undefined) { |
|
|
|
offset = 0; |
|
|
@ -1042,13 +1089,19 @@ Graph3d.prototype.drawAxisLabelZ = function(ctx, point3d, text, offset) { |
|
|
|
* Draw a line between 2d points 'from' and 'to'. |
|
|
|
* |
|
|
|
* If stroke style specified, set that as well. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {vis.Point2d} from |
|
|
|
* @param {vis.Point2d} to |
|
|
|
* @param {string} [strokeStyle] |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._line3d = function(ctx, from, to, strokeStyle) { |
|
|
|
var from2d = this._convert3Dto2D(from); |
|
|
|
var to2d = this._convert3Dto2D(to); |
|
|
|
|
|
|
|
this._line(ctx, from2d, to2d, strokeStyle); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
@ -1243,6 +1296,8 @@ Graph3d.prototype._redrawAxis = function() { |
|
|
|
* @param {Number} H Hue, a value be between 0 and 360 |
|
|
|
* @param {Number} S Saturation, a value between 0 and 1 |
|
|
|
* @param {Number} V Value, a value between 0 and 1 |
|
|
|
* @returns {string} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._hsv2rgb = function(H, S, V) { |
|
|
|
var R, G, B, C, Hi, X; |
|
|
@ -1266,6 +1321,12 @@ Graph3d.prototype._hsv2rgb = function(H, S, V) { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param {vis.Point3d} point |
|
|
|
* @returns {*} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._getStrokeWidth = function(point) { |
|
|
|
if (point !== undefined) { |
|
|
|
if (this.showPerspective) { |
|
|
@ -1287,6 +1348,14 @@ Graph3d.prototype._getStrokeWidth = function(point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw a bar element in the view with the given properties. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @param {number} xWidth |
|
|
|
* @param {number} yWidth |
|
|
|
* @param {string} color |
|
|
|
* @param {string} borderColor |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawBar = function(ctx, point, xWidth, yWidth, color, borderColor) { |
|
|
|
var surface; |
|
|
@ -1364,9 +1433,10 @@ Graph3d.prototype._redrawBar = function(ctx, point, xWidth, yWidth, color, borde |
|
|
|
/** |
|
|
|
* Draw a polygon using the passed points and fill it with the passed style and stroke. |
|
|
|
* |
|
|
|
* @param points an array of points. |
|
|
|
* @param fillStyle optional; the fill style to set |
|
|
|
* @param strokeStyle optional; the stroke style to set |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Array<vis.Point3d>} points an array of points. |
|
|
|
* @param {string} [fillStyle] the fill style to set |
|
|
|
* @param {string} [strokeStyle] the stroke style to set |
|
|
|
*/ |
|
|
|
Graph3d.prototype._polygon = function(ctx, points, fillStyle, strokeStyle) { |
|
|
|
if (points.length < 2) { |
|
|
@ -1394,7 +1464,12 @@ Graph3d.prototype._polygon = function(ctx, points, fillStyle, strokeStyle) { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @param size optional; if not specified use value from 'this._dotSize()`
|
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {object} point |
|
|
|
* @param {string} color |
|
|
|
* @param {string} borderColor |
|
|
|
* @param {number} [size=this._dotSize()] |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._drawCircle = function(ctx, point, color, borderColor, size) { |
|
|
|
var radius = this._calcRadius(point, size); |
|
|
@ -1411,6 +1486,10 @@ Graph3d.prototype._drawCircle = function(ctx, point, color, borderColor, size) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Determine the colors for the 'regular' graph styles. |
|
|
|
* |
|
|
|
* @param {object} point |
|
|
|
* @returns {{fill, border}} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._getColorsRegular = function(point) { |
|
|
|
// calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0
|
|
|
@ -1433,6 +1512,9 @@ Graph3d.prototype._getColorsRegular = function(point) { |
|
|
|
* The first option is useful when we have some pre-given legend, to which we have to adjust ourselves |
|
|
|
* The second option is useful when we are interested in automatically setting the color, from some value, |
|
|
|
* using some color scale |
|
|
|
* @param {object} point |
|
|
|
* @returns {{fill: *, border: *}} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._getColorsColor = function(point) { |
|
|
|
// calculate the color based on the value
|
|
|
@ -1457,6 +1539,9 @@ Graph3d.prototype._getColorsColor = function(point) { |
|
|
|
/** |
|
|
|
* Get the colors for the 'size' graph styles. |
|
|
|
* These styles are currently: 'bar-size' and 'dot-size' |
|
|
|
* |
|
|
|
* @returns {{fill: *, border: (string|undefinedOptions.colorOptions.stroke|{string, undefined}|string|colorOptions.stroke|{string}|*)}} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._getColorsSize = function() { |
|
|
|
return { |
|
|
@ -1470,8 +1555,11 @@ Graph3d.prototype._getColorsSize = function() { |
|
|
|
* Determine the size of a point on-screen, as determined by the |
|
|
|
* distance to the camera. |
|
|
|
* |
|
|
|
* @param size the size that needs to be translated to screen coordinates. |
|
|
|
* @param {Object} point |
|
|
|
* @param {number} [size=this._dotSize()] the size that needs to be translated to screen coordinates. |
|
|
|
* optional; if not passed, use the default point size. |
|
|
|
* @returns {number} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._calcRadius = function(point, size) { |
|
|
|
if (size === undefined) { |
|
|
@ -1500,6 +1588,10 @@ Graph3d.prototype._calcRadius = function(point, size) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'bar'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawBarGraphPoint = function(ctx, point) { |
|
|
|
var xWidth = this.xBarWidth / 2; |
|
|
@ -1512,6 +1604,10 @@ Graph3d.prototype._redrawBarGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'bar-color'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawBarColorGraphPoint = function(ctx, point) { |
|
|
|
var xWidth = this.xBarWidth / 2; |
|
|
@ -1524,6 +1620,10 @@ Graph3d.prototype._redrawBarColorGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'bar-size'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawBarSizeGraphPoint = function(ctx, point) { |
|
|
|
// calculate size for the bar
|
|
|
@ -1539,6 +1639,10 @@ Graph3d.prototype._redrawBarSizeGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'dot'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawDotGraphPoint = function(ctx, point) { |
|
|
|
var colors = this._getColorsRegular(point); |
|
|
@ -1549,6 +1653,10 @@ Graph3d.prototype._redrawDotGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'dot-line'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawDotLineGraphPoint = function(ctx, point) { |
|
|
|
// draw a vertical line from the XY-plane to the graph value
|
|
|
@ -1562,6 +1670,10 @@ Graph3d.prototype._redrawDotLineGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'dot-color'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawDotColorGraphPoint = function(ctx, point) { |
|
|
|
var colors = this._getColorsColor(point); |
|
|
@ -1572,6 +1684,10 @@ Graph3d.prototype._redrawDotColorGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'dot-size'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawDotSizeGraphPoint = function(ctx, point) { |
|
|
|
var dotSize = this._dotSize(); |
|
|
@ -1589,6 +1705,10 @@ Graph3d.prototype._redrawDotSizeGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'surface'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawSurfaceGraphPoint = function(ctx, point) { |
|
|
|
var right = point.pointRight; |
|
|
@ -1651,6 +1771,11 @@ Graph3d.prototype._redrawSurfaceGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Helper method for _redrawGridGraphPoint() |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} from |
|
|
|
* @param {Object} to |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._drawGridLine = function(ctx, from, to) { |
|
|
|
if (from === undefined || to === undefined) { |
|
|
@ -1669,6 +1794,10 @@ Graph3d.prototype._drawGridLine = function(ctx, from, to) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'Grid'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawGridGraphPoint = function(ctx, point) { |
|
|
|
this._drawGridLine(ctx, point, point.pointRight); |
|
|
@ -1678,6 +1807,10 @@ Graph3d.prototype._redrawGridGraphPoint = function(ctx, point) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Draw single datapoint for graph style 'line'. |
|
|
|
* |
|
|
|
* @param {CanvasRenderingContext2D} ctx |
|
|
|
* @param {Object} point |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Graph3d.prototype._redrawLineGraphPoint = function(ctx, point) { |
|
|
|
if (point.pointNext === undefined) { |
|
|
@ -1832,7 +1965,7 @@ Graph3d.prototype._onMouseMove = function (event) { |
|
|
|
/** |
|
|
|
* Stop moving operating. |
|
|
|
* This function activated from within the funcion Graph.mouseDown(). |
|
|
|
* @param {event} event The event |
|
|
|
* @param {Event} event The event |
|
|
|
*/ |
|
|
|
Graph3d.prototype._onMouseUp = function (event) { |
|
|
|
this.frame.style.cursor = 'auto'; |
|
|
@ -1845,7 +1978,7 @@ Graph3d.prototype._onMouseUp = function (event) { |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* @param {event} event The event |
|
|
|
* @param {Event} event The event |
|
|
|
*/ |
|
|
|
Graph3d.prototype._onClick = function (event) { |
|
|
|
if (!this.onclick_callback) |
|
|
@ -1918,6 +2051,7 @@ Graph3d.prototype._onTooltip = function (event) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Event handler for touchstart event on mobile devices |
|
|
|
* @param {Event} event The event |
|
|
|
*/ |
|
|
|
Graph3d.prototype._onTouchStart = function(event) { |
|
|
|
this.touchDown = true; |
|
|
@ -1933,6 +2067,7 @@ Graph3d.prototype._onTouchStart = function(event) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Event handler for touchmove event on mobile devices |
|
|
|
* @param {Event} event The event |
|
|
|
*/ |
|
|
|
Graph3d.prototype._onTouchMove = function(event) { |
|
|
|
this._onMouseMove(event); |
|
|
@ -1940,6 +2075,7 @@ Graph3d.prototype._onTouchMove = function(event) { |
|
|
|
|
|
|
|
/** |
|
|
|
* Event handler for touchend event on mobile devices |
|
|
|
* @param {Event} event The event |
|
|
|
*/ |
|
|
|
Graph3d.prototype._onTouchEnd = function(event) { |
|
|
|
this.touchDown = false; |
|
|
@ -1954,7 +2090,7 @@ Graph3d.prototype._onTouchEnd = function(event) { |
|
|
|
/** |
|
|
|
* Event handler for mouse wheel event, used to zoom the graph |
|
|
|
* Code from http://adomas.org/javascript-mouse-wheel/
|
|
|
|
* @param {event} event The event |
|
|
|
* @param {Event} event The event |
|
|
|
*/ |
|
|
|
Graph3d.prototype._onWheel = function(event) { |
|
|
|
if (!event) /* For IE. */ |
|
|
@ -1996,8 +2132,8 @@ Graph3d.prototype._onWheel = function(event) { |
|
|
|
/** |
|
|
|
* Test whether a point lies inside given 2D triangle |
|
|
|
* |
|
|
|
* @param {Point2d} point |
|
|
|
* @param {Point2d[]} triangle |
|
|
|
* @param {vis.Point2d} point |
|
|
|
* @param {vis.Point2d[]} triangle |
|
|
|
* @returns {boolean} true if given point lies inside or on the edge of the |
|
|
|
* triangle, false otherwise |
|
|
|
* @private |
|
|
|