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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more