Published
Edited
Nov 2, 2021
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// colors = ["#1b9e77","#d95f02","#7570b3","#e7298a","#66a61e","#e6ab02","#a6761d","#666666"]
Insert cell
colors = ["#4e79a7","#f28e2c","#e15759","#76b7b2","#59a14f","#edc949","#af7aa1","#ff9da7","#9c755f","#bab0ab"]
Insert cell
Insert cell
radius_ = 160
Insert cell
{
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("id", "box");

for(let j=0; j < arr[s].length; j++){
svg
.append('g')
.selectAll("ellipse")
.data(desiredData[arr[s][j]]) // j = index of region
.join("ellipse")
// .attr("cx", 0)
.attr("cy", d => rScale(maxDeaths) - rScale(d.deaths))
.attr("ry", d => rScale(d.deaths))
.attr("rx", d => rScale(d.deaths)/1.7)
// .attr("class", "rotate")
.attr("fill", d => colorByContinent3(d.region, 0.03))
.style("stroke", "white")
.attr("stroke-width", 0.5)
.attr('transform', function(d, i, e) {
// console.log("i==============")
// console.log(i)
// console.log(d) // object
// console.log("i==============")
// console.log(i) // region index
var cx = Math.cos(xcos(i)) * radius_;
var cy = Math.sin(ysin(i)) * radius_;
// console.log('attr~~~~~~~~~~~~~')
// console.log(e[i])
var Ry = e[i].getAttribute('ry');
// console.log("---------")
// console.log(cx)
// console.log(cy )
// return `translate(${cx},${cy - Ry}) cy- 大半徑與小半徑的差
return `translate(${cx},${cy})
rotate(${xcos(i) * 180 /Math.PI + 90})
scale(${0.8})`;
})
}

return svg.node()
}
Insert cell
radius = 200
Insert cell
// covert to radian
xcos = d3.scaleLinear()
.domain([0, desiredData[0].length]) // number of region
// .range([0, Math.PI * 2]);
.range([Math.PI * 0.82, Math.PI * 2.82]);
Insert cell
ysin = d3.scaleLinear()
.domain([0, desiredData[0].length])
.range([Math.PI * 0.82, Math.PI * 2.82]);
Insert cell
Insert cell
regionalFlower = (params) => {
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);
svg
.append('g')
.selectAll("ellipse")
.data(params)
.join("ellipse")
.attr("ry", d => rScale(d.deaths))
.attr("rx", d => rScale(d.deaths)/3)
.attr("fill", d => colorByContinent3(d.region, 0.2))
.attr("stroke", "white")
.attr("stroke-width", strokeWidth)
.attr('transform', function(d, i) {
var rx = Math.cos(xcos_(i)) * outerRadius_;
var ry = Math.sin(ysin_(i)) * outerRadius_;
return `translate(${rx},${ry})
rotate(${xcos_(i) * 180 /Math.PI + 90})
scale(${0.8})`;
})
return svg.node()
}
Insert cell
Insert cell
{
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);
svg
.append('g')
.selectAll("ellipse")
.data(desiredData.map(d=>d[viewRegion]))
.join("ellipse")
.attr("ry", d => rScale(d.deaths))
.attr("rx", d => rScale(d.deaths)/3)
.attr("fill", d => colorByContinent3(d.region, 0.1))
.attr("stroke", "white")
.attr("stroke-width", strokeWidth)
.attr('transform', function(d, i) {
var rx = Math.cos(xcos_(i)) * outerRadius_;
var ry = Math.sin(ysin_(i)) * outerRadius_;
return `translate(${rx},${ry})
rotate(${xcos_(i) * 180 /Math.PI + 90})
scale(${0.8})`;
})

svg.append("text")
.attr("class", "legend")
.style("font-size", "15px")
.attr("fill", "grey")
.attr("text-anchor", "middle")
.attr("font-family", "monospace")
.attr("dy", "0.35em")
.attr("x", 0)
.attr("y", 0)
.text(desiredData[0][viewRegion]['region']);
return svg.node()
}
Insert cell
// sin cos 1.95
// magicNumber = 3 / 8
//magicNumber = 3 / 12 // ~50 weeks = one round; 1/4 circle = one season
magicNumber = 3 / 12 // ~50 weeks = one round; 1/4 circle = one season
Insert cell
_xcos = d3.scaleLinear()
.domain([0, desiredData[0].length])
.range([Math.PI * 0, Math.PI * magicNumber]);
Insert cell
_ysin= d3.scaleLinear()
.domain([0, desiredData[0].length])
.range([Math.PI * 0, Math.PI * magicNumber]);
Insert cell
_outerRadius = 190
Insert cell
(_xcos(37) * _outerRadius) * 180 / Math.PI + 90
Insert cell
Insert cell
Insert cell
Insert cell
{
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);

const axis = svg.selectAll(".axis")
.data([1,0])
.enter()
.append("g")
.attr("class", "axis");

axis.append("line")
.attr("x1", -width/2)
.attr("y1", 0)
.attr("x2", width/2)
.attr("y2", 0)
.attr("class", "line")

axis.append("line")
.attr("x1", 0)
.attr("y1", -height/2)
.attr("x2", 0)
.attr("y2", height/2)
.attr("class", "line")


var slicedData = desiredData.map(d=>d[regions.indexOf(xxx)]).splice(0,z)
svg
.append('g')
.selectAll("ellipse")
.data(slicedData)
.join("ellipse")
.attr("class", "ellipse")
.attr("cy", d => rScale_(maxDeaths) - rScale_(d.deaths))
.attr("ry", d => rScale_(d.deaths))
.attr("rx", d => rScale_(d.deaths) /3)
.attr("fill", d => colorByContinent3(d.region, 0.1))
.attr("stroke", "white")
.attr("stroke-width", strokeWidth)
.attr('transform', function(d, i) {
var rx = Math.cos(_xcos(i)) * _outerRadius;
var ry = Math.sin(_ysin(i)) * _outerRadius;
return `translate(${rx},${ry})
rotate(${_xcos(i) * 180 / Math.PI + 90})
scale(${0.8})`;
})

svg.selectAll(".ellipse:nth-last-child(1)")
.attr("fill", d => colorByContinent3(d.region, 0.5))
.attr("stroke", "white")
.attr("stroke-width", 1.5)

svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", -15)
.text(desiredData.map(d=>d[regions.indexOf(xxx)])[z]["yearWeek"]);

svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", 0)
.text(desiredData.map(d=>d[regions.indexOf(xxx)])[0].region);

svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", 15)
.text(desiredData.map(d=>d[regions.indexOf(xxx)])[z]["deaths"]);


return svg.node()
}
Insert cell
{
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);

// const axis = svg.selectAll(".axis")
// .data([1,0])
// .enter()
// .append("g")
// .attr("class", "axis");

// axis.append("line")
// .attr("x1", -width/2)
// .attr("y1", 0)
// .attr("x2", width/2)
// .attr("y2", 0)
// .attr("class", "line")

// axis.append("line")
// .attr("x1", 0)
// .attr("y1", -height/2)
// .attr("x2", 0)
// .attr("y2", height/2)
// .attr("class", "line")


var slicedData = desiredData.map(d=>d[regions.indexOf(xxx)]).splice(0,z)
svg
.append('g')
.selectAll("ellipse")
.data(slicedData)
.join("ellipse")
.attr("class", "ellipse")
.attr("cy", d => rScale(maxDeaths) - rScale(d.deaths))
.attr("ry", d => rScale(d.deaths))
.attr("rx", d => rScale(d.deaths) /3)
.attr("fill", d => colorByContinent3(d.region, 0.1))
.attr("stroke", "white")
.attr("stroke-width", strokeWidth)
.attr('transform', function(d, i) {
var rx = Math.cos(_xcos(i)) * _outerRadius;
var ry = Math.sin(_ysin(i)) * _outerRadius;
return `translate(${rx},${ry})
rotate(${_xcos(i) * 180 / Math.PI + 90})
scale(${0.8})`;
})

svg.selectAll(".ellipse:nth-last-child(1)")
.attr("fill", d => colorByContinent3(d.region, 0.5))
.attr("stroke", "white")
.attr("stroke-width", 1.5)

svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", -15)
.text(desiredData.map(d=>d[regions.indexOf(xxx)])[z]["yearWeek"]);

svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", 0)
.text(desiredData.map(d=>d[regions.indexOf(xxx)])[0].region);

svg.append("text")
.attr("class", "label")
.attr("x", 0)
.attr("y", 15)
.text(desiredData.map(d=>d[regions.indexOf(xxx)])[z]["deaths"]);


return svg.node()
}
Insert cell
Insert cell
Insert cell
//outerRadius_ = 160
outerRadius_ = 180
Insert cell
rScaleNum = 3.8
Insert cell
regions = desiredData[0].map(d=>d.region)
Insert cell
function colorByContinent3(expr, op){
var c = colors.map(d => opacityTweak(d,op))
// var c = d3.schemePastel1.map(d => opacityTweak(d,op))
switch (expr) {
case regions[0]:
return c[0]
break;
case regions[1]:
return c[1]
break;
case regions[2]:
return c[2]
break;
case regions[3]:
return c[3]
break;
case regions[4]:
return c[4]
break;
case regions[5]:
return c[5]
break;
return c[6]
}}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const svg = d3.create("svg")
.attr("viewBox", [-width / 2, -height / 2, width, height]);

for(let j=0; j < arr[s].length; j++){
svg
.append('g')
.selectAll("ellipse")
.data(desiredData.map(d=>d[0])) // j = index of region
.join("ellipse")
.attr("class", "happy")
// .attr("cx", (d, i) => {console.log(d)})
.attr("cy", d => rScale(maxDeaths) - rScale(d.deaths))
.attr("ry", d => rScale(d.deaths))
.attr("rx", d => rScale(d.deaths)/2)
.attr("fill", d => colorByContinent3(d.region, 0.06))
.attr("stroke", "white")
.attr("stroke-width", strokeWidth)
}

return svg.node()
}
Insert cell
xcos_ = d3.scaleLinear()
.domain([0, desiredData[0].length])
.range([Math.PI * 0, Math.PI * magicNumber]);
//.range([Math.PI * 0, Math.PI * 1.98]);
Insert cell
xcos_2 = d3.scaleLinear()
.domain([0, 4])
.range([Math.PI * 0, Math.PI * magicNumber]);
//.range([Math.PI * 0, Math.PI * 1.98]);
Insert cell
ysin_2= d3.scaleLinear()
.domain([0, 4])
.range([Math.PI * 0, Math.PI * magicNumber]);
//.range([Math.PI * 0, Math.PI * 1.98]);
Insert cell
ysin_= d3.scaleLinear()
.domain([0, desiredData[0].length])
.range([Math.PI * 0, Math.PI * magicNumber]);
//.range([Math.PI * 0, Math.PI * 1.98]);
Insert cell
rScale= d3.scaleLog()
.domain([minDeaths, maxDeaths])
.range([0, height / rScaleNum])
Insert cell
rScale_= d3.scaleLinear()
.domain([minDeaths, maxDeaths])
.range([0, height / rScaleNum])
Insert cell
maxDeaths = d3.max(desiredData.map(d => d3.max(d)).map(d => d.deaths))
Insert cell
minDeaths = 1
Insert cell
Insert cell
outerRadius = 120;
Insert cell
function opacityTweak(color, number) {
const {l, c, h, opacity} = d3.lch(color);
return d3.lch(l, c, h,opacity* number);
}
Insert cell
height = 700
Insert cell
//width = 200
Insert cell
margin = 50
Insert cell
https://docs.aspose.com/svg/net/drawing-basics/svg-path-data/
Insert cell
## Helper functions|
Insert cell
arr = arrCreator(desiredData.length)
Insert cell
function arrCreator(n) {
let outer= []
for(let i=0; n >= i; i++){
outer.push(arrInner(i))
}
return outer.splice(1, outer.length - 1)
}
Insert cell
function arrInner(n) {
let inner= []
for(let i=0; i < n; i++){
inner.push(i)
}
return inner
}
Insert cell
function opacityLegend(a) {
a.opacity = 1
return a
}
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