Skip to content

Commit 864d5c5

Browse files
committed
Side surfaces of bars being drawn now (still depth ordering issues to fix)
1 parent 587fc5e commit 864d5c5

File tree

2 files changed

+82
-19
lines changed

2 files changed

+82
-19
lines changed

js/src/graph3d/examples/example14_bar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
google.setOnLoadCallback(drawVisualization);
2121

2222
function custom(x, y) {
23-
return (Math.sin(x/Math.PI) * Math.cos(y/Math.PI) * 50 + 50);
23+
return (Math.sin(x/Math.PI) * Math.cos(y/Math.PI) * 10 + 10);
2424
}
2525

2626
// Called when the Visualization API is loaded.
@@ -32,7 +32,7 @@
3232
data.addColumn('number', 'z');
3333

3434
// create some nice looking data with sin/cos
35-
var steps = 4; // number of datapoints will be steps*steps
35+
var steps = 5; // number of datapoints will be steps*steps
3636
var axisMax = 10;
3737
var axisStep = axisMax / steps;
3838
for (var x = 0; x <= axisMax; x+=axisStep) {

js/src/graph3d/graph3d.js

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -618,12 +618,20 @@ links.Graph3d.prototype._dataInitialize = function (data, style) {
618618

619619
// calculate minimums and maximums
620620
var xRange = data.getColumnRange(this.colX);
621+
if (this.style == links.Graph3d.STYLE.BAR) {
622+
xRange.min -= this.barWidth / 2;
623+
xRange.max += this.barWidth / 2;
624+
}
621625
this.xMin = (this.defaultXMin !== undefined) ? this.defaultXMin : xRange.min;
622626
this.xMax = (this.defaultXMax !== undefined) ? this.defaultXMax : xRange.max;
623627
if (this.xMax <= this.xMin) this.xMax = this.xMin + 1;
624628
this.xStep = (this.defaultXStep !== undefined) ? this.defaultXStep : (this.xMax-this.xMin)/5;
625629

626630
var yRange = data.getColumnRange(this.colY);
631+
if (this.style == links.Graph3d.STYLE.BAR) {
632+
yRange.min -= this.barWidth / 2;
633+
yRange.max += this.barWidth / 2;
634+
}
627635
this.yMin = (this.defaultYMin !== undefined) ? this.defaultYMin : yRange.min;
628636
this.yMax = (this.defaultYMax !== undefined) ? this.defaultYMax : yRange.max;
629637
if (this.yMax <= this.yMin) this.yMax = this.yMin + 1;
@@ -708,7 +716,7 @@ links.Graph3d.prototype._getDataPoints = function (data) {
708716
obj.point = point3d;
709717
obj.trans = undefined;
710718
obj.screen = undefined;
711-
obj.bottom = new links.Point3d(x, y, 0);
719+
obj.bottom = new links.Point3d(x, y, this.zMin);
712720

713721
dataMatrix[xIndex][yIndex] = obj;
714722

@@ -743,7 +751,7 @@ links.Graph3d.prototype._getDataPoints = function (data) {
743751

744752
obj = {};
745753
obj.point = point;
746-
obj.bottom = new links.Point3d(point.x, point.y, 0);
754+
obj.bottom = new links.Point3d(point.x, point.y, this.zMin);
747755
obj.trans = undefined;
748756
obj.screen = undefined;
749757

@@ -764,7 +772,7 @@ links.Graph3d.prototype._getDataPoints = function (data) {
764772

765773
obj = {};
766774
obj.point = point;
767-
obj.bottom = new links.Point3d(point.x, point.y, 0);
775+
obj.bottom = new links.Point3d(point.x, point.y, this.zMin);
768776
obj.trans = undefined;
769777
obj.screen = undefined;
770778

@@ -1756,6 +1764,10 @@ links.Graph3d.prototype._redrawDataBar = function() {
17561764
};
17571765
this.dataPoints.sort(sortDepth);
17581766

1767+
function sign(x) {
1768+
return x < 0 ? -1 : x > 0 ? 1 : 0;
1769+
}
1770+
17591771
// draw the datapoints as bars
17601772
var dotSize = this.frame.clientWidth * 0.02; // px
17611773
var halfWidth = this.barWidth / 2;
@@ -1802,25 +1814,76 @@ links.Graph3d.prototype._redrawDataBar = function() {
18021814
borderColor = this._hsv2rgb(hue, 1, 0.8);
18031815
}
18041816

1805-
// draw top surface
1817+
// calculate all corner points
1818+
var me = this;
18061819
var point3d = point.point;
1807-
var corners = [
1808-
this._convert3Dto2D(new links.Point3d(point3d.x - halfWidth, point3d.y - halfWidth, point3d.z)),
1809-
this._convert3Dto2D(new links.Point3d(point3d.x + halfWidth, point3d.y - halfWidth, point3d.z)),
1810-
this._convert3Dto2D(new links.Point3d(point3d.x + halfWidth, point3d.y + halfWidth, point3d.z)),
1811-
this._convert3Dto2D(new links.Point3d(point3d.x - halfWidth, point3d.y + halfWidth, point3d.z))
1820+
var top = [
1821+
{point: new links.Point3d(point3d.x - halfWidth, point3d.y - halfWidth, point3d.z)},
1822+
{point: new links.Point3d(point3d.x + halfWidth, point3d.y - halfWidth, point3d.z)},
1823+
{point: new links.Point3d(point3d.x + halfWidth, point3d.y + halfWidth, point3d.z)},
1824+
{point: new links.Point3d(point3d.x - halfWidth, point3d.y + halfWidth, point3d.z)}
18121825
];
1826+
var bottom = [
1827+
{point: new links.Point3d(point3d.x - halfWidth, point3d.y - halfWidth, this.zMin)},
1828+
{point: new links.Point3d(point3d.x + halfWidth, point3d.y - halfWidth, this.zMin)},
1829+
{point: new links.Point3d(point3d.x + halfWidth, point3d.y + halfWidth, this.zMin)},
1830+
{point: new links.Point3d(point3d.x - halfWidth, point3d.y + halfWidth, this.zMin)}
1831+
];
1832+
1833+
// calculate screen location of the points
1834+
top.forEach(function (obj) {
1835+
obj.screen = me._convert3Dto2D(obj.point);
1836+
});
1837+
bottom.forEach(function (obj) {
1838+
obj.screen = me._convert3Dto2D(obj.point);
1839+
});
1840+
1841+
// create five sides, calculate both corner points and center points
1842+
var surfaces = [
1843+
{corners: top},
1844+
{corners: [top[0], top[1], bottom[1], bottom[0]]},
1845+
{corners: [top[1], top[2], bottom[2], bottom[1]]},
1846+
{corners: [top[2], top[3], bottom[3], bottom[2]]},
1847+
{corners: [top[3], top[0], bottom[0], bottom[3]]}
1848+
];
1849+
1850+
// calculate center points of each of the surfaces, and their translation
1851+
for (var j = 0; j < surfaces.length; j++) {
1852+
var surface = surfaces[j],
1853+
corners = surface.corners;
1854+
1855+
surface.center = new links.Point3d(
1856+
(corners[0].point.x + corners[1].point.x + corners[2].point.x + corners[3].point.x) / 4,
1857+
(corners[0].point.y + corners[1].point.y + corners[2].point.y + corners[3].point.y) / 4,
1858+
(corners[0].point.z + corners[1].point.z + corners[2].point.z + corners[3].point.z) / 4
1859+
);
1860+
1861+
surface.trans = this._convertPointToTranslation(surface.center);
1862+
}
1863+
1864+
// order the surfaces by their (translated) depth
1865+
// TODO: must be sorted by distance to camera!
1866+
surfaces.sort(function (a, b) {
1867+
return a.trans.z - b.trans.z;
1868+
});
1869+
1870+
// draw the ordered surfaces
18131871
ctx.lineWidth = 1;
18141872
ctx.strokeStyle = borderColor;
18151873
ctx.fillStyle = color;
1816-
ctx.beginPath();
1817-
ctx.moveTo(corners[3].x, corners[3].y);
1818-
ctx.lineTo(corners[0].x, corners[0].y);
1819-
ctx.lineTo(corners[1].x, corners[1].y);
1820-
ctx.lineTo(corners[2].x, corners[2].y);
1821-
ctx.lineTo(corners[3].x, corners[3].y);
1822-
ctx.fill();
1823-
ctx.stroke();
1874+
// NOTE: we start at j=2 instead of j=0 as we don't need to draw the two surfaces at the backside
1875+
for (var j = 2; j < surfaces.length; j++) {
1876+
var surface = surfaces[j],
1877+
corners = surface.corners;
1878+
ctx.beginPath();
1879+
ctx.moveTo(corners[3].screen.x, corners[3].screen.y);
1880+
ctx.lineTo(corners[0].screen.x, corners[0].screen.y);
1881+
ctx.lineTo(corners[1].screen.x, corners[1].screen.y);
1882+
ctx.lineTo(corners[2].screen.x, corners[2].screen.y);
1883+
ctx.lineTo(corners[3].screen.x, corners[3].screen.y);
1884+
ctx.fill();
1885+
ctx.stroke();
1886+
}
18241887
}
18251888
};
18261889

0 commit comments

Comments
 (0)