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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more