chart = {
const margin = {top: 40, right: 40, bottom: 20, left: 50};
const svg_width = 600;
const svg_height = 400;
const group_width = svg_width - margin.left - margin.right;
const group_height = svg_height - margin.top - margin.bottom;
const colorScale = d3.scaleOrdinal()
.domain(["battleship", "carrier", "cruiser"])
.range(["#FF5733", "#338FFF", "#33FF57"]);
const svg = d3.create("svg")
.attr("width", svg_width)
.attr("height", svg_height);
const group = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
let dimensions = ['Displacement', 'Length', 'Beam', 'Draft', 'Speed', 'Crew']
const y = {};
dimensions.forEach(dim => {
y[dim] = d3.scaleLinear()
.domain(d3.extent(data_cleaned, d => d[dim]))
.range([group_height, 0]);
});
let x = d3.scalePoint()
.domain(dimensions)
.range([0, group_width]);
function row2points(row) {
return dimensions.map(dim => {
if (row[dim] === undefined) return null;
return [x(dim), y[dim](row[dim])];
}).filter(d => d !== null);
}
const line = d3.line()
.x(d => d[0])
.y(d => d[1]);
group.selectAll("myPath")
.data(data_cleaned)
.join("path")
.attr("d", d => line(row2points(d)))
.style("fill", "none")
.style("stroke", d => colorScale(d.Type) || "#000")
.style("opacity", 0.5)
const axes = group.selectAll("myAxis")
.data(dimensions)
.enter()
.append("g")
.attr("transform", d => `translate(${x(d)}, 0)`)
.each(function(d) {
d3.select(this).call(d3.axisLeft(y[d]));
});
axes.append("text")
.style("text-anchor", "middle")
.attr("y", -9)
.text(function(d) { return d; })
.style("fill", "black")
return svg.node();
}