blob: bea477a35175bf528c8edcc3ba2e453d179b4bed [file] [log] [blame]
/******************************************************************************
* Copyright � 2010-2011 Austin Riddle and others.
* All Rights Reserved.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Austin Riddle - initial API and implementation
* Austin Riddle (Texas Center for Applied Technology) -
* data passing and widget scaling
*
*
*****************************************************************************/
qx.Class.define("org.eclipse.rap.rwt.visualization.jit.TreeMap",
{ extend :qx.ui.layout.CanvasLayout,
construct : function(id,type) {
this.base(arguments);
this.setHtmlProperty("id", id);
this._id = id;
this._viz = null;
this._type = type;
},
properties : {
visible : {
init :"",
apply :"load"
},
widgetData : {
init :"",
apply :"refreshData"
}
},
destruct : function() {
},
members : {
_doActivate : function() {
var shell = null;
var parent = this.getParent();
while (shell == null && parent != null) {
if (parent.classname == "org.eclipse.swt.widgets.Shell") {
shell = parent;
}
parent = parent.getParent();
}
if (shell != null) {
shell.setActiveChild(this);
}
},
load : function() {
var parent = this;
try {
var vis = this.getVisible();
if (vis == "false") {
// make invisible
return;
}
qx.ui.core.Widget.flushGlobalQueues();
if (this._viz == null) {
this.info("Creating treemap.");
var qParent = document.getElementById(this._id);
var vizParent = document.createElement("div");
var vizId = "vizParent"+this._id;
vizParent.setAttribute("id", vizId);
vizParent.setAttribute("style","position:absolute;overflow:hidden;display:table-cell;width:100%;vertical-align:middle;height:100%;z-order:auto;");
qParent.appendChild(vizParent);
var vizStyle = "#infovis div {position:absolute;overflow:hidden;font-size:11px;font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;}#infovis .content {background-color:#333;border:0px solid #111;} #infovis .head {color:white;background-color:#444;} #infovis .head.in-path {background-color:#655;} #infovis .body {background-color:black;} #infovis .leaf {color:white;background-color:#111;display:table-cell;vertical-align:middle;border:1px solid #000;} #infovis .over-leaf {border:1px solid #9FD4FF;} #infovis .over-content {background-color: #9FD4FF;} #infovis .over-head {background-color:#A4D9FF;color:black;} .tip {color: #fff;width: 139px;background-color: black;opacity:0.9;filter:alpha(opacity=90);font-size:10px;font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;padding:7px;} .album {width:100px;margin:3px;} input {font-size:10px;font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;}";
vizStyle = vizStyle.replace(/infovis/gi,vizId);
qx.html.StyleSheet.createElement(vizStyle);
var config = {
titleHeight: 13,
//The id of the treemap container
rootId: vizId,
//Set the max. depth to be shown for a subtree
levelsToShow: 1,
offset:1,
//Add click handlers for
//zooming the Treemap in and out
addLeftClickHandler: true,
addRightClickHandler: true,
//When hovering a node highlight the nodes
//between the root node and the hovered node. This
//is done by adding the 'in-path' CSS class to each node.
selectPathOnHover: true,
Color: {
//Allow coloring
allow: true,
//Set min value and max value constraints
//for the *$color* property value.
//Default's to -100 and 100.
minValue: 1,
maxValue: 50,
//Set color range. Default's to reddish and greenish.
//It takes an array of three
//integers as R, G and B values.
minColorValue: [0, 255, 50],
maxColorValue: [255, 0, 50]
},
//Allow tips
Tips: {
allow: true,
//add positioning offsets
offsetX: 20,
offsetY: 20,
//implement the onShow method to
//add content to the tooltip when a node
//is hovered
onShow: function(tip, node, isLeaf, domElement) {
tip.innerHTML = "<div>" + node.name + "</div>" +
"<div>" + this.makeHTMLFromData(node.data) + "</div>";
},
//Aux method: Build the tooltip inner html by using the data property
makeHTMLFromData: function(data){
var html = '';
html += "playcount" + ': ' + data.$area + '<br />';
if ("$color" in data)
html += "rank" + ': ' + data.$color + '<br />';
if ("image" in data)
html += "<img src=\"" + data.image + "\" />";
return html;
}
},
//Implement this method for retrieving a requested
//subtree that has as root a node with id = nodeId,
//and level as depth. This method could also make a server-side
//call for the requested subtree. When completed, the onComplete
//callback method should be called.
// request: function(nodeId, level, onComplete){
// this.info("Refreshing treemap child.");
// var data = this.getWidgetData();
//// this.info(data);
//// if (data != undefined) {
//// var root = data.substring(0,data.length);
//// var subtree = TreeUtil.getSubtree(root, nodeId);
//// TreeUtil.prune(subtree, 1);
//// onComplete.onComplete(nodeId, subtree);
//// }
// },
//Remove all events for the element before destroying it.
onDestroyElement: function(content, tree, isLeaf, leaf){
if(leaf.clearAttributes) leaf.clearAttributes();
}
};
var tm = null;
if (this._type == 2) {
tm = new TM.Strip(config);
}
else if (this._type == 1) {
tm = new TM.Squarified(config);
}
else {
tm = new TM.SliceAndDice(config);
}
// tm.onLeftClick = function(elem) {
// this.enter(elem);
// var node = elem;
// qParent.selection = node;
// //fire selection event
// var req = org.eclipse.swt.Request.getInstance();
// req.addParameter(widgetId + ".selectedNode", node.id);
// req.addEvent( "org.eclipse.swt.events.widgetSelected", widgetId );
// req.send();
// };
//
// tm.onRightClick = function() {
// this.out();
// qParent.selection = node;
// //fire selection event
// var req = org.eclipse.swt.Request.getInstance();
// req.addParameter(widgetId + ".selectedNode", this.shownTree.id);
// req.addEvent( "org.eclipse.swt.events.widgetSelected", widgetId );
// req.send();
//
// };
this.addEventListener("changeWidth", function(e) {
vizParent.width = this.getWidth();
qx.client.Timer.once(function() {
parent.refreshData();
},this,100);
});
this.addEventListener("changeHeight", function(e) {
vizParent.height = this.getHeight();
qx.client.Timer.once(function() {
parent.refreshData();
},this,100);
});
this._viz = tm;
this._vizParent = vizParent;
//This is a hack to ensure that a refresh is called after the style tag above is
//initialized
qx.client.Timer.once(function() {
this.refreshData();
},this,100);
}
}
catch (e) {
this.info(e);
}
},
addTreeEvent : function (obj, type, fn) {
if (obj.addEventListener) obj.addEventListener(type, fn, false);
else obj.attachEvent('on' + type, fn);
},
refreshData : function () {
try {
var tm = this._viz;
if (tm != null) {
var data = this.getWidgetData();
if (data != null) {
this.info("Loading treemap data.");
tm.loadJSON(data);
this.info("Refreshing treemap.");
}
}
}
catch (e) {
this.info(e);
}
},
selectNode : function (id) {
try {
var tm = this._viz;
if (tm != null) {
tm.onLeftClick(id);
}
}
catch (e) {
this.info(e);
}
},
_doResize : function() {
qx.ui.core.Widget.flushGlobalQueues();
}
}
});