Unlisted
Edited
Jul 4, 2024
Insert cell
Insert cell
compositepltAllSF = html`
<div class="ifrblock">
<div class="grphcontainer">
<div class="halfcol">
<font size="+1.5"><strong>¿Qué mariscos son los que más se consumen?</strong></font></br>
${SFdonutItemsNat}</div>
<div class="halfcol">
<font size="+1.5"><strong>¿Dónde se consumen?</strong></font></br>
${SFdonutNationalRest}
</div>
</div>
</br>


<style>
@import url('https://fonts.googleapis.com/css2?family=Raleway&display=swap');
body, svg {
font-family: 'Raleway', serif;
}

#scalesvg {
width: 100%; /* thx, http://www.sarasoueidan.com/blog/svg-coordinate-systems/ !!! */
}

.ifrblock {
display: block;
margin: 0;
height: 430px;
padding: 0;
}

.grphcontainer {
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: 0px;
text-align: center;
padding-top: 0px;
padding-bottom: 0px;
}

.list_2Column {
margin: 0px;
padding: 0px;
position: "absolute";
}

.halfcol {
display: "flex";
flex-basis: "50%"
text-align: "center";
}
@font-face {
font-family: cocogoose;
src: url('${await cocogoose.url()}');
}
</style>
`
Insert cell
regMarplt = html`
<div class="ifrblockm">
<div> ${viewof selReg}</div>
</br>
<div style="display: grid; grid-template-columns: 1fr 1fr; column-gap: -2px; text-align: center ">
<div class="halfcol">
<font size="+1.5"><strong>¿Qué mariscos son los que más se consumen?</strong></font></br>
${SFdonutItemsReg}
</div>
<div class="halfcol">
<font size="+1.5"><strong>¿Dónde se consumen?</strong></font></br>
${SFdonutRestReg}
</div>
</div>
</div>
<style>
@import url('https://fonts.googleapis.com/css2?family=Raleway&display=swap');
body, svg {
font-family: 'Raleway', serif;
}

#scalesvg {
width: 100%; /* thx, http://www.sarasoueidan.com/blog/svg-coordinate-systems/ !!! */
}

.vport {
height 200px;
width: 200px;
border: 1px solid green;
}

.list_2Column {
margin: 0px;
padding: 0px;
position: "absolute";
}

.ifrblockm {
display: block;
margin: 0;
height: 490px;
padding: 0;
}
@font-face {
font-family: cocogoose;
src: url('${await cocogoose.url()}');
}
</style>
`
Insert cell
Insert cell
cocogoose = FileAttachment("Cocogoose-Pro-Semilight-trial.ttf")
Insert cell
viewof selReg = Inputs.select(regionalseafood.map(d => d.region), {sort: true, unique: true, label: "Seleccione:", width: 320})

Insert cell
SFdonutItemsReg = {
var margin = { top: 10, left: 20, right: 5, bottom: 10 }
const height = (750 - margin.left - margin.right);
const width = height
const radius = (Math.min(width, height) - margin.top - margin.bottom )/ 2;
const arc = d3.arc()
.innerRadius(radius * 0.35) // This is the size of the donut hole
.outerRadius(radius * 0.8);

const arcIns = d3.arc()
.innerRadius(radius * 0.8) // line insertion
.outerRadius(radius * 0.8);

const outerArc = d3.arc()
.innerRadius(radius * 0.7)
.outerRadius(radius * 1)
const pie = d3.pie()
.padAngle(1 / radius)
.sort(null)
.value(d => d.pct);

const color = d3.scaleOrdinal()
.domain(filteredRegSF.map(d => d.item))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), filteredRegSF.length).reverse());

const svg = d3.create("svg")
.attr("width", width-2)
.attr("height", height-150)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "width: 100%; height: auto; font: 32px Raleway;");
svg.append("g")
.selectAll()
.data(pie(filteredRegSF))
.join("path")
.attr("fill", d => color(d.data.item))
.attr("d", arc)
.append("title")
.text((d) => `n = ${d.data.SbjNum}`)
;

// polylines to labels
svg.append("g")
.selectAll('allPolylines')
.data(pie(filteredRegSF))
.join('polyline')
.attr("stroke", "gray")
.style("fill", "none")
.attr("stroke-width", 0.5)
.attr('points', function(d) {
const posA = (arcIns.centroid(d)) // line insertion in the slice
const posB = outerArc.centroid(d) // line break: we use the other arc generator that has been built only for that
const posC = outerArc.centroid(d); // Label position = almost the same as posB
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 // we need the angle to see if the X position will be at the extreme right or extreme left
posC[0] = radius * 0.86 * (midangle < Math.PI ? 1 : -1); // multiply by 1 or -1 to put it on the right or on the left
return [posA, posB, posC]
})
//labels
svg.append("g")
.selectAll('allLabels')
.data(pie(filteredRegSF))
.join('text')
.text(d => d.data.item)
.attr('transform', function(d) {
const pos = outerArc.centroid(d);
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
pos[0] = radius * 0.87 * (midangle < Math.PI ? 1 : -1);
return `translate(${pos})`;
})
.style('text-anchor', function(d) {
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
return (midangle < Math.PI ? 'start' : 'end')
});

// percentages
svg.append("g")
.attr("text-anchor", "middle")
.selectAll()
.data(pie(filteredRegSF))
.join("text")
.attr("transform", d => `translate(${arc.centroid(d)})`)
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("font-weight", "bold")
.attr("fill-opacity", 1)
.text(d => d.data.pct.toFixed(0)+"%"));

//svg.append("text")
// .attr("x", 5)
// .attr("y", 5)
// .attr("text-anchor", "middle")
// .style("font-size", "16px")
// .style("text-decoration", "underline")
// .text("Consumo reg");


return svg.node();


}
Insert cell
Math.min(width, 750);
Insert cell
SFdonutRestReg = {

var margin = { top: 10, left: 20, right: 5, bottom: 10 }
const height = (750 - margin.left - margin.right);
const width = height
const radius = (Math.min(width, height) - margin.top - margin.bottom )/ 2;

const arc = d3.arc()
.innerRadius(radius * 0.35) // This is the size of the donut hole
.outerRadius(radius * 0.8);

const arcIns = d3.arc()
.innerRadius(radius * 0.8) // line insertion
.outerRadius(radius * 0.8);

const outerArc = d3.arc()
.innerRadius(radius * 0.7)
.outerRadius(radius * 1)
const pie = d3.pie()
.padAngle(1 / radius)
.sort(null)
.value(d => d.value);

const color = d3.scaleOrdinal()
.domain(filterRegRestSF.map(d => d.name))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), filterRegRestSF.length).reverse());

const svg = d3.create("svg")
.attr("width", width-30)
.attr("height", height-150)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "width: 100%; height: auto; font: 32px Raleway;");
svg.append("g")
.selectAll()
.data(pie(filterRegRestSF))
.join("path")
.attr("fill", d => color(d.data.name))
.attr("d", arc);

// polylines to labels
svg.append("g")
.selectAll('allPolylines')
.data(pie(filterRegRestSF))
.join('polyline')
.attr("stroke", "gray")
.style("fill", "none")
.attr("stroke-width", 0.7)
.attr('points', function(d) {
const posA = (arcIns.centroid(d)) // line insertion in the slice
const posB = outerArc.centroid(d) // line break: we use the other arc generator that has been built only for that
const posC = outerArc.centroid(d); // Label position = almost the same as posB
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 // we need the angle to see if the X position will be at the extreme right or extreme left
posC[0] = radius * 0.6 * (midangle < Math.PI ? 1 : -1); // multiply by 1 or -1 to put it on the right or on the left
return [posA, posB, posC]
})
//labels
svg.append("g")
.attr("font-family", "Raleway")
//.attr("font-size", "2em")
.selectAll('allLabels')
.data(pie(filterRegRestSF))
.join('text')
.text(d => d.data.name)
.attr('transform', function(d) {
const pos = outerArc.centroid(d);
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
pos[0] = radius * 0.61 * (midangle < Math.PI ? 1 : -1);
return `translate(${pos})`;
})
.style('text-anchor', function(d) {
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
return (midangle < Math.PI ? 'start' : 'end')
});

// percentages
svg.append("g")
.attr("font-family", "Raleway")
// .attr("font-size", "1.7em")
.attr("text-anchor", "middle")
.selectAll()
.data(pie(filterRegRestSF))
.join("text")
.attr("transform", d => `translate(${arc.centroid(d)})`)
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("font-weight", "bold")
.attr("fill-opacity", 1)
.text(d => d.data.value.toFixed(0)+"%"));

return svg.node();
}
Insert cell

SFdonutNationalRest = {
var margin = { top: 10, left: 20, right: 5, bottom: 10 }
const height = (750 - margin.left - margin.right);
const width = height
const radius = (Math.min(width, height) - margin.top - margin.bottom )/ 2;

const arc = d3.arc()
.innerRadius(radius * 0.35) // This is the size of the donut hole
.outerRadius(radius * 0.8);

const arcIns = d3.arc()
.innerRadius(radius * 0.8) // line insertion
.outerRadius(radius * 0.8);

const outerArc = d3.arc()
.innerRadius(radius * 0.7)
.outerRadius(radius * 1)
const pie = d3.pie()
.padAngle(1 / radius)
.sort(null)
.value(d => d.value);

const color = d3.scaleOrdinal()
.domain(sfnatrestconsdic.map(d => d.name))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), sfnatrestconsdic.length).reverse());

const svg = d3.create("svg")
.attr("width", width-30)
.attr("height", height-150)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "width: 100%; height: auto; font: 32px Raleway;");

svg.append("g")
.selectAll()
.data(pie(sfnatrestconsdic))
.join("path")
.attr("fill", d => color(d.data.name))
.attr("d", arc)
.append("title")
.text((d) => `${d.data.name}: ${d.data.value*100 + "%"}`)
;

// polylines to labels
svg.append("g")
.selectAll('allPolylines')
.data(pie(sfnatrestconsdic))
.join('polyline')
.attr("stroke", "gray")
.style("fill", "none")
.attr("stroke-width", 1)
.attr('points', function(d) {
const posA = (arcIns.centroid(d)) // line insertion in the slice
const posB = outerArc.centroid(d) // line break: we use the other arc generator that has been built only for that
const posC = outerArc.centroid(d); // Label position = almost the same as posB
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 // we need the angle to see if the X position will be at the extreme right or extreme left
posC[0] = radius * 0.6 * (midangle < Math.PI ? 1 : -1); // multiply by 1 or -1 to put it on the right or on the left
return [posA, posB, posC]
})
//labels
svg.append("g")
.attr("font-family", "Raleway")
// .attr("font-size", "2em")
.selectAll('allLabels')
.data(pie(sfnatrestconsdic))
.join('text')
.text(d => d.data.name)
.attr('transform', function(d) {
const pos = outerArc.centroid(d);
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
pos[0] = radius * 0.61 * (midangle < Math.PI ? 1 : -1);
return `translate(${pos})`;
})
.style('text-anchor', function(d) {
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
return (midangle < Math.PI ? 'start' : 'end')
});

// percentages
svg.append("g")
.attr("font-family", "Raleway")
// .attr("font-size", "1.7em")
.attr("text-anchor", "middle")
.selectAll()
.data(pie(sfnatrestconsdic))
.join("text")
.attr("transform", d => `translate(${arc.centroid(d)})`)
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("font-weight", "bold")
.attr("fill-opacity", 1)
.text(d => (d.data.value.toFixed(1)*100)+"%"));

return svg.node();
}
Insert cell
SFdonutItemsNat = {
var margin = { top: 10, left: 20, right: 5, bottom: 10 }
const height = (750 - margin.left - margin.right);
const width = height
const radius = (Math.min(width, height) - margin.top - margin.bottom )/ 2;
const arc = d3.arc()
.innerRadius(radius * 0.35) // This is the size of the donut hole
.outerRadius(radius * 0.8);

const arcIns = d3.arc()
.innerRadius(radius * 0.8) // line insertion
.outerRadius(radius * 0.8);

const outerArc = d3.arc()
.innerRadius(radius * 0.7)
.outerRadius(radius * 1)
const pie = d3.pie()
.padAngle(1 / radius)
.sort(null)
.value(d => d.value);

const color = d3.scaleOrdinal()
.domain(conssfallrd.map(d => d.name))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), conssfallrd.length).reverse());

const svg = d3.create("svg")
.attr("width", width-3)
.attr("height", height-150)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "width: 100%; height: auto; font: 32px Raleway;");

svg.append("g")
.selectAll()
.data(pie(conssfallrd))
.join("path")
.attr("fill", d => color(d.data.name))
.attr("d", arc)
.append("title")
.text((d) => `n = ${d.data.SbjNum}`)
;

// polylines to labels
svg.append("g")
.selectAll('allPolylines')
.data(pie(conssfallrd))
.join('polyline')
.attr("stroke", "gray")
.style("fill", "none")
.attr("stroke-width", 1)
.attr('points', function(d) {
const posA = (arcIns.centroid(d)) // line insertion in the slice
const posB = outerArc.centroid(d) // line break: we use the other arc generator that has been built only for that
const posC = outerArc.centroid(d); // Label position = almost the same as posB
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 // we need the angle to see if the X position will be at the extreme right or extreme left
posC[0] = radius * 0.9 * (midangle < Math.PI ? 1 : -1); // multiply by 1 or -1 to put it on the right or on the left
return [posA, posB, posC]
})
//labels
svg.append("g")
.attr("font-family", "Raleway")
//.attr("font-size", "2em")
.selectAll('allLabels')
.data(pie(conssfallrd))
.join('text')
.text(d => d.data.name)
.attr('transform', function(d) {
const pos = outerArc.centroid(d);
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
pos[0] = radius * 0.91 * (midangle < Math.PI ? 1 : -1);
return `translate(${pos})`;
})
.style('text-anchor', function(d) {
const midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
return (midangle < Math.PI ? 'start' : 'end')
});

// percentages
svg.append("g")
.attr("font-family", "Raleway")
//.attr("font-size", "1.7em")
.attr("text-anchor", "middle")
.selectAll()
.data(pie(conssfallrd))
.join("text")
.attr("transform", d => `translate(${arc.centroid(d)})`)
.call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25).append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("font-weight", "bold")
.attr("fill-opacity", 1)
.text(d => d.data.value.toFixed(0)+"%"));

return svg.node();
}
Insert cell
consSFallrd@1.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
filteredRegSF = regionalseafood.filter(d => d.region == selReg)
Insert cell
filterRegRestSF = sfregrest.filter(d=> d.region== selReg)
Insert cell
regionalSeafood@2.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
SFnatrestconsdic@1.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
SFregRest.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
d3 = require("d3@6")
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