diff --git a/lib/graph3d/Graph3d.js b/lib/graph3d/Graph3d.js index 95be0634..c6f27569 100644 --- a/lib/graph3d/Graph3d.js +++ b/lib/graph3d/Graph3d.js @@ -836,6 +836,12 @@ Graph3d.prototype.redraw = function() { case Graph3d.STYLE.BAR: pointDrawingMethod = Graph3d.prototype._redrawBarGraphPoint; break; + case Graph3d.STYLE.BARCOLOR: + pointDrawingMethod = Graph3d.prototype._redrawBarColorGraphPoint; + break; + case Graph3d.STYLE.BARSIZE: + pointDrawingMethod = Graph3d.prototype._redrawBarSizeGraphPoint; + break; } if (pointDrawingMethod !== undefined) { @@ -851,9 +857,6 @@ Graph3d.prototype.redraw = function() { } else if (this.style === Graph3d.STYLE.LINE) { this._redrawDataLine(); - } else if (this.style === Graph3d.STYLE.BARCOLOR || - this.style === Graph3d.STYLE.BARSIZE) { - this._redrawDataBar(); } else { // style is DOT, DOTLINE, DOTCOLOR, DOTSIZE @@ -1577,12 +1580,19 @@ Graph3d.prototype._redrawDataDot = function() { }; +// ----------------------------------------------------------------------------- +// Methods for drawing points per graph style. +// ----------------------------------------------------------------------------- + /** * Draw a bar element in the view with the given properties. */ Graph3d.prototype._redrawBar = function(ctx, point, xWidth, yWidth, color, borderColor) { var i, j, surface, corners; + ctx.lineJoin = 'round'; + ctx.lineCap = 'round'; + // calculate all corner points var me = this; var point3d = point.point; @@ -1661,24 +1671,50 @@ Graph3d.prototype._redrawBar = function(ctx, point, xWidth, yWidth, color, borde /** - * Draw single datapoint for graph style 'Bar'. + * Draw single datapoint for graph style 'bar'. */ Graph3d.prototype._redrawBarGraphPoint = function(ctx, point) { - var i, j, surface, corners; + var xWidth = this.xBarWidth / 2; + var yWidth = this.yBarWidth / 2; + + // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 + var hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; + var color = this._hsv2rgb(hue, 1, 1); + var borderColor = this._hsv2rgb(hue, 1, 0.8); + + this._redrawBar(ctx, point, xWidth, yWidth, color, borderColor); +}; - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; +/** + * Draw single datapoint for graph style 'bar-color'. + */ +Graph3d.prototype._redrawBarColorGraphPoint = function(ctx, point) { var xWidth = this.xBarWidth / 2; var yWidth = this.yBarWidth / 2; + // calculate the color based on the value + var hue = (1 - (point.point.value - this.valueMin) * this.scale.value) * 240; + var color = this._hsv2rgb(hue, 1, 1); + var borderColor = this._hsv2rgb(hue, 1, 0.8); + + this._redrawBar(ctx, point, xWidth, yWidth, color, borderColor); +}; + + +/** + * Draw single datapoint for graph style 'bar-size'. + */ +Graph3d.prototype._redrawBarSizeGraphPoint = function(ctx, point) { + // calculate size for the bar + var fraction = (point.point.value - this.valueMin) / (this.valueMax - this.valueMin); + var xWidth = (this.xBarWidth / 2) * (fraction * 0.8 + 0.2); + var yWidth = (this.yBarWidth / 2) * (fraction * 0.8 + 0.2); + // determine color - var hue, color, borderColor; - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); + var color = this.dataColor.fill; + var borderColor = this.dataColor.stroke; this._redrawBar(ctx, point, xWidth, yWidth, color, borderColor); }; @@ -1707,131 +1743,9 @@ Graph3d.prototype._redrawDataGraph = function(pointDrawMethod) { }; -/** - * Draw all datapoints as bars. - * This function can be used when the style is 'bar', 'bar-color', or 'bar-size' - */ -Graph3d.prototype._redrawDataBar = function() { - var ctx = this._getContext(); - var i, j, surface, corners; - - if (this.dataPoints === undefined || this.dataPoints.length <= 0) - return; // TODO: throw exception? - - this._calcTranslations(this.dataPoints); - - ctx.lineJoin = 'round'; - ctx.lineCap = 'round'; - - // draw the datapoints as bars - var xWidth = this.xBarWidth / 2; - var yWidth = this.yBarWidth / 2; - for (i = 0; i < this.dataPoints.length; i++) { - var point = this.dataPoints[i]; - - // TODO: Remove code for style `Bar` here - it has been refactored to separate routine - - // determine color - var hue, color, borderColor; - if (this.style === Graph3d.STYLE.BARCOLOR ) { - // calculate the color based on the value - hue = (1 - (point.point.value - this.valueMin) * this.scale.value) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); - } - else if (this.style === Graph3d.STYLE.BARSIZE) { - color = this.dataColor.fill; - borderColor = this.dataColor.stroke; - } - else { - // calculate Hue from the current value. At zMin the hue is 240, at zMax the hue is 0 - hue = (1 - (point.point.z - this.zMin) * this.scale.z / this.verticalRatio) * 240; - color = this._hsv2rgb(hue, 1, 1); - borderColor = this._hsv2rgb(hue, 1, 0.8); - } - - // calculate size for the bar - if (this.style === Graph3d.STYLE.BARSIZE) { - xWidth = (this.xBarWidth / 2) * ((point.point.value - this.valueMin) / (this.valueMax - this.valueMin) * 0.8 + 0.2); - yWidth = (this.yBarWidth / 2) * ((point.point.value - this.valueMin) / (this.valueMax - this.valueMin) * 0.8 + 0.2); - } - - // calculate all corner points - var me = this; - var point3d = point.point; - var top = [ - {point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, point3d.z)}, - {point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, point3d.z)}, - {point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, point3d.z)}, - {point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, point3d.z)} - ]; - var bottom = [ - {point: new Point3d(point3d.x - xWidth, point3d.y - yWidth, this.zMin)}, - {point: new Point3d(point3d.x + xWidth, point3d.y - yWidth, this.zMin)}, - {point: new Point3d(point3d.x + xWidth, point3d.y + yWidth, this.zMin)}, - {point: new Point3d(point3d.x - xWidth, point3d.y + yWidth, this.zMin)} - ]; - - // calculate screen location of the points - top.forEach(function (obj) { - obj.screen = me._convert3Dto2D(obj.point); - }); - bottom.forEach(function (obj) { - obj.screen = me._convert3Dto2D(obj.point); - }); - - // create five sides, calculate both corner points and center points - var surfaces = [ - {corners: top, center: Point3d.avg(bottom[0].point, bottom[2].point)}, - {corners: [top[0], top[1], bottom[1], bottom[0]], center: Point3d.avg(bottom[1].point, bottom[0].point)}, - {corners: [top[1], top[2], bottom[2], bottom[1]], center: Point3d.avg(bottom[2].point, bottom[1].point)}, - {corners: [top[2], top[3], bottom[3], bottom[2]], center: Point3d.avg(bottom[3].point, bottom[2].point)}, - {corners: [top[3], top[0], bottom[0], bottom[3]], center: Point3d.avg(bottom[0].point, bottom[3].point)} - ]; - point.surfaces = surfaces; - - // calculate the distance of each of the surface centers to the camera - for (j = 0; j < surfaces.length; j++) { - surface = surfaces[j]; - var transCenter = this._convertPointToTranslation(surface.center); - surface.dist = this.showPerspective ? transCenter.length() : -transCenter.z; - // TODO: this dept calculation doesn't work 100% of the cases due to perspective, - // but the current solution is fast/simple and works in 99.9% of all cases - // the issue is visible in example 14, with graph.setCameraPosition({horizontal: 2.97, vertical: 0.5, distance: 0.9}) - } - - // order the surfaces by their (translated) depth - surfaces.sort(function (a, b) { - var diff = b.dist - a.dist; - if (diff) return diff; - - // if equal depth, sort the top surface last - if (a.corners === top) return 1; - if (b.corners === top) return -1; - - // both are equal - return 0; - }); - - // draw the ordered surfaces - ctx.lineWidth = this._getStrokeWidth(point); - ctx.strokeStyle = borderColor; - ctx.fillStyle = color; - // NOTE: we start at j=2 instead of j=0 as we don't need to draw the two surfaces at the backside - for (j = 2; j < surfaces.length; j++) { - surface = surfaces[j]; - corners = surface.corners; - ctx.beginPath(); - ctx.moveTo(corners[3].screen.x, corners[3].screen.y); - ctx.lineTo(corners[0].screen.x, corners[0].screen.y); - ctx.lineTo(corners[1].screen.x, corners[1].screen.y); - ctx.lineTo(corners[2].screen.x, corners[2].screen.y); - ctx.lineTo(corners[3].screen.x, corners[3].screen.y); - ctx.fill(); - ctx.stroke(); - } - } -}; +// ----------------------------------------------------------------------------- +// End methods for drawing points per graph style. +// ----------------------------------------------------------------------------- /**