Public
Edited
Apr 2
1 fork
19 stars
Insert cell
Insert cell
//beeswarm(dataset, assex,assey,colore)
beeswarm(data, "Data", "Zona Geografica", "sent")
Insert cell
beeswarm = (data, date, type, toColor) => {
////// Chart configuration
const radius = 2.5;
const padding = 1;
const size = { w: 600, h: 500 };
const margin = { top: 100, bottom: 30, left: 130, right: 100 };

const colors = "#e6ab02";

const xScale = d3
.scaleTime()
.range([0, size.w])
.domain(d3.extent(data, (d) => d.Data));

const colorScale = d3
.scaleSequential()
.domain([0, d3.max(data, (d) => d[toColor])])
.interpolator(d3.interpolateHcl("pink", "darkblue"));
//https://observablehq.com/@philippkoytek/color-interpolations

let category = [...new Set(data.map((d) => d[type]))];
category.reverse();

////// Chart drawing
const svg = d3.select(
DOM.svg(
size.w + margin.left + margin.right,
size.h + margin.top + margin.bottom
)
);

const g = svg
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);

// x axis
const xAxis = d3.axisBottom().scale(xScale).ticks(d3.timeYear);
g.append("g")
.attr("transform", `translate(0, ${size.h - margin.top})`)
.call(xAxis)
.select(".domain")
.remove();

// y scale
const yScale = d3
.scalePoint()
.domain(category)
.range([0, size.h - margin.top - margin.bottom]);
const yAxis = d3.axisLeft().scale(yScale);

g.append("g")
.attr("transform", `translate(0,0)`)
.call(yAxis)
.select(".domain")
.remove();

//Tooltip
const toolTip = d3.select("body").append("div").attr("class", "toolTip");

// mouseover function

const formatDate = d3.timeFormat("%d %b %Y");

function nodeMouseOver(event, d) {
toolTip
.style("left", event.pageX + 18 + "px")
.style("top", event.pageY + 18 + "px")
.style("display", "block")
.html(
`${d["Città"].toUpperCase()} - <em>${formatDate(
d["Data"]
)}</em><br><strong>${d.Title}</strong><br>${d.Text.slice(0, 200)}...`
);

d3.select(event.target).style("cursor", "pointer");

d3.select(event.target).transition().attr("fill", "#A8234E").attr("r", 10);
}

// mouseout function
function nodeMouseOut(event, d) {
// Hide tooltip on mouse out
toolTip.style("display", "none"); // Hide toolTip

// Optional cursor change removed
d3.select(event.target).style("cursor", "default");

// Optional highlight removed
d3.select(event.target)
.transition()
.attr("fill", (d) => colorScale(d[toColor]))
.attr("r", radius);
}

// circles
const bee = g
.append("g")
.attr("class", "bee")
.attr("transform", `translate(0,0)`);

const nodes = bee
.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("class", "node")
.attr("cy", (d) => {
d.y = size.h / 2;
return d.y;
})
.attr("cx", (d) => {
d.x = xScale(d[date]);
return d.x;
})
.attr("r", radius)
.attr("fill", (d) => colorScale(d[toColor]))
.attr("fill-opacity", 0.7)
.on("mousemove", nodeMouseOver)
.on("mouseout", nodeMouseOut);

let simulation = d3
.forceSimulation()
.force("collide", d3.forceCollide(radius + padding))
.force("x", d3.forceX((d) => d.x).strength(1))
.alphaMin(0.00001);

if (category) {
simulation.force("y", d3.forceY((d) => yScale(d[type])).strength(1));
} else {
simulation.force("y", d3.forceY((d) => d.y).strength(1));
}

simulation.nodes(data).on("tick", () => {
nodes.attr("cx", (d) => d.x).attr("cy", (d) => d.y);
});

return svg.node();
}
Insert cell
html`
<style>
.toolTip {
position: absolute;
display: none;
min-width: 30px;
max-width: 350px;
border-radius: 4px;
height: auto;
background: rgba(250,250,250, 0.9);
border: 1px solid #DDD;
padding: 4px 8px;
font-size: .85rem;
text-align: left;
z-index: 1000;
}
</style>
`
Insert cell
Insert cell
dataFile = FileAttachment("CN_omofobia_+TAGME_v2+SENT+LABEL-1.csv").csv()
Insert cell
dataFileOld = FileAttachment("CN_Omofobia_justText.csv").csv()
Insert cell
parseDate = d3.timeParse("%d/%m/%Y")
Insert cell
data = dataFile.map((d) => {
return {
...d,
Data: parseDate(d.Data),
sent: +d.sent
};
})
Insert cell
Insert cell
d3 = require("d3@v6")
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