Published
Edited
Jun 9, 2020
Insert cell
md`# Les Miserables (Exercício 2)

Data from [lesmiserables.json](https://gist.githubusercontent.com/emanueles/1dc73efc65b830f111723e7b877efdd5/raw/2c7a42b5d27789d74c8708e13ed327dc52802ec6/lesmiserables.json).
<br/><br/>
`
Insert cell
buildvis = {
const width = 960
const height = 820
const svg = d3.select(DOM.svg(width, height))
.attr("viewBox", [-width / 2, -height / 2, width, height])
// Configure os nodes e os links
const nodes = dataset.nodes;
const links = dataset.links;

// Crie a constante simulation usando a função forceSimulation definida em outra célula
const simulation = forceSimulation(nodes, links).on("tick", ticked)
//Crie os elementos svg para os links e guarde-os em link
const link = svg.append("g")
.selectAll("line")
.data(links)
.enter()
.append("line")
.attr("class", "link")
//Obter todos os ids dos nós de destino
const targetIds = links.map(link => link.target.id )
//Agrupar os ids dos nós de destino, associando-os o número de conexões (arestas) dos nós de origem
const dataGroupedTargetIds = groupedTargetIds(targetIds)
//Escala com base no número de conexões(arestas) de cada id da variável 'dataGroupedTargetIds'
const circleScale = d3.scaleSqrt()
.domain(d3.extent(dataGroupedTargetIds, d=>d.connections))
.range([8,28])
//Crie os elementos svg para os nodes e guarde-os em node
const node = svg.append("g")
.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("r",d => circleScale(numberOfConnections(dataGroupedTargetIds,d.id)))
.attr("fill","#3B5FC0")
.call(drag(simulation))
node.append("title").text(d=> "Name:" + d.id + " - Number of connections:" + numberOfConnections(dataGroupedTargetIds,d.id))
// Defina a função ticked
function ticked() {
link.attr("x1", d => d.source.x)
link.attr("y1", d => d.source.y)
link.attr("x2", d => d.target.x)
link.attr("y2", d => d.target.y)
node.attr("cx", d => d.x)
.attr("cy", d => d.y)
}
// Once we append the vis elments to it, we return the DOM element for Observable to display above.
return svg.node()
}
Insert cell
//retorna o número de conexões (arestas) associados a um id específico de um nó
numberOfConnections = (groupedTargetIds,id) => {
let result = groupedTargetIds.find(obj => obj.id == id)
let numberOfConnections = (result!=undefined) ? result.connections:0
return numberOfConnections
}
Insert cell
//retorna vetores de objetos: { id ; número de conexões (arestas) associados a esse id}
groupedTargetIds = (targetIds) => {
//Inicializar o primeiro item do vetor (id, connections), devido a checagem do primeiro item do includes.
let grouped = [{'id':targetIds[0], 'connections':1}]

return targetIds.reduce((x,y) => {
if(!grouped.includes(grouped.find(obj => obj.id == y))) {
grouped.push({'id':y,'connections':1})
}
else {
grouped.find(obj => obj.id == y).connections+=1;
}
return grouped
})
}
Insert cell
function drag(simulation){
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
d.fx = d.x
d.fy = d.y
}
function dragged(d) {
d.fx = d3.event.x
d.fy = d3.event.y
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0)
d.fx = null
d.fy = null
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
}
Insert cell
function forceSimulation(nodes, links) {
return d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.id).distance(90))
.force("charge", d3.forceManyBody().strength(-180).distanceMax(320))
.force("center", d3.forceCenter())
}
Insert cell
Insert cell
dataset = d3.json("https://gist.githubusercontent.com/emanueles/1dc73efc65b830f111723e7b877efdd5/raw/2c7a42b5d27789d74c8708e13ed327dc52802ec6/lesmiserables.json")
Insert cell
html`Esta célula contém os estilos da visualização.
<style>
line.link {
fill: none;
stroke: #ddd;
stroke-opacity: 0.8;
stroke-width: 1.5px;
}
<style>`
Insert cell
d3 = require('d3')
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