6 if (typeof JSROOT !=
'object') {
7 var e1 =
new Error(
'JSROOT is not defined');
8 e1.source =
'JSRoot3DPainter.js';
12 if (typeof d3 !=
'object') {
13 var e1 =
new Error(
'This extension requires d3.v3.js');
14 e1.source =
'JSRoot3DPainter.js';
18 if (typeof JSROOT.Painter !=
'object') {
19 var e1 =
new Error(
'JSROOT.Painter is not defined');
20 e1.source =
'JSRoot3DPainter.js';
24 JSROOT.Painter.add3DInteraction =
function(renderer, scene, camera, toplevel, painter) {
26 var mouseX, mouseY, mouseDowned =
false;
27 var mouse = { x : 0, y : 0 }, INTERSECTED;
29 var tooltip =
function() {
39 var ie = document.all ?
true :
false;
41 show :
function(v, w) {
43 tt = document.createElement(
'div');
44 tt.setAttribute(
'id',
id);
45 t = document.createElement(
'div');
46 t.setAttribute(
'id',
id +
'top');
47 c = document.createElement(
'div');
48 c.setAttribute(
'id',
id +
'cont');
49 b = document.createElement(
'div');
50 b.setAttribute(
'id',
id +
'bot');
54 document.body.appendChild(tt);
56 tt.style.filter =
'alpha(opacity=0)';
57 document.onmousemove = this.pos;
59 tt.style.display =
'block';
61 tt.style.width = w ? w +
'px' :
'auto';
62 tt.style.width =
'auto';
64 t.style.display =
'none';
65 b.style.display =
'none';
66 tt.style.width = tt.offsetWidth;
67 t.style.display =
'block';
68 b.style.display =
'block';
71 h = parseInt(tt.offsetHeight) + top;
72 clearInterval(tt.timer);
73 tt.timer = setInterval(
function() { tooltip.fade(1) }, timer);
76 var u = ie ?
event.clientY + document.documentElement.scrollTop : e.pageY;
77 var l = ie ?
event.clientX + document.documentElement.scrollLeft : e.pageX;
78 tt.style.top = u + 15 +
'px';
79 tt.style.left = (l + left) +
'px';
83 if ((a != endalpha && d == 1) || (a != 0 && d == -1)) {
85 if (endalpha - a < speed && d == 1) {
87 }
else if (alpha < speed && d == -1) {
91 tt.style.opacity = alpha * .01;
92 tt.style.filter =
'alpha(opacity=' + alpha +
')';
94 clearInterval(tt.timer);
96 tt.style.display =
'none';
103 clearInterval(tt.timer);
104 tt.timer = setInterval(
function() {
113 var projector =
new THREE.Projector();
114 function findIntersection() {
118 INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
119 renderer.render(scene, camera);
122 if (JSROOT.gStyle.Tooltip)
126 var vector =
new THREE.Vector3(mouse.x, mouse.y, 1);
127 projector.unprojectVector(vector, camera);
128 var raycaster =
new THREE.Raycaster(camera.position, vector.sub(
129 camera.position).normalize());
130 var intersects = raycaster.intersectObjects(scene.children,
true);
131 if (intersects.length > 0) {
133 for (var i = 0; i < intersects.length; ++i) {
134 if (
'emissive' in intersects[i].
object.material) {
135 pick = intersects[i];
139 if (pick && INTERSECTED != pick.object) {
141 INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
142 INTERSECTED = pick.object;
143 INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
144 INTERSECTED.material.emissive.setHex(0x5f5f5f);
145 renderer.render(scene, camera);
146 if (JSROOT.gStyle.Tooltip)
147 tooltip.show(INTERSECTED.name.length > 0 ? INTERSECTED.name
148 : INTERSECTED.parent.name, 200);
152 INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
153 renderer.render(scene, camera);
156 if (JSROOT.gStyle.Tooltip)
162 $(renderer.domElement).on(
'touchstart mousedown',
function(e) {
164 if (JSROOT.gStyle.Tooltip)
168 if (
'changedTouches' in e)
169 touch = e.changedTouches[0];
170 else if (
'touches' in e)
171 touch = e.touches[0];
172 else if (
'originalEvent' in e) {
173 if (
'changedTouches' in e.originalEvent)
174 touch = e.originalEvent.changedTouches[0];
175 else if (
'touches' in e.originalEvent)
176 touch = e.originalEvent.touches[0];
178 mouseX = touch.pageX;
179 mouseY = touch.pageY;
182 $(renderer.domElement).on(
'touchmove mousemove',
function(e) {
185 if (
'changedTouches' in e)
186 touch = e.changedTouches[0];
187 else if (
'touches' in e)
188 touch = e.touches[0];
189 else if (
'originalEvent' in e) {
190 if (
'changedTouches' in e.originalEvent)
191 touch = e.originalEvent.changedTouches[0];
192 else if (
'touches' in e.originalEvent)
193 touch = e.originalEvent.touches[0];
195 var moveX = touch.pageX - mouseX;
196 var moveY = touch.pageY - mouseY;
198 if ((moveY > 0 && toplevel.rotation.x < Math.PI * 3 / 4)
199 || (moveY < 0 && toplevel.rotation.x > -Math.PI / 4)) {
200 toplevel.rotation.x += moveY * 0.02;
202 toplevel.rotation.y += moveX * 0.02;
203 renderer.render(scene, camera);
204 mouseX = touch.pageX;
205 mouseY = touch.pageY;
208 var mouse_x =
'offsetX' in e.originalEvent ? e.originalEvent.offsetX : e.originalEvent.layerX;
209 var mouse_y =
'offsetY' in e.originalEvent ? e.originalEvent.offsetY : e.originalEvent.layerY;
210 mouse.x = (mouse_x / renderer.domElement.width) * 2 - 1;
211 mouse.y = -(mouse_y / renderer.domElement.height) * 2 + 1;
216 $(renderer.domElement).on(
'touchend mouseup',
function(e) {
220 $(renderer.domElement).on(
'mousewheel',
function(e, d) {
222 camera.position.z += d * 20;
223 renderer.render(scene, camera);
226 $(renderer.domElement).on(
'contextmenu',
function(e) {
230 if (JSROOT.gStyle.Tooltip) tooltip.hide();
232 var menu = JSROOT.Painter.createmenu(e.originalEvent);
234 var item = JSROOT.gStyle.Tooltip ?
"Disable tooltip" :
"Enable tooltip";
236 JSROOT.Painter.menuitem(menu, item,
function() {
237 JSROOT.gStyle.Tooltip = !JSROOT.gStyle.Tooltip;
242 JSROOT.Painter.menuitem(menu,
"Switch to 2D",
function() {
243 $(painter.svg_pad()).show().parent().find(renderer.domElement).remove();
247 JSROOT.Painter.menuitem(menu,
"Close",
function() { });
252 JSROOT.Painter.real_drawHistogram2D =
function(painter) {
254 var w = Number(painter.svg_pad(
true).attr(
"width")),
255 h = Number(painter.svg_pad(
true).attr(
"height")), size = 100;
257 var xmin = painter.xmin, xmax = painter.xmax;
258 if (painter.zoom_xmin != painter.zoom_xmax) {
259 xmin = painter.zoom_xmin;
260 xmax = painter.zoom_xmax;
262 var ymin = painter.ymin, ymax = painter.ymax;
263 if (painter.zoom_ymin != painter.zoom_ymax) {
264 ymin = painter.zoom_ymin;
265 ymax = painter.zoom_ymax;
268 var tx, utx, ty, uty, tz, utz;
270 if (painter.options.Logx) {
271 tx = d3.scale.log().domain([ xmin, xmax ]).range([ -size, size ]);
272 utx = d3.scale.log().domain([ -size, size ]).range([ xmin, xmax ]);
274 tx = d3.scale.linear().domain([ xmin, xmax ]).range([ -size, size ]);
275 utx = d3.scale.linear().domain([ -size, size ]).range([ xmin, xmax ]);
277 if (painter.options.Logy) {
278 ty = d3.scale.log().domain([ ymin, ymax ]).range([ -size, size ]);
279 uty = d3.scale.log().domain([ size, -size ]).range([ ymin, ymax ]);
281 ty = d3.scale.linear().domain([ ymin, ymax ]).range([ -size, size ]);
282 uty = d3.scale.linear().domain([ size, -size ]).range([ ymin, ymax ]);
284 if (painter.options.Logz) {
285 tz = d3.scale.log().domain([ painter.gminbin, Math.ceil(painter.gmaxbin / 100) * 105 ]).range([ 0, size * 2 ]);
286 utz = d3.scale.log().domain([ 0, size * 2 ]).range([ painter.gminbin, Math.ceil(painter.gmaxbin / 100) * 105 ]);
288 tz = d3.scale.linear().domain([ painter.gminbin, Math.ceil(painter.gmaxbin / 100) * 105 ]).range( [ 0, size * 2 ]);
289 utz = d3.scale.linear().domain([ 0, size * 2 ]).range( [ painter.gminbin, Math.ceil(painter.gmaxbin / 100) * 105 ]);
292 var constx = (size * 2 / painter.nbinsx) / painter.gmaxbin;
293 var consty = (size * 2 / painter.nbinsy) / painter.gmaxbin;
295 var colorFlag = (painter.options.Color > 0);
296 var fcolor = d3.rgb(JSROOT.Painter.root_colors[painter.histo[
'fFillColor']]);
298 var local_bins = painter.CreateDrawBins(100, 100, 2, (JSROOT.gStyle.Tooltip ? 1 : 0));
301 var scene =
new THREE.Scene();
303 var toplevel =
new THREE.Object3D();
304 toplevel.rotation.x = 30 * Math.PI / 180;
305 toplevel.rotation.y = 30 * Math.PI / 180;
308 var wireMaterial =
new THREE.MeshBasicMaterial({
311 wireframeLinewidth : 0.5,
312 side : THREE.DoubleSide
316 var cube =
new THREE.Mesh(
new THREE.BoxGeometry(size * 2, size * 2, size * 2), wireMaterial);
319 var helper =
new THREE.BoxHelper(cube);
320 helper.material.color.set(0x000000);
322 var box =
new THREE.Object3D();
324 box.position.y = size;
329 var textMaterial =
new THREE.MeshBasicMaterial({ color : 0x000000 });
332 var geometry =
new THREE.Geometry();
333 var imax, istep, len = 3, plen, sin45 = Math.sin(45);
335 var xmajors = tx.ticks(8);
336 var xminors = tx.ticks(50);
337 for (var i = -size, j = 0, k = 0; i < size; ++i) {
338 var is_major = (utx(i) <= xmajors[j] && utx(i + 1) > xmajors[j]) ?
true :
false;
339 var is_minor = (utx(i) <= xminors[k] && utx(i + 1) > xminors[k]) ?
true :
false;
340 plen = (is_major ? len + 2 : len) * sin45;
342 text3d =
new THREE.TextGeometry(xmajors[j], { size : 7, height : 0, curveSegments : 10 });
345 text3d.computeBoundingBox();
346 var centerOffset = 0.5 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
348 text =
new THREE.Mesh(text3d, textMaterial);
349 text.position.set(i - centerOffset, -13, size + plen);
352 text =
new THREE.Mesh(text3d, textMaterial);
353 text.position.set(i + centerOffset, -13, -size - plen);
354 text.rotation.y = Math.PI;
357 if (is_major || is_minor) {
359 geometry.vertices.push(
new THREE.Vector3(i, 0, size));
360 geometry.vertices.push(
new THREE.Vector3(i, -plen, size + plen));
361 geometry.vertices.push(
new THREE.Vector3(i, 0, -size));
362 geometry.vertices.push(
new THREE.Vector3(i, -plen, -size - plen));
365 var ymajors = ty.ticks(8);
366 var yminors = ty.ticks(50);
367 for (var i = size, j = 0, k = 0; i > -size; --i) {
368 var is_major = (uty(i) <= ymajors[j] && uty(i - 1) > ymajors[j]) ?
true :
false;
369 var is_minor = (uty(i) <= yminors[k] && uty(i - 1) > yminors[k]) ?
true :
false;
370 plen = (is_major ? len + 2 : len) * sin45;
372 text3d =
new THREE.TextGeometry(ymajors[j], { size : 7, height : 0, curveSegments : 10 });
375 text3d.computeBoundingBox();
376 var centerOffset = 0.5 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
378 text =
new THREE.Mesh(text3d, textMaterial);
379 text.position.set(size + plen, -13, i + centerOffset);
380 text.rotation.y = Math.PI / 2;
383 text =
new THREE.Mesh(text3d, textMaterial);
384 text.position.set(-size - plen, -13, i - centerOffset);
385 text.rotation.y = -Math.PI / 2;
388 if (is_major || is_minor) {
390 geometry.vertices.push(
new THREE.Vector3(size, 0, i));
391 geometry.vertices.push(
new THREE.Vector3(size + plen, -plen, i));
392 geometry.vertices.push(
new THREE.Vector3(-size, 0, i));
393 geometry.vertices.push(
new THREE.Vector3(-size - plen, -plen, i));
396 var zmajors = tz.ticks(8);
397 var zminors = tz.ticks(50);
398 for (var i = 0, j = 0, k = 0; i < (size * 2); ++i) {
399 var is_major = (utz(i) <= zmajors[j] && utz(i + 1) > zmajors[j]) ?
true :
false;
400 var is_minor = (utz(i) <= zminors[k] && utz(i + 1) > zminors[k]) ?
true :
false;
401 plen = (is_major ? len + 2 : len) * sin45;
403 text3d =
new THREE.TextGeometry(zmajors[j], { size : 7, height : 0, curveSegments : 10 });
406 text3d.computeBoundingBox();
407 var offset = 0.8 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
409 text =
new THREE.Mesh(text3d, textMaterial);
410 text.position.set(size + offset + 5, i - 2.5, size + offset + 5);
411 text.rotation.y = Math.PI * 3 / 4;
414 text =
new THREE.Mesh(text3d, textMaterial);
415 text.position.set(size + offset + 5, i - 2.5, -size - offset - 5);
416 text.rotation.y = -Math.PI * 3 / 4;
419 text =
new THREE.Mesh(text3d, textMaterial);
420 text.position.set(-size - offset - 5, i - 2.5, size + offset + 5);
421 text.rotation.y = Math.PI / 4;
424 text =
new THREE.Mesh(text3d, textMaterial);
425 text.position.set(-size - offset - 5, i - 2.5, -size - offset - 5);
426 text.rotation.y = -Math.PI / 4;
429 if (is_major || is_minor) {
431 geometry.vertices.push(
new THREE.Vector3(size, i, size));
432 geometry.vertices.push(
new THREE.Vector3(size + plen, i, size + plen));
433 geometry.vertices.push(
new THREE.Vector3(size, i, -size));
434 geometry.vertices.push(
new THREE.Vector3(size + plen, i, -size - plen));
435 geometry.vertices.push(
new THREE.Vector3(-size, i, size));
436 geometry.vertices.push(
new THREE.Vector3(-size - plen, i, size + plen));
437 geometry.vertices.push(
new THREE.Vector3(-size, i, -size));
438 geometry.vertices.push(
new THREE.Vector3(-size - plen, i, -size - plen));
443 var lineMaterial =
new THREE.LineBasicMaterial({ color : 0x000000 });
444 var line =
new THREE.Line(geometry, lineMaterial);
445 line.type = THREE.LinePieces;
450 var fillcolor =
new THREE.Color(0xDDDDDD);
451 fillcolor.setRGB(fcolor.r / 255, fcolor.g / 255, fcolor.b / 255);
454 for (var i = 0; i < local_bins.length; ++i) {
458 bin = THREE.SceneUtils.createMultiMaterialObject(
459 new THREE.BoxGeometry(2 * size / painter.nbinsx, wei, 2 * size / painter.nbinsy),
460 [
new THREE.MeshLambertMaterial({ color : fillcolor.getHex(), shading : THREE.NoShading }), wireMaterial ]);
461 bin.position.x = tx(hh.x);
462 bin.position.y = wei / 2;
463 bin.position.z = -(ty(hh.y));
465 if (JSROOT.gStyle.Tooltip)
474 var pointLight =
new THREE.PointLight(0xcfcfcf);
475 pointLight.position.set(0, 50, 250);
476 scene.add(pointLight);
484 var camera =
new THREE.PerspectiveCamera(45, w / h, 1, 1000);
485 camera.position.set(0, size / 2, 500);
486 camera.lookat = cube;
493 canvas : !!window.CanvasRenderingContext2D,
494 webgl : (
function() {
try {
495 return !!window.WebGLRenderingContext && !!document.createElement(
'canvas').getContext(
'experimental-webgl');
500 workers : !!window.Worker,
501 fileapi : window.File && window.FileReader && window.FileList && window.Blob
504 var renderer = Detector.webgl ?
new THREE.WebGLRenderer({ antialias :
true }) :
505 new THREE.CanvasRenderer({ antialias :
true });
506 renderer.setClearColor(0xffffff, 1);
507 renderer.setSize(w, h);
508 $(painter.svg_pad()).hide().parent().append(renderer.domElement);
509 renderer.render(scene, camera);
511 JSROOT.Painter.add3DInteraction(renderer, scene, camera, toplevel, painter);
514 JSROOT.Painter.real_drawHistogram3D =
function(divid, histo, opt) {
516 var logx =
false, logy =
false, logz =
false, gridx =
false, gridy =
false, gridz =
false;
518 var painter =
new JSROOT.TObjectPainter();
519 painter.SetDivId(divid, -1);
520 var pad = painter.root_pad();
523 if (painter.svg_pad())
524 render_to = $(painter.svg_pad()).hide().parent();
526 render_to = $(
"#" + divid);
528 var opt = histo[
'fOption'].toLowerCase();
535 gridx = pad[
'fGridx'];
536 gridy = pad[
'fGridy'];
537 gridz = pad[
'fGridz'];
540 var fillcolor = JSROOT.Painter.root_colors[histo[
'fFillColor']];
541 var linecolor = JSROOT.Painter.root_colors[histo[
'fLineColor']];
542 if (histo[
'fFillColor'] == 0) {
543 fillcolor =
'#4572A7';
545 if (histo[
'fLineColor'] == 0) {
546 linecolor =
'#4572A7';
548 var nbinsx = histo[
'fXaxis'][
'fNbins'];
549 var nbinsy = histo[
'fYaxis'][
'fNbins'];
550 var nbinsz = histo[
'fZaxis'][
'fNbins'];
551 var scalex = (histo[
'fXaxis'][
'fXmax'] - histo[
'fXaxis'][
'fXmin']) / histo[
'fXaxis'][
'fNbins'];
552 var scaley = (histo[
'fYaxis'][
'fXmax'] - histo[
'fYaxis'][
'fXmin']) / histo[
'fYaxis'][
'fNbins'];
553 var scalez = (histo[
'fZaxis'][
'fXmax'] - histo[
'fZaxis'][
'fXmin']) / histo[
'fZaxis'][
'fNbins'];
554 var maxbin = -1e32, minbin = 1e32;
555 maxbin = d3.max(histo[
'fArray']);
556 minbin = d3.min(histo[
'fArray']);
557 var bins =
new Array();
558 for (var i = 0; i <= nbinsx + 2; ++i) {
559 for (var j = 0; j < nbinsy + 2; ++j) {
560 for (var k = 0; k < nbinsz + 2; ++k) {
561 var bin_content = histo.getBinContent(i, j, k);
562 if (bin_content > minbin) {
564 x : histo[
'fXaxis'][
'fXmin'] + (i * scalex),
565 y : histo[
'fYaxis'][
'fXmin'] + (j * scaley),
566 z : histo[
'fZaxis'][
'fXmin'] + (k * scalez),
574 var w = render_to.width(), h = render_to.height(), size = 100;
575 if (h<10) { render_to.height(0.66*w); h = render_to.height(); }
578 var tx = d3.scale.log().domain([ histo[
'fXaxis'][
'fXmin'], histo[
'fXaxis'][
'fXmax'] ]).range( [ -size, size ]);
579 var utx = d3.scale.log().domain([ -size, size ]).range([ histo[
'fXaxis'][
'fXmin'], histo[
'fXaxis'][
'fXmax'] ]);
581 var tx = d3.scale.linear().domain( [ histo[
'fXaxis'][
'fXmin'], histo[
'fXaxis'][
'fXmax'] ]).range( [ -size, size ]);
582 var utx = d3.scale.linear().domain([ -size, size ]).range([ histo[
'fXaxis'][
'fXmin'], histo[
'fXaxis'][
'fXmax'] ]);
585 var ty = d3.scale.log().domain([ histo[
'fYaxis'][
'fXmin'], histo[
'fYaxis'][
'fXmax'] ]).range( [ -size, size ]);
586 var uty = d3.scale.log().domain([ size, -size ]).range([ histo[
'fYaxis'][
'fXmin'], histo[
'fYaxis'][
'fXmax'] ]);
588 var ty = d3.scale.linear().domain( [ histo[
'fYaxis'][
'fXmin'], histo[
'fYaxis'][
'fXmax'] ]).range([ -size, size ]);
589 var uty = d3.scale.linear().domain([ size, -size ]).range([ histo[
'fYaxis'][
'fXmin'], histo[
'fYaxis'][
'fXmax'] ]);
592 var tz = d3.scale.log().domain([ histo[
'fZaxis'][
'fXmin'], histo[
'fZaxis'][
'fXmax'] ]).range([ -size, size ]);
593 var utz = d3.scale.log().domain([ -size, size ]).range([ histo[
'fZaxis'][
'fXmin'], histo[
'fZaxis'][
'fXmax'] ]);
595 var tz = d3.scale.linear().domain([ histo[
'fZaxis'][
'fXmin'], histo[
'fZaxis'][
'fXmax'] ]).range([ -size, size ]);
596 var utz = d3.scale.linear().domain([ -size, size ]).range([ histo[
'fZaxis'][
'fXmin'], histo[
'fZaxis'][
'fXmax'] ]);
600 var scene =
new THREE.Scene();
602 var toplevel =
new THREE.Object3D();
603 toplevel.rotation.x = 30 * Math.PI / 180;
604 toplevel.rotation.y = 30 * Math.PI / 180;
607 var wireMaterial =
new THREE.MeshBasicMaterial({
610 wireframeLinewidth : 0.5,
611 side : THREE.DoubleSide
615 var cube =
new THREE.Mesh(
new THREE.BoxGeometry(size * 2, size * 2, size * 2), wireMaterial);
617 var helper =
new THREE.BoxHelper(cube);
618 helper.material.color.set(0x000000);
621 toplevel.add(helper);
623 var textMaterial =
new THREE.MeshBasicMaterial({ color : 0x000000 });
626 var geometry =
new THREE.Geometry();
627 var imax, istep, len = 3, plen, sin45 = Math.sin(45);
629 var xmajors = tx.ticks(5);
630 var xminors = tx.ticks(25);
631 for (var i = -size, j = 0, k = 0; i <= size; ++i) {
632 var is_major = (utx(i) <= xmajors[j] && utx(i + 1) > xmajors[j]) ?
true :
false;
633 var is_minor = (utx(i) <= xminors[k] && utx(i + 1) > xminors[k]) ?
true :
false;
634 plen = (is_major ? len + 2 : len) * sin45;
636 text3d =
new THREE.TextGeometry(xmajors[j], { size : 7, height : 0, curveSegments : 10 });
639 text3d.computeBoundingBox();
640 var centerOffset = 0.5 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
642 text =
new THREE.Mesh(text3d, textMaterial);
643 text.position.set(i - centerOffset, -size - 13, size + plen);
646 text =
new THREE.Mesh(text3d, textMaterial);
647 text.position.set(i + centerOffset, -size - 13, -size - plen);
648 text.rotation.y = Math.PI;
651 if (is_major || is_minor) {
653 geometry.vertices.push(
new THREE.Vector3(i, -size, size));
654 geometry.vertices.push(
new THREE.Vector3(i, -size - plen, size + plen));
655 geometry.vertices.push(
new THREE.Vector3(i, -size, -size));
656 geometry.vertices.push(
new THREE.Vector3(i, -size - plen, -size - plen));
659 var ymajors = ty.ticks(5);
660 var yminors = ty.ticks(25);
661 for (var i = size, j = 0, k = 0; i > -size; --i) {
662 var is_major = (uty(i) <= ymajors[j] && uty(i - 1) > ymajors[j]) ?
true :
false;
663 var is_minor = (uty(i) <= yminors[k] && uty(i - 1) > yminors[k]) ?
true :
false;
664 plen = (is_major ? len + 2 : len) * sin45;
666 text3d =
new THREE.TextGeometry(ymajors[j], { size : 7, height : 0, curveSegments : 10 });
669 text3d.computeBoundingBox();
670 var centerOffset = 0.5 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
672 text =
new THREE.Mesh(text3d, textMaterial);
673 text.position.set(size + plen, -size - 13, i + centerOffset);
674 text.rotation.y = Math.PI / 2;
677 text =
new THREE.Mesh(text3d, textMaterial);
678 text.position.set(-size - plen, -size - 13, i - centerOffset);
679 text.rotation.y = -Math.PI / 2;
682 if (is_major || is_minor) {
684 geometry.vertices.push(
new THREE.Vector3(size, -size, i));
685 geometry.vertices.push(
new THREE.Vector3(size + plen, -size - plen, i));
686 geometry.vertices.push(
new THREE.Vector3(-size, -size, i));
687 geometry.vertices.push(
new THREE.Vector3(-size - plen, -size - plen, i));
690 var zmajors = tz.ticks(5);
691 var zminors = tz.ticks(25);
692 for (var i = -size, j = 0, k = 0; i <= size; ++i) {
693 var is_major = (utz(i) <= zmajors[j] && utz(i + 1) > zmajors[j]) ?
true :
false;
694 var is_minor = (utz(i) <= zminors[k] && utz(i + 1) > zminors[k]) ?
true :
false;
695 plen = (is_major ? len + 2 : len) * sin45;
697 text3d =
new THREE.TextGeometry(zmajors[j], { size : 7, height : 0, curveSegments : 10 });
700 text3d.computeBoundingBox();
701 var offset = 0.6 * (text3d.boundingBox.max.x - text3d.boundingBox.min.x);
703 text =
new THREE.Mesh(text3d, textMaterial);
704 text.position.set(size + offset + 7, i - 2.5, size + offset + 7);
705 text.rotation.y = Math.PI * 3 / 4;
708 text =
new THREE.Mesh(text3d, textMaterial);
709 text.position.set(size + offset + 7, i - 2.5, -size - offset - 7);
710 text.rotation.y = -Math.PI * 3 / 4;
713 text =
new THREE.Mesh(text3d, textMaterial);
714 text.position.set(-size - offset - 7, i - 2.5, size + offset + 7);
715 text.rotation.y = Math.PI / 4;
718 text =
new THREE.Mesh(text3d, textMaterial);
719 text.position.set(-size - offset - 7, i - 2.5, -size - offset - 7);
720 text.rotation.y = -Math.PI / 4;
723 if (is_major || is_minor) {
725 geometry.vertices.push(
new THREE.Vector3(size, i, size));
726 geometry.vertices.push(
new THREE.Vector3(size + plen, i, size + plen));
727 geometry.vertices.push(
new THREE.Vector3(size, i, -size));
728 geometry.vertices.push(
new THREE.Vector3(size + plen, i, -size - plen));
729 geometry.vertices.push(
new THREE.Vector3(-size, i, size));
730 geometry.vertices.push(
new THREE.Vector3(-size - plen, i, size + plen));
731 geometry.vertices.push(
new THREE.Vector3(-size, i, -size));
732 geometry.vertices.push(
new THREE.Vector3(-size - plen, i, -size - plen));
737 var lineMaterial =
new THREE.LineBasicMaterial({ color : 0x000000 });
738 var line =
new THREE.Line(geometry, lineMaterial);
739 line.type = THREE.LinePieces;
743 var constx = (size * 2 / histo[
'fXaxis'][
'fNbins']) / maxbin;
744 var consty = (size * 2 / histo[
'fYaxis'][
'fNbins']) / maxbin;
745 var constz = (size * 2 / histo[
'fZaxis'][
'fNbins']) / maxbin;
747 var optFlag = (opt.indexOf(
'colz') != -1 || opt.indexOf(
'col') != -1);
748 var fcolor = d3.rgb(JSROOT.Painter.root_colors[histo[
'fFillColor']]);
749 var fillcolor =
new THREE.Color(0xDDDDDD);
750 fillcolor.setRGB(fcolor.r / 255, fcolor.g / 255, fcolor.b / 255);
752 for (var i = 0; i < bins.length; ++i) {
753 wei = (optFlag ? maxbin : bins[i].n);
754 if (opt.indexOf(
'box1') != -1) {
755 bin =
new THREE.Mesh(
new THREE.SphereGeometry(0.5 * wei * constx ),
756 new THREE.MeshPhongMaterial({ color : fillcolor.getHex(), specular : 0xbfbfbf}));
758 bin = THREE.SceneUtils.createMultiMaterialObject(
759 new THREE.BoxGeometry(wei * constx, wei * constz, wei * consty),
760 [
new THREE.MeshLambertMaterial({ color : fillcolor.getHex(), shading : THREE.NoShading }), wireMaterial ]);
762 bin.position.x = tx(bins[i].x - (scalex / 2));
763 bin.position.y = tz(bins[i].z - (scalez / 2));
764 bin.position.z = -(ty(bins[i].y - (scaley / 2)));
765 bin.name =
"x: [" + bins[i].x.toPrecision(4) +
", "
766 + (bins[i].x + scalex).toPrecision(4) +
"]<br/>"
767 +
"y: [" + bins[i].y.toPrecision(4) +
", "
768 + (bins[i].y + scaley).toPrecision(4) +
"]<br/>"
769 +
"z: [" + bins[i].z.toPrecision(4) +
", "
770 + (bins[i].z + scalez).toPrecision(4) +
"]<br/>"
771 +
"entries: " + bins[i].n.toFixed();
775 var pointLight =
new THREE.PointLight(0xcfcfcf);
776 pointLight.position.set(0, 50, 250);
777 scene.add(pointLight);
783 var camera =
new THREE.PerspectiveCamera(45, w / h, 1, 1000);
784 camera.position.set(0, 0, 500);
785 camera.lookat = cube;
792 canvas : !!window.CanvasRenderingContext2D,
793 webgl : (
function() {
795 return !!window.WebGLRenderingContext
796 && !!document.createElement(
'canvas')
797 .getContext(
'experimental-webgl');
802 workers : !!window.Worker,
803 fileapi : window.File && window.FileReader
804 && window.FileList && window.Blob
807 var renderer = Detector.webgl ?
808 new THREE.WebGLRenderer({ antialias :
true }) :
809 new THREE.CanvasRenderer({antialias :
true });
810 renderer.setClearColor(0xffffff, 1);
811 renderer.setSize(w, h);
812 render_to.append(renderer.domElement);
813 renderer.render(scene, camera);
815 JSROOT.Painter.add3DInteraction(renderer, scene, camera, toplevel, null);