<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Indicator test</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
body,
html {
margin: 0px;
height: 0px;
font-family: sans-serif;
}
.parent {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
}
.child {
border: 1px solid red
}
div.tooltip {
position: absolute;
text-align: center;
padding: 2px;
/* font: 12px sans-serif; */
background: lightsteelblue;
border: 0px;
border-radius: 8px;
}
.highlight {
fill: steelblue;
}
.hover {
fill: #69c !important;
stroke: #333 !important;
stroke-width: 2px !important;
}
.d3map {
border: 1px solid red;
}
.map-title {
font-size: 30px
}
.map-text {
/* font-size: 12px; */
text-align: center;
}
.map-text-container {
display: flex;
flex-direction: column;
font-size: 14px;
line-height: 1;
align-items: center;
max-width: 155px;
}
</style>
</head>
<body>
<div id="main">
<div class="parent">
<div id="d3map" class="child" style="width:100%; height:100%; "></div>
</div>
</div>
<script>
createMap("d3map")
function createMap(divId) {
const mainData = {
cities: []
}
const svgDiv = document.getElementById(divId).getBoundingClientRect();
let width = 600;
let height = 600;
const radius = width / 2
const svg = d3
.select("#" + divId)
.append("svg")
.attr("viewBox", `0 0 ${width} ${height}`)
ready(null, randomData())
async function ready(error, data) {
// console.log('data: ', data);
// const numberOfPies = data.children.reduce((partialSum, a) => partialSum + a.children.length, 0);
const numberOfPies = 5
console.log("123", numberOfPies);
svg.append("circle")
.style("stroke", "rgba(0,0,0,0.2)")
.style("stroke-width", "1")
.style("fill", "rgba(0,0,0,0)")
.attr("r", radius - 1)
.attr("cx", width / 2)
.attr("cy", height / 2);
const sectors = [...Array(numberOfPies)].map((i, key) => {
return {
name: key, size: 10,
}
});
console.log('pie(sectors): ', sectors);
const arc = (offset = 5) => {
return d3.arc()
.outerRadius(radius - offset)
.innerRadius(radius)
}
const labelArc = d3.arc()
.innerRadius(150)
.outerRadius(radius)
// const labelArcCircle = d3.arc()
// .innerRadius(210)
// .outerRadius(radius)
const pie = d3.pie()
.startAngle(-90 * Math.PI / 180)
.endAngle(-90 * Math.PI / 180 + 2 * Math.PI)
.value(1)
.padAngle(.05) // space between pies
.sort(null);
// prepare a helper function
const lineFunc = d3.line()
.x(function (d) { return d.x })
.y(function (d) { return d.y })
const labels = svg.append('g')
.attr("class", "labels")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
labels.selectAll('.pies')
.data(pie(sectors))
.enter()
.append('path')
.attr('d', labelArc)
.attr('class', "pies")
.attr("stroke", "none")
.attr("fill", d => "gray")
.style("stroke-width", "1px")
.style("opacity", d => {
return d.data.skipThisSector ? 0 : 1
})
labels.selectAll('.lines')
.data(pie(sectors))
.enter()
.append('path')
.attr('d', d => {
console.log('d: ', d);
const pies = d3.pie()
.startAngle(d.startAngle)
.endAngle(d.endAngle)
.value(1)
.padAngle(.01) // space between pies
.sort(null);
labels.selectAll('.piesss')
.data(pies(randomData()))
.enter()
.append('path')
.attr('d', labelArc)
.attr('class', "pies")
.attr("stroke", "none")
.attr("fill", d => "red")
.style("stroke-width", "1px")
.style("opacity", "0.4")
})
labels.selectAll(".labelsText")
.data(pie(sectors))
.enter()
.append("text")
.attr("dx", d => {
const [x, y] = labelArc.centroid(d)
return x
})
.attr("dy", d => {
const [x, y] = labelArc.centroid(d)
return y + 5
})
.text(function (d) {
if (!d.data.skipThisSector) {
return d.data.name
} else {
return //Draw numbers around the circle
}
})
.style("font-size", "8px")
.style("text-anchor", "middle")
.attr("transform", function (d) {
var locationData = this.getBBox();
var x = locationData.x + (locationData.width / 2);
var y = locationData.y + (locationData.height / 2);
let angle = (Math.atan2(y, x) * 180) / Math.PI;
if (angle > 90) angle = 180 + angle
if (angle < -90 && angle > -180) angle = 180 + angle
var result = 'translate(' + x + ',' + y + ')';
result += `rotate(${angle})`;
result += 'translate(' + (-x) + ',' + (-y) + ')';
return result;
})
.style("text-anchor", function (d) {
var locationData = this.getBBox();
var x = locationData.x + (locationData.width / 2);
var y = locationData.y + (locationData.height / 2);
let angle = (Math.atan2(y, x) * 180) / Math.PI;
if (angle > 90) return "end"
if (angle < -90 && angle > -180) return "end"
return "start"
})
.attr("fill", d => {
return "white"
})
}
}
function randomData() {
return [...Array(Math.floor(Math.random() * 11))].map((i, key) => {
return {
name: key, size: 10,
}
});
}
const delay = ms => new Promise(res => setTimeout(res, ms));
</script>
</body>
</html>