A Venn diagram draws each group as a circle, and the overlap holds what belongs to both. Here, a joke in black and white: a polar bear and a black bear overlap in a panda, filled with a dot pattern.
Patterns tell areas apart without color: they survive black-and-white printing, help people who can’t tell some colors apart, and can carry meaning of their own, like the panda’s spots. Keep them few and simple, so they don’t buzz.
Built with amCharts 5, a JavaScript library. The JavaScript includes your theme and renderer (canvas or SVG); the JSON also follows the changes you make with the controls.
npm install @amcharts/amcharts5. See Getting started.
The same chart as a JSON config. Chart Maker reads and writes this format, the library's JSON parser turns it into a chart, and the <am5-chart> element puts it on a page with no code."type" is the class to create and "settings" what you would pass to its new() in code; "properties" fill in its parts, lists such as series and axes or templates such as columns.template; "refs" holds objects used in more than one place ("#series-0" stands for the one named series-0); a string starting with "@" takes a value from another object, such as "@series.get('fill')".
A complete page. Save it as an .html file and open it in a browser.
Paste this into an AI coding assistant to build the chart from scratch. More in amCharts & AI.
// Create root
var root = am5.Root.new("chartdiv");
// Set themes
root.setThemes([
am5themes_Animated.new(root),
am5themes_Responsive.new(root)
]);
// Create wrapper container
var chart = root.container.children.push(am5.SerialChartContainer.new(root, {
width: am5.p100, // the container fills the whole chart div
height: am5.p100,
layout: root.verticalLayout
}));
// Create venn series
var series = chart.series.push(am5venn.Venn.new(root, {
categoryField: "name",
valueField: "value",
intersectionsField: "sets", // an overlap lists, in "sets", the circles it belongs to
paddingTop: 40, // 40px of room on every side
paddingBottom: 40,
paddingLeft: 40,
paddingRight: 40
}));
// the panda overlap's fill: white dots on black, every second dot left out for a checkered look
var pattern = am5.CirclePattern.new(root, {
fill: am5.color(0x000000), // black background...
color: am5.color(0xffffff), // ...with white dots
radius: 10, // dots with a 10px radius...
gap: 10, // ...10px apart
checkered: true
})
// Outlines in the theme's text color: black on a white page, white on a dark one, so the black circle never
// disappears into the background
series.slices.template.setAll({
templateField: "sliceSettings", // each circle takes its fill from the data
stroke: root.interfaceColors.get("text"),
strokeWidth: 1 // 1px outlines
});
series.labels.template.set("fill", am5.color(0xffffff)); // white text, on the black boxes below
// setup runs for each new label: here it gives every label its own black rounded box
series.labels.template.setup = function(target) {
target.set("background", am5.RoundedRectangle.new(root, {
stroke: am5.color(0xffffff), // a white outline, so the box shows on the black circle
fill: am5.color(0x000000),
cornerRadiusTL: 5, // rounded corners
cornerRadiusTR: 5,
cornerRadiusBL: 5,
cornerRadiusBR: 5,
fillOpacity: 1 // solid
}));
}
// Set data
series.data.setAll([{
name: "Polar bear",
value: 100,
sliceSettings: {
fill: am5.color(0xFFFFFF)
}
}, {
name: "Black bear",
value: 100,
sliceSettings: {
fill: am5.color(0x000000)
}
}, {
name: "Panda",
value: 30,
sets: ["Polar bear", "Black bear"],
sliceSettings: {
fillPattern: pattern
}
}]);
// Set up hover appearance: a dashed outline in a color that shows on white, black and the dots
series.hoverGraphics.setAll({
strokeDasharray: [3, 3], // 3px dashes with 3px gaps
stroke: am5.color(0xe8743b),
strokeWidth: 3 // 3px wide
});
{
"type": "SerialChartContainer",
"settings": {
"width": {
"type": "Percent",
"value": 100
},
"height": {
"type": "Percent",
"value": 100
},
"layout": {
"type": "VerticalLayout"
}
},
"properties": {
"series": [
"#series-0"
]
},
"refs": [
{
"data-0": [
{
"name": "Polar bear",
"value": 100,
"sliceSettings": {
"fill": {
"type": "Color",
"value": "#ffffff"
},
"__parse": true
},
"__parse": true
},
{
"name": "Black bear",
"value": 100,
"sliceSettings": {
"fill": {
"type": "Color",
"value": "#000000"
},
"__parse": true
},
"__parse": true
},
{
"name": "Panda",
"value": 30,
"sets": [
"Polar bear",
"Black bear"
],
"sliceSettings": {
"fillPattern": {
"type": "CirclePattern",
"settings": {
"fill": {
"type": "Color",
"value": "#000000"
},
"color": {
"type": "Color",
"value": "#ffffff"
},
"radius": 10,
"gap": 10,
"checkered": true,
"width": 60,
"height": 60
}
},
"__parse": true
},
"__parse": true
}
]
},
{
"series-0": {
"type": "Venn",
"settings": {
"categoryField": "name",
"valueField": "value",
"intersectionsField": "sets",
"paddingTop": 40,
"paddingBottom": 40,
"paddingLeft": 40,
"paddingRight": 40
},
"properties": {
"data": "#data-0",
"slices": {
"properties": {
"template": {
"settings": {
"templateField": "sliceSettings",
"stroke": "@root.interfaceColors.get('text')",
"strokeWidth": 1
}
}
}
},
"labels": {
"properties": {
"template": {
"settings": {
"fill": {
"type": "Color",
"value": "#ffffff"
}
}
}
}
}
}
}
}
]
}