Notebooks 2.0 is here.

Published
Edited
Oct 14, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
var currentValue = 0;
var formatDateIntoYear = d3.timeFormat("%H:%M");
const svg = d3.select(DOM.svg(time_width + 50, time_height));
var slider = svg.append("g")
.attr("class", "slider")
.attr("transform", "translate(" + 25 + "," + 100/2 + ")");

var startDate = data_time[0]["StartTime"];
var endDate = data_time[data_time.length - 1]["LastTime"];

slider.append("line")
.attr("class", "track")
.attr("x1", x_time.range()[0])
.attr("x2", x_time.range()[1])
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "track-inset")
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
.attr("class", "track-overlay")
.call(d3.drag()
.on("start.interrupt", function() { slider.interrupt(); })
.on("start drag", function(event, d) {
currentValue = event.x;
//update(x_time.invert(currentValue));
})
);

slider.insert("g", ".track-overlay")
.attr("class", "ticks")
.attr("transform", "translate(0," + 18 + ")")
.selectAll("text")
.data(x_time.ticks(15))
.enter()
.append("text")
.attr("x", x_time)
.attr("y", 10)
.attr("text-anchor", "middle")
.text(function(d) { return formatDateIntoYear(d); });


var handle = slider.insert("circle", ".track-overlay")
.attr("class", "handle")
.attr("r", 9);

var label = slider.append("text")
.attr("class", "label")
.attr("text-anchor", "middle")
.text(formatDateIntoYear(startDate))
.attr("transform", "translate(0," + (-25) + ")")


var moving = false;
var currentValue = 0;
var targetValue = time_width;
var timer;
function step() {
update(x_time.invert(currentValue));
//currentValue = currentValue + (targetValue/151);
currentValue = currentValue + 1;
if (currentValue > targetValue) {
moving = false;
currentValue = 0;
clearInterval(timer);
// timer = 0;
}
}

function update(h) {
// update position and text of label according to slider scale
handle.attr("cx", x_time(h));
label
.attr("x", x_time(h))
.text(formatDateIntoYear(h));
// filter data set and redraw plot
//console.log(h)
var newData = data_time.filter(function(d) {
var check = d.StartTime < h;
var check_2 = new Date(d.LastTime.getTime() + 1 * 60000) > h;
return (check && check_2)
//return check
})
//console.log(newData)
drawPlot(newData);
}
function onClick() {
if ((replay %2) == 0) {
console.log("I am even");
moving=true
timer = setInterval(step, 100);
} else {
console.log("I am odd");
moving=false
clearInterval(timer);
}
}

//function drawCircle(selection) {
// selection.attr("r", function (d) { return z(d.TotBytes); } )
//}

function drawPlot(dataset, h) {
var dots = svg.select(".graphContent")
.selectAll(".bubbles")
.data(dataset)
.join(
enter =>
enter.append("circle")
.attr("class", function(d) { return "bubbles ".concat(classification_mapping[d.Classification]) })
//.attr("start", d => d.StartTime)
//.attr("last", d=>d.LastTime)
//.attr("extra", d => new Date(d.LastTime.getTime() + 0.5 * 60000))
//.attr("h", h)
.style("opacity", "0")
,
update => update,
function(exit) {
//console.log("I get in exit")
exit
.transition()
.attr("r", 0)
.on('end', function() {
d3.select(this).remove();
})
}
)
.attr("cx", function (d) {
return x(ipaddress_map_time[d.SrcAddr]);
})
.attr("cy", function (d) { return y(d.Sport); } )
.style("fill", function (d) { return myColor(d.Classification); } )
.style("opacity", "0.6")
.attr("r", function (d) { return z(d.TotBytes); } )


}
var ip_values = [];
Object.keys(ipaddress_map_time).forEach(function(key) {
ip_values.push(ipaddress_map_time[key]);
});

var classification_mapping = {0:"Normal", 1:"Ransomware", 2:"MiTM", 3:"Trojan"};
var portRange = d3.extent(data_time, d=>d.Sport);
var srcRange = d3.extent(data_time, d=>d.SrcRate);

// Add X axis
// scalePoint creates scale functions that map from a discrete set of values to equally spaced points along the specified range
var x = d3.scalePoint()
.domain(ip_values)
.range([50, time_width]);

var xAxis = g => g
.attr("transform", "translate(0," + (time_height-time_margin.bottom)+")")
.call(d3.axisBottom(x).ticks(ip_values.length))

svg.append("g")
.attr("class", "x axis")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");

// Add X axis label:
svg.append("text")
.attr("text-anchor", "end")
.attr("x", time_width - 100)
.attr("y", time_height )
.text("IP Address");

// Add Y axis
var y = d3.scaleLinear()
.domain(portRange)
.range([ time_height - time_margin.bottom, time_margin.top]);

const gy = svg.append("g")
.attr("class", "yaxis")
.attr("transform", "translate(50,0)")
.call(yAxis, y);
// Add Y axis label:
svg.append("text")
.attr("text-anchor", "end")
.attr("x", 10)
.attr("y", 0 )
.text("Source Port")
.attr("text-anchor", "start")

svg.append('g')
.attr("class", "graphContent")
//update(dateFormatter(data_time[10]["StartTime"]));
onClick()
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
new Date(new Date("Wed Jun 23 2021 12:34:56 GMT+0100 (British Summer Time)").getTime() + 5 * 60000)
Insert cell
replay
Insert cell
md`## Appendix`
Insert cell
Insert cell
d3 = require("d3@6")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more