Built with blockbuilder.org
forked from GitNoise's block: donut chart
forked from GitNoise's block: necklace around square
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-scale-chromatic.v0.3.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
svg {
position: absolute;
}
path {
stroke: black;
}
line {
stroke: #000000;
stroke-opacity: 0.5;
stroke-dasharray: 10;
}
.mix {
mix-blend-mode: luminosity;
}
.chartArea {
display: inline-block;
position: absolute;
isolation: isolate;
}
.leftRight {
position: absolute;
display: inline-block;
height: 100%;
width: 100%;
background: rgb(0,59,255);
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,255,255,0.5) 50%, rgba(0,59,255,1) 100%);
}
.progCons {
position: absolute;
display: inline-block;
height: 100%;
width: 100%;
background: rgb(7,255,0);
background: linear-gradient(180deg, rgba(7,255,0,1) 0%, rgba(255,255,255,0.5) 50%, rgba(255,254,0,1) 100%);
}
.connector {
stroke-dasharray: 0;
stroke-width: 1;
stroke: black !important;
stroke-opacity: 0.5;
}
.dot {
r: 4;
stroke-width: 0.5;
stroke: black;
}
.label {
position: absolute;
font-family: verdana;
font-size: 9px;
font-weight: bold;
text-transform: uppercase;
background: rgba(255, 255, 255, 0.6);
color: #222222;
}
path {
stroke: none;
}
</style>
</head>
<body>
<script>
var length = 400,
margin = 75,
iconRadius = 15;
const chartAreaScale = d3.scaleLinear()
.domain([0, 1])
.range([margin, length - margin]);
const iconScale = d3.scaleLinear()
.domain([0, 8])
.range([margin, length - margin])
const colorScale = d3.scaleOrdinal(["#FE96BD","#E4A9E0","#B8BEF6","#83D2FA","#55E2EB","#55ECCD","#81F2A6","#B7F382","#EFEE6A" ]);
var data = [
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(0) },
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(1)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(2)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(3)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(4)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(5)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(6)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(7)},
{ value: 100 / 9, x: chartAreaScale(Math.random()), y: chartAreaScale(Math.random()), color: colorScale(8)},
];
var pie = d3.pie()
.value(function(d) { return d.value; })
.sort(null);
// chart area
const chartContainer = d3.select("body").append("div")
.classed("chartArea", true)
.attr("style", `
top:${margin}px;
left:${margin}px;
height:${length - margin*2}px;
width:${length - margin*2}px;`);
chartContainer
.append("div")
.attr("class", "mix leftRight")
chartContainer
.append("div")
.attr("class", "mix progCons")
var svg = d3.select("body").append("svg")
.attr("width", length)
.attr("height", length);
// chart crosshair
const lineVertical = svg.append("line")
.attr("x1", margin)
.attr("x2", length - margin)
.attr("y1", length/2)
.attr("y2", length/2)
const lineHorizontal = svg.append("line")
.attr("x2", length/2)
.attr("x1", length/2)
.attr("y1", margin)
.attr("y2", length - margin)
// chart data
var slice = svg.append("g")
.attr("class", "field")
.selectAll(".slice")
.data(data)
.enter()
.append("g")
.classed("slice", true)
// connector
slice.append("line")
.classed("connector", true)
.attr("x1", (d, i) => iconScale(i))
.attr("y1", d => iconScale(0) - iconRadius - 20)
.attr("x2", d => d.x)
.attr("y2", d => d.y)
.style("stroke", d => d.color)
// icon
slice.append("circle")
.attr("cx", (d, i) => iconScale(i))
.attr("cy", iconScale(0) - iconRadius - 20)
.attr("r", d => iconRadius)
.style("fill", d => d.color)
// data point
slice.append("circle")
.classed("dot", true)
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", 3)
.style("fill", d => d.color)
// labels
let compensationBCR = undefined;
const labelMargin = 4;
const progressive = d3.select("body")
.append("div")
.classed("label", true)
.html("Mer progressiv")
compensationBCR = progressive.node().getBoundingClientRect();
progressive
.attr("style",
`top:${margin - labelMargin - compensationBCR.height}px;
left:${length/2 - compensationBCR.width/2}px`)
const conservative = d3.select("body")
.append("div")
.classed("label", true)
.html("Mer konservativ");
compensationBCR = conservative.node().getBoundingClientRect();
conservative
.attr("style",
`top:${length - margin + labelMargin}px;
left:${length/2 - compensationBCR.width/2}px`)
const left = d3.select("body")
.append("div")
.classed("label", true)
.html("Mer<br/>vänster")
compensationBCR = left.node().getBoundingClientRect();
left
.attr("style",
`top:${length/2 - compensationBCR.height/2}px;
left:${margin - compensationBCR.width - labelMargin}px`)
const right = d3.select("body")
.append("div")
.classed("label", true)
.html("Mer<br/>höger")
compensationBCR = right.node().getBoundingClientRect();
right
.attr("style",
`top:${length/2 - compensationBCR.height/2}px;
left:${length + labelMargin - margin}px`)
</script>
</body>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-scale-chromatic.v0.3.min.js