Skip to content

Instantly share code, notes, and snippets.

@poezn
Created June 21, 2013 21:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poezn/5834400 to your computer and use it in GitHub Desktop.
Save poezn/5834400 to your computer and use it in GitHub Desktop.
Temperature Timeline
{"description":"Temperature Timeline","endpoint":"","display":"svg","public":true,"require":[{"name":"Backbone","url":"http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"}],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"structure.svg":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"model.js":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01}
var Model = Backbone.Model.extend({
defaults: {
"month": 5,
"year": 1989,
"isDragging": false
},
nextMonth: function() {
var month = this.get("month");
var year = this.get("year");
month++;
console.log('next month', month, year);
if (month > 12) {
month = month % 12;
year++;
}
this.set({
"month": month,
"year": year
});
},
getCurrentDate: function() {
return new Date(this.get("year"), this.get("month"), 1);
},
setCurrentDate: function(dt) {
this.set({
"month": dt.getMonth(),
"year": dt.getFullYear()
})
}
});
var MagnifierView = Backbone.View.extend({
numMonthsMagnified: 6,
widthMagnifier: 100,
initialize: function() {
_.bindAll(this, "render", "renderMonthSelector", "_drag", "_dragend");
this.monthWidth = this.widthMagnifier / (this.numMonthsMagnified * 2 + 1),
this.drag = d3.behavior.drag()
.on("drag", this._drag)
.on("dragend", this._dragend)
;
this.model.on("change:year", this.render);
this.model.on("change:month", this.render);
},
_drag: function(d, i) {
var origin = timelineScale(this.model.getCurrentDate());
var tx = d3.event.x - 50;
var targetDate = timelineScale.invert(tx);
var widthMagnifier = this.widthMagnifier;
var monthWidth = this.monthWidth;
// move magnifier
d3.select(this.el).attr("transform", function(d,i){
return "translate(" + [tx, 20] + ")"
})
// hide month selector
d3.select(this.el).selectAll("#months")
.style({
opacity: 0
});
// =============
// update month and year display
var year = d3.select(this.el).select("#years text");
year.text(targetDate.getFullYear())
d3.select(this.el).select("text.month")
.text(monthLabels[targetDate.getMonth()])
// ========
// update model
this.model.set({
"isDragging": true
});
return false;
},
_dragend: function(d, i) {
if (this.model.get("isDragging") === false) {
return;
}
var xNew = d3.event.sourceEvent.x - 50;
var dtNew = timelineScale.invert(xNew);
// ======
// update model
this.model.set({
"month": dtNew.getMonth(),
"year": dtNew.getFullYear() ,
"isDragging": false
});
var model = this.model;
this.renderMonthSelector();
return false;
},
renderMonthSelector: function() {
// =============
// display month selector
var monthsMagnified = d3.time.months(
d3.time.month.offset(this.model.getCurrentDate(), -1*this.numMonthsMagnified),
d3.time.month.offset(this.model.getCurrentDate(), this.numMonthsMagnified + 1)
);
var monthWidth = this.monthWidth;
var g = d3.select(this.el);
var gMonths = g.select("#months");
gMonths.style({
"opacity": 1
});
var months = gMonths.selectAll("rect.month-magnified")
.data(monthsMagnified, function(d, i) { return +d });
months.exit().remove();
months.enter().append("rect").attr({
"class": "month-magnified",
"x": function(d, i) {
return i * monthWidth
},
"y": 0,
"width": function(d, i) {
return monthWidth - 0.5;
},
"height": this.widthMagnifier
});
months.attr({
"class": function(d, i) {
var cls = ["month-magnified"];
if (d - model.getCurrentDate() === 0) {
cls.push("current");
}
return cls.join(" ")
},
"x": function(d, i) {
return i * monthWidth
},
"y": 0,
"width": function(d, i) {
return monthWidth - 0.5;
},
"height": this.widthMagnifier
})
.on("mouseover", function(d, i) {
var tx = (i + 0.5) * monthWidth;
var ty = 120;
var month = monthLabels[d.getMonth()];
var curr = d;
d3.selectAll("rect.month-magnified")
.classed("current", function(d, i) {
return d == curr;
})
d3.select("#date-magnifier text.month")
.text(function(d, i) {
return month;
})
})
.on("click", function(d, i) {
model.setCurrentDate(d);
d3.event.stopPropagation()
})
},
render: function() {
var currentDate = this.model.getCurrentDate();
var tx = timelineScale(currentDate) - this.widthMagnifier / 2 + 50
d3.select(this.el)
.attr("transform", function(d,i){
return "translate(" + [tx, 20] + ")"
})
.call(this.drag);
this.renderMonthSelector();
}
});
var monthLabels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var model = new Model();
var magnifier = new MagnifierView({"model": model, "el": "#date-magnifier"});
// =========
var timelineWidth = 586;
var dateEarliest = new Date(1900, 0, 1),
dateLatest = new Date(2013, 3, 1)
var months = d3.time.months(dateEarliest, dateLatest);
var years = d3.time.years(dateEarliest, dateLatest);
var timelineScale = d3.time.scale()
.domain([dateEarliest, dateLatest])
.range([0, timelineWidth]);
g = g.select("#timeline")
g.append("rect")
.attr({
"width": timelineWidth,
"height": 40
})
.style({
"fill": "#9B9B9B",
"opacity": 0.1
})
var months = g.selectAll("circle.month-tick")
.data(years)
.enter().append("circle")
.attr({
"class": function(d, i) {
var cls = ["year-tick"]
if (d.getFullYear() % 10 === 0) {
cls.push("decade");
}
return cls.join(" ")
},
"cx": timelineScale,
"cy": 20,
"r": function(d, i) {
if (d.getFullYear() % 10 === 0) {
return 3;
}
return 2
}
});
magnifier.render();
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
#display {
background-color: #111431
}
.year-tick {
stroke: #FFFFFF;
fill: #BDBDBD;
}
.year-tick.decade {
fill: #818285;
}
.month-magnified {
fill: #4C4D4F;
}
.month-magnified.current {
stroke: #1F7DC0;
fill: white
}
#date-magnifier .background {
fill: #2b2834;
stroke-opacity: 0.2;
opacity: 0.8;
stroke: #818285;
}
#date-magnifier text {
fill: #FFF;
font-size: 12px;
}
#months {
/*display: none*/
}
#years .year {
font-size: 22px;
fill: #000000;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment