Public
Edited
Dec 12, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
{
const svg = d3.create("svg").attr("width", width).attr("height", height);

const container = svg
.append("g")
.attr("transform", `translate(${width / 2}, ${height / 2})`);

// Axis
const radiusAxis = container
.selectAll("radius-axis")
.data(radius.reverse())
.enter()
.append("circle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", (d) => radiusScale(d))
.attr("fill", "rgba(10,10,10,0.01)") // 0.01
.attr("stroke", "#c3c3c3") // #ccc
.attr("stroke-width", 0.5);

const angleAxis = container
.selectAll("angle-axis")
.data(attributes)
.enter()
.append("line")
.attr("x1", 0)
.attr("y1", 0)
.attr(
"x2",
(d, i) => radiusScale(100) * Math.cos(angleScale(i) - Math.PI / 2)
)
.attr(
"y2",
(d, i) => radiusScale(100) * Math.sin(angleScale(i) - Math.PI / 2)
)
.attr("stroke", "#ccc")
.attr("stroke-width", 0.5);

const axisLabels = container
.selectAll("axis-labels")
.data(radius)
.enter()
.append("text")
.attr("x", (d, i) => radiusScale(d))
.attr("y", 0 + 4)
.text((d) => d)
.attr("class", "axis-labels");

// Path
const path = container
.append("path")
.datum(attributes)
.attr("d", radarLine)
.attr("fill", "none")
.attr("stroke", pointColor)
.attr("stroke-width", 1.32)
.attr("fill", pointColor)
.style("fill-opacity", 0.1);

// Points
const points = container
.selectAll("points")
.data(attributes)
.enter()
.append("circle")
.attr(
"cx",
(d, i) => radiusScale(player[d]) * Math.cos(angleScale(i) - Math.PI / 2)
)
.attr(
"cy",
(d, i) => radiusScale(player[d]) * Math.sin(angleScale(i) - Math.PI / 2)
)
.attr("r", 4.3)
.attr("fill", pointColor)
.attr("stroke", "#fff")
.attr("stroke-width", 2.6);

// Labels
const labels = container
.selectAll("labels")
.data(attributes)
.enter()
.append("text")
.attr(
"x",
(d, i) => radiusScale(116) * Math.cos(angleScale(i) - Math.PI / 2)
)
.attr(
"y",
(d, i) => radiusScale(116) * Math.sin(angleScale(i) - Math.PI / 2) + 10
)
.text((d) => d)
.attr("class", "labels");

// Name
const name = container
.append("text")
.attr("x", 0)
.attr("y", -radiusScale(135))
.text(player.long_name)
.attr("class", "name");

return svg.node();
}
Insert cell
Insert cell
Insert cell
pointColor = "#5232B9" //'#5383bb'
Insert cell
Insert cell
radarLine = d3
.lineRadial()
// .curve(d3.curveLinearClosed)
.curve(d3.curveCardinalClosed)
.angle((d, i) => angleScale(i))
.radius((d) => radiusScale(player[d]))
Insert cell
Insert cell
angleScale = d3
.scaleLinear()
.domain([0, attributes.length])
.range([0, 2 * Math.PI])
Insert cell
radiusScale = d3
.scaleLinear()
.domain([0, 100])
.range([0, height / 2 - margin.top])
Insert cell
margin = ({ top: 130, right: 100, bottom: 130, left: 100 })
Insert cell
height = 580
Insert cell
Insert cell
Insert cell
player = data.filter((d) => d.short_name === selectedPlayer)[0]
Insert cell
data = d3
.csvParse(await FileAttachment("fifa23_maleplayers.csv").text(), d3.autoType)
.map((d) => {
const obj = {
pace: parseInt(d.pace),
shooting: parseInt(d.shooting),
passing: parseInt(d.passing),
dribbling: parseInt(d.dribbling),
defending: parseInt(d.defending),
physic: parseInt(d.physic),
overall: parseInt(d.overall),
long_name: d.long_name,
short_name: d.short_name
};

// check for null values
const hasNull = Object.values(obj).some(
(value) => value === null || Number.isNaN(value)
);
obj.hasNull = hasNull;
return obj;
})
.filter((d) => d.overall > 88 && !d.hasNull) // && d.passing)
Insert cell
Insert cell
html`<style>
.labels {
font-size: 13px;
font-family: arial;
font-weight: 400;
text-transform: capitalize;
text-anchor: middle;
}

.axis-labels {
font-size: 12px;
font-family: arial;
fill: #aaa;
text-anchor: middle;
}

.name {
font-size: 19.5px;
font-family: arial;
font-weight: 600;
text-transform: capitalize;
text-anchor: middle;
// fill: ${pointColor};
fill: #111;
}
</style>`
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