parallel_coordinates = {
var margin = {top: 30, right: 30, bottom: 20, left: 20};
var width = 1100 - margin.left - margin.right;
var height =1000 - margin.top - margin.bottom;
var x = d3.scalePoint().range([0, width]).padding(1),
y = {},
dragging= {};
var line = d3.line(),
axis = d3.axisLeft(),
background,
foreground;
var dimensions = null;
const svg = d3.select(DOM.svg(width + margin.left + margin.right, height+margin.top + margin.bottom));
const svg_adjusted = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var out = d3.select(output)
out.text(d3.tsvFormat(sample_data));
x.domain(dimensions = d3.keys(sample_data[0]).filter(function(d) {
return (y['Name']=d3.scalePoint()
.range([height,0])
.domain(NMDomain)) && d!="Gender" && d!= "Allegiances" && d!="Book Intro Chapter" && d!="GoT" && d!="CoK"&& d!="SoS" && d!="FfC" && d!="DwD" && (y[d] = d3.scaleLinear()
.domain(d3.extent(sample_data, function(p) { return +p[d]; }))
.range([height, 0]));
}));
background = svg_adjusted.append("g")
.attr("class", "background")
.selectAll("path")
.data(sample_data)
.enter().append("path")
.attr("d", path);
// Add blue foreground lines for focus.
foreground = svg_adjusted.append("g")
.attr("class", "foreground")
.selectAll("path")
.data(sample_data)
.enter().append("path")
.attr("d", path)
.attr('stroke',d=>color(d.Gender));
// Add a group element for each dimension.
function position(d) {
var v = dragging[d];
return v == null ? x(d) : v;
}
function transition(g) {
return g.transition().duration(500);
}
const g = svg_adjusted.selectAll(".dimension")
.data(dimensions)
.enter()
.append("g")
.attr("class", "dimension")
.attr("transform", function(d) { return "translate(" + x(d) + ")"; })
.call(d3.drag()
.subject(function(d) { return {x: x(d)}; })
.on("start", function(d) {
dragging[d] = x(d);
background.attr("visibility", "hidden");
})
.on("drag", function(d) {
dragging[d] = Math.min(width, Math.max(0, d3.event.x));
foreground.attr("d", path);
dimensions.sort(function(a, b) { return position(a) - position(b); });
x.domain(dimensions);
g.attr("transform", function(d) { return "translate(" + position(d) + ")"; })
})
.on("end", function(d) {
delete dragging[d];
transition(d3.select(this)).attr("transform", "translate(" + x(d) + ")");
transition(foreground).attr("d", path);
background
.attr("d", path)
.transition()
.delay(500)
.duration(0)
.attr("visibility", null);
}));
// Creating array
var arr = [];
var i;
for (i = 0; i < 301; i++) {
arr.push(i);
}
// Add an axis and title.
g.append("g")
.attr("class", "axis")
.attr("id", function(d) {return ("axis" + d).replace(/\s+/g, '');})
.each(function(d) {
if(d ==="Allegiance Index")
{
d3.select(this).call(axis.scale(y[d]).tickFormat(
function(d)
{
if(d===1) {return "Arryn";}
else if(d===2) {return "Baratheon";}
else if(d===3) {return "Greyjoy";}
else if(d===4) {return "Lannister";}
else if(d===5) {return "Martell";}
else if(d===6) {return "Night's Watch";}
else if(d===7) {return "Stark";}
else if(d===8) {return "Targaryen";}
else if(d===9) {return "Tully";}
else if(d===10) {return "Tyrell";}
else if(d===11) {return "Wilding";}
else {return "None";}
}).tickValues([0,1,2,3,4,5,6,7,8,9,10,11])
)
}
else if( d === "Death Year")
{
d3.select(this).call(axis.scale(y[d]).tickFormat(
function(d)
{
if(d===296) {return "Unknow";}
else {return d;}
}).tickValues([296, 297, 298, 299, 300])
)
}
else if( d === "Book of Death")
{
d3.select(this).call(axis.scale(y[d]).tickFormat(
function(d)
{
if(d===1) {return "I GoT";}
if(d===2) {return "II CoK";}
if(d===3) {return "III SoS";}
if(d===4) {return "IV FfC";}
if(d===5) {return "V DwD";}
else {return "Unkown";}
}).tickValues([0,1,2,3,4,5,])
)
}
else if( d === "Death Chapter")
{
d3.select(this).call(axis.scale(y[d]).tickFormat(
function(d)
{
return d;
}).tickValues([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75
,76,77,78,79,80])
)
}
else
{
d3.select(this).call(axis.scale(y[d]));
}
})
.append("text")
.style("text-anchor", "middle")
.attr("y", -9)
.text(function(d) { return d; });
// Add and store a brush for each axis.
g.append("g")
.attr("class", "brush")
.each(function(d) {
d3.select(this).call(y[d].brush = d3.brushY()
.extent([[-10,-10], [10,height+10]])
.on("brush", brush)
.on("end", brush)
)
})
.selectAll("rect")
.attr("x", -8)
.attr("width", 16);
// Returns the path for a given data point.
function path(d) {
return line(dimensions.map(function(p) { return [x(p), y[p](d[p])]; }));
}
function brushstart() {
d3.event.sourceEvent.stopPropagation();
}
// Handles a brush event, toggling the display of foreground lines.
function brush() {
var actives = [];
svg.selectAll(".brush")
.filter(function(d) {
y[d].brushSelectionValue = d3.brushSelection(this);
return d3.brushSelection(this);
})
.each(function(d) {
// Get extents of brush along each active selection axis (the Y axes)
actives.push({
dimension: d,
extent: d3.brushSelection(this).map(y[d].invert)
});
});
var selected = [];
// Update foreground to only display selected values
foreground.style("display", function(d) {
return actives.every(function(active) {
let result = active.extent[1] <= d[active.dimension] && d[active.dimension] <= active.extent[0];
if(result)selected.push(d);
return result;
}) ? null : "none";
});
(actives.length>0)? out.text(d3.tsvFormat(selected)):out.text(d3.tsvFormat(sample_data));
}
function updatepath(){
var str=document.getElementById("searchid").value;
var searched = [];
foreground.style("display", function(d) {
let rst = issubstr(d['Name'],str);
if (rst) searched.push(d);
return rst;
})? null: "none";
(searched.length>0)? out.text(d3.tsvFormat(searched)):out.text(d3.tsvFormat(sample_data));
}
return svg.node();
}