@@ -110,7 +110,13 @@ d3.json(url, function(error, data) {
110
110
111
111
112
112
// Time Overall chart:
113
- var overallVolumeChart = dc . lineChart ( "#timelineChart" ) ;
113
+ // https://dc-js.github.io/dc.js/docs/html/dc.lineChart.html
114
+ var statusChart = dc . compositeChart ( "#timelineChart" ) ;
115
+
116
+ // Please check at https://github.com/dc-js/dc.js/issues/878
117
+ // for a bug preventing brush filter to work properly on multiline
118
+ // charts.
119
+
114
120
115
121
// Set the range of time x-axis:
116
122
var timeParser = d3 . time . format ( "%Y-%m-%d" ) ;
@@ -126,54 +132,131 @@ d3.json(url, function(error, data) {
126
132
}
127
133
}
128
134
129
- // https://github.com/dc-js/dc.js/wiki/FAQ#what-if-the-rows-contain-multiple-values
130
-
131
- function reduceFieldsAdd ( fields ) {
132
- return function ( p , v ) {
133
- fields . forEach ( function ( f ) {
134
- p [ f ] += v [ f ] ;
135
- } ) ;
136
- return p ;
137
- } ;
135
+ var overallDim = ndx . dimension ( function ( d ) { return timeParser . parse ( d [ "identification_date" ] ) ; } ) ;
136
+
137
+ // I was unable to pass the status value as a parameter
138
+ // so I had to reduce one by one:
139
+
140
+ //Reduce "Solved" entries:
141
+ function reduceSolvedAdd ( p , v ) {
142
+ if ( v [ 'status' ] == "Solved" )
143
+ p . status += + 1 ;
144
+ return p ;
145
+ }
146
+
147
+ function reduceSolvedRemove ( p , v ) {
148
+ if ( v [ 'status' ] == "Solved" )
149
+ p . status -= + 1 ;
150
+ return p ;
138
151
}
139
- function reduceFieldsRemove ( fields ) {
140
- return function ( p , v ) {
141
- fields . forEach ( function ( f ) {
142
- p [ f ] -= v [ f ] ;
143
- } ) ;
144
- return p ;
145
- } ;
152
+
153
+ //Reduce "Notified" entries:
154
+ function reduceNotifiedAdd ( p , v ) {
155
+ if ( v [ 'status' ] == "Notified" )
156
+ p . status += + 1 ;
157
+ return p ;
146
158
}
147
- function reduceFieldsInitial ( fields ) {
148
- return function ( ) {
149
- var ret = { } ;
150
- fields . forEach ( function ( f ) {
151
- ret [ f ] = 0 ;
152
- } ) ;
153
- return ret ;
154
- } ;
159
+
160
+ function reduceNotifiedRemove ( p , v ) {
161
+ if ( v [ 'status' ] == "Notified" )
162
+ p . status -= + 1 ;
163
+ return p ;
155
164
}
156
165
157
- var fields = [ 'status' ] ;
158
- var overallDim = ndx . dimension ( function ( d ) { return timeParser . parse ( d [ "identification_date" ] ) ; } ) ;
159
- // var overallGroup = overallDim.group().reduceCount(function(d) { return d.identification_date; });
160
- var overallGroup = overallDim . group ( ) . reduce ( reduceFieldsAdd ( fields ) , reduceFieldsRemove ( fields ) , reduceFieldsInitial ( fields ) ) ;
166
+ //Reduce "Mitigated" entries:
167
+ function reduceMitigatedAdd ( p , v ) {
168
+ if ( v [ 'status' ] == "Mitigated" )
169
+ p . status += + 1 ;
170
+ return p ;
171
+ }
172
+
173
+ function reduceMitigatedRemove ( p , v ) {
174
+ if ( v [ 'status' ] == "Mitigated" )
175
+ p . status -= + 1 ;
176
+ return p ;
177
+ }
161
178
179
+ //Reduce "Not identified" entries:
180
+ function reduceNIdentifiedAdd ( p , v ) {
181
+ if ( v [ 'status' ] == "Not identified" )
182
+ p . status += + 1 ;
183
+ return p ;
184
+ }
185
+
186
+ function reduceNIdentifiedRemove ( p , v ) {
187
+ if ( v [ 'status' ] == "Not identified" )
188
+ p . status -= + 1 ;
189
+ return p ;
190
+ }
191
+
192
+ //Reduce "Risk accepted" entries:
193
+ function reduceRiskAcceptedAdd ( p , v ) {
194
+ if ( v [ 'status' ] == "Risk accepted" )
195
+ p . status += + 1 ;
196
+ return p ;
197
+ }
198
+
199
+ function reduceRiskAcceptedRemove ( p , v ) {
200
+ if ( v [ 'status' ] == "Risk accepted" )
201
+ p . status -= + 1 ;
202
+ return p ;
203
+ }
162
204
163
- console . log ( overallDim . top ( Infinity ) ) ;
164
- console . log ( overallGroup . top ( Infinity ) ) ;
165
- overallVolumeChart
166
- . x ( d3 . time . scale ( ) . domain ( [ min , max ] ) )
167
- . dimension ( overallDim )
168
- . group ( overallGroup )
169
- . legend ( dc . legend ( ) . x ( 80 ) . y ( 20 ) . itemHeight ( 13 ) . gap ( 5 ) )
170
- . elasticX ( true ) ;
205
+ function reduceInitial ( ) {
206
+ return {
207
+ identification_date :0 ,
208
+ status :0
209
+ } ;
210
+ }
211
+
212
+ var notifiedGroup = overallDim . group ( ) . reduce ( reduceNotifiedAdd , reduceNotifiedRemove , reduceInitial ) ;
213
+
214
+ var solvedGroup = overallDim . group ( ) . reduce ( reduceSolvedAdd , reduceSolvedRemove , reduceInitial ) ;
215
+
216
+ var mitigatedGroup = overallDim . group ( ) . reduce ( reduceMitigatedAdd , reduceMitigatedRemove , reduceInitial ) ;
217
+
218
+ var nIdentifiedGroup = overallDim . group ( ) . reduce ( reduceNIdentifiedAdd , reduceNIdentifiedRemove , reduceInitial ) ;
171
219
220
+ var riskAcceptedGroup = overallDim . group ( ) . reduce ( reduceRiskAcceptedAdd , reduceRiskAcceptedRemove , reduceInitial ) ;
221
+
222
+ statusChart
223
+ . x ( d3 . time . scale ( ) . domain ( [ min , max ] ) )
224
+ . yAxisLabel ( "Vulnerabilities" )
225
+ . elasticX ( true )
226
+ . legend ( dc . legend ( ) . x ( 80 ) . y ( 20 ) . itemHeight ( 13 ) . gap ( 5 ) )
227
+ . compose ( [
228
+ dc . lineChart ( statusChart )
229
+ . dimension ( overallDim )
230
+ . colors ( 'grey' )
231
+ . valueAccessor ( function ( d ) { return d . value . status } )
232
+ . group ( notifiedGroup , "Notified" ) ,
233
+ dc . lineChart ( statusChart )
234
+ . dimension ( overallDim )
235
+ . colors ( 'green' )
236
+ . valueAccessor ( function ( d ) { return d . value . status } )
237
+ . group ( solvedGroup , "Solved" ) ,
238
+ dc . lineChart ( statusChart )
239
+ . dimension ( overallDim )
240
+ . valueAccessor ( function ( d ) { return d . value . status } )
241
+ . group ( mitigatedGroup , "Mitigated" ) ,
242
+ dc . lineChart ( statusChart )
243
+ . dimension ( overallDim )
244
+ . colors ( 'Crimson' )
245
+ . valueAccessor ( function ( d ) { return d . value . status } )
246
+ . group ( mitigatedGroup , "Not identified" ) ,
247
+ dc . lineChart ( statusChart )
248
+ . dimension ( overallDim )
249
+ . colors ( 'LightGrey' )
250
+ . valueAccessor ( function ( d ) { return d . value . status } )
251
+ . group ( riskAcceptedGroup , "Risk accepted" )
252
+
253
+ ] )
172
254
// Rendering all charts:
173
255
d3 . selectAll ( "svg" )
174
256
. attr ( "width" , "90%" )
175
257
. attr ( "viewbox" , "0 0 20 20" ) ;
176
258
177
259
dc . renderAll ( ) ;
260
+
178
261
} ) ;
179
262
0 commit comments