ela 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile.lock +3 -1
- data/app/css/screen.styl +22 -11
- data/app/js/lib/views/1_viewport_view.coffee +4 -0
- data/app/js/lib/views/axis_handler.coffee +62 -0
- data/app/js/lib/views/base_app.coffee +23 -100
- data/app/js/lib/views/canvas.coffee +8 -1
- data/app/js/lib/views/graph_view.coffee +102 -0
- data/app/js/lib/views/interpolated_graph.coffee +75 -62
- data/app/js/lib/views/legend.coffee +13 -2
- data/app/js/lib/views/viewport.coffee +26 -0
- data/app/views/general/app.jst.hamlc +2 -12
- data/ela.gemspec +1 -1
- data/lib/ela/version.rb +1 -1
- metadata +15 -7
- data/app/js/lib/views/legend_handler.coffee +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 17010b55c4244377534fb008bb8b00701b2ec1f3a03b8c08e57ca9ffb8321860
|
4
|
+
data.tar.gz: 9ea5fbd11fb13b0ed539ffb903a8f4d543a3a2e7ab92054dcb2afd2d31f9a22f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 226cd20184cdde3a1f651d205995e4de2c0527357a789ff3a49aa6d268da1eea5431a16298e422d6be5fa75220c10af07577929d7675f361f8b8146e8f9c5b5b
|
7
|
+
data.tar.gz: 0b6e09af8f8b0cd19557e2030c139cbbd84ff84d14c53996c3ae88f8decb33e38fc71728608a7673f5d905b8c6c87814e954533536eacd57ac546d7a0c5a2fa1
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ela (1.0
|
4
|
+
ela (1.1.0)
|
5
|
+
andand (~> 1.3, >= 1.3.3)
|
5
6
|
bundler (~> 1.13)
|
6
7
|
coffee-script (~> 2.4, >= 2.4.1)
|
7
8
|
guard (~> 2.10)
|
@@ -23,6 +24,7 @@ PATH
|
|
23
24
|
GEM
|
24
25
|
remote: https://rubygems.org/
|
25
26
|
specs:
|
27
|
+
andand (1.3.3)
|
26
28
|
coderay (1.1.2)
|
27
29
|
coffee-script (2.4.1)
|
28
30
|
coffee-script-source
|
data/app/css/screen.styl
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
// ELA specific
|
2
|
-
$
|
2
|
+
$axis-handler-size = 59px
|
3
3
|
|
4
4
|
// Remember that this color should be set in CurveGraph aswell
|
5
5
|
// to resemble the fillColor of the range indicator triangles:
|
@@ -112,9 +112,22 @@ li.share-form
|
|
112
112
|
&.failure:before
|
113
113
|
content "\f00d"
|
114
114
|
|
115
|
-
article.
|
115
|
+
article.viewport
|
116
116
|
display flex
|
117
|
-
|
117
|
+
|
118
|
+
.view
|
119
|
+
flex 1
|
120
|
+
display flex
|
121
|
+
flex-direction column
|
122
|
+
border-right 1px solid #bbb
|
123
|
+
overflow hidden
|
124
|
+
|
125
|
+
&:last-child
|
126
|
+
border-right: none
|
127
|
+
|
128
|
+
.horizontal-wrapper
|
129
|
+
display flex
|
130
|
+
flex 1
|
118
131
|
|
119
132
|
div.legend
|
120
133
|
z-layer 'section', 'legend'
|
@@ -180,8 +193,6 @@ article.graph
|
|
180
193
|
|
181
194
|
&.legend-simple
|
182
195
|
border-bottom 1px solid #ccc
|
183
|
-
absolute 0
|
184
|
-
width 100%
|
185
196
|
|
186
197
|
.curve
|
187
198
|
display inline-block
|
@@ -217,15 +228,15 @@ article.graph
|
|
217
228
|
padding 10px
|
218
229
|
background-color rgba(255, 255, 255, 0.8)
|
219
230
|
|
220
|
-
div.
|
231
|
+
div.axis-handler
|
221
232
|
text-align center
|
222
233
|
cursor pointer
|
223
234
|
background $legend-background
|
224
235
|
padding 14px 5px
|
225
236
|
|
226
|
-
&.
|
227
|
-
|
228
|
-
|
237
|
+
&.axis-handler-left
|
238
|
+
width $axis-handler-size
|
239
|
+
position relative
|
229
240
|
|
230
241
|
span.hint
|
231
242
|
absolute 50% none none 50%
|
@@ -234,7 +245,7 @@ article.graph
|
|
234
245
|
|
235
246
|
// vertical range slider and large, non-transparent legend with values
|
236
247
|
#international-standard-atmosphere article.graph div.graph
|
237
|
-
margin-left $
|
248
|
+
margin-left $axis-handler-size
|
238
249
|
|
239
250
|
// Some space for the delete button
|
240
251
|
#composites
|
@@ -349,7 +360,7 @@ aside.curves
|
|
349
360
|
|
350
361
|
img.logo
|
351
362
|
absolute none 0 0 none
|
352
|
-
height $
|
363
|
+
height $axis-handler-size
|
353
364
|
z-layer 'section', 'graph'
|
354
365
|
|
355
366
|
@media $media-lt-phone
|
@@ -0,0 +1,62 @@
|
|
1
|
+
ELA.Views ?= {}
|
2
|
+
class ELA.Views.AxisHandler extends Backbone.Poised.View
|
3
|
+
className: 'axis-handler'
|
4
|
+
|
5
|
+
events:
|
6
|
+
'pan': 'updateValue'
|
7
|
+
'tap': 'updateValue'
|
8
|
+
|
9
|
+
hammerjs:
|
10
|
+
recognizers: [
|
11
|
+
[Hammer.Rotate, { enable: false }],
|
12
|
+
[Hammer.Pinch, { enable: false }, ['rotate']],
|
13
|
+
[Hammer.Swipe, { enable: false }],
|
14
|
+
[Hammer.Pan, { direction: Hammer.DIRECTION_ALL, threshold: 1 }, ['swipe']],
|
15
|
+
[Hammer.Tap, { threshold: 5 }],
|
16
|
+
[Hammer.Press, { enable: false }]
|
17
|
+
]
|
18
|
+
|
19
|
+
initialize: (options) ->
|
20
|
+
@displayParams = options.displayParams
|
21
|
+
@position = options.position or 'bottom'
|
22
|
+
@orientation = switch @position
|
23
|
+
when 'bottom' then 'x'
|
24
|
+
when 'left' then 'y'
|
25
|
+
@attribute = options.attribute
|
26
|
+
@precision = @model.get("#{@attribute}Precision")
|
27
|
+
@precision ?= options.precision
|
28
|
+
@precision ?= 2
|
29
|
+
|
30
|
+
@listenTo @model, "change:#{@attribute}", @renderText
|
31
|
+
|
32
|
+
updateValue: (e) =>
|
33
|
+
origin = @displayParams.get("#{@orientation}Origin")
|
34
|
+
range = @displayParams.get("#{@orientation}Range")
|
35
|
+
graphOffset = @parentView.subviews.graph.$el.offset()
|
36
|
+
if @orientation is 'x'
|
37
|
+
width = @displayParams.get('width')
|
38
|
+
point = (range / width) *
|
39
|
+
(e.gesture.pointers[0].clientX - graphOffset.left - origin)
|
40
|
+
else # @orientation is 'y'
|
41
|
+
height = @displayParams.get('height')
|
42
|
+
y = e.gesture.pointers[0].clientY - graphOffset.top
|
43
|
+
y = Math.min(Math.max(y, 0), height)
|
44
|
+
point = (range / height) * (origin - y)
|
45
|
+
|
46
|
+
pow = Math.pow(10, @precision)
|
47
|
+
point = Math.round(point * pow) / pow
|
48
|
+
@model.set(@attribute, point)
|
49
|
+
|
50
|
+
renderText: =>
|
51
|
+
@$el.find('span').text(t(
|
52
|
+
"#{@model.name}.axisHandler.#{@attribute}.label"
|
53
|
+
"#{@model.name}.axisHandler.label"
|
54
|
+
'axisHandler.label'
|
55
|
+
value: @model.get(@attribute).toFixed(@precision)
|
56
|
+
))
|
57
|
+
|
58
|
+
render: =>
|
59
|
+
@$el.html('<span class="hint"></span>')
|
60
|
+
@$el.addClass("axis-handler-#{@position}")
|
61
|
+
@renderText()
|
62
|
+
this
|
@@ -9,28 +9,10 @@ class ELA.Views.BaseApp extends Backbone.Poised.View
|
|
9
9
|
# Typically in a subclass we override the list of asides. This may
|
10
10
|
# be a list of classes inheriting from ELA.Views.BaseAside or an
|
11
11
|
# object with `name` and `klass` attributes.
|
12
|
-
|
12
|
+
asides: []
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
graphView: null
|
17
|
-
graphOverlayView: null
|
18
|
-
graphDefaults: {}
|
19
|
-
|
20
|
-
rangeHandlerView: null
|
21
|
-
|
22
|
-
# TODO: Rename valueAtRange name pattern to something like selectValue
|
23
|
-
# TODO: use correct attribute in every app instead of generic valueAtRange
|
24
|
-
valueAtRange: null
|
25
|
-
valueAtRangeAxis: 'x'
|
26
|
-
valueAtRangeAttribute: 'valueAtRange'
|
27
|
-
valueAtRangePrecision: null
|
28
|
-
|
29
|
-
legendValueAtRange: null
|
30
|
-
legendValueAtRangeAxis: null
|
31
|
-
legendValueAtRangeAttribute: null
|
32
|
-
|
33
|
-
useHeadup: false
|
14
|
+
# Typically in a subclass we override the list of views.
|
15
|
+
views: []
|
34
16
|
|
35
17
|
events:
|
36
18
|
'tap header .overview.icon': 'backToOverview'
|
@@ -55,16 +37,13 @@ class ELA.Views.BaseApp extends Backbone.Poised.View
|
|
55
37
|
initialize: ->
|
56
38
|
@listenTo @model, 'change:currentAside', @toggleAside
|
57
39
|
@listenTo @model, 'change:showHelp', @renderHelp
|
58
|
-
|
59
|
-
|
60
|
-
@on 'controlLiveChangeEnd', @liveChangeEnd
|
40
|
+
@on 'controlLiveChangeStart', @liveChangeStart
|
41
|
+
@on 'controlLiveChangeEnd', @liveChangeEnd
|
61
42
|
|
62
|
-
for
|
63
|
-
|
43
|
+
for aside in @asides
|
44
|
+
aside.link ?= 'icon'
|
64
45
|
|
65
|
-
|
66
|
-
GraphParams = @graphView.toFunction()['Params']
|
67
|
-
@model.displayParams = new GraphParams if GraphParams?
|
46
|
+
@model.displayParams ?= {}
|
68
47
|
|
69
48
|
viewSubappOptions: =>
|
70
49
|
@$('.subapps.select').toggleClass('view')
|
@@ -117,16 +96,16 @@ class ELA.Views.BaseApp extends Backbone.Poised.View
|
|
117
96
|
|
118
97
|
iconAsideNames: ->
|
119
98
|
@_iconAsideNames ?= do =>
|
120
|
-
_.compact(_.map(@
|
121
|
-
|
99
|
+
_.compact(_.map(@asides, (aside) ->
|
100
|
+
aside.name if aside.link is 'icon'
|
122
101
|
))
|
123
102
|
|
124
103
|
contextAsides: ->
|
125
104
|
@_contextAsideNames ?= do =>
|
126
|
-
_.compact(_.map(@
|
127
|
-
if
|
128
|
-
name:
|
129
|
-
label: @loadLocale("contextMenu.#{
|
105
|
+
_.compact(_.map(@asides, (aside) =>
|
106
|
+
if aside.link is 'contextMenu'
|
107
|
+
name: aside.name
|
108
|
+
label: @loadLocale("contextMenu.#{aside.name}")
|
130
109
|
))
|
131
110
|
|
132
111
|
backToOverview: =>
|
@@ -181,11 +160,6 @@ class ELA.Views.BaseApp extends Backbone.Poised.View
|
|
181
160
|
hasHelpText: @model.hasHelpText
|
182
161
|
iconAsideNames: @iconAsideNames()
|
183
162
|
contextAsides: @contextAsides()
|
184
|
-
legendView: @legendView?
|
185
|
-
graphOverlayView: @graphOverlayView?
|
186
|
-
graphView: @graphView?
|
187
|
-
rangeHandlerView: @rangeHandlerView?
|
188
|
-
useHeadup: @useHeadup
|
189
163
|
relatedApps: @relatedApps()
|
190
164
|
currentPath: @model.path
|
191
165
|
@$shareLink = @$('li.share-link')
|
@@ -194,7 +168,7 @@ class ELA.Views.BaseApp extends Backbone.Poised.View
|
|
194
168
|
@$shareCopyButton = @$shareForm.find('button')
|
195
169
|
|
196
170
|
@$app = @$('section.app')
|
197
|
-
for aside in @
|
171
|
+
for aside in @asides
|
198
172
|
AsideView = aside.view.toFunction()
|
199
173
|
view = @subviews[aside.name] = new AsideView
|
200
174
|
model: @model
|
@@ -203,70 +177,19 @@ class ELA.Views.BaseApp extends Backbone.Poised.View
|
|
203
177
|
localePrefix: @localePrefix
|
204
178
|
@$app.append(view.render().el)
|
205
179
|
|
206
|
-
|
207
|
-
@$legend = @$('article .legend')
|
208
|
-
LegendView = @legendView.toFunction()
|
209
|
-
@subviews.legend = view = new LegendView
|
210
|
-
model: @model
|
211
|
-
parentView: this
|
212
|
-
el: @$legend
|
213
|
-
useValueAtRange: @legendValueAtRange or @valueAtRange or @rangeHandlerView?
|
214
|
-
valueAtRangeAxis: @legendValueAtRangeAxis or @valueAtRangeAxis
|
215
|
-
valueAtRangeAttribute: @legendValueAtRangeAttribute or @valueAtRangeAttribute
|
216
|
-
localePrefix: @localePrefix
|
217
|
-
view.render()
|
218
|
-
|
219
|
-
if @graphOverlayView? and not @subviews.graphOverlayView
|
220
|
-
@$graphOverlay = @$('article .graph-overlay')
|
221
|
-
GraphOverlayView = @graphOverlayView.toFunction()
|
222
|
-
@subviews.graphOverlayView = view = new GraphOverlayView
|
223
|
-
model: @model
|
224
|
-
parentView: this
|
225
|
-
el: @$graphOverlay
|
226
|
-
localPrefix: @localePrefix
|
227
|
-
view.render()
|
228
|
-
|
229
|
-
if @rangeHandlerView? and not @subviews.rangeHandler?
|
230
|
-
@$rangeHandler = @$('article .range-handler')
|
231
|
-
RangeHandlerView = @rangeHandlerView.toFunction()
|
232
|
-
@subviews.rangeHandler = view = new RangeHandlerView
|
233
|
-
model: @model
|
234
|
-
parentView: this
|
235
|
-
el: @$rangeHandler
|
236
|
-
axis: @valueAtRangeAxis
|
237
|
-
attribute: @valueAtRangeAttribute
|
238
|
-
precision: @valueAtRangePrecision
|
239
|
-
localePrefix: @localePrefix
|
240
|
-
view.render()
|
241
|
-
|
242
|
-
if @useHeadup and not @subviews.headup?
|
180
|
+
unless @subviews.headup?
|
243
181
|
@$headup = @$('aside.headup')
|
244
182
|
@subviews.headup = new ELA.Views.Headup
|
245
183
|
el: @$headup
|
246
184
|
localePrefix: @localePrefix
|
247
185
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
@
|
253
|
-
|
254
|
-
|
255
|
-
params: @model.displayParams
|
256
|
-
defaults: _.defaults
|
257
|
-
# Taken from ELA.Views.Canvas::readCanvasResolution
|
258
|
-
width: @$graph[0].clientWidth
|
259
|
-
height: @$graph[0].clientHeight
|
260
|
-
valueAtRangeAxis: @valueAtRangeAxis
|
261
|
-
valueAtRangeAttribute: @valueAtRangeAttribute
|
262
|
-
, @graphDefaults
|
263
|
-
localePrefix: @localePrefix
|
264
|
-
@$graph.html(view.render().el)
|
265
|
-
|
266
|
-
# If the legend uses the value at range feature, it's height
|
267
|
-
# may change with updated calculators
|
268
|
-
if @subviews.legend?.useValueAtRange
|
269
|
-
@listenTo(@model, 'change:calculators', view.readCanvasResolution)
|
186
|
+
unless @subviews.viewport
|
187
|
+
view = @subviews.viewport = new ELA.Views.Viewport
|
188
|
+
model: @model
|
189
|
+
parentView: this
|
190
|
+
views: @views
|
191
|
+
localePrefix: @localePrefix
|
192
|
+
@$('.viewport').replaceWith(view.render().el)
|
270
193
|
|
271
194
|
@renderHelp()
|
272
195
|
@toggleAside(@model, @model.get('currentAside'))
|
@@ -21,11 +21,18 @@ class ELA.Views.Canvas extends Backbone.Poised.View
|
|
21
21
|
@params = options.params
|
22
22
|
@params.set(@defaults)
|
23
23
|
else
|
24
|
+
@model.displayParams ?= {}
|
24
25
|
@params = new @constructor.Params(@defaults)
|
26
|
+
@model.displayParams[options.name] = @params
|
25
27
|
|
26
28
|
@setCanvasResolution()
|
27
29
|
|
28
|
-
$(window).resize
|
30
|
+
$(window).on('resize', @readCanvasResolution)
|
31
|
+
|
32
|
+
# If the legend uses the value at range feature, it's height
|
33
|
+
# may change with updated calculators
|
34
|
+
@listenTo(@model, 'change:calculators', @readCanvasResolution)
|
35
|
+
|
29
36
|
@listenTo(@params, 'change:width change:height', @setCanvasResolution)
|
30
37
|
|
31
38
|
remove: ->
|
@@ -0,0 +1,102 @@
|
|
1
|
+
ELA.Views ?= {}
|
2
|
+
|
3
|
+
class ELA.Views.GraphView extends ELA.Views.ViewportView
|
4
|
+
initialize: (options = {}) ->
|
5
|
+
unless options.name?
|
6
|
+
throw 'ELA.Views.GraphView: option `name` is required'
|
7
|
+
|
8
|
+
if options.graph?.view
|
9
|
+
@GraphView = options.graph.view.toFunction()
|
10
|
+
else
|
11
|
+
@GraphView = ELA.Views.InterpolatedGraph
|
12
|
+
@displayParams = @model.displayParams[options.name] = new @GraphView.Params
|
13
|
+
|
14
|
+
unless options.legend is false
|
15
|
+
if _.isObject(options.legend) and options.legend.view?
|
16
|
+
@LegendView = options.legend.view.toFunction()
|
17
|
+
else
|
18
|
+
@LegendView = ELA.Views.Legend
|
19
|
+
|
20
|
+
if options.graphOverlay?.view?
|
21
|
+
@GraphOverlayView = options.graphOverlay.view.toFunction()
|
22
|
+
|
23
|
+
for axis, props of options.graph?.axes
|
24
|
+
if props.handler
|
25
|
+
attribute: props.attribute
|
26
|
+
position: switch axis
|
27
|
+
when 'x' then @bottomAxisHandler = attribute: props.attribute
|
28
|
+
when 'y' then @leftAxisHandler = attribute: props.attribute
|
29
|
+
|
30
|
+
@curves = options.graph?.curves?.slice()
|
31
|
+
|
32
|
+
@subviews = {}
|
33
|
+
|
34
|
+
render: =>
|
35
|
+
@$el.empty()
|
36
|
+
|
37
|
+
if @LegendView?
|
38
|
+
view = @subviews.legend ?= new @LegendView
|
39
|
+
model: @model
|
40
|
+
parentView: this
|
41
|
+
localePrefix: @localePrefix
|
42
|
+
curves: @curves
|
43
|
+
@$el.append(view.render().el)
|
44
|
+
|
45
|
+
if @GraphOverlayView?
|
46
|
+
view = @subviews.graphOverlay ?= new @GraphOverlayView
|
47
|
+
model: @model
|
48
|
+
parentView: this
|
49
|
+
localePrefix: @localePrefix
|
50
|
+
@$el.append(view.render().el)
|
51
|
+
|
52
|
+
$horizontalWrapper = $('<div>', class: 'horizontal-wrapper')
|
53
|
+
|
54
|
+
if @leftAxisHandler?
|
55
|
+
view = @subviews.leftAxisHandler ?= new ELA.Views.AxisHandler
|
56
|
+
model: @model
|
57
|
+
displayParams: @displayParams
|
58
|
+
attribute: @leftAxisHandler.attribute
|
59
|
+
position: 'left'
|
60
|
+
parentView: this
|
61
|
+
localePrefix: @localePrefix
|
62
|
+
$horizontalWrapper.append(view.render().el)
|
63
|
+
|
64
|
+
$horizontalWrapper.append($('<div>', class: 'graph'))
|
65
|
+
@$el.append($horizontalWrapper)
|
66
|
+
|
67
|
+
if @bottomAxisHandler?
|
68
|
+
view = @subviews.bottomAxisHandler ?= new ELA.Views.AxisHandler
|
69
|
+
model: @model
|
70
|
+
displayParams: @displayParams
|
71
|
+
attribute: @bottomAxisHandler.attribute
|
72
|
+
position: 'bottom'
|
73
|
+
parentView: this
|
74
|
+
localePrefix: @localePrefix
|
75
|
+
@$el.append(view.render().el)
|
76
|
+
|
77
|
+
delay =>
|
78
|
+
$graph = @$('.graph')
|
79
|
+
guides = []
|
80
|
+
if @bottomAxisHandler?
|
81
|
+
guides.push
|
82
|
+
orientation: 'vertical'
|
83
|
+
attribute: @bottomAxisHandler.attribute
|
84
|
+
if @leftAxisHandler?
|
85
|
+
guides.push
|
86
|
+
orientation: 'horizontal'
|
87
|
+
attribute: @leftAxisHandler.attribute
|
88
|
+
view = @subviews.graph ?= new @GraphView
|
89
|
+
model: @model
|
90
|
+
parentView: this
|
91
|
+
params: @displayParams
|
92
|
+
defaults: _.defaults
|
93
|
+
# Taken from ELA.Views.Canvas::readCanvasResolution
|
94
|
+
width: $graph[0].clientWidth
|
95
|
+
height: $graph[0].clientHeight
|
96
|
+
guides: guides
|
97
|
+
curves: @curves
|
98
|
+
, @graphDefaults
|
99
|
+
localePrefix: @localePrefix
|
100
|
+
$graph.html(view.render().el)
|
101
|
+
|
102
|
+
this
|
@@ -14,8 +14,9 @@ class ELA.Views.InterpolatedGraph extends ELA.Views.BaseGraph
|
|
14
14
|
@bindCalculatorEvents()
|
15
15
|
@requestRepaint()
|
16
16
|
|
17
|
-
|
18
|
-
@model
|
17
|
+
for guide in @params.get('guides')
|
18
|
+
@listenTo(@model, "change:#{guide.attribute}", @requestRepaint)
|
19
|
+
|
19
20
|
@model.on 'change:axisLabelingForCurve', @requestRepaint
|
20
21
|
|
21
22
|
bindCalculatorEvents: ->
|
@@ -23,14 +24,15 @@ class ELA.Views.InterpolatedGraph extends ELA.Views.BaseGraph
|
|
23
24
|
@stopListening(@model.previous('calculators'))
|
24
25
|
|
25
26
|
for calc in @model.get('calculators')
|
26
|
-
|
27
|
+
filteredCurves = @_filteredCurves()
|
28
|
+
for curve in filteredCurves
|
27
29
|
@listenTo calc, "change:#{curve.get('function')}", @requestRepaint
|
28
30
|
|
29
31
|
@listenTo calc, 'change:maxX change:xRange', @calculateRangeX
|
30
32
|
@listenTo calc, 'change:maxY change:yRange', @calculateRangeY
|
31
33
|
# TODO: Add dynamic dependencies to calculator, so that we can
|
32
34
|
# actually only listen to maxY changes and recalculate ranges.
|
33
|
-
oldestCurve =
|
35
|
+
oldestCurve = filteredCurves[0]
|
34
36
|
if oldestCurve?
|
35
37
|
@listenTo calc, "change:#{oldestCurve.get('function')}", @calculateRanges
|
36
38
|
|
@@ -124,9 +126,18 @@ class ELA.Views.InterpolatedGraph extends ELA.Views.BaseGraph
|
|
124
126
|
else
|
125
127
|
@drawSpline(points, tension, closed, xPos, yPos)
|
126
128
|
|
129
|
+
_filteredCurves: ->
|
130
|
+
curves = @model.curves.history
|
131
|
+
if graphCurves = @params.get('curves')
|
132
|
+
_.filter curves, (curve) ->
|
133
|
+
graphCurves.indexOf(curve.get('function')) >= 0
|
134
|
+
else
|
135
|
+
curves
|
136
|
+
|
127
137
|
_sortedCurves: ->
|
128
|
-
_.sortBy @
|
129
|
-
|
138
|
+
_.sortBy @_filteredCurves(), (curve) ->
|
139
|
+
curve.get('zIndex')
|
140
|
+
|
130
141
|
|
131
142
|
beforeRenderCurves: (resultCurves) ->
|
132
143
|
afterRenderCurves: (resultCurves) ->
|
@@ -135,7 +146,6 @@ class ELA.Views.InterpolatedGraph extends ELA.Views.BaseGraph
|
|
135
146
|
resultCurves = []
|
136
147
|
for calc, i in @model.get('calculators')
|
137
148
|
for curve, j in @_sortedCurves()
|
138
|
-
|
139
149
|
func = curve.get('function')
|
140
150
|
resultCurves.push
|
141
151
|
curve: curve
|
@@ -219,63 +229,66 @@ class ELA.Views.InterpolatedGraph extends ELA.Views.BaseGraph
|
|
219
229
|
@context.fill()
|
220
230
|
@context.closePath()
|
221
231
|
|
222
|
-
|
223
|
-
|
224
|
-
@context.beginPath()
|
225
|
-
@context.setLineDash []
|
226
|
-
@context.strokeStyle = '#999999'
|
227
|
-
@context.lineWidth = 2
|
228
|
-
|
229
|
-
# Border below legend
|
230
|
-
@context.moveTo(@width, 0)
|
231
|
-
@context.lineTo(0, 0)
|
232
|
-
|
233
|
-
if (axis = @params.get('valueAtRangeAxis')) is 'x'
|
234
|
-
# Border next to range handler
|
235
|
-
@context.moveTo(0, @height)
|
236
|
-
@context.lineTo(@width, @height)
|
237
|
-
@context.lineTo(@width, @height-10)
|
238
|
-
|
239
|
-
# Range handler line
|
240
|
-
xPos = @xOrigin + valueAtPoint * @width / @xRange
|
241
|
-
@context.moveTo(xPos, 0)
|
242
|
-
@context.lineTo(xPos, @height)
|
243
|
-
else
|
244
|
-
# Border next to range handler
|
245
|
-
@context.lineTo(0, @height)
|
232
|
+
renderGuide: (guide) ->
|
233
|
+
valueAtPoint = @model.get(guide.attribute)
|
246
234
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
@context.
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
235
|
+
@context.beginPath()
|
236
|
+
@context.setLineDash []
|
237
|
+
@context.strokeStyle = '#999999'
|
238
|
+
@context.lineWidth = 2
|
239
|
+
|
240
|
+
# Border below legend
|
241
|
+
@context.moveTo(@width, 0)
|
242
|
+
@context.lineTo(0, 0)
|
243
|
+
|
244
|
+
if guide.orientation is 'vertical'
|
245
|
+
# Border next to range handler
|
246
|
+
@context.moveTo(0, @height)
|
247
|
+
@context.lineTo(@width, @height)
|
248
|
+
@context.lineTo(@width, @height-10)
|
249
|
+
|
250
|
+
# Range handler line
|
251
|
+
xPos = @xOrigin + valueAtPoint * @width / @xRange
|
252
|
+
@context.moveTo(xPos, 0)
|
253
|
+
@context.lineTo(xPos, @height)
|
254
|
+
else
|
255
|
+
# Border next to range handler
|
256
|
+
@context.lineTo(0, @height)
|
257
|
+
|
258
|
+
# Range handler line
|
259
|
+
yPos = - valueAtPoint * @height / @yRange + @yOrigin
|
260
|
+
@context.moveTo(0, yPos)
|
261
|
+
@context.lineTo(@width, yPos)
|
262
|
+
|
263
|
+
@context.stroke()
|
264
|
+
@context.closePath()
|
265
|
+
|
266
|
+
@context.beginPath()
|
267
|
+
# The fillStyle of the triangle should match the color of the
|
268
|
+
# background set for the legend and range handler in screen.styl:
|
269
|
+
@context.fillStyle = "#f2f2f2"
|
270
|
+
@context.lineWidth = 1
|
271
|
+
|
272
|
+
if guide.orientation is 'vertical'
|
273
|
+
@context.moveTo(xPos + 8, 0)
|
274
|
+
@context.lineTo(xPos, 8)
|
275
|
+
@context.lineTo(xPos - 8, 0)
|
276
|
+
@context.moveTo(xPos - 8, @height)
|
277
|
+
@context.lineTo(xPos, @height - 8)
|
278
|
+
@context.lineTo(xPos + 8, @height)
|
279
|
+
else
|
280
|
+
@context.moveTo(0, yPos - 8)
|
281
|
+
@context.lineTo(8, yPos)
|
282
|
+
@context.lineTo(0, yPos + 8)
|
283
|
+
@context.moveTo(@width, yPos - 8)
|
284
|
+
@context.lineTo(@width - 8, yPos)
|
285
|
+
@context.lineTo(@width, yPos + 8)
|
286
|
+
@context.stroke()
|
287
|
+
@context.fill()
|
288
|
+
@context.closePath()
|
277
289
|
|
278
290
|
render: =>
|
279
291
|
super
|
280
|
-
@
|
292
|
+
for guide in @params.get('guides')
|
293
|
+
@renderGuide(guide)
|
281
294
|
this
|
@@ -1,5 +1,7 @@
|
|
1
1
|
ELA.Views ?= {}
|
2
2
|
class ELA.Views.Legend extends Backbone.Poised.View
|
3
|
+
className: 'legend'
|
4
|
+
|
3
5
|
valueCurveColumnTemplate: _.template '
|
4
6
|
<div class="values col<%= activeClass %>"
|
5
7
|
data-index="<%= curveIndex %>"
|
@@ -29,6 +31,7 @@ class ELA.Views.Legend extends Backbone.Poised.View
|
|
29
31
|
@useValueAtRange = options.useValueAtRange
|
30
32
|
@valueAtRangeAxis = options.valueAtRangeAxis or 'x'
|
31
33
|
@valueAtRangeAttribute = options.valueAtRangeAttribute or 'valueAtRange'
|
34
|
+
@_curves = options.curves
|
32
35
|
|
33
36
|
@model.on "change:#{@valueAtRangeAttribute}", @render
|
34
37
|
|
@@ -115,6 +118,14 @@ class ELA.Views.Legend extends Backbone.Poised.View
|
|
115
118
|
calculatorFunction: (curve) ->
|
116
119
|
"#{curve.get('function')}_value"
|
117
120
|
|
121
|
+
curves: =>
|
122
|
+
curves = @model.curves.whereInHistory()
|
123
|
+
if @_curves
|
124
|
+
_.filter curves, (curve) =>
|
125
|
+
@_curves.indexOf(curve.get('function')) >= 0
|
126
|
+
else
|
127
|
+
curves
|
128
|
+
|
118
129
|
render: =>
|
119
130
|
if @useValueAtRange
|
120
131
|
@range = @model.get(@valueAtRangeAttribute)
|
@@ -125,7 +136,7 @@ class ELA.Views.Legend extends Backbone.Poised.View
|
|
125
136
|
|
126
137
|
@renderValueHeaderColumn()
|
127
138
|
|
128
|
-
_.each
|
139
|
+
_.each(@curves(), @renderValueCurveColumn)
|
129
140
|
|
130
141
|
# Replace keeping horizontal scroll position
|
131
142
|
scrollLeft = @$el.find('.scroll-x').scrollLeft()
|
@@ -134,5 +145,5 @@ class ELA.Views.Legend extends Backbone.Poised.View
|
|
134
145
|
this
|
135
146
|
else
|
136
147
|
@$el.empty().addClass('legend-simple')
|
137
|
-
_.each
|
148
|
+
_.each(@curves(), @renderSimpleCurveColumn)
|
138
149
|
this
|
@@ -0,0 +1,26 @@
|
|
1
|
+
ELA.Views ?= {}
|
2
|
+
|
3
|
+
class ELA.Views.Viewport extends Backbone.Poised.View
|
4
|
+
tagName: 'article'
|
5
|
+
className: 'viewport'
|
6
|
+
|
7
|
+
initialize: (options = {}) ->
|
8
|
+
@views = for view in options.views
|
9
|
+
view.options = _.omit(view, 'view')
|
10
|
+
view.options.name = view.name or Math.random().toString(36).slice(-8)
|
11
|
+
view.View = view.view?.toFunction() or ELA.Views.GraphView
|
12
|
+
view
|
13
|
+
|
14
|
+
@subviews = {}
|
15
|
+
|
16
|
+
render: ->
|
17
|
+
@$el.empty()
|
18
|
+
for view in @views
|
19
|
+
options = _.extend
|
20
|
+
model: @model
|
21
|
+
parentView: this
|
22
|
+
localePrefix: @localePrefix
|
23
|
+
, view.options
|
24
|
+
view = @subviews[view.options.name] ?= new view.View(options)
|
25
|
+
@$el.append(view.render().el)
|
26
|
+
this
|
@@ -26,17 +26,7 @@
|
|
26
26
|
%button.button.poised.copy
|
27
27
|
- if @hasHelpText
|
28
28
|
%li.help= t('contextMenu.help')
|
29
|
-
|
30
|
-
- if @legendView
|
31
|
-
.legend
|
32
|
-
- if @graphOverlayView
|
33
|
-
.graph-overlay-wrapper
|
34
|
-
.graph-overlay
|
35
|
-
- if @graphView
|
36
|
-
.graph
|
37
|
-
- if @rangeHandlerView
|
38
|
-
.range-handler
|
29
|
+
.viewport
|
39
30
|
%a{ href: ELA.settings.upstream.url, target: '_blank' }
|
40
31
|
%img.logo{ src: 'images/logo.png' }
|
41
|
-
|
42
|
-
%aside.right.headup
|
32
|
+
%aside.right.headup
|
data/ela.gemspec
CHANGED
@@ -46,5 +46,5 @@ Gem::Specification.new do |spec|
|
|
46
46
|
spec.add_dependency "jasmine", "~> 2.9", ">= 2.9.0"
|
47
47
|
spec.add_dependency "rake", "~> 10.5", ">= 10.5.0"
|
48
48
|
spec.add_dependency "uglifier", "~> 4.1", ">= 4.1.5"
|
49
|
-
spec.add_dependency "andand"
|
49
|
+
spec.add_dependency "andand", "~> 1.3", ">= 1.3.3"
|
50
50
|
end
|
data/lib/ela/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ela
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Franz Kißig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -342,16 +342,22 @@ dependencies:
|
|
342
342
|
name: andand
|
343
343
|
requirement: !ruby/object:Gem::Requirement
|
344
344
|
requirements:
|
345
|
+
- - "~>"
|
346
|
+
- !ruby/object:Gem::Version
|
347
|
+
version: '1.3'
|
345
348
|
- - ">="
|
346
349
|
- !ruby/object:Gem::Version
|
347
|
-
version:
|
350
|
+
version: 1.3.3
|
348
351
|
type: :runtime
|
349
352
|
prerelease: false
|
350
353
|
version_requirements: !ruby/object:Gem::Requirement
|
351
354
|
requirements:
|
355
|
+
- - "~>"
|
356
|
+
- !ruby/object:Gem::Version
|
357
|
+
version: '1.3'
|
352
358
|
- - ">="
|
353
359
|
- !ruby/object:Gem::Version
|
354
|
-
version:
|
360
|
+
version: 1.3.3
|
355
361
|
description:
|
356
362
|
email:
|
357
363
|
- fkissig@velalu.qa
|
@@ -422,7 +428,9 @@ files:
|
|
422
428
|
- app/js/lib/models/base_subapp_container.coffee
|
423
429
|
- app/js/lib/models/curve.coffee
|
424
430
|
- app/js/lib/router.coffee
|
431
|
+
- app/js/lib/views/1_viewport_view.coffee
|
425
432
|
- app/js/lib/views/app.coffee
|
433
|
+
- app/js/lib/views/axis_handler.coffee
|
426
434
|
- app/js/lib/views/base_app.coffee
|
427
435
|
- app/js/lib/views/base_aside.coffee
|
428
436
|
- app/js/lib/views/base_graph.coffee
|
@@ -431,16 +439,17 @@ files:
|
|
431
439
|
- app/js/lib/views/curve_graph.coffee
|
432
440
|
- app/js/lib/views/curves_aside.coffee
|
433
441
|
- app/js/lib/views/curves_list_item.coffee
|
442
|
+
- app/js/lib/views/graph_view.coffee
|
434
443
|
- app/js/lib/views/grouped_parameters_aside.coffee
|
435
444
|
- app/js/lib/views/headup.coffee
|
436
445
|
- app/js/lib/views/help.coffee
|
437
446
|
- app/js/lib/views/interpolated_graph.coffee
|
438
447
|
- app/js/lib/views/legend.coffee
|
439
|
-
- app/js/lib/views/legend_handler.coffee
|
440
448
|
- app/js/lib/views/overview.coffee
|
441
449
|
- app/js/lib/views/overview_tile.coffee
|
442
450
|
- app/js/lib/views/parameters_aside.coffee
|
443
451
|
- app/js/lib/views/three_graph.coffee
|
452
|
+
- app/js/lib/views/viewport.coffee
|
444
453
|
- app/js/vendor/Markdown.Converter.js
|
445
454
|
- app/js/vendor/Markdown.Extra.js
|
446
455
|
- app/js/vendor/Markdown.Toc.coffee
|
@@ -674,7 +683,6 @@ files:
|
|
674
683
|
- dist/app_js/lib/views/help.js
|
675
684
|
- dist/app_js/lib/views/interpolated_graph.js
|
676
685
|
- dist/app_js/lib/views/legend.js
|
677
|
-
- dist/app_js/lib/views/legend_handler.js
|
678
686
|
- dist/app_js/lib/views/overview.js
|
679
687
|
- dist/app_js/lib/views/overview_tile.js
|
680
688
|
- dist/app_js/lib/views/parameters_aside.js
|
@@ -4358,7 +4366,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
4358
4366
|
version: '0'
|
4359
4367
|
requirements: []
|
4360
4368
|
rubyforge_project:
|
4361
|
-
rubygems_version: 2.
|
4369
|
+
rubygems_version: 2.7.3
|
4362
4370
|
signing_key:
|
4363
4371
|
specification_version: 4
|
4364
4372
|
summary: HTML5 E-Learning Framework
|
@@ -1,51 +0,0 @@
|
|
1
|
-
ELA.Views ?= {}
|
2
|
-
class ELA.Views.LegendHandler extends Backbone.Poised.View
|
3
|
-
events:
|
4
|
-
'pan': 'updateRange'
|
5
|
-
'tap': 'updateRange'
|
6
|
-
|
7
|
-
hammerjs:
|
8
|
-
recognizers: [
|
9
|
-
[Hammer.Rotate, { enable: false }],
|
10
|
-
[Hammer.Pinch, { enable: false }, ['rotate']],
|
11
|
-
[Hammer.Swipe, { enable: false }],
|
12
|
-
[Hammer.Pan, { direction: Hammer.DIRECTION_ALL, threshold: 1 }, ['swipe']],
|
13
|
-
[Hammer.Tap, { threshold: 5 }],
|
14
|
-
[Hammer.Press, { enable: false }]
|
15
|
-
]
|
16
|
-
|
17
|
-
initialize: (options) ->
|
18
|
-
super
|
19
|
-
@axis = options.axis or 'x'
|
20
|
-
@attribute = options.attribute or @axis
|
21
|
-
@precision = @model.get('valueAtRangePrecision') # TODO: Make this obsolete
|
22
|
-
@precision ?= options.precision
|
23
|
-
@precision ?= 2
|
24
|
-
|
25
|
-
@listenTo @model, "change:#{@attribute}", @renderText
|
26
|
-
|
27
|
-
updateRange: (e) =>
|
28
|
-
origin = @model.displayParams.get("#{@axis}Origin")
|
29
|
-
range = @model.displayParams.get("#{@axis}Range")
|
30
|
-
if @axis is 'x'
|
31
|
-
width = @model.displayParams.get('width')
|
32
|
-
point = (range / width) * (e.gesture.pointers[0].clientX - origin)
|
33
|
-
else
|
34
|
-
height = @model.displayParams.get('height')
|
35
|
-
y = e.gesture.pointers[0].clientY - @$el.offset().top
|
36
|
-
y = Math.min(Math.max(y, 0), height)
|
37
|
-
point = (range / height) * (origin - y)
|
38
|
-
|
39
|
-
pow = Math.pow(10, @precision)
|
40
|
-
point = Math.round(point * pow) / pow
|
41
|
-
@model.set(@attribute, point)
|
42
|
-
|
43
|
-
renderText: =>
|
44
|
-
@$el.find('span').text(t(@model.name + '.legendHandler.label', 'legendHandler.label', value: @model.get(@attribute).toFixed(@precision)))
|
45
|
-
|
46
|
-
render: =>
|
47
|
-
@$el.html('<span class="hint"></span>')
|
48
|
-
@$el.toggleClass('orientation-x', @axis is 'x')
|
49
|
-
@$el.toggleClass('orientation-y', @axis is 'y')
|
50
|
-
@renderText()
|
51
|
-
this
|