25
25
'#zoom-in-btn': {click: 'zoom_in'}
28
zoom: {callback: 'zoomHandler'},
29
rendered: {callback: 'renderedHandler'}
29
rendered: 'renderedHandler'
33
initializer: function(options) {
34
PanZoomModule.superclass.constructor.apply(this, arguments);
35
this._translate = [0, 0];
39
// Handler for 'zoom' event.
40
zoomHandler: function(evt) {
42
vis = this.get('component').vis;
44
s.set('value', Math.floor(evt.scale * 100));
45
this.rescale(vis, evt);
33
componentBound: function() {
34
var topo = this.get('component'),
35
options = topo.options;
37
this.toScale = d3.scale.linear()
38
.domain([options.minZoom, options.maxZoom])
41
this.toSlider = d3.scale.linear()
43
.range([options.minZoom, options.maxZoom])
48
47
renderSlider: function() {
50
49
topo = this.get('component'),
52
currentScale = topo.get('scale');
50
options = topo.options,
51
currentScale = topo.get('scale'),
57
// Build a slider to control zoom level
59
value = currentScale * 100;
61
var slider = new Y.Slider({
58
slider = new Y.Slider({
61
value: this.toSlider(currentScale)
63
// XXX: selection to module option
66
64
slider.render('#slider-parent');
67
65
topo.recordSubscription(this,
68
66
slider.after('valueChange', function(evt) {
69
// Don't fire a zoom if there's a zoom event
70
// already in progress; that will run rescale
72
67
if (d3.event && d3.event.scale &&
73
68
d3.event.translate) {
77
evt.newVal - evt.prevVal) / 100);
71
self._fire_zoom(self.toScale(evt.newVal));
83
PanZoomModule.superclass.update.apply(this, arguments);
76
// Handler for 'zoom' event.
77
zoomHandler: function(evt) {
78
var slider = this.slider,
79
topo = this.get('component'),
80
height = topo.get('height'),
81
width = topo.get('width'),
82
options = topo.options;
87
slider.set('value', this.toSlider(evt.scale));
88
this.rescale(d3.event);
99
103
zoom_in: function(data, context) {
100
104
var slider = context.slider,
101
val = slider.get('value');
105
val = slider.get('value');
102
106
slider.set('value', val + 25);
106
110
* Wrapper around the actual rescale method for zoom buttons.
108
_fire_zoom: function(delta) {
112
_fire_zoom: function(scale) {
109
113
var topo = this.get('component'),
111
115
zoom = topo.zoom,
116
rect = topo.zoomPlane,
120
delta = scale - topo.get('scale');
114
122
// Build a temporary event that rescale can use of a similar
115
123
// construction to d3.event.
116
evt.translate = zoom.translate();
117
evt.scale = zoom.scale() + delta;
119
125
// Update the scale in our zoom behavior manager to maintain state.
120
zoom.scale(evt.scale);
126
zoom.scale(Math.floor(scale));
122
127
// Update the translate so that we scale from the center
123
128
// instead of the origin.
124
var rect = vis.select('rect');
125
evt.translate[0] -= parseInt(rect.attr('width'), 10) / 2 * delta;
126
evt.translate[1] -= parseInt(rect.attr('height'), 10) / 2 * delta;
129
evt.translate = zoom.translate();
130
evt.translate[0] -= (parseInt(rect.attr('width'), 10) / 2) * delta;
131
evt.translate[1] -= (parseInt(rect.attr('height'), 10) / 2) * delta;
127
132
zoom.translate(evt.translate);
129
this.rescale(vis, evt);
133
138
* Rescale the visualization on a zoom/pan event.
135
rescale: function(vis, evt) {
140
rescale: function(evt) {
136
141
// Make sure we don't scale outside of our bounds.
137
142
// This check is needed because we're messing with d3's zoom
138
143
// behavior outside of mouse events (e.g.: with the slider),
139
144
// and can't trust that zoomExtent will play well.
140
var new_scale = Math.floor(evt.scale * 100),
141
topo = this.get('component');
145
var topo = this.get('component'),
146
options = topo.options,
143
if (new_scale < 25 || new_scale > 200) {
144
evt.scale = topo.get('scale');
153
evt.scale = this.toSlider(evt.scale) / 100.0;
146
155
// Store the current value of scale so that it can be restored later.
147
this._scale = evt.scale;
156
topo.set('scale', evt.scale);
148
157
// Store the current value of translate as well, by copying the event
149
158
// array in order to avoid reference sharing.
150
this._translate = Y.mix(evt.translate);
151
vis.attr('transform', 'translate(' + evt.translate + ')' +
152
' scale(' + evt.scale + ')');
159
topo.set('translate', Y.mix(evt.translate));
160
vis.attr('transform', 'translate(' + topo.get('translate') + ')' +
161
' scale(' + topo.get('scale') + ')');
153
162
topo.fire('rescaled');
157
166
// Preserve zoom when the scene is updated.
158
167
var topo = this.get('component'),
160
currentScale = this._scale,
161
currentTranslate = this._translate;
169
currentScale = topo.get('scale'),
170
currentTranslate = topo.get('translate');
163
172
this.renderSlider();
164
173
if (currentTranslate && currentTranslate !== topo.get('translate')) {