Bubble chart created with d3Kit v3.
forked from kristw's block: d3Kit - Reusable chart
license: mit |
Bubble chart created with d3Kit v3.
forked from kristw's block: d3Kit - Reusable chart
<!DOCTYPE html> | |
<title>blockup</title> | |
<link href='style.css' rel='stylesheet' /> | |
<body> | |
<button id="data-btn">Change data</button> | |
<button id="resize-btn">Resize</button> | |
<div id="chart"></div> | |
<div id="info"></div> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://rawgit.com/twitter/d3kit/master/dist/d3kit.min.js"></script> | |
<script src="https://unpkg.com/[email protected]/browser.min.js"></script> | |
<script type="text/babel" src="MyChart.js"></script> | |
<script type="text/babel" src='main.js'></script> | |
</body> |
//--------------------------------------------------- | |
// Generate random data | |
//--------------------------------------------------- | |
function generateBubbles() { | |
const array = []; | |
for(let i=0;i<100;i++){ | |
array.push({ | |
x: Math.random()*100, | |
y: Math.random()*100, | |
r: Math.random()*5+3 | |
}); | |
} | |
return array; | |
} | |
const bubbles = generateBubbles(); | |
//--------------------------------------------------- | |
// Use the bubble chart | |
//--------------------------------------------------- | |
const chart = new MyChart('#chart', { | |
margin: { top: 20 }, | |
initialWidth: 300, | |
initialHeight: 300, | |
pixelRatio: 1 | |
}) | |
.data(bubbles) | |
// handle bubbleClick event | |
.fit({ | |
width: '100%', | |
height: 300 | |
}, true); | |
//--------------------------------------------------- | |
// Buttons | |
//--------------------------------------------------- | |
document.querySelector('#data-btn') | |
.addEventListener('click', () => { | |
chart.data(generateBubbles()); | |
}) | |
let i = 1; | |
document.querySelector('#resize-btn') | |
.addEventListener('click', () => { | |
chart.dimension([200 * i, 200 * i]); | |
i = i===1 ? 2 : 1; | |
}) |
const { scaleLinear, scaleOrdinal, schemeCategory10 } = d3; | |
const { extent } = d3; | |
const { CanvasChart, helper } = d3Kit; | |
class MyChart extends CanvasChart { | |
static getDefaultOptions() { | |
return helper.deepExtend( | |
super.getDefaultOptions(), | |
{ | |
margin: {top: 60, right: 60, bottom: 60, left: 60}, | |
initialWidth: 800, | |
initialHeight: 460 | |
} | |
); | |
} | |
/** | |
* Define the names of custom events that can be dispatched from this chart | |
* @return {Array[String]} event names | |
*/ | |
static getCustomEventNames() { | |
return []; | |
} | |
constructor(selector, options) { | |
super(selector, options); | |
// add custom variables | |
this.xScale = scaleLinear(); | |
this.yScale = scaleLinear(); | |
this.color = scaleOrdinal(schemeCategory10); | |
// add basic event listeners | |
this.visualize = this.visualize.bind(this); | |
this.on('resize.default', this.visualize); | |
this.on('data.default', this.visualize); | |
} | |
// You can define a new function for this class. | |
visualize() { | |
this.clear(); | |
if(!this.hasData()){ | |
return; | |
} | |
const data = this.data(); | |
this.xScale.domain(extent(data, d => d.x)) | |
.range([0, this.getInnerWidth()]); | |
this.yScale.domain(extent(data, d => d.y)) | |
.range([this.getInnerHeight(), 0]); | |
const ctx = this.getContext2d(); | |
data.forEach((d,i) => { | |
ctx.fillStyle = this.color(i); | |
ctx.fillRect( | |
this.xScale(d.x) - d.r, | |
this.yScale(d.y) - d.r, | |
d.r * 2, | |
d.r * 2 | |
); | |
}); | |
} | |
} | |
window.MyChart = MyChart; |