Skip to content
This repository was archived by the owner on Jul 29, 2019. It is now read-only.

Added point draw methods for graph styles 'bar-color' and 'bar-size' #2210

Merged
merged 1 commit into from
Oct 22, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 51 additions & 137 deletions lib/graph3d/Graph3d.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
};
Expand Down Expand Up @@ -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.
// -----------------------------------------------------------------------------


/**
Expand Down