Comparing version 0.0.28 to 0.1.0
@@ -6,5 +6,9 @@ var ChartModel = require("./lib/ChartModel"); | ||
this.model = new ChartModel(options); | ||
if (options.type === undefined) { | ||
throw new Error('When instantiating a chart, please specify the type'); | ||
} | ||
this.view = new ChartView({ | ||
this.model = new ChartModel[options.type](options); | ||
this.view = new ChartView[options.type]({ | ||
model: this.model | ||
@@ -11,0 +15,0 @@ }); |
@@ -1,191 +0,2 @@ | ||
/** | ||
* Chart Model | ||
* | ||
* Holds all pertinent state information about the chart. | ||
*/ | ||
var _ = require('underscore'), Backbone = require('backbone'); | ||
var Plots = require('./Plots'); | ||
var Data = require('./Data'); | ||
var x_formats = require('./x_formatters'); | ||
var ChartModel = Backbone.Model.extend({ | ||
defaults: { | ||
multi_y: false, | ||
mode: "line", | ||
vp_width: 500, | ||
vp_height: 300, | ||
min_spacing_y: 75, | ||
min_spacing_x: 225, | ||
data: [], | ||
render_x: true, | ||
render_y: true, | ||
x_key: "", | ||
x_formatter: "", | ||
x_formatter_fn: undefined, | ||
x_ascending: true, | ||
draw_guides: true, | ||
dot_radius: 3, | ||
dot_hover_radius:7, | ||
resizer: true | ||
}, | ||
initialize: function(attrs, options) { | ||
// Check for predefined x formatters | ||
if (attrs.x_formatter) { | ||
this.setXFormatter(attrs.x_formatter); | ||
} | ||
// Listen for changes to x_formatter | ||
this.on('change:x_formatter', function(model, formatter){ | ||
this.setXFormatter(formatter); | ||
}); | ||
this.set('data',new Data(attrs.data, {chart: this})); | ||
this.loadStoredInfo(); | ||
this.plots = new Plots([], { chart: this }); | ||
}, | ||
x_formats: x_formats, | ||
setXFormatter: function(formatter) { | ||
if (typeof formatter !== 'function') { | ||
if (this.x_formats[formatter] === undefined) { | ||
// throw new Error('X formatter string not found in this charted version'); | ||
return; | ||
} | ||
formatter = this.x_formats[formatter]; | ||
} | ||
this.set('x_formatter_fn', formatter); | ||
}, | ||
// Some sensible default validation | ||
validate: function(attrs) { | ||
if (attrs.vp_width < 100 || attrs.vp_width > 2000) return "Viewport must have a reasonable width"; | ||
if (attrs.vp_height < 100 || attrs.vp_height > 2000) return "Viewport must have a reasonable width"; | ||
}, | ||
serialize: function() { | ||
var json = this.toJSON(); | ||
json['plots'] = this.plots.toJSON(); | ||
delete json['x_formatter_fn']; | ||
return json; | ||
}, | ||
// Tells the chart to plot the key on the data objects. | ||
// The lowerY and upperY params can either be the string | ||
// "auto" or numeric values. | ||
// The max detail option can be set to override the chart detail value | ||
// for this specific key. If only two arguments are present, | ||
// the second is assummed to be this. | ||
plot: function(attrs) { | ||
var plots = [].concat(attrs); | ||
for (var i = plots.length - 1; i >= 0; i--){ | ||
var plot = plots[i]; | ||
plot.label = plot.label || plot.key; | ||
this.plots.add(plot, {merge: true, chart: this} ); | ||
}; | ||
}, | ||
// Removes plot key from the plots hash. | ||
unplot: function(key) { | ||
var model = this.plots.get(key); | ||
if (model) { | ||
this.plots.remove(model); | ||
model.destroy(); | ||
} | ||
}, | ||
// This function looks up any and all values that should be restored from previous sessions. | ||
loadStoredInfo: function() { | ||
var chart_id = this.get("id"); | ||
if (!chart_id) return; | ||
// Check for viewport width and height | ||
var prevWidth = this.state('vp_width'); | ||
var prevHeight = this.state('vp_height'); | ||
if (prevWidth) this.set('vp_width', prevWidth); | ||
if (prevHeight) this.set('vp_height', prevHeight); | ||
}, | ||
// Set or get an attribute in localStorage | ||
state: function(key, value) { | ||
var storage_key = 'charted.'+this.get("id"); | ||
var store = this.store || localStorage.getItem(storage_key) || {}; | ||
if (typeof store !== "object") { | ||
try { | ||
store = JSON.parse(store); | ||
} catch(e) { | ||
store = {}; | ||
} | ||
} | ||
this.store = store; | ||
if (value !== undefined) { | ||
store[key] = value; | ||
localStorage.setItem(storage_key, JSON.stringify(store)); | ||
return this; | ||
} else { | ||
return store[key]; | ||
} | ||
}, | ||
getNumYGuides: function() { | ||
return Math.max( 2, Math.floor(this.get('vp_height')/this.get('min_spacing_y')) ); | ||
}, | ||
getYGuideInterval: function(num) { | ||
num = num === undefined ? this.getNumYGuides() : num; | ||
return Math.round( (this.get('vp_height')*10) / (num - 1) )/10; | ||
}, | ||
getNumXGuides: function() { | ||
return Math.max( 2, Math.floor(this.get('vp_width')/this.get('min_spacing_x')) ); | ||
}, | ||
getXGuideInterval: function(num) { | ||
num = num === undefined ? this.getNumXGuides() : num; | ||
return Math.round( this.get('vp_width')/(num-1) ); | ||
}, | ||
scheduleFunction: function(key, fn, delay) { | ||
this.__schedule__ = this.__schedule__ || {}; | ||
if (this.__schedule__[key] !== undefined) clearTimeout(this.__schedule__[key]); | ||
this.__schedule__[key] = setTimeout(fn,delay); | ||
}, | ||
unscheduleFunction: function(key) { | ||
if (this.__schedule__ === undefined) return; | ||
clearTimeout(this.__schedule__[key]); | ||
delete this.__schedule__[key]; | ||
}, | ||
destroy: function() { | ||
// Ensure that no circular references will crop up | ||
this.trigger('destroy'); | ||
this.plots = undefined; | ||
this.unset('data'); | ||
} | ||
}); | ||
exports = module.exports = ChartModel; | ||
exports.line = require('./Line/LineChartModel'); | ||
exports.candle = require('./Candle/CandleChartModel'); |
@@ -1,125 +0,2 @@ | ||
/** | ||
* Chart View | ||
* | ||
* Main backbone view that holds all elements and subviews of module | ||
*/ | ||
var kt = require('knights-templar'); | ||
var _ = require('underscore'); | ||
var Viewport = require('./Viewport'); | ||
var YaxesView = require('./YaxesView'); | ||
var XaxisView = require('./XaxisView'); | ||
var bassview = require('bassview'); | ||
var ChartView = bassview.extend({ | ||
className: 'charted-ctnr', | ||
initialize: function() { | ||
// Initialize all subviews | ||
this.subview( 'viewport', new Viewport({ | ||
model: this.model, | ||
collection: this.model.get('data'), | ||
plots: this.model.plots, | ||
rootView: this } | ||
)); | ||
if (this.model.get('render_y')) { | ||
this.subview( 'yaxes', new YaxesView({ | ||
model: this.model, | ||
collection: this.model.plots, | ||
data: this.model.get('data') | ||
})); | ||
} | ||
if (this.model.get('render_x')) { | ||
this.subview( 'xaxis', new XaxisView({ | ||
model: this.model, | ||
collection: this.model.plots, | ||
data: this.model.get('data') | ||
})); | ||
} | ||
// Listeners | ||
this.listenTo(this.model, 'trigger_render change:vp_height', this.render); | ||
this.listenTo(this.model, 'change:multi_y', this.toggleMultiY) | ||
this.listenTo(this.model.get('data'), 'add remove reset update', this.render); | ||
this.listenTo(this.model, 'destroy', this.remove); | ||
}, | ||
// Override of setElement because we want | ||
// a single inner table inside this.$el. | ||
// This is to solve a horizontal scrollbar | ||
// issue when data is being re-rendered. | ||
setElement: function(element, delegate) { | ||
// Call parent setElement | ||
bassview.prototype.setElement.call(this, element, delegate); | ||
// Create inner table | ||
this.$inner = $('<table class="chart-inner"></table>'); | ||
this.$el.html(this.$inner); | ||
return this; | ||
}, | ||
render: function() { | ||
if (this.model.get('no_render')) { | ||
return this; | ||
} | ||
this.lockDimensions(); | ||
// For other elements to do things before render process | ||
this.model.trigger('before_render'); | ||
// Set up markup | ||
var json = this.model.toJSON(); | ||
var markup = this.template(json); | ||
// Replace html | ||
this.$inner.html(markup); | ||
// Assign subviews | ||
this.assign('.chart-viewport','viewport'); | ||
if (json.render_y) { | ||
this.assign('.chart-yaxes','yaxes'); | ||
} | ||
if (json.render_x) { | ||
this.assign('.chart-xaxis','xaxis'); | ||
} | ||
this.unlockDimensions(); | ||
return this; | ||
}, | ||
toggleMultiY: function() { | ||
this.lockDimensions(); | ||
var yaxes = this.subview('yaxes'); | ||
if (yaxes) yaxes.toggleMultiY(); | ||
}, | ||
lockDimensions: function() { | ||
// Lock height to prevent scrollbar craziness | ||
var new_height = this.$('.chart-xaxis').height() + this.model.get('vp_height'); | ||
var new_width = this.$('.chart-yaxes').width() + this.model.get('vp_width'); | ||
this.$el.css({ | ||
'height':new_height+'px' | ||
}); | ||
this.$inner.css({'width':new_width+'px'}); | ||
}, | ||
unlockDimensions: function() { | ||
this.$el.css({'height':'auto','width':'auto'}); | ||
this.$inner.css({'width':'auto'}); | ||
}, | ||
resizeChartToCtnr: function() { | ||
this.subview('viewport').subview('resizer').autoSize(); | ||
}, | ||
template: kt.make(__dirname+'/ChartView.html','_'), | ||
}); | ||
exports = module.exports = ChartView; | ||
exports.line = require('./Line/LineChartView'); | ||
exports.candle = require('./Candle/CandleChartView'); |
{ | ||
"name": "charted", | ||
"version": "0.0.28", | ||
"version": "0.1.0", | ||
"description": "Charts an entire collection of data. Single or multiple y-axes. Support for 64-bit integers. Auto-resizing axes.", | ||
@@ -21,3 +21,3 @@ "main": "index.js", | ||
"backbone": ">=1.0.0", | ||
"bassview": ">=0.0.5", | ||
"bassview": "0.0.6", | ||
"ktbr": ">=0.0.3", | ||
@@ -24,0 +24,0 @@ "raphael": ">=2.1.0", |
635223
54
18504
+ Addedbassview@0.0.6(transitive)
- Removedbassview@0.1.0(transitive)
Updatedbassview@0.0.6