Skip to content

Commit efaa885

Browse files
committed
use click events rather than hit testing
1 parent fec60a5 commit efaa885

File tree

1 file changed

+47
-16
lines changed

1 file changed

+47
-16
lines changed

examples/landmark-demo/client/landmark-demo.js

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -148,24 +148,12 @@ Template.d3Demo.right = function () {
148148
return { group: "right" };
149149
};
150150

151-
var hitTest = function (x, y, selector) {
152-
var circles = Circles.find(selector).fetch();
153-
for (var i = 0; i < circles.length; i++) {
154-
var c = circles[i];
155-
var dist2 = (x - c.x) * (x - c.x) + (y - c.y) * (y - c.y);
156-
if (dist2 < c.r*c.r)
157-
return c;
158-
}
159-
return null;
160-
};
161-
162151
Template.circles.events = {
163-
'click svg': function (evt, template) {
164-
var circle = hitTest(evt.offsetX / 200, evt.offsetY / 200,
165-
{group: this.group});
166-
console.log("click " + (circle ? circle._id : "null"));
152+
'click circle': function (evt, template) {
167153
// XXX actually want to create a ReactiveVar on the template!
168-
Session.set("selectedCircle:" + this.group, circle);
154+
// (but how will it be preserved across migration?)
155+
// (maybe template.get, template.set?? rather than form??)
156+
Session.set("selectedCircle:" + this.group, evt.currentTarget.id);
169157
},
170158
'click .add': function () {
171159
Circles.insert({x: Meteor.random(), y: Meteor.random(),
@@ -226,11 +214,53 @@ Template.circles.render = function () {
226214

227215
d3.select(self.node).append("rect");
228216
self.handle = autorun(function () {
217+
// XXX In an ideal world, we'd pass a cursor to .data(), and as
218+
// long as we were within an autorun, the "right thing" would
219+
// happen, meaning that d3 would process only the changed
220+
// elements.
221+
//
222+
// You could model this as a getChanges() method on a cursor,
223+
// which reactively returns the changes since you last called it
224+
// (as an object with added, removed, moved, changed sections.)
225+
// Except you should be able to have N per cursor.
226+
//
227+
// Actually, you could make a function Meteor.getChanges(cursor)
228+
// that returns a changes function that has the above
229+
// properties.
230+
//
231+
// Then, we'd need to reach inside d3's matching logic to make
232+
// it detect a Meteor cursor and call getChanges ...
233+
//
234+
// XXX no, you need one getchanges per cursor per autorun. hmm.
235+
// maybe a factory that memoizes them somehow? but, per autorun?
236+
//
237+
// Maybe:
238+
// var stream = ChangeStream(cursor);
239+
// autorun(function () { d3.select(...).stream(stream) ... }
240+
// Streams are the factory described above. returns ChangeSets
241+
//
242+
// XXX what this doesn't answer is, what if you depend on other
243+
// reactive values, eg Session.get("color")?
244+
//
245+
// XXX why can't we just do this stuff declaratively with
246+
// Handlebars and an <svg> element? what does that imply about
247+
// missing animation support in Spark?
248+
//
249+
// XXX make Session be a ReactiveDict (ReactiveMap?) and put the
250+
// ReactiveDiff impl in packages/deps/tools.js. Keep the
251+
// low-level deps machinery as it is (maybe add invalidation
252+
// sequencing.) Rename Meteor.deps.Context =>
253+
// InvalidationContext.
254+
//
255+
// XXX allow query selectors, sorts, to be lambdas?
229256
var circle = d3.select(self.node).selectAll("circle")
230257
.data(Circles.find({group: data.group}).fetch(),
231258
function (d) { return d._id; });
232259

233260
circle.enter().append("circle")
261+
.attr("id", function (d) {
262+
return d._id;
263+
})
234264
.attr("cx", function (d) {
235265
return d.x * 200;
236266
})
@@ -265,6 +295,7 @@ Template.circles.render = function () {
265295
.attr("r", 0)
266296
.remove();
267297

298+
// XXX this doesn't animate as I'd hoped when you press Scram
268299
var selectionId = Session.get("selectedCircle:" + data.group);
269300
var s = selectionId && Circles.findOne(selectionId);
270301
var rect = d3.select(self.node).select("rect");

0 commit comments

Comments
 (0)