Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
359 lines (303 sloc) 13.2 KB
"""
This file contains baseclasses for thejit widgets
- JitWidget - contains parameters common to all jit widgets
- JitTreeOrGraphWidget - contains parameters common to Tree and Graph Widgets
"""
import tw2.core as twc
from tw2.core.resources import JSLink, CSSLink
from tw2.core.resources import JSSymbol, JSFuncCall
from tw2.core.resources import JSSource
from tw2.core.resources import encoder
from tw2.core.widgets import WidgetMeta
from tw2.core.widgets import Widget
from tw2.jit import jit_base
from tw2.jit.resources import CompoundJSSource
import tw2.jquery
import urllib
# TODO -- the tw2 devtools give me __name__ as tw2.jit.widgets but the resources are all in tw2.jit/static
modname = ".".join(__name__.split('.')[:-1])
modname = "tw2.jit"
# TODO -- what's the right way to choose minified or not in tw2?
jit_yc_js = JSLink(modname=modname, filename="%s/jit-yc.js" % jit_base)
jit_js = JSLink(modname=modname, filename="%s/jit.js" % jit_base)
jit_glue_js = JSLink(modname=modname, filename="static/js/tw2.jit.glue.js")
jit_css = CSSLink(modname=modname, filename="static/css/jit_base.css")
# TODO -- redo all of these with mako so we have examples of that and genshi
class JitWidget(twc.Widget):
""" Baseclass for all other tw2.jit.widgets
Provides a set of parameters common to widgets in the library.
Uses tw2.jit.resources.CompoundJSSource for client-side initialization
"""
# Hide docs from the widget browser. They're very verbose.
_hide_docs = True
template = "tw2.jit.templates.jitwidget"
resources = [jit_js, jit_glue_js]
# Internal twc Variables
jitClassName = twc.Variable('Name of the Jit class for this widget')
jitSecondaryClassName = twc.Variable(
'Secondary Jit class for this widget', default=None)
injectInto = twc.Variable(
'name of the DOM element containing the canvas',
attribute=True, default=property(lambda s: s.compound_id))
config = twc.Variable( 'jsonified version of other attrs.', default={} )
# End internal twc Variables
# Start twc Params
init_delay = twc.Param(
'value in milliseconds to delay js initialization and rendering',
default=0)
postInitJSCallback = twc.Param(
'javascript to run after client-side initialization of the widget',
default=JSSymbol(src='(function(jitwidget){})'), attribute=True)
data = twc.Param('python data to be jsonified and passed to the widget',
default=None, attribute=True)
base_url = twc.Param('url for json data to be loaded into the widget',
default=None, attribute=True)
url_args = twc.Param('dict of keyword args for the json url',
default={}, attribute=True)
url = twc.Variable('internal use only. full json url', attribute=True)
# End twc Params
# Start twc Attributes
backgroundcolor = twc.Param(
'(string) background color of the jit container div',
default='#3a3a3a', attribute=True)
width = twc.Param('(string) widget width', default='750',attribute=True)
height = twc.Param('(string) widget height', default='750',attribute=True)
animate = twc.Param(
'(boolean) Whether to add animated transitions.',
default=True, attribute=True)
transition = twc.Param(
"""javascript symbol of the type of jit transition to use.
All the possible transitions are listed here:
http://thejit.org/static/v20/Docs/files/Options/Options-Fx-js.html#Options.Fx
""",
default=JSSymbol(src="$jit.Trans.Quart.easeOut"), attribute=True)
duration = twc.Param(
'(number) Duration of the animation in milliseconds.',
default=1000, attribute=True)
fps = twc.Param(
'(number) Frames per second of the animation.',
default=45, attribute=True)
offset = twc.Param(
'(number) Margin between the display and the canvas.',
default=25, attribute=True)
Canvas = twc.Param(
'(dict) Of the form Options.Canvas in the jit docs.', attribute=True,
default = {
'width' : False,
'height' : False,
'useCanvas' : False,
'withLabels' : True,
'background' : False
})
Label = twc.Param(
'(dict) Of the form Options.Label in the jit docs.', attribute=True,
default={
'overridable' : False,
'type': 'HTML',
'style' : ' ',
'size': 10,
'family': 'sans-serif',
'textAlign' : 'center',
'textBaseline' : 'alphabetic',
'color': 'white',
})
Tips = twc.Param(
'(dict) Of the form of Options.Tips in the jit docs.', attribute=True,
default={
'enable' : False,
'type' : 'auto',
'offsetX' : 20,
'offsetY' : 20,
'onShow' : "(function() {})",
'onHide' : "(function() {})",
})
Events = twc.Param(
'(dict) Of the form Options.Events in the jit docs.', attribute=True,
default={
'enable': False,
'type': 'auto',
'onClick': '(function() {})',
'onRightClick': '(function() {})',
'onMouseMove': '(function() {})',
'onMouseEnter': '(function() {})',
'onMouseLeave': '(function() {})',
'onDragStart': '(function() {})',
'onDragMove': '(function() {})',
'onDragCancel': '(function() {})',
'onDragEnd': '(function() {})',
'onTouchStart': '(function() {})',
'onTouchMove': '(function() {})',
'onTouchEnd': '(function() {})',
'onTouchCancel': '(function() {})',
'onMouseWheel': '(function() {})'
})
deep_linking = twc.Param(
"""(bool) Use 'deep-linking'.
Only employed by *some* widgets. (AjaxRadialGraph,
SQLARadialGraph).
Warning: This will conflict with and probably break any other
form of deep-linking you may have on the page. Disabled by default.
""", default=False)
jsVariables = twc.Param(
'A dictionary of special jsVariables for substitution',
default={
'$$url': lambda s: s.url,
'$$base_url': lambda s: s.base_url,
'$$jitwidget': lambda s:'window._jitwidgets["%s"]' % s.compound_id,
'$$deep_linking': lambda s: s.deep_linking,
'$$duration': lambda s: s.duration,
'$$transition': lambda s: s.transition.src,
}
)
# End twc attrs
@classmethod
def request(cls, req):
msg = "Subclass of %s must override 'request' for ajax." % cls.__name__
raise UnimplementedError, msg
def prepare(self):
super(JitWidget, self).prepare()
# Some validation
if not self.jitClassName:
msg = "{0.__name__} requires a 'jitClassName'.".format(type(self))
raise ValueError, msg
if not self.data and not self.base_url:
msg = "%s requires 'data' or 'base_url' param." % self.__class__.__name__
raise ValueError, msg
self.url = self.base_url
if getattr(self, 'url_kw', {}):
q_str = urllib.urlencode(self.url_kw)
self.url += '?' + q_str
for k, v in self.attrs.iteritems():
if type(v) in [JSSymbol]:
for var, fun in self.jsVariables.iteritems():
if not var in v.src:
continue
res = fun(self)
if not isinstance(res, basestring):
res = encoder.encode(res)
self.attrs[k] = JSSymbol(
src=self.attrs[k].src.replace(var, res))
setupcall = JSFuncCall(
function='var jitwidget = setupTW2JitWidget',
args=[
self.jitClassName,
self.jitSecondaryClassName,
self.compound_id,
self.attrs
])
if self.data:
# For normal loading
loadcall = JSFuncCall(
function='jitwidget.loadJSON',
args=[self.data],)
postcall = JSSource(
src=self.attrs['postInitJSCallback'].src+'(jitwidget)')
else:
# For asynchronous loading
self.resources.append(tw2.jquery.jquery_js)
loadcall = None
postcall = JSSource(src="""
$.getJSON(
'%s',
function (data) {
// load data when we get it
jitwidget.loadJSON(data);
// Do post-init stuff
%s(jitwidget);
}
);""" % (self.url,
self.attrs['postInitJSCallback'].src))
composite_js_call = CompoundJSSource(
exec_delay=self.init_delay,
setupcall=setupcall,
loadcall=loadcall,
postcall=postcall)
self.resources.append(composite_js_call)
class JitTreeOrGraphWidget(JitWidget):
""" Baseclass common to all Tree and Graph JitWidgets """
# TODO - http://thejit.org/static/v20/Docs/files/Options/Options-Controller-js.html#Options.Controller
Navigation = twc.Param(
'(dict) Panning and zooming options for Graph/Tree visualziations.',
default={
'enable': False,
'type': 'auto',
'panning': False, #True, 'avoid nodes'
'zooming': False
}, attribute=True)
Node = twc.Param(
'(dict) Provides Node rendering options for ' +
'Tree and Graph based visualizations.',
default = {
# 'overridable': False,
# 'type': 'circle',
'color': '#ccb',
'alpha': 1,
'dim': 3,
'height': 20,
'width': 90,
'autoHeight': False,
'autoWidth': False,
'lineWidth': 1,
'transform': True,
'align': "center",
'angularWidth':1,
'span':1,
'CanvasStyles': {}
}, attribute=True)
Edge = twc.Param(
"(dict) Provides Edge rendering options for " +
"Tree and Graph based visualizations.",
default = {
# 'overridable': False,
# 'type': 'line',
'color': '#ccb',
'lineWidth': 1,
'dim':15,
'alpha': 1,
'CanvasStyles': {}
}, attribute=True)
onBeforeCompute = twc.Param(
"(javascript) This method is called right before performing all " +
"computations and animations. The selected Graph.Node " +
"is passed as parameter.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onAfterCompute = twc.Param(
"(javascript) This method is triggered after all animations " +
"or computations ended.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onCreateLabel = twc.Param(
"(javascript) This method receives a new label DIV element as " +
"first parameter, and the corresponding Graph.Node as second " +
"parameter. This method will only be called once for each label. " +
"This method is useful when adding events or styles to the labels " +
"used by the JIT.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onPlaceLabel = twc.Param(
"(javascript) This method receives a label DIV element as first " +
"parameter and the corresponding Graph.Node as second parameter. " +
"This method is called each time a label has been placed in the " +
"visualization, for example at each step of an animation, and thus " +
"it allows you to update the labels properties, such as size or " +
"position. Note that onPlaceLabel will be triggered after updating " +
"the labels positions. That means that, for example, the left and " +
"top css properties are already updated to match the nodes " +
"positions. Width and height properties are not set however.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onBeforePlotNode = twc.Param(
"(javascript) This method is triggered right before plotting " +
"each Graph.Node. This method is useful for changing a node " +
"style right before plotting it.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onAfterPlotNode = twc.Param(
"(javascript) This method is triggered right after plotting " +
"each Graph.Node.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onBeforePlotLine = twc.Param(
"(javascript) This method is triggered right before plotting " +
"a Graph.Adjacence. This method is useful for adding some " +
"styles to a particular edge before being plotted.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
onAfterPlotLine = twc.Param(
"(javascript) This method is triggered right after plotting " +
"a Graph.Adjacence.",
default=JSSymbol(src="(function(node) {})"), attribute=True)
Something went wrong with that request. Please try again.