Skip to content

Commit

Permalink
bring the state into the layout to reduce complexity and boost portab…
Browse files Browse the repository at this point in the history
…ility
  • Loading branch information
Frencil committed Apr 11, 2016
1 parent cf8aab7 commit ea2095b
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 245 deletions.
9 changes: 2 additions & 7 deletions assets/js/app/DataLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/

LocusZoom.DataLayer = function(id, layout, state) {
LocusZoom.DataLayer = function(id, layout) {

this.initialized = false;

Expand All @@ -23,8 +23,6 @@ LocusZoom.DataLayer = function(id, layout, state) {

this.layout = LocusZoom.mergeLayouts(layout || {}, LocusZoom.DataLayer.DefaultLayout);

this.state = LocusZoom.mergeLayouts(state || {}, LocusZoom.DataLayer.DefaultState);

this.data = [];
this.metadata = {};

Expand Down Expand Up @@ -125,9 +123,6 @@ LocusZoom.DataLayer = function(id, layout, state) {

};

LocusZoom.DataLayer.DefaultState = {
};

LocusZoom.DataLayer.DefaultLayout = {
type: "",
fields: []
Expand Down Expand Up @@ -188,7 +183,7 @@ LocusZoom.DataLayer.prototype.draw = function(){
LocusZoom.DataLayer.prototype.reMap = function(){
this.destroyAllTooltips(); // hack - only non-visible tooltips should be destroyed
// and then recreated if returning to visibility
var promise = this.parent.parent.lzd.getData(this.parent.parent.state, this.layout.fields); //,"ld:best"
var promise = this.parent.parent.lzd.getData(this.parent.parent.layout.state, this.layout.fields); //,"ld:best"
promise.then(function(new_data){
this.data = new_data.body;
}.bind(this));
Expand Down
31 changes: 11 additions & 20 deletions assets/js/app/Instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
LocusZoom.Instance Class
An Instance is an independent LocusZoom object. Many such LocusZoom objects can exist simultaneously
on a single page, each having its own layout, data sources, and state.
on a single page, each having its own layout.
*/

LocusZoom.Instance = function(id, datasource, layout, state) {
LocusZoom.Instance = function(id, datasource, layout) {

this.initialized = false;

Expand All @@ -29,22 +29,11 @@ LocusZoom.Instance = function(id, datasource, layout, state) {
// If no layout was passed, use the Standard Layout
// Otherwise merge whatever was passed with the Default Layout
if (typeof layout == "undefined"){
this.layout = LocusZoom.mergeLayouts({}, LocusZoom.StandardLayout);
this.layout = LocusZoom.mergeLayouts(LocusZoom.StandardLayout, LocusZoom.DefaultLayout);
} else {
this.layout = LocusZoom.mergeLayouts(layout, LocusZoom.DefaultLayout);
}

// The state property stores any parameters subject to change via user input
// At this step pre-parse layouts for panels and data layers and make sure they're all present in the state
this.state = LocusZoom.mergeLayouts(state || {}, LocusZoom.DefaultState);
var panel_id, data_layer_id;
for (panel_id in this.layout.panels){
this.state.panels[panel_id] = LocusZoom.mergeLayouts(this.state.panels[panel_id] || {}, LocusZoom.Panel.DefaultState);
for (data_layer_id in this.layout.panels[panel_id].data_layers){
this.state.panels[panel_id].data_layers[data_layer_id] = LocusZoom.mergeLayouts(this.state.panels[panel_id].data_layers[data_layer_id] || {}, LocusZoom.DataLayer.DefaultState);
}
}

// LocusZoom.Data.Requester
this.lzd = new LocusZoom.Data.Requester(datasource);

Expand Down Expand Up @@ -97,7 +86,7 @@ LocusZoom.Instance.prototype.initializeLayout = function(){
// Add panels
var panel_id;
for (panel_id in this.layout.panels){
this.addPanel(panel_id, this.layout.panels[panel_id], this.state.panels[panel_id]);
this.addPanel(panel_id, this.layout.panels[panel_id]);
}

};
Expand Down Expand Up @@ -334,9 +323,9 @@ LocusZoom.Instance.prototype.mapTo = function(chr, start, end){

// Apply new state values
// TODO: preserve existing state until new state is completely loaded+rendered or aborted?
this.state.chr = +chr;
this.state.start = +start;
this.state.end = +end;
this.layout.state.chr = +chr;
this.layout.state.start = +start;
this.layout.state.end = +end;

this.remap_promises = [];
// Trigger reMap on each Panel Layer
Expand All @@ -349,13 +338,15 @@ LocusZoom.Instance.prototype.mapTo = function(chr, start, end){
console.log(error);
this.curtain.drop(error);
}.bind(this))
.done(this.triggerOnUpdate);
.done(function(){
this.triggerOnUpdate()
}.bind(this));

return this;

};

// Refresh an instance's data from sources without changing position
LocusZoom.Instance.prototype.refresh = function(){
this.mapTo(this.state.chr, this.state.start, this.state.end);
this.mapTo(this.layout.state.chr, this.layout.state.start, this.layout.state.end);
};
30 changes: 12 additions & 18 deletions assets/js/app/LocusZoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
/* eslint-disable no-console */

var LocusZoom = {
version: "0.3.6"
version: "0.3.7"
};

// Populate a single element with a LocusZoom instance.
// selector can be a string for a DOM Query or a d3 selector.
LocusZoom.populate = function(selector, datasource, layout, state) {
LocusZoom.populate = function(selector, datasource, layout) {
if (typeof selector == "undefined"){
throw ("LocusZoom.populate selector not defined");
}
Expand All @@ -23,7 +23,7 @@ LocusZoom.populate = function(selector, datasource, layout, state) {
this.attr("id", "#lz-" + iterator);
}
// Create the instance
instance = new LocusZoom.Instance(this.node().id, datasource, layout, state);
instance = new LocusZoom.Instance(this.node().id, datasource, layout);
// Add an SVG to the div and set its dimensions
instance.svg = d3.select("div#" + instance.id)
.append("svg")
Expand All @@ -35,11 +35,7 @@ LocusZoom.populate = function(selector, datasource, layout, state) {
instance.initialize();
// Detect data-region and fill in state values if present
if (typeof this.node().dataset !== "undefined" && typeof this.node().dataset.region !== "undefined"){
var region = LocusZoom.parsePositionQuery(this.node().dataset.region);
var attr;
for (attr in region){
instance.state[attr] = region[attr];
}
instance.layout.state = LocusZoom.mergeLayouts(LocusZoom.parsePositionQuery(this.node().dataset.region), instance.layout.state);
}
// If the instance has defined data sources then trigger its first mapping based on state values
if (typeof datasource == "object" && Object.keys(datasource).length){
Expand All @@ -51,10 +47,10 @@ LocusZoom.populate = function(selector, datasource, layout, state) {

// Populate arbitrarily many elements each with a LocusZoom instance
// using a common datasource, layout, and/or state
LocusZoom.populateAll = function(selector, datasource, layout, state) {
LocusZoom.populateAll = function(selector, datasource, layout) {
var instances = [];
d3.selectAll(selector).each(function(d,i) {
instances[i] = LocusZoom.populate(this, datasource, layout, state);
instances[i] = LocusZoom.populate(this, datasource, layout);
});
return instances;
};
Expand Down Expand Up @@ -278,17 +274,10 @@ LocusZoom.parseFields = function (data, html) {
}
return html;
};

// Default State
LocusZoom.DefaultState = {
chr: 0,
start: 0,
end: 0,
panels: {}
};

// Default Layout
LocusZoom.DefaultLayout = {
state: {},
width: 1,
height: 1,
min_width: 1,
Expand All @@ -300,6 +289,11 @@ LocusZoom.DefaultLayout = {

// Standard Layout
LocusZoom.StandardLayout = {
state: {
chr: 0,
start: 0,
end: 0
},
width: 800,
height: 450,
min_width: 400,
Expand Down
26 changes: 11 additions & 15 deletions assets/js/app/Panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ LocusZoom.Panel = function(id, layout, state) {

// The layout is a serializable object used to describe the composition of the Panel
this.layout = LocusZoom.mergeLayouts(layout || {}, LocusZoom.Panel.DefaultLayout);

// The state property stores any parameters subject to change via user input
this.state = LocusZoom.mergeLayouts(state || {}, LocusZoom.Panel.DefaultState);

this.data_layers = {};
this.data_layer_ids_by_z_index = [];
Expand All @@ -50,11 +47,10 @@ LocusZoom.Panel = function(id, layout, state) {

};

LocusZoom.Panel.DefaultState = {
data_layers: {}
};

LocusZoom.Panel.DefaultLayout = {
state: {
data_layers: {}
},
width: 0,
height: 0,
origin: { x: 0, y: 0 },
Expand All @@ -73,7 +69,7 @@ LocusZoom.Panel.DefaultLayout = {
x: {},
y1: {},
y2: {}
}
}
};

LocusZoom.Panel.prototype.initializeLayout = function(){
Expand Down Expand Up @@ -101,7 +97,7 @@ LocusZoom.Panel.prototype.initializeLayout = function(){
if (typeof this.layout.data_layers == "object"){
var data_layer_id;
for (data_layer_id in this.layout.data_layers){
this.addDataLayer(data_layer_id, this.layout.data_layers[data_layer_id], this.state.data_layers[data_layer_id]);
this.addDataLayer(data_layer_id, this.layout.data_layers[data_layer_id]);
}
}

Expand Down Expand Up @@ -244,7 +240,7 @@ LocusZoom.Panel.prototype.initialize = function(){


// Create a new data layer by layout object
LocusZoom.Panel.prototype.addDataLayer = function(id, layout, state){
LocusZoom.Panel.prototype.addDataLayer = function(id, layout){
if (typeof id !== "string"){
throw "Invalid data layer id passed to LocusZoom.Panel.prototype.addDataLayer()";
}
Expand All @@ -259,7 +255,7 @@ LocusZoom.Panel.prototype.addDataLayer = function(id, layout, state){
}

// Create the Data Layer and set its parent
var data_layer = LocusZoom.DataLayers.get(layout.type, id, layout, state);
var data_layer = LocusZoom.DataLayers.get(layout.type, id, layout);
data_layer.parent = this;

// Store the Data Layer on the Panel
Expand All @@ -271,7 +267,7 @@ LocusZoom.Panel.prototype.addDataLayer = function(id, layout, state){
this.xExtent = this.data_layers[data_layer.id].getAxisExtent("x");
} else {
this.xExtent = function(){
return d3.extent([this.parent.state.start, this.parent.state.end]);
return d3.extent([this.parent.layout.state.start, this.parent.layout.state.end]);
};
}
// Generate the yExtent function
Expand Down Expand Up @@ -374,7 +370,7 @@ LocusZoom.Panel.prototype.render = function(){
.attr("transform", "translate(" + this.layout.margin.left + "," + (this.layout.height - this.layout.margin.bottom) + ")")
.call(this.x_axis);
if (this.layout.axes.x.label_function){
this.layout.axes.x.label = LocusZoom.LabelFunctions.get(this.layout.axes.x.label_function, this.parent.state);
this.layout.axes.x.label = LocusZoom.LabelFunctions.get(this.layout.axes.x.label_function, this.parent.layout.state);
}
if (this.layout.axes.x.label != null){
var x_label = this.layout.axes.x.label;
Expand All @@ -393,7 +389,7 @@ LocusZoom.Panel.prototype.render = function(){
.attr("transform", "translate(" + this.layout.margin.left + "," + this.layout.margin.top + ")")
.call(this.y1_axis);
if (this.layout.axes.y1.label_function){
this.layout.axes.y1.label = LocusZoom.LabelFunctions.get(this.layout.axes.y1.label_function, this.parent.state);
this.layout.axes.y1.label = LocusZoom.LabelFunctions.get(this.layout.axes.y1.label_function, this.parent.layout.state);
}
if (this.layout.axes.y1.label != null){
var y1_label = this.layout.axes.y1.label;
Expand All @@ -414,7 +410,7 @@ LocusZoom.Panel.prototype.render = function(){
.attr("transform", "translate(" + (this.layout.width - this.layout.margin.right) + "," + this.layout.margin.top + ")")
.call(this.y2_axis);
if (this.layout.axes.y2.label_function){
this.layout.axes.y2.label = LocusZoom.LabelFunctions.get(this.layout.axes.y2.label_function, this.parent.state);
this.layout.axes.y2.label = LocusZoom.LabelFunctions.get(this.layout.axes.y2.label_function, this.parent.layout.state);
}
if (this.layout.axes.y2.label != null){
var y2_label = this.layout.axes.y2.label;
Expand Down
Loading

0 comments on commit ea2095b

Please sign in to comment.