149 lines
5.0 KiB
Markdown
149 lines
5.0 KiB
Markdown
venn.js [![Build Status](https://travis-ci.org/benfred/venn.js.svg?branch=master)](https://travis-ci.org/benfred/venn.js)
|
|
=======
|
|
|
|
A javascript library for laying out area proportional venn and euler diagrams.
|
|
|
|
Details of how this library works can be found on the [blog
|
|
post](http://www.benfrederickson.com/venn-diagrams-with-d3.js/)
|
|
I wrote about this. A follow up post [discusses testing strategy and
|
|
algorithmic improvements](http://www.benfrederickson.com/better-venn-diagrams/).
|
|
|
|
|
|
### Installing
|
|
|
|
If you use NPM, `npm install venn.js`. Otherwise, download the [latest release](https://github.com/benfred/venn.js/releases/latest).
|
|
|
|
|
|
### Usage
|
|
|
|
This library depends on [d3.js](http://d3js.org/) to display the venn
|
|
diagrams.
|
|
|
|
|
|
##### Simple layout
|
|
|
|
To lay out a simple diagram, just define the sets and their sizes along with the sizes
|
|
of all the set intersections.
|
|
|
|
The VennDiagram object will calculate a layout that is proportional to the
|
|
input sizes, and display it in the appropriate selection when called:
|
|
|
|
```javascript
|
|
var sets = [ {sets: ['A'], size: 12},
|
|
{sets: ['B'], size: 12},
|
|
{sets: ['A','B'], size: 2}];
|
|
|
|
var chart = venn.VennDiagram()
|
|
d3.select("#venn").datum(sets).call(chart);
|
|
```
|
|
|
|
[View this example ](http://benfred.github.io/venn.js/examples/simple.html)
|
|
|
|
##### Changing the Style
|
|
|
|
The style of the Venn Diagram can be customized by using D3 after the diagram
|
|
has been drawn. For instance to draw a Venn Diagram with white text and a darker fill:
|
|
|
|
```javascript
|
|
var chart = venn.VennDiagram()
|
|
d3.select("#inverted").datum(sets).call(chart)
|
|
|
|
d3.selectAll("#inverted .venn-circle path")
|
|
.style("fill-opacity", .8);
|
|
|
|
d3.selectAll("#inverted text").style("fill", "white");
|
|
```
|
|
|
|
[View this example, along with other possible styles](http://benfred.github.io/venn.js/examples/styled.html)
|
|
|
|
|
|
##### Dynamic layout
|
|
|
|
To have a layout that reacts to a change in input, all that you need to do is
|
|
update the dataset and call the chart again:
|
|
|
|
```javascript
|
|
// draw the initial diagram
|
|
var chart = venn.VennDiagram()
|
|
d3.select("#venn").datum(getSetIntersections()).call(chart);
|
|
|
|
// redraw the diagram on any change in input
|
|
d3.selectAll("input").on("change", function() {
|
|
d3.select("#venn").datum(getSetIntersections()).call(chart);
|
|
});
|
|
```
|
|
|
|
[View this example](http://benfred.github.io/venn.js/examples/dynamic.html)
|
|
|
|
##### Making the diagram interactive
|
|
|
|
Making the diagram interactive is basically the same idea as changing the style: just add event listeners to the elements in the venn diagram. To change the text size and circle colours on mouseover:
|
|
|
|
```javascript
|
|
d3.selectAll("#rings .venn-circle")
|
|
.on("mouseover", function(d, i) {
|
|
var node = d3.select(this).transition();
|
|
node.select("path").style("fill-opacity", .2);
|
|
node.select("text").style("font-weight", "100")
|
|
.style("font-size", "36px");
|
|
})
|
|
.on("mouseout", function(d, i) {
|
|
var node = d3.select(this).transition();
|
|
node.select("path").style("fill-opacity", 0);
|
|
node.select("text").style("font-weight", "100")
|
|
.style("font-size", "24px");
|
|
});
|
|
```
|
|
[View this example](http://benfred.github.io/venn.js/examples/interactive.html)
|
|
|
|
##### Adding tooltips
|
|
|
|
Another common case is adding a tooltip when hovering over the elements in the diagram. The only
|
|
tricky thing here is maintaining the correct Z-order so that the smallest intersection areas
|
|
are on top, while still making the area that is being hovered over appear on top of the others:
|
|
|
|
```javascript
|
|
// draw venn diagram
|
|
var div = d3.select("#venn")
|
|
div.datum(sets).call(venn.VennDiagram());
|
|
|
|
// add a tooltip
|
|
var tooltip = d3.select("body").append("div")
|
|
.attr("class", "venntooltip");
|
|
|
|
// add listeners to all the groups to display tooltip on mouseover
|
|
div.selectAll("g")
|
|
.on("mouseover", function(d, i) {
|
|
// sort all the areas relative to the current item
|
|
venn.sortAreas(div, d);
|
|
|
|
// Display a tooltip with the current size
|
|
tooltip.transition().duration(400).style("opacity", .9);
|
|
tooltip.text(d.size + " users");
|
|
|
|
// highlight the current path
|
|
var selection = d3.select(this).transition("tooltip").duration(400);
|
|
selection.select("path")
|
|
.style("stroke-width", 3)
|
|
.style("fill-opacity", d.sets.length == 1 ? .4 : .1)
|
|
.style("stroke-opacity", 1);
|
|
})
|
|
|
|
.on("mousemove", function() {
|
|
tooltip.style("left", (d3.event.pageX) + "px")
|
|
.style("top", (d3.event.pageY - 28) + "px");
|
|
})
|
|
|
|
.on("mouseout", function(d, i) {
|
|
tooltip.transition().duration(400).style("opacity", 0);
|
|
var selection = d3.select(this).transition("tooltip").duration(400);
|
|
selection.select("path")
|
|
.style("stroke-width", 0)
|
|
.style("fill-opacity", d.sets.length == 1 ? .25 : .0)
|
|
.style("stroke-opacity", 0);
|
|
});
|
|
```
|
|
[View this example](http://benfred.github.io/venn.js/examples/intersection_tooltip.html)
|
|
|
|
Released under the MIT License.
|