Browse Source

Animate lol

pull/8/head
Florian Mounier 13 years ago
parent
commit
3b6f6f26a3
  1. 28
      pygal/graph/graph.py
  2. 65
      pygal/js/graph.coffee
  3. 105
      pygal/js/graph.js

28
pygal/graph/graph.py

@ -49,19 +49,21 @@ class Graph(BaseGraph):
self.graph_node, class_="plot tooltip-overlay", self.graph_node, class_="plot tooltip-overlay",
transform="translate(%d, %d)" % ( transform="translate(%d, %d)" % (
self.margin.left, self.margin.top)) self.margin.left, self.margin.top))
self.tooltip_node = self.svg.node(tooltip_overlay, id="tooltip") self.tooltip_node = self.svg.node(tooltip_overlay, id="tooltip",
self.svg.node( transform='translate(0 0)')
self.tooltip_node, 'animateTransform', # self.svg.node(
attributeName='transform', # self.tooltip_node, 'animateTransform',
attributeType='XML', # id="tooltip-slide",
type='translate', # attributeName='transform',
dur='1.5s', # attributeType='XML',
end='indefinite', # type='translate',
begin='indefinite', # calcMode='spline',
from_="0 0", # dur='100ms',
to="100 100", # end='indefinite',
additive="sum", # begin='indefinite',
repeatCount='indefinite') # from_="0 0",
# to="100 100",
# fill='freeze')
self.svg.node(self.tooltip_node, 'rect', self.svg.node(self.tooltip_node, 'rect',
id="tooltip-box", id="tooltip-box",

65
pygal/js/graph.coffee

@ -4,6 +4,36 @@ padding = 5
tooltip_timeout = 0 tooltip_timeout = 0
tooltip_font_size = parseInt("{{ font_sizes.tooltip }}") tooltip_font_size = parseInt("{{ font_sizes.tooltip }}")
class Queue
constructor: (@delay) ->
@queue = []
@running = false
add: (f, args...) ->
@queue.push f: f, a: args
if (!@running)
@running = true
@_back()
_run: (f) ->
if(!f)
@running = false
else
setTimeout (=>
f.f f.a...
@_back()
), @delay
_back: ->
@_run @queue.shift()
clear: ->
if @running
@queue = []
@running = false
tooltip_anim_Q = new Queue 1
has_class = (e, class_name) -> has_class = (e, class_name) ->
return if not e return if not e
cn = e.getAttribute('class').split(' ') cn = e.getAttribute('class').split(' ')
@ -27,6 +57,9 @@ rm_class = (e, class_name) ->
cn.splice(i, 1) cn.splice(i, 1)
e.setAttribute('class', cn.join(' ')) e.setAttribute('class', cn.join(' '))
width = (e) -> (e.getBBox() and e.getBBox().width) or e.offsetWidth
height = (e) -> (e.getBBox() and e.getBBox().height) or e.offsetHeight
svg = (tag) -> document.createElementNS('http://www.w3.org/2000/svg', tag) svg = (tag) -> document.createElementNS('http://www.w3.org/2000/svg', tag)
activate = (elements...) -> activate = (elements...) ->
@ -47,33 +80,49 @@ hover = (elts, over, out) ->
elt.addEventListener('mouseout', out.bind(elt) , false) elt.addEventListener('mouseout', out.bind(elt) , false)
tooltip = (elt) -> tooltip = (elt) ->
tooltip_anim_Q.clear()
clearTimeout(tooltip_timeout) clearTimeout(tooltip_timeout)
_tooltip = __('tooltip') _tooltip = __('tooltip')
# _tooltip.setAttribute('display', 'inline') _tooltip.setAttribute('display', 'inline')
_text = _tooltip.getElementsByTagName('text')[0] _text = _tooltip.getElementsByTagName('text')[0]
_rect = _tooltip.getElementsByTagName('rect')[0] _rect = _tooltip.getElementsByTagName('rect')[0]
value = elt.nextElementSibling value = elt.nextElementSibling
_text.textContent = value.textContent _text.textContent = value.textContent
w = _text.offsetWidth + 2 * padding w = width(_text) + 2 * padding
h = _text.offsetHeight + 2 * padding h = height(_text) + 2 * padding
_rect.setAttribute('width', w) _rect.setAttribute('width', w)
_rect.setAttribute('height', h) _rect.setAttribute('height', h)
_text.setAttribute('x', padding) _text.setAttribute('x', padding)
_text.setAttribute('y', padding + tooltip_font_size) _text.setAttribute('y', padding + tooltip_font_size)
x_elt = value.nextElementSibling x_elt = value.nextElementSibling
y_elt = x_elt.nextElementSibling y_elt = x_elt.nextElementSibling
x = x_elt.textContent x = parseInt(x_elt.textContent)
if has_class(x_elt, 'centered') if has_class(x_elt, 'centered')
x -= w / 2 x -= w / 2
y = y_elt.textContent y = parseInt(y_elt.textContent)
if has_class(y_elt, 'centered') if has_class(y_elt, 'centered')
y -= h / 2 y -= h / 2
_tooltip.setAttribute('transform', "translate(#{x} #{y})")
untooltip = -> 0 [current_x, current_y] = (parseInt(s) for s in _tooltip.getAttribute('transform').replace('translate(', '').replace(')', '').split ' ')
return if current_x == x and current_y == y
step = 20
x_step = (x - current_x) / step
y_step = (y - current_y) / step
anim_x = current_x
anim_y = current_y
for i in [0..step]
anim_x += x_step
anim_y += y_step
tooltip_anim_Q.add ((_x, _y) ->
_tooltip.setAttribute('transform', "translate(#{_x} #{_y})")), anim_x, anim_y
tooltip_anim_Q.add ((_x, _y) ->
_tooltip.setAttribute('transform', "translate(#{_x} #{_y})")), x, y
untooltip = ->
tooltip_timeout = setTimeout (-> tooltip_timeout = setTimeout (->
__('tooltip').setfAttribute('display', 'none')), 1000 __('tooltip').setAttribute('display', 'none')), 1000
@svg_load = -> @svg_load = ->
for text in _('.text-overlay .series') for text in _('.text-overlay .series')

105
pygal/js/graph.js

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.2.1-pre // Generated by CoffeeScript 1.2.1-pre
(function() { (function() {
var activate, add_class, deactivate, has_class, hover, padding, rm_class, svg, tooltip, tooltip_font_size, tooltip_timeout, untooltip, _, __, var Queue, activate, add_class, deactivate, has_class, height, hover, padding, rm_class, svg, tooltip, tooltip_anim_Q, tooltip_font_size, tooltip_timeout, untooltip, width, _, __,
__slice = [].slice; __slice = [].slice;
_ = function(x) { _ = function(x) {
@ -17,6 +17,58 @@
tooltip_font_size = parseInt("{{ font_sizes.tooltip }}"); tooltip_font_size = parseInt("{{ font_sizes.tooltip }}");
Queue = (function() {
Queue.name = 'Queue';
function Queue(delay) {
this.delay = delay;
this.queue = [];
this.running = false;
}
Queue.prototype.add = function() {
var args, f;
f = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
this.queue.push({
f: f,
a: args
});
if (!this.running) {
this.running = true;
return this._back();
}
};
Queue.prototype._run = function(f) {
var _this = this;
if (!f) {
return this.running = false;
} else {
return setTimeout((function() {
f.f.apply(f, f.a);
return _this._back();
}), this.delay);
}
};
Queue.prototype._back = function() {
return this._run(this.queue.shift());
};
Queue.prototype.clear = function() {
if (this.running) {
this.queue = [];
return this.running = false;
}
};
return Queue;
})();
tooltip_anim_Q = new Queue(1);
has_class = function(e, class_name) { has_class = function(e, class_name) {
var cls, cn, i, _i, _len; var cls, cn, i, _i, _len;
if (!e) return; if (!e) return;
@ -47,6 +99,14 @@
return e.setAttribute('class', cn.join(' ')); return e.setAttribute('class', cn.join(' '));
}; };
width = function(e) {
return (e.getBBox() && e.getBBox().width) || e.offsetWidth;
};
height = function(e) {
return (e.getBBox() && e.getBBox().height) || e.offsetHeight;
};
svg = function(tag) { svg = function(tag) {
return document.createElementNS('http://www.w3.org/2000/svg', tag); return document.createElementNS('http://www.w3.org/2000/svg', tag);
}; };
@ -93,30 +153,59 @@
}; };
tooltip = function(elt) { tooltip = function(elt) {
var h, value, w, x, x_elt, y, y_elt, _rect, _text, _tooltip; var anim_x, anim_y, current_x, current_y, h, i, s, step, value, w, x, x_elt, x_step, y, y_elt, y_step, _i, _rect, _ref, _text, _tooltip;
tooltip_anim_Q.clear();
clearTimeout(tooltip_timeout); clearTimeout(tooltip_timeout);
_tooltip = __('tooltip'); _tooltip = __('tooltip');
_tooltip.setAttribute('display', 'inline');
_text = _tooltip.getElementsByTagName('text')[0]; _text = _tooltip.getElementsByTagName('text')[0];
_rect = _tooltip.getElementsByTagName('rect')[0]; _rect = _tooltip.getElementsByTagName('rect')[0];
value = elt.nextElementSibling; value = elt.nextElementSibling;
_text.textContent = value.textContent; _text.textContent = value.textContent;
w = _text.offsetWidth + 2 * padding; w = width(_text) + 2 * padding;
h = _text.offsetHeight + 2 * padding; h = height(_text) + 2 * padding;
_rect.setAttribute('width', w); _rect.setAttribute('width', w);
_rect.setAttribute('height', h); _rect.setAttribute('height', h);
_text.setAttribute('x', padding); _text.setAttribute('x', padding);
_text.setAttribute('y', padding + tooltip_font_size); _text.setAttribute('y', padding + tooltip_font_size);
x_elt = value.nextElementSibling; x_elt = value.nextElementSibling;
y_elt = x_elt.nextElementSibling; y_elt = x_elt.nextElementSibling;
x = x_elt.textContent; x = parseInt(x_elt.textContent);
if (has_class(x_elt, 'centered')) x -= w / 2; if (has_class(x_elt, 'centered')) x -= w / 2;
y = y_elt.textContent; y = parseInt(y_elt.textContent);
if (has_class(y_elt, 'centered')) y -= h / 2; if (has_class(y_elt, 'centered')) y -= h / 2;
return _tooltip.setAttribute('transform', "translate(" + x + " " + y + ")"); _ref = (function() {
var _i, _len, _ref, _results;
_ref = _tooltip.getAttribute('transform').replace('translate(', '').replace(')', '').split(' ');
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
s = _ref[_i];
_results.push(parseInt(s));
}
return _results;
})(), current_x = _ref[0], current_y = _ref[1];
if (current_x === x && current_y === y) return;
step = 20;
x_step = (x - current_x) / step;
y_step = (y - current_y) / step;
anim_x = current_x;
anim_y = current_y;
for (i = _i = 0; 0 <= step ? _i <= step : _i >= step; i = 0 <= step ? ++_i : --_i) {
anim_x += x_step;
anim_y += y_step;
tooltip_anim_Q.add((function(_x, _y) {
return _tooltip.setAttribute('transform', "translate(" + _x + " " + _y + ")");
}), anim_x, anim_y);
}
return tooltip_anim_Q.add((function(_x, _y) {
return _tooltip.setAttribute('transform', "translate(" + _x + " " + _y + ")");
}), x, y);
}; };
untooltip = function() { untooltip = function() {
return 0; return tooltip_timeout = setTimeout((function() {
return __('tooltip').setAttribute('display', 'none');
}), 1000);
}; };
this.svg_load = function() { this.svg_load = function() {

Loading…
Cancel
Save