Published
Edited
Aug 22, 2019
Fork of Burbujitas
1 fork
Insert cell
Insert cell
margin = ({left:50, right:10, top: 10, bottom:50})
Insert cell
iwidth = width/2 - margin.left -margin.right
Insert cell
iheight = height - margin.top - margin.bottom
Insert cell
exps
Insert cell
height
Insert cell
viewof height = html`<input type="range" min="400" max="800" step="1">`
Insert cell
viewof exps = html`<input type="range" min="0.01" max="5" step="0.01">`
Insert cell
d3 = require('d3', 'd3-transform')
Insert cell
dd = {
var pie_st = [false,false];
var xx = d3.select(DOM.svg(width, height));
var svg = xx
.attr("width", width)
.attr("height", height);

var data = d3.range(17).map(d => {
const ods = histograma.find(x => x.text == `ods_${d + 1}`);
return {
radius: radio_calc(parseInt(ods['count' ]) || 0),
id: `ods_${d + 1}`,
name: `ods ${d + 1}`,
marked: false,
value: parseInt(ods['count']) || 0
}
});
var forceCollide = d3.forceCollide(function(d) {
return d.radius;
})
.strength(0.8);

var s = 0.02;

var forceX = d3.forceX(width / 2).strength(s);
var forceY = d3.forceY(height / 2).strength(s);

var force = d3.forceSimulation(data)
.force('x', forceX)
.force('y', forceY)
.force('center', d3.forceCenter(width / 2, height / 2))
.force("cluster", forceCluster())
.force('collide', forceCollide)
.on('tick', function() {
svg.selectAll('.node')
.attr('cx', function(d) {
if (d.marked === true){
console.log(pie_st);
if(pie_st[1]){
svg.selectAll('.inside')
.transition().duration(90)
.attr('transform', d3.transform()
.scale(_ => !pie_st[0]?0:1)
.translate(_ => [d.x, d.y]))
//pie_st[1] = false;
}else {
svg.selectAll('.inside')
.attr('transform', d3.transform()
.scale(_ => !pie_st[0]?0:1)
.translate(_ => [d.x, d.y]))
}
}
// .attr('transform', _ => `translate(${d.x},${d.y})}`)
// .attr('cx', _ => d.marked?d.x:990)
// .attr('x', _ => d.marked?d.x:990)
return d.x;
})
.attr('cy', function(d) {


svg.selectAll('.inside')
// .attr('transform', `translate(${d.x},${d.y})}`)
// .attr('cy', _ => d.marked?d.y:990)
// .attr('y', _ => d.marked?d.y:990)
return d.y;
})

svg.selectAll('.text_node')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
.attr('x', function(d) {
return d.x - d.radius / 5;
})
.attr('y', function(d) {
return d.y;
})
});

function forceCluster() {
const strength = 0.2;
let nodes;

function force(alpha) {
const l = alpha * strength;
for (const d of nodes) {
const {
x: cx,
y: cy
} = {
x: iwidth / 2,
y: iheight / 2
};
d.vx -= (d.x - cx) * l;
d.vy -= (d.y - cy) * l;
}
}

force.initialize = _ => nodes = _;

return force;
}
const main_g = svg.append("g");
const node = main_g
.selectAll(".node")
.data(data)
.join("g");

const circle = node.append('circle')
.classed('node', true).call(drag(force))
.on('click', (d, i) => switchRadius(iheight / 4, i)());

circle.attr('r', function(d) {
return d.radius;
})
.attr("fill", d => odss[d.id].color);

const circle_is = circle.append('circle').classed('inside', true).attr('r', 5)
.attr("fill", d => '#ddd');

node.append("text")
.attr("class", "text_node")
.text(function(d, i) {
return i + 1;
})
.style('fill', '#000')
.style('font-size', '12px')

force.nodes(data)
.alpha(1)
.restart();

function drag(force) {

function dragstarted(d) {
if (!d3.event.active) force.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) force.alphaTarget(0);
d.fx = null;
d.fy = null;
}

return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}



function switchRadius(newRadius, index) {
return function() {

const marked_finder = d3.selectAll('.node')
.filter(function(d, i) {
return d.marked === true;
});

if (marked_finder._groups[0].length == 0) {
pie_st = [true, true];
d3.selectAll('.node')
.transition().duration(1000)
.tween('radius', function(d) {
var that = d3.select(this);
var i = d3.interpolate(d.radius, iheight / 20);
return function(t) {
d.radius = i(t);
that.attr('r', function(d) {
return d.radius;
});
force.nodes(data)
}
});

//creamos pie
const pie = d3.pie()
.value((d) => d.value);


const arc = d3.arc()
.innerRadius(0)
.outerRadius(newRadius);


const amigito = d3.selectAll('.node')
.filter(function(d, i) {
return i === index;
});
amigito.transition().duration(1000)
.tween('radius', function(d) {
var that = d3.select(this);
var i = d3.interpolate(d.radius, newRadius);
return function(t) {
d.radius = i(t);
d.marked = true;
that.attr('r', function(d) {
return d.radius;
});
force.nodes(data)
}
});
const grupito = main_g.append('g').attr('class', 'inside').call(drag(force));
const part = grupito.selectAll('.part')
.data(pie(d3.entries(dataset)))
.enter()
.append('g');
part.call(drag(force));
part.append('path')
.attr('d', arc)
.attr('fill', (d, i) => color(i));
part.append("text").call(drag(force))
.attr('transform', (d) => 'translate(' + arc.centroid(d) + ')')
.text((d) => d.data.key)
.attr('fill', 'white');
/*
.transition().delay(1000).duration(100)
.attr('transform', d3.transform()
.scale(_ => 1));
*/
force.alpha(1).restart();

//fin del if
} else {
pie_st = [false, true];
d3.selectAll('.node')
.transition().duration(1000)
.tween('radius', function(d) {
var that = d3.select(this);
var i = d3.interpolate(d.radius, radio_calc(d.value || 0));
return function(t) {
d.radius = i(t);
d.marked = false;
that.attr('r', function(d) {
return d.radius;
});
force.nodes(data)
}
});

// d3.selectAll('.inside').transition().attr('visibility', 'hidden').duration(2500);
// d3.selectAll('.inside').transition().attr('opacity', 0.5);
}
}
}


return xx.node();
}
Insert cell
radio_calc(12)
Insert cell
radio_calc = d3.scalePow().exponent(exps).domain([0, d3.max(histograma, d => d.count)]).range([10,iheight/6]);
Insert cell
histograma = await d3.json("https://raw.githubusercontent.com/whatevercamps/graph_jsons_tw_unfpa/master/histograma_ods.json").then(res => res.items)
Insert cell
odss = await d3.json('https://raw.githubusercontent.com/whatevercamps/graph_jsons_tw_unfpa/master/ods.json')
Insert cell
ss= d3.selectAll('.node')
.filter(function (d, i) { return d.marked === true; })
Insert cell
ss._groups[0].length
Insert cell
chart = {
const svg = d3.select(DOM.svg(width, height));
svg.attr('width', width)
.attr('height', height);

const color = d3.scaleOrdinal()
.domain(dataset)
.range(['#F1892D', '#0EAC51', '#0077C0', '#7E349D', '#DA3C78', '#E74C3C']);

const g = svg.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
const elip = g.append("clipPath") // define a clip path
.attr("id", "ellipse-clip") // give the clipPath an ID
.append("ellipse") // shape it as an ellipse
.attr("cx", 175) // position the x-centre
.attr("cy", 100) // position the y-centre
.attr("rx", 100) // set the x radius
.attr("ry", 50) // set the y radius
.attr("fill", "black");
const rect = g.append("rect") // attach a rectangle
.attr("x", -400) // position the left of the rectangle
.attr("y", -100) // position the top of the rectangle
.style("fill", "lightgrey") // fill the clipped path with grey
.attr("height", 600) // set the height
.attr("width", 600); // set the width
const pie = d3.pie()
.value((d) => d.value);
const arc = d3.arc()
.innerRadius(0)
.outerRadius(200);

const part = g.selectAll('.part')
.data(pie(d3.entries(dataset)))
.enter()
.append('g');
// part.
//attr("clip-path", "url(#ellipse-clip)") // clip the rectangle
part.append('path')
.attr('d', arc)
.attr('fill', (d, i) => color(i));
part.append("text")
.attr('transform', (d) => 'translate(' + arc.centroid(d) + ')')
.text((d) => d.data.key)
.attr('fill', 'white')
return svg.node();
}
Insert cell
color = d3.scaleOrdinal()
.domain(dataset)
.range(['#F1892D', '#0EAC51', '#0077C0', '#7E349D', '#DA3C78', '#E74C3C']);
Insert cell
dataset = ({ 'A': 35, 'B': 30, 'C':25, 'D': 20, 'E': 15, 'F': 10})
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