Chartist - add text to center of donut chart - javascript

I am trying to create a donut chart with text in the center. I need the donut chart to look like below:
The total value is a variable that I am passing to the function that creates the chart. As of now this is what I have:
Code for the above chart is below:
new Chartist.Pie('.ct-chart', {
series: [{
value: 10,
className: 'pieChart1',
}, {
value: 6,
className: 'pieChart2',
}, {
value: 5,
className: 'pieChart3',
}]
}, {
donut: true,
donutWidth: 20,
width: '138px',
height: '138px',
showLabel: false
});
Can someone please help me create the text inside the donut?

It exist a plugin to do this !
http://gionkunz.github.io/chartist-js/plugins.html#filldonut-plugin
Implement ths dependences and add this code to your object definition params :
plugins: [
Chartist.plugins.fillDonut({
items: [{
content: '<h3>160<span class="small">mph</span></h3>'
}]
})
],

Related

Make a bar chart in Chart.js with a legend that reflects the labels in the X-axis

In Charts.js, i am trying to create a bar chart with a single data set and each column being differently coloured.
The desired result would look like this:
However, when i try to create something like this, at best, i get the following
The following code is the chart config object used to initialise the chart:
var config_canvas_alerts = {
type: 'bar',
data: {
datasets: [{
data: [
value0,value1,value2,value3,
],
backgroundColor: [
"#F7464A","#46BFBD","#FDB45C","#949FB1",
],
}],
labels: [
"Move - Match " + value0,
"Move - Unmatch " + value1,
"Permit - Match " + value2,
"Permit - UnMatch" + value3,
]
},
options: {
responsive: true,
legend: {
position: 'right',
onClick: function (e, p) {
alert(p.text);
},
},
title: {
display: true,
text: '#Model.mgt_dash_alert.graph_title',
position: 'top',
fontStyle: 'normal',
fontSize: 14,
padding: 10
}
}
};
I have tried to restructure the data so that each data value becomes its own dataset object with accompanying value, background colour and label but that didnt work out well either.
The only way i was able to achieve this (and hence how i generated the first screenshot) was by dynamically changing the graph from a pie chart to a bar chart after initialisation. The legend seemed to work well.
Changing dynamically from pie to bar chart is not ideal. Any suggestions here?

How to add text in bar graph not middle in graph

We are using chartist js to make graph chart, but i can not find any solution to how to add text after bar grid.
Please see the below image to clear the pitcher:-
Jquery setting :-
new Chartist.Bar('#ct-campaignsBy', {
labels: ['Campaigns 1', 'Campaigns 2', 'Campaigns 3' ],
series: [
[5, 4, 3 ]
]
}, {
seriesBarDistance: 10,
reverseData: false,
horizontalBars: true,
axisY: {
offset: 80
}
});

Non-static values for chart using CanvasJS?

I'm trying to figure out how to make a dynamic bar chart using CanvasJs.
The basic set up for the chart is as follows:
var chart = new CanvasJS.Chart("chartContainer", {
theme: "theme2",//theme1
title:{
text: "Basic Column Chart - CanvasJS"
},
animationEnabled: false, // change to true
data: [
{
// Change type to "bar", "area", "spline", "pie",etc.
type: "column",
dataPoints: [
{ label: "apple", y: 10 },
{ label: "orange", y: 15 },
{ label: "banana", y: 25 },
{ label: "mango", y: 30 },
{ label: "grape", y: 28 }
]
}
]
});
chart.render();
}
My goal is to use a simple variable to update the dataPoints instead of static numbers such as 10,15, 25.
User's will input numbers and the chart should update based on their input.
Is this possible to do? Setting "Y" to a variable breaks the chart thus far. I'm unsure how to make this work.
I've also tried setting var input = $('input').html
and setting y as input but it does not work.
Thanks!
If anyone else is trying to figure this out here is how this is handled:
Use variable to assign data points in creating CanvasJS graph?.
This also works with Charts.JS.

Change data source of Chart on select

I need a little bit of help to change data from a chart, when an option is selected from a drop-down menu. I've searched for similar questions but nothing was really helpful.
So far I have this code and I don't understand what am I missing that it's not working?
the html:
<div id="scroll-container">
<select id="menu">
<option value="Oil">Oil</option>
<option value="Gas">Gas</option>
</select>
<div id="container_Oil" data-role="ejmchart" style="height: 320px"></div>
</div>
and the javascript part:
<script>
$(function () {
var value = document.getElementById("menu").value;
var chart = document.getElementById("container_Oil");
$('#menu').change(function(evt){
var dataSelection = eval($("#menu").val());
var chart = $('#container_Oil').ejChart ({
dataSource: dataSelection
})
})
})
</script>
The date I am using for the chart, I have in another file, app.js and it contains the following:
var Oil = ...
var Gas = ...
$("#container_Oil").ejChart(
{
primaryXAxis:
{
//labelFormat: 'dd, MM',
//labelFormat: "{value}",
range: { min: 1, max: 30, interval: 2 },
font: { size: '10px' },
labelRotation: 20,
visible :false
},
primaryYAxis:
{
labelFormat: "{value}",
//range: { min: 39, max: 40, interval: 0.1 },
rangePadding: 'normal',
font: { size: '10px' },
visible : false
},
commonSeriesOptions: {
tooltip: { visible: true },
type: 'line', enableAnimation: false,
marker:
{
shape: 'circle',
size:
{
height: 5, width: 5
},
visible: true
},
border: { width: 2 }
},
series: [{
//Binding series with a JSON data source
dataSource: Oil,
//Mapping name of the field containing X value to series
//xName: 'Day',
//Mapping name of the field containing Y value to series
yName: 'Actual',
name: 'Actual'
},
{ dataSource: Oil,
//xName: 'Day',
yName: 'Plan',
name: 'Plan'
}
],
canResize: true,
load: 'onchartload',
title: { text: 'Product - Oil', font: { size: '12px' } },
legend: { visible: true, position: "top" }
});
I want when I select for example Gas in the selector to change the dataSource for the chart from Oil to Gas.
I tried debugging and it said that "Oil" and "Gas" were undefined. Then I tried to put the data for "Oil" and "Gas" in the same file with the script. No more error, but still not working. I think I am missing something important in my code, but I can't seem to understand what. A little help would be more than welcomed!
Perhaps it only creates the charts on page load? Since it's only two charts, you could create them both on page load, and then hide and show the divs depending on the dropdown value for a quick fix.
Did you tried?
$('#menu').on( "change", function(evt){
Instade of:
$('#menu').change(function(evt){

Data Not Showing in Highcharts

I'm attempting to combine a couple of different chart demos from Highcharts.
My examples are: Data classes and popup and Small US with data labels
I want the map from the first with the popup feature of the second. I need to connect the map to my own google spreadsheet but for now I'm just trying to get the data from the first example to work.
This is what I have so far but can't seem to get any data in the map. I thought I had a joinBy problem, and I may still, but when I set joinBy to null I thought "the map items are joined by their position in the array", yet nothing happened.
https://jsfiddle.net/9eq6mydv/
$(function () {
// Load the data from a Google Spreadsheet
// https://docs.google.com/a/highsoft.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0AoIaUO7wH1HwdFJHaFI4eUJDYlVna3k5TlpuXzZubHc&output=html
Highcharts.data({
googleSpreadsheetKey: '0AoIaUO7wH1HwdDFXSlpjN2J4aGg5MkVHWVhsYmtyVWc',
googleSpreadsheetWorksheet: 1,
// custom handler for columns
parsed: function (columns) {
// Make the columns easier to read
var keys = columns[0],
names = columns[1],
percent = columns[10],
// Initiate the chart
options = {
chart : {
renderTo: 'container',
type: 'map',
borderWidth : 1
},
title : {
text : 'US presidential election 2008 result'
},
subtitle: {
text: 'Source: <a href="http://en.wikipedia.org/wiki/United_States_presidential_election,' +
'_2008#Election_results">Wikipedia</a>'
},
mapNavigation: {
enabled: true,
enableButtons: false
},
legend: {
align: 'right',
verticalAlign: 'top',
x: -100,
y: 70,
floating: true,
layout: 'vertical',
valueDecimals: 0,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || 'rgba(255, 255, 255, 0.85)'
},
colorAxis: {
dataClasses: [{
from: -100,
to: 0,
color: '#C40401',
name: 'McCain'
}, {
from: 0,
to: 100,
color: '#0200D0',
name: 'Obama'
}]
},
series : [{
data : data,
dataLabels: {
enabled: true,
color: '#FFFFFF',
format: '{point.code}',
style: {
textTransform: 'uppercase'
}
},
mapData: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']),
joinBy: keys,
name: 'Democrats margin',
point: {
events: {
click: pointClick
}
},
tooltip: {
ySuffix: ' %'
},
cursor: 'pointer'
}, {
type: 'mapline',
data: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small'], 'mapline'),
color: 'silver'
}]
};
/**
* Event handler for clicking points. Use jQuery UI to pop up
* a pie chart showing the details for each state.
*/
function pointClick() {
var row = this.options.row,
$div = $('<div></div>')
.dialog({
title: this.name,
width: 400,
height: 300
});
window.chart = new Highcharts.Chart({
chart: {
renderTo: $div[0],
type: 'pie',
width: 370,
height: 240
},
title: {
text: null
},
series: [{
name: 'Votes',
data: [{
name: 'Obama',
color: '#0200D0',
y: parseInt(columns[3][row], 10)
}, {
name: 'McCain',
color: '#C40401',
y: parseInt(columns[4][row], 10)
}],
dataLabels: {
format: '<b>{point.name}</b> {point.percentage:.1f}%'
}
}]
});
}
// Read the columns into the data array
var data = [];
$.each(keys, function (i, key) {
data.push({
key: key,//.toUpperCase(),
value: parseFloat(percent[i]),
name: names,
row: i
});
});
// Initiate the chart
window.chart = new Highcharts.Map(options);
},
error: function () {
$('#container').html('<div class="loading">' +
'<i class="icon-frown icon-large"></i> ' +
'Error loading data from Google Spreadsheets' +
'</div>');
}
});
});
UPDATE:
I wanted to share with everyone my final solution. Although Ondkloss did a magnificent job answering my question the popup feature still didn't work and this is because I forgot to include the jQuery for the .dialog call. Once I included that I had an empty popup with a highchart error 17, this is because the highmaps.js code doesn't include the pie chart class. So I had to add the highcharts.js code and include map.js module afterward. You can see my final jsfiddle here.
Thanks again to Ondkloss for the excellent answer!
The problem here mostly comes down to the use of joinBy. Also to correct it there are some required changes to your data and mapData.
Currently your joinBy is an array of strings, like ["al", "ak", ...]. This is quite simply not an accepted format of the joinBy option. You can read up on the details in the API documentation, but the simplest approach is to have a attribute in common in data and mapData and then supply a string in joinBy which then joins those two arrays by that attribute. For example:
series : [{
data : data,
mapData: mapData,
joinBy: "hc-key",
]
Here the "hc-key" attribute must exist in both data and mapData.
Here's how I'd create the data variable in your code:
var data = [];
$.each(keys, function (i, key) {
if(i != 0)
data.push({
"hc-key": "us-"+key,
code: key.toUpperCase(),
value: parseFloat(percent[i]),
name: names[i],
row: i
});
});
This skips the first key, which is just "Key" (the title of the column). Here we make the "hc-key" fit the format of the "hc-key" in our map data. An example would be "us-al". The rest is just metadata that will be joined in. Note that you were referencing your data in the options prior to filling it with data, so this has to be moved prior to this.
This is how I'd create the mapData variable in your code:
var mapData = Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']);
// Process mapdata
$.each(mapData, function () {
var path = this.path,
copy = { path: path };
// This point has a square legend to the right
if (path[1] === 9727) {
// Identify the box
Highcharts.seriesTypes.map.prototype.getBox.call(0, [copy]);
// Place the center of the data label in the center of the point legend box
this.middleX = ((path[1] + path[4]) / 2 - copy._minX) / (copy._maxX - copy._minX);
this.middleY = ((path[2] + path[7]) / 2 - copy._minY) / (copy._maxY - copy._minY);
}
// Tag it for joining
this.ucName = this.name.toUpperCase();
});
The first part is your "standard map data". The rest is to correctly center the labels for the popout states, and gotten directly from the example.
And voila, see this JSFiddle demonstration to witness your map in action.
I suggest doing some console.log-ing to see how data and mapData have the hc-key in common and that leads to the joining of the data in the series.

Categories