I would like to create a Euler diagram with Highcharts library :
My goal example:
I found this solution, which involves forcing the x attribute of the points.
I would like to do something similar to the example, but I need the dataLabels and I want them to be correctly positioned on each circle.
Highcharts.chart('container', {
chart: {
events: {
load: function() {
var points = this.series[0].points,
point1R = points[0].shapeArgs.r;
points[1].graphic.attr({
y: points[1].graphic.getBBox().y - (point1R - points[1].shapeArgs.r)
});
points[2].graphic.attr({
y: points[2].graphic.getBBox().y - (point1R - points[2].shapeArgs.r)
});
}
}
},
series: [{
type: 'venn',
dataLabels: {
inside: true,
enabled: true,
verticalAlign: 'top'
},
data: [{
sets: ['A'],
value: 10
}, {
sets: ['B'],
value: 3
}, {
sets: ['C'],
value: 1,
}, {
sets: ['A', 'C'],
value: 1
}, {
sets: ['A', 'B'],
value: 3
}, {
sets: ['B', 'C'],
value: 1
}]
}]
});
Could someone help me to design it ? Thank you in advance !
hello actually you can apply what you did for y chart offset (on your first jsfiddle , not the one inside the comment) to the x and y offset of the labels
except for put your code inside a loop i've just applied the same concept to the labels:
Highcharts.chart('container', {
chart: {
events: {
load: function() {
var points = this.series[0].points;
var point1R = points[0].shapeArgs.r;
points.forEach((p)=>{
if((p.shapeArgs ?? false)!=false){
//this is the same of your code but inside the loop
//it just move the y circles offsset
p.graphic.attr({
y: p.graphic.getBBox().y - (point1R - p.shapeArgs.r)
});
//and you can do the same with labels in this way
p.dataLabel.translate(
p.shapeArgs.x-(p.dataLabel.bBox.width),
(p.shapeArgs.r * 2)-(p.dataLabel.bBox.height*2)
);
}
});
}
}
},
series: [{
type: 'venn',
dataLabels: {
inside: true,
enabled: true,
verticalAlign: 'left'
},
data: [{
sets: ['A'],
value: 10
}, {
sets: ['B'],
value: 3
}, {
sets: ['C'],
value: 1,
}, {
sets: ['A', 'C'],
value: 1
}, {
sets: ['A', 'B'],
value: 3
}, {
sets: ['B', 'C'],
value: 1
}]
}]
});
#container {
height: 400px;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/venn.js"></script>
<div id="container"></div>
if you want to invert the chart like in the pics you need some math
you should search something about coordinate translation , this is a good starting point:
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations#translating
and apply it to both shapes and labels
Highcharts.chart('container', {
chart: {
events: {
load: function() {
var points = this.series[0].points;
var point1R = points[0].shapeArgs.r;
var maxR = 0;
points.forEach((p)=>{if(p?.shapeArgs?.r>maxR){maxR=p?.shapeArgs?.r;}})
points.forEach((p)=>{
if((p.shapeArgs ?? false)!=false){
//this is the same of your code but inside the loop
//it just move the y circles offsset
p._newY=maxR+(maxR-p.shapeArgs.r);
p.graphic.attr({
//do some math here
y: maxR+(maxR-p.shapeArgs.r)
});
//and you can do the same with labels in this way
p.dataLabel.translate(
p.shapeArgs.x-(p.dataLabel.bBox.width),
//do some math here
p._newY-p.shapeArgs.r
);
}
});
}
}
},
series: [{
type: 'venn',
dataLabels: {
inside: true,
enabled: true,
verticalAlign: 'left'
},
data: [{
sets: ['A'],
value: 10
}, {
sets: ['B'],
value: 3
}, {
sets: ['C'],
value: 1,
}, {
sets: ['A', 'C'],
value: 1
}, {
sets: ['A', 'B'],
value: 3
}, {
sets: ['B', 'C'],
value: 1
}]
}]
});
#container {
height: 400px;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/venn.js"></script>
<div id="container"></div>