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",
transform="translate(%d, %d)" % (
self.margin.left, self.margin.top))
self.tooltip_node = self.svg.node(tooltip_overlay, id="tooltip")
self.svg.node(
self.tooltip_node, 'animateTransform',
attributeName='transform',
attributeType='XML',
type='translate',
dur='1.5s',
end='indefinite',
begin='indefinite',
from_="0 0",
to="100 100",
additive="sum",
repeatCount='indefinite')
self.tooltip_node = self.svg.node(tooltip_overlay, id="tooltip",
transform='translate(0 0)')
# self.svg.node(
# self.tooltip_node, 'animateTransform',
# id="tooltip-slide",
# attributeName='transform',
# attributeType='XML',
# type='translate',
# calcMode='spline',
# dur='100ms',
# end='indefinite',
# begin='indefinite',
# from_="0 0",
# to="100 100",
# fill='freeze')
self.svg.node(self.tooltip_node, 'rect',
id="tooltip-box",

65
pygal/js/graph.coffee

@ -4,6 +4,36 @@ padding = 5
tooltip_timeout = 0
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) ->
return if not e
cn = e.getAttribute('class').split(' ')
@ -27,6 +57,9 @@ rm_class = (e, class_name) ->
cn.splice(i, 1)
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)
activate = (elements...) ->
@ -47,33 +80,49 @@ hover = (elts, over, out) ->
elt.addEventListener('mouseout', out.bind(elt) , false)
tooltip = (elt) ->
tooltip_anim_Q.clear()
clearTimeout(tooltip_timeout)
_tooltip = __('tooltip')
# _tooltip.setAttribute('display', 'inline')
_tooltip.setAttribute('display', 'inline')
_text = _tooltip.getElementsByTagName('text')[0]
_rect = _tooltip.getElementsByTagName('rect')[0]
value = elt.nextElementSibling
_text.textContent = value.textContent
w = _text.offsetWidth + 2 * padding
h = _text.offsetHeight + 2 * padding
w = width(_text) + 2 * padding
h = height(_text) + 2 * padding
_rect.setAttribute('width', w)
_rect.setAttribute('height', h)
_text.setAttribute('x', padding)
_text.setAttribute('y', padding + tooltip_font_size)
x_elt = value.nextElementSibling
y_elt = x_elt.nextElementSibling
x = x_elt.textContent
x = parseInt(x_elt.textContent)
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
_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').setfAttribute('display', 'none')), 1000
__('tooltip').setAttribute('display', 'none')), 1000
@svg_load = ->
for text in _('.text-overlay .series')

105
pygal/js/graph.js

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.2.1-pre
(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;
_ = function(x) {
@ -17,6 +17,58 @@
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) {
var cls, cn, i, _i, _len;
if (!e) return;
@ -47,6 +99,14 @@
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) {
return document.createElementNS('http://www.w3.org/2000/svg', tag);
};
@ -93,30 +153,59 @@
};
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);
_tooltip = __('tooltip');
_tooltip.setAttribute('display', 'inline');
_text = _tooltip.getElementsByTagName('text')[0];
_rect = _tooltip.getElementsByTagName('rect')[0];
value = elt.nextElementSibling;
_text.textContent = value.textContent;
w = _text.offsetWidth + 2 * padding;
h = _text.offsetHeight + 2 * padding;
w = width(_text) + 2 * padding;
h = height(_text) + 2 * padding;
_rect.setAttribute('width', w);
_rect.setAttribute('height', h);
_text.setAttribute('x', padding);
_text.setAttribute('y', padding + tooltip_font_size);
x_elt = value.nextElementSibling;
y_elt = x_elt.nextElementSibling;
x = x_elt.textContent;
x = parseInt(x_elt.textContent);
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;
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() {
return 0;
return tooltip_timeout = setTimeout((function() {
return __('tooltip').setAttribute('display', 'none');
}), 1000);
};
this.svg_load = function() {

Loading…
Cancel
Save