4
4
* http://www.opensource.org/licenses/mit-license.php
5
5
*/
6
6
7
+ /*global define, WorldWind*/
8
+
7
9
/**
8
10
* FireLookout content module.
9
11
*
@@ -27,19 +29,35 @@ define(['knockout',
27
29
* The view model for an individual FireLookout.
28
30
* @constructor
29
31
*/
30
- function FireLookoutView ( ) {
32
+ function FireLookoutView ( globe ) {
31
33
var self = this ;
32
- this . margin = { top : 20 , right : 15 , bottom : 60 , left : 60 } ;
33
-
34
+ this . globe = globe ;
35
+
36
+ // Haul Chart dimensions
37
+ this . haulChartContainter = null ;
38
+ this . margin = { top : 20 , right : 15 , bottom : 30 , left : 40 } ;
34
39
this . width = 400 - this . margin . left - this . margin . right ;
35
40
this . height = 300 - this . margin . top - this . margin . bottom ;
36
- this . btuDomain = [ 10 , 11000 ] ;
37
- this . rosDomain = [ 1 , 1100 ] ;
41
+ // Chart x/y domains
42
+ this . btuDomain = [ 10 , 11000 ] ; // btu/ft^2
43
+ this . rosDomain = [ 0.1 , 1100 ] ; // chains/hr
44
+ // Chart colors for fire behavior adjectives
45
+ this . COLOR_LOW = WorldWind . Color . colorFromBytes ( 128 , 127 , 255 , 200 ) ; // blue
46
+ this . COLOR_MODERATE = WorldWind . Color . colorFromBytes ( 127 , 193 , 151 , 200 ) ; // green
47
+ this . COLOR_ACTIVE = WorldWind . Color . colorFromBytes ( 255 , 179 , 130 , 200 ) ; // tan
48
+ this . COLOR_VERY_ACTIVE = WorldWind . Color . colorFromBytes ( 255 , 128 , 255 , 200 ) ; // magenta
49
+ this . COLOR_EXTREME = WorldWind . Color . colorFromBytes ( 253 , 128 , 124 , 200 ) ; // orange
50
+ // Flame Length thresholds
51
+ this . FL_THRESHOLD_LOW = 1 ;
52
+ this . FL_THRESHOLD_MODERATE = 3 ;
53
+ this . FL_THRESHOLD_ACTIVE = 7 ;
54
+ this . FL_THRESHOLD_VERY_ACTIVE = 15 ;
55
+
38
56
39
57
40
58
// Define custom Knockout bindings for a FireLookout.
41
59
ko . bindingHandlers . visualizeWildfireDiamond = {
42
- init : function ( element , valueAccessor , allBindings , viewModel , bindingContext ) {
60
+ init : function ( element , valueAccessor , allBindings , viewModel /*deprecated*/ , bindingContext ) {
43
61
// This will be called when the binding is first applied to an element
44
62
// Set up any initial state, event handlers, etc. here
45
63
} ,
@@ -50,19 +68,26 @@ define(['knockout',
50
68
}
51
69
} ;
52
70
ko . bindingHandlers . visualizeHaulChart = {
53
- init : function ( element , valueAccessor , allBindings , lookout , bindingContext ) {
71
+ init : function ( element , valueAccessor , allBindings , viewModel /*deprecated*/ , bindingContext ) {
54
72
// This will be called when the binding is first applied to an element
55
73
// Set up any initial state, event handlers, etc. here
56
- self . createHaulChart ( element ) ;
74
+ console . log ( "visualizeHaulChart.init called" ) ;
75
+ self . haulChartContainter = element ;
76
+ // Draw the initial haul chart
77
+ var lookout = bindingContext . $data ; // observable
78
+ self . createHaulChart ( lookout . fireBehavior ( ) ) ; // observable
57
79
} ,
58
- update : function ( element , valueAccessor , allBindings , lookout , bindingContext ) {
80
+ update : function ( element , valueAccessor , allBindings , viewModel /*deprecated*/ , bindingContext ) {
59
81
// This will be called once when the binding is first applied to an element,
60
82
// and again whenever any observables/computeds that are accessed change.
61
- self . updateHaulChart ( element , lookout ) ;
83
+ console . log ( "visualizeHaulChart.update called" ) ;
84
+ // Update the haul chart
85
+ var lookout = bindingContext . $data ; // observable
86
+ self . updateHaulChart ( lookout . fireBehavior ( ) ) ; // observable
62
87
}
63
88
} ;
64
89
ko . bindingHandlers . visualizeFuelModel = {
65
- init : function ( element , valueAccessor , allBindings , viewModel , bindingContext ) {
90
+ init : function ( element , valueAccessor , allBindings , viewModel /*deprecated*/ , bindingContext ) {
66
91
// This will be called when the binding is first applied to an element
67
92
// Set up any initial state, event handlers, etc. here
68
93
} ,
@@ -73,7 +98,7 @@ define(['knockout',
73
98
}
74
99
} ;
75
100
ko . bindingHandlers . visualizeFireBehavior = {
76
- init : function ( element , valueAccessor , allBindings , viewModel , bindingContext ) {
101
+ init : function ( element , valueAccessor , allBindings , viewModel /*deprecated*/ , bindingContext ) {
77
102
// This will be called when the binding is first applied to an element
78
103
// Set up any initial state, event handlers, etc. here
79
104
} ,
@@ -86,11 +111,9 @@ define(['knockout',
86
111
}
87
112
88
113
/**
89
- * Display the wildfire's timeline with a vis.js Timeline.
90
- * See: http://visjs.org/docs/timeline/
91
- *
114
+ * Display the Wildfire Diamond representing the current fire behavior
92
115
* @param {type } element DOM element where the Timeline will be attached
93
- * @param {type } wildfire The Wildfire model element
116
+ * @param {type } lookout
94
117
*/
95
118
FireLookoutView . prototype . drawWildfireDiamond = function ( element , lookout ) {
96
119
// TODO: Draw .png as a placemark for future d3 development
@@ -99,121 +122,143 @@ define(['knockout',
99
122
100
123
101
124
/**
102
- * Display the percent contained in a radial progress chart via d3,
103
- * with the uncontained percentage displayed in red (e.g., uncontrolled fire).
104
- * See: https://github.com/d3/d3/blob/master/API.md
125
+ * Display the Haul Chart
105
126
*
106
- * @param {type } element DOM element where the Timeline will be attached
107
- * @param {type } wildfire The Wildfire model element
127
+ * @param {type } fireBehavior The fire behavior to be visualized
108
128
*/
109
- FireLookoutView . prototype . createHaulChart = function ( element , lookout ) {
110
- var fireBehavior = lookout . fireBehavior ;
111
- var heatRelease = ( fireBehavior === null ? 0 : fireBehavior . heatRelease ) ,
112
- rateOfSpreadMax = ( fireBehavior === null ? 0 : fireBehavior . rateOfSpreadMax ) ,
113
- rateOfSpreadFlanking = ( fireBehavior === null ? 0 : fireBehavior . rateOfSpreadFlanking ) ,
114
- rateOfSpreadBacking = ( fireBehavior === null ? 0 : fireBehavior . rateOfSpreadNoWindNoSlope ) ,
115
- data = [ [ heatRelease , rateOfSpreadMax ] , [ heatRelease , rateOfSpreadFlanking ] ] ;
129
+ FireLookoutView . prototype . createHaulChart = function ( fireBehavior ) {
130
+ console . log ( "createHaulChart called" ) ;
131
+ this . width = parseInt ( d3 . select ( this . haulChartContainter ) . style ( 'width' ) , 10 ) ;
132
+ this . width = this . width - this . margin . left - this . margin . right ;
133
+
134
+ var heatRelease = ( Number . isNaN ( fireBehavior . heatRelease ) ? 0 : Number ( fireBehavior . heatRelease ) ) ,
135
+ rateOfSpreadHead = ( Number . isNaN ( fireBehavior . rateOfSpreadMax ) ? 0 : Number ( fireBehavior . rateOfSpreadMax ) ) / 1.1 , //ft/min to ch/hr
136
+ rateOfSpreadFlanking = ( Number . isNaN ( fireBehavior . rateOfSpreadFlanking ) ? 0 : Number ( fireBehavior . rateOfSpreadFlanking ) ) / 1.1 ,
137
+ rateOfSpreadBacking = ( Number . isNaN ( fireBehavior . rateOfSpreadBacking ) ? 0 : Number ( fireBehavior . rateOfSpreadBacking ) ) / 1.1 ,
138
+ dataset = [
139
+ [ heatRelease , rateOfSpreadHead ] ,
140
+ [ heatRelease , rateOfSpreadFlanking ] ,
141
+ [ heatRelease , rateOfSpreadBacking ] ] ;
116
142
117
143
var x = d3 . scaleLog ( ) // btu
118
144
. domain ( this . btuDomain )
119
145
. range ( [ 0 , this . width ] ) ;
120
146
121
- var y = d3 . scaleLog ( ) // ros ft/min
147
+ var y = d3 . scaleLog ( ) // ros ch/hr
122
148
. domain ( this . rosDomain )
123
149
. range ( [ this . height , 0 ] ) ;
124
150
125
- var chart = d3 . select ( element )
151
+ var chart = d3 . select ( this . haulChartContainter )
126
152
. append ( 'svg:svg' )
127
153
. attr ( 'width' , this . width + this . margin . right + this . margin . left )
128
154
. attr ( 'height' , this . height + this . margin . top + this . margin . bottom )
129
- . attr ( 'class' , 'chart' )
155
+ . attr ( 'class' , 'chart' ) ;
130
156
131
- var main = chart . append ( 'g' )
157
+ var xyPlot = chart . append ( 'g' )
132
158
. attr ( 'transform' , 'translate(' + this . margin . left + ',' + this . margin . top + ')' )
133
159
. attr ( 'width' , this . width )
134
160
. attr ( 'height' , this . height )
135
- . attr ( 'class' , 'main' )
161
+ . attr ( 'class' , 'xyplot' ) ;
136
162
137
163
// draw the x axis
138
- var xAxis = d3 . axisBottom ( x ) ;
139
- main . append ( 'g' )
164
+ var xAxis = d3 . axisBottom ( x )
165
+ . ticks ( 4 , d3 . format ( ",.0f" ) ) ;
166
+ xyPlot . append ( 'g' )
140
167
. attr ( 'transform' , 'translate(0,' + this . height + ')' )
141
- . attr ( 'class' , 'main axis btu' )
142
- . call ( xAxis ) ;
168
+ . attr ( 'class' , 'xyplot axis btu' )
169
+ . call ( xAxis ) ;
143
170
144
171
// draw the y axis
145
- var yAxis = d3 . axisLeft ( y ) ;
146
- main . append ( 'g' )
172
+ var yAxis = d3 . axisLeft ( y )
173
+ . ticks ( 5 , d3 . format ( ",.0f" ) ) ;
174
+ xyPlot . append ( 'g' )
147
175
. attr ( 'transform' , 'translate(0,0)' )
148
- . attr ( 'class' , 'main axis ros' )
176
+ . attr ( 'class' , 'xyplot axis ros' )
149
177
. call ( yAxis ) ;
150
178
151
- var g = main . append ( "svg:g" )
179
+ var g = xyPlot . append ( "svg:g" )
152
180
. attr ( 'id' , 'plot' ) ;
153
181
154
182
g . selectAll ( "scatter-dots" )
155
- . data ( data )
183
+ . data ( dataset )
156
184
. enter ( ) . append ( "svg:circle" )
157
185
. attr ( "cx" , function ( d ) {
158
186
return x ( d [ 0 ] ) ;
159
187
} )
160
188
. attr ( "cy" , function ( d ) {
161
189
return y ( d [ 1 ] ) ;
162
190
} )
163
- . attr ( "r" , 8 ) ;
191
+ . attr ( "r" , 4 ) ;
164
192
} ;
165
193
/**
166
- * Display the percent contained in a radial progress chart via d3,
167
- * with the uncontained percentage displayed in red (e.g., uncontrolled fire).
168
- * See: https://github.com/d3/d3/blob/master/API.md
169
- *
170
- * @param {type } element DOM element where the Timeline will be attached
171
- * @param {type } wildfire The Wildfire model element
194
+ * Update the Haul Chart.
195
+ * @param {type } fireBehavior The fire behavior data
172
196
*/
173
- FireLookoutView . prototype . updateHaulChart = function ( element , lookout ) {
174
- var self = this ;
175
- // Everytime the selected FireLookout is changed, we need to
176
- // subscribe to the lookout's fire behavior observable to update
177
- // the chart when the fire behavior changes.
178
- //
179
- // TODO: does the leak if we don't unsubscribe?
180
- lookout . fireBehavior . subscribe ( function ( fireBehavior ) {
181
-
182
- var heatRelease = ( fireBehavior === null ? 0 : fireBehavior . heatRelease ) ,
183
- rateOfSpreadMax = ( fireBehavior === null ? 0 : fireBehavior . rateOfSpreadMax ) ,
184
- rateOfSpreadFlanking = ( fireBehavior === null ? 0 : fireBehavior . rateOfSpreadFlanking ) ,
185
- rateOfSpreadBacking = ( fireBehavior === null ? 0 : fireBehavior . rateOfSpreadNoWindNoSlope ) ,
186
- data = [ [ heatRelease , rateOfSpreadMax ] , [ heatRelease , rateOfSpreadFlanking ] ] ;
187
-
188
- var x = d3 . scaleLog ( ) // btu
189
- . domain ( self . btuDomain )
190
- . range ( [ 0 , self . width ] ) ;
191
-
192
- var y = d3 . scaleLog ( ) // ros ft/min
193
- . domain ( self . rosDomain )
194
- . range ( [ self . height , 0 ] ) ;
197
+ FireLookoutView . prototype . updateHaulChart = function ( fireBehavior ) {
198
+ console . log ( "updateHaulChart called" ) ;
199
+
200
+ var heatRelease = ( Number . isNaN ( fireBehavior . heatRelease ) ? 0 : Number ( fireBehavior . heatRelease ) ) ,
201
+ rateOfSpreadHead = ( Number . isNaN ( fireBehavior . rateOfSpreadMax ) ? 0 : Number ( fireBehavior . rateOfSpreadMax ) ) / 1.1 ,
202
+ rateOfSpreadFlanking = ( Number . isNaN ( fireBehavior . rateOfSpreadFlanking ) ? 0 : Number ( fireBehavior . rateOfSpreadFlanking ) ) / 1.1 ,
203
+ rateOfSpreadBacking = ( Number . isNaN ( fireBehavior . rateOfSpreadBacking ) ? 0 : Number ( fireBehavior . rateOfSpreadBacking ) ) / 1.1 ,
204
+ dataset = [
205
+ [ heatRelease , rateOfSpreadHead ] ,
206
+ [ heatRelease , rateOfSpreadFlanking ] ,
207
+ [ heatRelease , rateOfSpreadBacking ] ] ;
195
208
196
- var chart = d3 . select ( element ) ;
197
- var g = chart . selectAll ( "#plot" ) ;
209
+ // TODO: Rescale to fire behavior vals
210
+ var x = d3 . scaleLog ( ) // btu
211
+ . domain ( this . btuDomain )
212
+ . range ( [ 0 , this . width ] ) ;
213
+ var y = d3 . scaleLog ( ) // ros ft/min
214
+ . domain ( this . rosDomain )
215
+ . range ( [ this . height , 0 ] ) ;
198
216
199
- g . selectAll ( "scatter-dots" )
200
- . data ( data )
201
- . attr ( "cx" , function ( d ) {
202
- return x ( d [ 0 ] ) ;
203
- } )
204
- . attr ( "cy" , function ( d ) {
205
- return y ( d [ 1 ] ) ;
206
- } )
207
- . attr ( "r" , 8 ) ;
208
- } ) ;
217
+ var chart = d3 . select ( this . haulChartContainter ) ;
218
+ var g = chart . selectAll ( "#plot" ) ;
219
+
220
+ // Update the values
221
+ g . selectAll ( "circle" )
222
+ . data ( dataset )
223
+ . attr ( "cx" , function ( d ) {
224
+ return x ( d [ 0 ] ) ;
225
+ } )
226
+ . attr ( "cy" , function ( d ) {
227
+ return y ( d [ 1 ] ) ;
228
+ } )
229
+ . attr ( "r" , 4 ) ;
230
+
231
+ // // Update all circles
232
+ // chart.selectAll('circle')
233
+ // .data(dataset)
234
+ // .transition() // Transition 1
235
+ // .duration(1000)
236
+ // .ease('circle')
237
+ // .each('start', function() {
238
+ // d3.select(this)
239
+ // .attr('fill', 'gray')
240
+ // .attr('r', 2);
241
+ // })
242
+ // .attr('cx', function(d) {
243
+ // return xScale(d[0]);
244
+ // })
245
+ // .attr('cy', function(d) {
246
+ // return yScale(d[1]);
247
+ // })
248
+ // .transition() // Transition 2, equiv to below
249
+ // .duration(250)
250
+ // .attr('fill', 'teal')
251
+ // .attr('r', 4);
252
+ //
253
+
254
+
209
255
} ;
210
256
211
257
/**
212
- * Display the wildfire size as a category in a segmented chart via d3.
213
- * See: https://github.com/d3/d3/blob/master/API.md
214
- *
215
- * @param {type } element DOM element where the Timeline will be attached
216
- * @param {type } wildfire The Wildfire model element
258
+ * Render a photo and description of the current fuel model
259
+ * @param {type } element
260
+ * @param {type } wildfire
261
+ * @returns {undefined }
217
262
*/
218
263
FireLookoutView . prototype . drawFuelModel = function ( element , wildfire ) {
219
264
0 commit comments