Skip to content
This repository was archived by the owner on Oct 4, 2023. It is now read-only.

Commit 055215c

Browse files
committed
Introducing mullti line Status chart but unfortunately, it was not able to produce a selection over identification_dates due to this bug: dc-js/dc.js#878
1 parent 136111a commit 055215c

File tree

1 file changed

+120
-37
lines changed

1 file changed

+120
-37
lines changed

metadata/static/catalog/js/panorama-generator.js

+120-37
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ d3.json(url, function(error, data) {
110110

111111

112112
// 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+
114120

115121
// Set the range of time x-axis:
116122
var timeParser = d3.time.format("%Y-%m-%d");
@@ -126,54 +132,131 @@ d3.json(url, function(error, data) {
126132
}
127133
}
128134

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;
138151
}
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;
146158
}
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;
155164
}
156165

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+
}
161178

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+
}
162204

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);
171219

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+
])
172254
// Rendering all charts:
173255
d3.selectAll("svg")
174256
.attr("width", "90%")
175257
.attr("viewbox","0 0 20 20");
176258

177259
dc.renderAll();
260+
178261
});
179262

0 commit comments

Comments
 (0)