/
Data.js
167 lines (136 loc) · 4.81 KB
/
Data.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
'use strict';
var _ = require('lodash');
var Model = require('backbone').Model;
var events = require('../lib/events');
var datahelper = require('../helpers/data');
/**
* This is primary data store for Data Lasso. It also acts as a
* coordinator in the data flow through the Data Lasso
*/
var DataModel = Model.extend({
// TODO: Refactor to make it work and behave like a Model
defaults: {
entries: null,
selectedEntries: [],
mappings: null,
scales: null,
attributes: null
},
initialize: function (options) {
this.options = options;
this.setupEventListeners();
// TODO: Put snapshots in it's own model
this.dataSnapshots = [];
},
setupEventListeners: function () {
// Data processing events
this.listenTo(events, 'datalasso:data:uploaded', this.processNewData);
// Axis mappings events (selecting what attribute will be on what axis)
this.listenTo(events, 'datalasso:axismappings:updated', this.processAxisMappings);
// Listen to things that have to do with selection
this.listenTo(events, 'datalasso:selection:new', this.newSelection);
this.listenTo(events, 'datalasso:selection:zoomin', this.zoomIntoSelection);
this.listenTo(events, 'datalasso:selection:zoomout', this.zoomOutOfSelection);
this.listenTo(events, 'datalasso:selection:download', this.downloadSelectedAsCSV);
},
/**
* New data was uploaded
*/
processNewData: function (e) {
this.data = _.extend({}, this.defaults, datahelper.processInput(e.data, this.options));
events.trigger('datalasso:input:processed', {
data: this.data
});
},
/**
* New axis mappings were selected
*/
processAxisMappings: function (e) {
this.data.mappings = e.mappings;
events.trigger('datalasso:data:new', {
data: this.data
});
},
/**
* New selection was made
*/
newSelection: function (e) {
this.data.entries = e.entries;
this.data.selectedEntries = e.selectedEntries;
events.trigger('datalasso:data:new', {
data: this.data
});
},
/**
* Selection is zoomed in
*/
zoomIntoSelection: function () {
if (this.data.selectedEntries && this.data.selectedEntries.length < this.data.entries.length) {
this.saveDataSnapshot();
this.data.entries = _.clone(this.data.selectedEntries);
this.data.selectedEntries = [];
this.data.scales = datahelper.getUpdatedScales(this.data.entries, this.options);
events.trigger('datalasso:data:new', {
data: this.data
});
events.trigger('datalasso:selection:new', {
entries: this.data.entries,
selectedEntries: this.data.selectedEntries
});
}
},
/**
* Selection is zoomed out
*/
zoomOutOfSelection: function () {
this.restoreLastDataSnapshot();
// Reset the drawing data
events.trigger('datalasso:data:new', {
data: this.data
});
// Reset the selection to where it was before
events.trigger('datalasso:selection:new', {
entries: this.data.entries,
selectedEntries: this.data.selectedEntries
});
},
/**
* Preserve whatever is in `data` now in an array of
* chronological snapshots
*/
saveDataSnapshot: function () {
this.dataSnapshots.push(_.clone(this.data));
events.trigger('datalasso:data:snapshots', this.dataSnapshots.length);
},
/**
* Get last snapshot stored, and use that as current data object
*/
restoreLastDataSnapshot: function () {
this.data = this.dataSnapshots.pop();
this.restoreSelection();
events.trigger('datalasso:data:snapshots', this.dataSnapshots.length);
},
/**
* Restore the selection attributes on entries based on the list
* of selected entries
*/
restoreSelection: function () {
var selectedIds = _.pluck(this.data.selectedEntries, '__id');
_.each(this.data.entries, function (entry, index) {
this.data.entries[index].isSelected = selectedIds.indexOf(entry.__id) > -1;
}, this);
},
/**
* Generate CSV and trigger download
*/
downloadSelectedAsCSV: function () {
var csvContent = 'data:text/csv;charset=utf-8,';
csvContent += _.keys(this.data.attributes).join(',');
_.each(this.data.selectedEntries, function (entry, index) {
csvContent += _.values(entry).join(',');
csvContent += index < this.data.selectedEntries.length ? '\n' : '';
}, this);
window.open(encodeURI(csvContent));
}
});
module.exports = DataModel;