Skip to content
This repository has been archived by the owner on Jul 19, 2019. It is now read-only.

Doughnut Chart with Text Inside #89

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
61d197f
Update core.js
lemonCMS Feb 3, 2016
7d471ff
Create doughnutTextInside.js
lemonCMS Feb 3, 2016
246a5fa
Create doughnutTextInside.js
lemonCMS Feb 3, 2016
8d055e6
Delete doughnutTextInside.js
lemonCMS Feb 3, 2016
3e934e0
Update index.js
lemonCMS Feb 3, 2016
d9032d7
Update README.md
lemonCMS Feb 3, 2016
0e0f560
Update core.js
lemonCMS Feb 4, 2016
100e762
Update core.js
lemonCMS Feb 4, 2016
6f7b119
Minor fixes
lemonCMS Feb 4, 2016
c2a1517
Modified update function and added labelScale to chart options for th…
Malachi-M Feb 10, 2016
a76cf64
Working towards changing the font size
Malachi-M Feb 10, 2016
5ac0501
testing
Malachi-M Feb 10, 2016
17c86eb
Merge pull request #1 from LiveBy/labelSize
Malachi-M Feb 11, 2016
a585715
updating
Malachi-M Feb 11, 2016
8fd03d0
Merge pull request #2 from LiveBy/labelSize
Malachi-M Feb 11, 2016
03fd79e
looking into animation fix
Malachi-M Feb 11, 2016
716ca2b
Merge pull request #3 from LiveBy/labelSize
Malachi-M Feb 11, 2016
d491ddf
modifying core.js
Malachi-M Feb 11, 2016
4bbf74d
Merge pull request #4 from LiveBy/labelSize
Malachi-M Feb 11, 2016
cf57c5f
testing
Malachi-M Feb 11, 2016
ed1a2e7
Merge pull request #5 from LiveBy/labelSize
Malachi-M Feb 11, 2016
0d95f33
Revert "testing"
Malachi-M Feb 11, 2016
05f784d
Merge pull request #6 from LiveBy/revert-5-labelSize
Malachi-M Feb 11, 2016
a8f6e57
updating the draw function
Malachi-M Feb 11, 2016
bc5e3b2
Merge pull request #7 from LiveBy/labelSize
Malachi-M Feb 11, 2016
f4d2cef
updating draw function's apply call
Malachi-M Feb 11, 2016
5b5067c
Merge pull request #8 from LiveBy/labelSize
Malachi-M Feb 11, 2016
b19eee8
Fixing update function, removes old segments on update.
cryptic-mystic Mar 20, 2016
07b095c
Merge pull request #88 from TheCrow1213/master
austinpray Mar 27, 2016
a0e8895
Update core.js
lemonCMS Feb 3, 2016
3df5d0e
Create doughnutTextInside.js
lemonCMS Feb 3, 2016
31ad743
Create doughnutTextInside.js
lemonCMS Feb 3, 2016
b9260dc
Delete doughnutTextInside.js
lemonCMS Feb 3, 2016
7dceb83
Update index.js
lemonCMS Feb 3, 2016
8d860fd
Update README.md
lemonCMS Feb 3, 2016
e808135
Update core.js
lemonCMS Feb 4, 2016
b85abeb
Update core.js
lemonCMS Feb 4, 2016
6eb1a63
Minor fixes
lemonCMS Feb 4, 2016
d002f2f
Modified update function and added labelScale to chart options for th…
Malachi-M Feb 10, 2016
6021af9
Working towards changing the font size
Malachi-M Feb 10, 2016
5732f9a
testing
Malachi-M Feb 10, 2016
0dfb1f0
updating
Malachi-M Feb 11, 2016
a0faeb1
looking into animation fix
Malachi-M Feb 11, 2016
51e1bb8
modifying core.js
Malachi-M Feb 11, 2016
f608512
testing
Malachi-M Feb 11, 2016
c97c93d
Revert "testing"
Malachi-M Feb 11, 2016
1969f3a
updating the draw function
Malachi-M Feb 11, 2016
fd29a75
updating draw function's apply call
Malachi-M Feb 11, 2016
ec4c521
Merge branch 'master' of github.com:LiveBy/react-chartjs
Malachi-M Mar 29, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rich interactive react charting components using [chart.js](http://www.chartjs.o
* Polar area chart
* Pie chart
* Doughnut chart
* Doughnut chart with text inside

[view chart examples](http://jhudson8.github.io/react-chartjs/index.html)

Expand Down
67 changes: 59 additions & 8 deletions dist/react-chartjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ return /******/ (function(modules) { // webpackBootstrap
module.exports = {
Bar: __webpack_require__(1),
Doughnut: __webpack_require__(6),
Line: __webpack_require__(7),
Pie: __webpack_require__(8),
PolarArea: __webpack_require__(9),
Radar: __webpack_require__(10),
DoughnutTextInside: __webpack_require__(7),
Line: __webpack_require__(8),
Pie: __webpack_require__(9),
PolarArea: __webpack_require__(10),
Radar: __webpack_require__(11),
createClass: __webpack_require__(2).createClass
};

Expand Down Expand Up @@ -137,6 +138,43 @@ return /******/ (function(modules) { // webpackBootstrap
var Chart = __webpack_require__(5);
var el = ReactDOM.findDOMNode(this);
var ctx = el.getContext("2d");
Chart.types.Doughnut.extend({
name: "DoughnutTextInside",
showTooltip: function() {
this.chart.ctx.save();
Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments);
this.chart.ctx.restore();
},
draw: function() {
Chart.types.Doughnut.prototype.draw.apply(this,chart, arguments);
var width = this.chart.width,
height = this.chart.height;

var fontSize = (height / 114).toFixed(2);
this.chart.ctx.fillStyle = '#000';
this.chart.ctx.font = fontSize + "em Verdana";
this.chart.ctx.textBaseline = "middle";

var total = 0;
var filled = 0;
var clone = this.segments.slice();
clone.map(function(val) {
total = total + val.value;
})
clone.pop();
clone.map(function(val) {
filled = filled + val.value;
})

var text = Math.round((100 / total) * filled) + "%",
textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2),
textY = height / 2;

this.chart.ctx.fillText(text, textX, textY);
}
});


var chart = new Chart(ctx)[chartType](nextProps.data, nextProps.options || {});
this.state.chart = chart;
};
Expand Down Expand Up @@ -184,8 +222,12 @@ return /******/ (function(modules) { // webpackBootstrap
});
}
});

while(nextProps.data.length < chart.segments.length) {
chart.removeData();
}
} else {
while (chart.scale.xLabels.length > nextProps.data.labels.length) {
while (chart.scale && chart.scale.xLabels.length > nextProps.data.labels.length) {
chart.removeData();
}
nextProps.data.datasets.forEach(function(set, setIndex) {
Expand Down Expand Up @@ -242,7 +284,7 @@ return /******/ (function(modules) { // webpackBootstrap

var vars = __webpack_require__(2);

module.exports = vars.createClass('Line', ['getPointsAtEvent']);
module.exports = vars.createClass('DoughnutTextInside', ['getSegmentsAtEvent']);


/***/ },
Expand All @@ -251,7 +293,7 @@ return /******/ (function(modules) { // webpackBootstrap

var vars = __webpack_require__(2);

module.exports = vars.createClass('Pie', ['getSegmentsAtEvent']);
module.exports = vars.createClass('Line', ['getPointsAtEvent']);


/***/ },
Expand All @@ -260,7 +302,7 @@ return /******/ (function(modules) { // webpackBootstrap

var vars = __webpack_require__(2);

module.exports = vars.createClass('PolarArea', ['getSegmentsAtEvent']);
module.exports = vars.createClass('Pie', ['getSegmentsAtEvent']);


/***/ },
Expand All @@ -269,6 +311,15 @@ return /******/ (function(modules) { // webpackBootstrap

var vars = __webpack_require__(2);

module.exports = vars.createClass('PolarArea', ['getSegmentsAtEvent']);


/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {

var vars = __webpack_require__(2);

module.exports = vars.createClass('Radar', ['getPointsAtEvent']);


Expand Down
2 changes: 1 addition & 1 deletion dist/react-chartjs.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module.exports = {
Bar: require('./lib/bar'),
Doughnut: require('./lib/doughnut'),
DoughnutTextInside: require('./lib/doughnutTextInside'),
Line: require('./lib/line'),
Pie: require('./lib/pie'),
PolarArea: require('./lib/polar-area'),
Expand Down
204 changes: 123 additions & 81 deletions lib/core.js
Original file line number Diff line number Diff line change
@@ -1,129 +1,171 @@
var React = require('react');
var ReactDOM = require('react-dom');
var React = require('react')
var ReactDOM = require('react-dom')

module.exports = {
createClass: function(chartType, methodNames, dataKey) {
createClass: function (chartType, methodNames, dataKey) {
var classData = {
displayName: chartType + 'Chart',
getInitialState: function() { return {}; },
render: function() {
getInitialState: function () {
return {}
},
render: function () {
var _props = {
ref: 'canvass'
};
}
for (var name in this.props) {
if (this.props.hasOwnProperty(name)) {
if (name !== 'data' && name !== 'options') {
_props[name] = this.props[name];
_props[name] = this.props[name]
}
}
}
return React.createElement('canvas', _props);
return React.createElement('canvas', _props)
}
};
}

var extras = ['clear', 'stop', 'resize', 'toBase64Image', 'generateLegend', 'update', 'addData', 'removeData']

var extras = ['clear', 'stop', 'resize', 'toBase64Image', 'generateLegend', 'update', 'addData', 'removeData'];
function extra(type) {
classData[type] = function() {
return this.state.chart[type].apply(this.state.chart, arguments);
};
function extra (type) {
classData[type] = function () {
return this.state.chart[type].apply(this.state.chart, arguments)
}
}

classData.componentDidMount = function() {
this.initializeChart(this.props);
};
classData.componentDidMount = function () {
this.initializeChart(this.props)
}

classData.componentWillUnmount = function() {
var chart = this.state.chart;
chart.destroy();
};
classData.componentWillUnmount = function () {
var chart = this.state.chart
chart.destroy()
}

classData.componentWillReceiveProps = function(nextProps) {
var chart = this.state.chart;
classData.componentWillReceiveProps = function (nextProps) {
var chart = this.state.chart
if (nextProps.redraw) {
chart.destroy();
this.initializeChart(nextProps);
chart.destroy()
this.initializeChart(nextProps)
} else {
dataKey = dataKey || dataKeys[chart.name];
updatePoints(nextProps, chart, dataKey);
dataKey = dataKey || dataKeys[chart.name]
updatePoints(nextProps, chart, dataKey)
if (chart.scale) {
chart.scale.xLabels = nextProps.data.labels;
chart.scale.calculateXLabelRotation();
chart.scale.xLabels = nextProps.data.labels
chart.scale.calculateXLabelRotation()
}
chart.update();
chart.update()
}
};
}

classData.initializeChart = function (nextProps) {
var Chart = require('chart.js')
var el = ReactDOM.findDOMNode(this)
var ctx = el.getContext('2d')
Chart.types.Doughnut.extend({
name: 'DoughnutTextInside',
showTooltip: function () {
this.chart.ctx.save()
Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments)
this.chart.ctx.restore()
},
defaults: {
labelScale: 100
},
draw: function () {
Chart.types.Doughnut.prototype.draw.apply(this, arguments)
var width = this.chart.width,
height = this.chart.height

var fontSize = (height / this.options.labelScale).toFixed(2)
this.chart.ctx.fillStyle = '#000'
this.chart.ctx.font = fontSize + "em 'Open Sans'"
this.chart.ctx.textBaseline = 'middle'

classData.initializeChart = function(nextProps) {
var Chart = require('chart.js');
var el = ReactDOM.findDOMNode(this);
var ctx = el.getContext("2d");
var chart = new Chart(ctx)[chartType](nextProps.data, nextProps.options || {});
this.state.chart = chart;
};
var total = this.total
var clone = this.segments.slice()
clone.pop()
var filled = clone.reduce(function (a, val) {
return a + val.value
}, 0)

var text = Math.round(total > 0 ? (100 / total) * filled : 0) + '%'
var textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2),
textY = height / 2

this.chart.ctx.fillText(text, textX, textY)
}
})

var chart = new Chart(ctx)[chartType](nextProps.data, nextProps.options || {})
this.state.chart = chart
}

// return the chartjs instance
classData.getChart = function() {
return this.state.chart;
};
classData.getChart = function () {
return this.state.chart
}

// return the canvass element that contains the chart
classData.getCanvass = function() {
return this.refs.canvass;
};
classData.getCanvass = function () {
return this.refs.canvass
}

classData.getCanvas = classData.getCanvass;
classData.getCanvas = classData.getCanvass

var i;
for (i=0; i<extras.length; i++) {
extra(extras[i]);
var i
for (i = 0; i < extras.length; i++) {
extra(extras[i])
}
for (i=0; i<methodNames.length; i++) {
extra(methodNames[i]);
for (i = 0; i < methodNames.length; i++) {
extra(methodNames[i])
}

return React.createClass(classData);
return React.createClass(classData)
}
};
}

var dataKeys = {
'Line': 'points',
'Radar': 'points',
'Bar': 'bars'
};
}

var updatePoints = function(nextProps, chart, dataKey) {
var name = chart.name;
var updatePoints = function (nextProps, chart, dataKey) {
var name = chart.name

if (name === 'PolarArea' || name === 'Pie' || name === 'Doughnut') {
nextProps.data.forEach(function(segment, segmentIndex) {
if (name === 'PolarArea' || name === 'Pie' || name === 'Doughnut' || name === 'DoughnutTextInside') {
nextProps.data.forEach(function (segment, segmentIndex) {
if (!chart.segments[segmentIndex]) {
chart.addData(segment);
chart.addData(segment)
} else {
Object.keys(segment).forEach(function (key) {
chart.segments[segmentIndex][key] = segment[key];
});
chart.segments[segmentIndex][key] = segment[key]
})
}
});
})
} else {
while (chart.scale.xLabels.length > nextProps.data.labels.length) {
chart.removeData();
if (chart.scale) {
while (chart.scale.xLabels.length > nextProps.data.labels.length) {
chart.removeData()
}
}
if (nextProps.data && nextProps.data.datasets) {
nextProps.data.datasets.forEach(function (set, setIndex) {
set.data.forEach(function (val, pointIndex) {
if (typeof (chart.datasets[setIndex][dataKey][pointIndex]) == 'undefined') {
addData(nextProps, chart, setIndex, pointIndex)
} else {
chart.datasets[setIndex][dataKey][pointIndex].value = val
}
})
})
}
nextProps.data.datasets.forEach(function(set, setIndex) {
set.data.forEach(function(val, pointIndex) {
if (typeof(chart.datasets[setIndex][dataKey][pointIndex]) == "undefined") {
addData(nextProps, chart, setIndex, pointIndex);
} else {
chart.datasets[setIndex][dataKey][pointIndex].value = val;
}
});
});
}
};

var addData = function(nextProps, chart, setIndex, pointIndex) {
var values = [];
nextProps.data.datasets.forEach(function(set) {
values.push(set.data[pointIndex]);
});
chart.addData(values, nextProps.data.labels[setIndex]);
};
}

var addData = function (nextProps, chart, setIndex, pointIndex) {
var values = []
nextProps.data.datasets.forEach(function (set) {
values.push(set.data[pointIndex])
})
chart.addData(values, nextProps.data.labels[setIndex])
}
3 changes: 3 additions & 0 deletions lib/doughnutTextInside.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var vars = require('./core');

module.exports = vars.createClass('DoughnutTextInside', ['getSegmentsAtEvent']);