ela 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c15b734be84e2dddf4635beb7aa6abe1f47fc239
4
- data.tar.gz: 78645f77c6010b814633efbada7d16ac0aaee886
2
+ SHA256:
3
+ metadata.gz: 17010b55c4244377534fb008bb8b00701b2ec1f3a03b8c08e57ca9ffb8321860
4
+ data.tar.gz: 9ea5fbd11fb13b0ed539ffb903a8f4d543a3a2e7ab92054dcb2afd2d31f9a22f
5
5
  SHA512:
6
- metadata.gz: f1a654e0bd2929e6dc48708fcbee1287201eb21eadb2210b03cd5a9f8aa85321594015437b6b9eac162765b4b7226d0717c22161e6710506bab151978680ae28
7
- data.tar.gz: 4dab676b14d1335be385368ef38eebb06e1947928faa7c951b6ac182f16a1ebc4e9d3605ebc171ee824d6e6cc96356531dda15c58a96cb78dc1291b1fbe371cc
6
+ metadata.gz: 226cd20184cdde3a1f651d205995e4de2c0527357a789ff3a49aa6d268da1eea5431a16298e422d6be5fa75220c10af07577929d7675f361f8b8146e8f9c5b5b
7
+ data.tar.gz: 0b6e09af8f8b0cd19557e2030c139cbbd84ff84d14c53996c3ae88f8decb33e38fc71728608a7673f5d905b8c6c87814e954533536eacd57ac546d7a0c5a2fa1
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ela (1.0.4)
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
@@ -1,5 +1,5 @@
1
1
  // ELA specific
2
- $range-handler-width = 59px
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.graph
115
+ article.viewport
116
116
  display flex
117
- flex-direction column
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.range-handler
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
- &.orientation-y
227
- absolute 0 none 0 0
228
- width $range-handler-width
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 $range-handler-width
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 $range-handler-width
363
+ height $axis-handler-size
353
364
  z-layer 'section', 'graph'
354
365
 
355
366
  @media $media-lt-phone
@@ -0,0 +1,4 @@
1
+ ELA.Views ?= {}
2
+
3
+ class ELA.Views.ViewportView extends Backbone.Poised.View
4
+ className: 'view active'
@@ -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
- asideViews: []
12
+ asides: []
13
13
 
14
- legendView: null
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
- if @useHeadup
59
- @on 'controlLiveChangeStart', @liveChangeStart
60
- @on 'controlLiveChangeEnd', @liveChangeEnd
40
+ @on 'controlLiveChangeStart', @liveChangeStart
41
+ @on 'controlLiveChangeEnd', @liveChangeEnd
61
42
 
62
- for asideView in @asideViews
63
- asideView.link ?= 'icon'
43
+ for aside in @asides
44
+ aside.link ?= 'icon'
64
45
 
65
- if @graphView?
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(@asideViews, (asideView) ->
121
- asideView.name if asideView.link is 'icon'
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(@asideViews, (asideView) =>
127
- if asideView.link is 'contextMenu'
128
- name: asideView.name
129
- label: @loadLocale("contextMenu.#{asideView.name}")
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 @asideViews
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
- if @legendView? and not @subviews.legend
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
- delay =>
249
- if @graphView? and not @subviews.graph
250
- @$graph = @$('article .graph')
251
- GraphView = @graphView.toFunction()
252
- @subviews.graph = view = new GraphView
253
- model: @model
254
- parentView: this
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(@readCanvasResolution)
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
- if attr = @params.get('valueAtRangeAttribute')
18
- @model.on "change:#{attr}", @requestRepaint
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
- for curve in @model.curves.history
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 = @model.curves.history[0]
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 @model.curves.history, (c) ->
129
- c.attributes.zIndex
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
- renderRangeIndicator: ->
223
- if @params.get('valueAtRangeAttribute') and (valueAtPoint = @model.get(@params.get('valueAtRangeAttribute')))?
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
- # Range handler line
248
- yPos = - valueAtPoint * @height / @yRange + @yOrigin
249
- @context.moveTo(0, yPos)
250
- @context.lineTo(@width, yPos)
251
- @context.stroke()
252
- @context.closePath()
253
-
254
- @context.beginPath()
255
- # The fillStyle of the triangle should match the color of the
256
- # background set for the legend and range handler in screen.styl:
257
- @context.fillStyle = "#f2f2f2"
258
- @context.lineWidth = 1
259
-
260
- if axis is 'x'
261
- @context.moveTo(xPos + 8, 0)
262
- @context.lineTo(xPos, 8)
263
- @context.lineTo(xPos - 8, 0)
264
- @context.moveTo(xPos - 8, @height)
265
- @context.lineTo(xPos, @height - 8)
266
- @context.lineTo(xPos + 8, @height)
267
- else
268
- @context.moveTo(0, yPos - 8)
269
- @context.lineTo(8, yPos)
270
- @context.lineTo(0, yPos + 8)
271
- @context.moveTo(@width, yPos - 8)
272
- @context.lineTo(@width - 8, yPos)
273
- @context.lineTo(@width, yPos + 8)
274
- @context.stroke()
275
- @context.fill()
276
- @context.closePath()
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
- @renderRangeIndicator()
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 @model.curves.whereInHistory(), @renderValueCurveColumn
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 @model.curves.whereInHistory(), @renderSimpleCurveColumn
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
- %article.graph.active
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
- - if @useHeadup
42
- %aside.right.headup
32
+ %aside.right.headup
@@ -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
@@ -1,3 +1,3 @@
1
1
  module ELA
2
- VERSION = '1.1.0'
2
+ VERSION = '2.0.0'
3
3
  end
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: 1.1.0
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-05 00:00:00.000000000 Z
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: '0'
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: '0'
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.6.12
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