Based on the code of this Highchart example, I would like to display some text in the center of the donut circle, when a certain tile is clicked. Is it now possible, to make the displayed text scrollable when it doesn't fit nicely into the circle's inner area?
What I have so far
$(function () {
var colors = ['#8d62a0', '#ceb3d8', '#d5dddd'];
var chart = new Highcharts.Chart({
chart: {
renderTo: 'vacation-time-chart',
type: 'pie',
height: 300,
width: 300,
borderRadius: 0
},
credits: {
enabled: false
},
title: false,
tooltip: {
formatter: function() {
return '<b>'+this.y+'</b>';
}
},
plotOptions: {
pie: {
borderWidth: 6,
startAngle: 90,
innerSize: '75%',
size: '100%',
shadow: true,
// {
// color: '#000000',
// offsetX: 0,
// offsetY: 2,
// opacity: 0.7,
// width: 3
// },
dataLabels: false,
stickyTracking: false,
states: {
hover: {
enabled: false
}
},
point: {
events: {
click: function(){
this.series.chart.innerText.attr({text: this.txt});
}
}
}
}
},
series: [{
data: [
{y:40, color: colors[0], txt: 'yoyo'},
{y:10, color: colors[1], txt: 'dada'},
{y:60, color: colors[2], txt: 'this is a longer text that I would like to be scrollable. this is a longer text that I would like to be scrollable. this is a longer text that I would like to be scrollable. this is a longer text that I would like to be scrollable. this is a longer text that I would like to be scrollable.this is a longer text that I would like to be scrollable. this is a longer text that I would like to be scrollable.'}
]
// data: [
// ['Firefox', 44.2],
// ['IE7', 26.6],
// ['IE6', 20],
// ['Chrome', 3.1],
// ['Other', 5.4]
// ]
}]
},
function(chart) { // on complete
var xpos = '50%';
var ypos = '53%';
var circleradius = 102;
var boundingBox;
var series = chart.series[0];
var zones;
// Render the text
chart.innerText = chart.renderer.label('Articles mentioning XY', 135, 125).add();
boundingBox = chart.innerText.getBBox();
chart.innerText.css({
display:"inline-block",
position:"absolute",
top:"1px",
width: "150px",
height:"30px",
color: '#4572A7',
fontSize: '12px',
overflow: 'auto',
textAlign: 'block'
}).attr({
// why doesn't zIndex get the text in front of the chart?
x: series.center[0] - boundingBox.width / 2 + chart.plotLeft / 2,
y: series.center[1] + boundingBox.height / 2 + chart.plotTop,
zIndex: 999
}).add();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<script src="http://code.highcharts.com/highcharts.js"></script>
</head>
<body>
<div id="vacation-time-chart" style="min-width: 300px; height: 300px; margin: 0 auto"></div>
<script src="testfile.js"></script>
</body>
</html>
Could anyone please help me with this? Adding overflow: auto (or scroll) to the innterText.css properties doesn't seem to be the solution here.
You can do this,
function defineInnerData(name, y, obj) { // on complete
var chart=$("#container").highcharts();
$( "#pieChartInfoText" ).remove();
var textX = chart.plotLeft + (chart.plotWidth * 0.5);
var textY = chart.plotTop + (chart.plotHeight * 0.5);
var span = '<span id="pieChartInfoText" style="position:absolute; text-align:center;left: 235px;top:210px;width: 130px;">';
span += '<span style="font-size: 15px">'+ y +'</span><br>';
span += '<span style="font-size: 12px">'+ name +'</span>';
span += '</span>';
$("#addText").append(span);
span = $('#pieChartInfoText');
span.css('left', textX + (span.width() * -0.5));
span.css('top', textY + (span.height() * -0.5));
}
defineInnerData("", "Tap the slices of this chart to see more");
And call it inside,
series: {
cursor: 'pointer',
point: {
events: {
mouseOver: function() {
console.log(this)
defineInnerData(this.name, this.y, this);
}
}
},
DEMO
Related
I am creating 5 sections of gauge using chartjs-gauge. I am using the following data.
[150,200,250,300,400]
From this data, I want to display the circumference until 300. But the angle should calculated by including the last section value too. I had custom the text showing in section by setting it to empty string if more than 300. For section colour, I set 4 colours["green", "yellow", "orange", "red"]. Now, last section showing as silver colour which is default background of gauge. I have add rgba(0,0,0,0) to colour array ["green", "yellow", "orange", "red","rgba(0,0,0,0)"] which will show transparent colour for last section. But, when hover on section, it is responsive showing border. I would like to know if have other way to show the circumference until certain value from our data ,but calculating section area in chart using all value from data.
var data = [150, 200, 250, 300, 400];
var config = {
type: "gauge",
data: {
labels: ['Success', 'Warning', 'Warning', 'Error'],
datasets: [{
data: data,
value: 300,
backgroundColor: ["green", "yellow", "orange", "red"],
borderWidth: 2
}]
},
options: {
responsive: true,
title: {
display: true,
text: "Gauge chart with datalabels plugin"
},
layout: {
padding: {
bottom: 30
}
},
needle: {
// Needle circle radius as the percentage of the chart area width
radiusPercentage: 2,
// Needle width as the percentage of the chart area width
widthPercentage: 3.2,
// Needle length as the percentage of the interval between inner radius (0%) and outer radius (100%) of the arc
lengthPercentage: 80,
// The color of the needle
color: "rgba(0, 0, 0, 1)"
},
valueLabel: {
formatter: Math.round
},
plugins: {
datalabels: {
display: true,
formatter: function(value, context) {
//return '>'+value;
if (value <= 300) {
return value;
} else {
return '';
}
},
color: function(context) {
//return context.dataset.backgroundColor;
return 'black';
},
//color: 'rgba(255, 255, 255, 1.0)',
/*backgroundColor: "rgba(0, 0, 0, 1.0)",*/
borderWidth: 0,
borderRadius: 5,
font: {
weight: "bold"
}
}
}
}
};
window.onload = function() {
var ctx = document.getElementById("chart").getContext("2d");
window.myGauge = new Chart(ctx, config);
};
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en-US">
<head>
<script src="jQuery/jquery-3.4.1.min.js"></script>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Gauge Chart with datalabels plugin</title>
<script src="https://unpkg.com/chart.js#2.8.0/dist/Chart.bundle.js"></script>
<script src="https://unpkg.com/chartjs-gauge#0.3.0/dist/chartjs-gauge.js"></script>
<script src="https://unpkg.com/chartjs-plugin-datalabels#0.7.0/dist/chartjs-plugin-datalabels.js"></script>
</head>
<body>
<div id="canvas-holder" style="width:100%">
<canvas id="chart"></canvas>
</div>
</body>
</html>
var data = [150, 200, 250, 300, 400];
colour_array = ["#11d8ee", "#3cc457", "#f12b0e", "#dda522", "#808080"];
let sum = data.reduce(function(a, b) {
return a + b;
}, 0);
var perc = 0;
perc_array = [];
for (i = 0; i < data.length; i++) {
perc = (data[i] / sum * 100).toFixed(2);
perc_array.push(perc);
}
Chart.plugins.register({ //increase distance between legend and chart
id: 'paddingBelowLegends',
beforeInit: function(chart, options) {
chart.legend.afterFit = function() {
this.height = this.height + 50; //custom 50 to value you wish
};
}
});
//when want to disable this plugin in other chart, paddingBelowLegends: false in plugin{}
var config = {
type: "doughnut",
data: {
labels: ['A', 'B', 'C', 'D', 'Others'],
datasets: [{
data: data,
value: data[(colour_array.length - 1)], //300
backgroundColor: colour_array,
borderWidth: 2
}]
},
options: {
responsive: true,
cutoutPercentage: 60,//thickness of chart
title: {
display: true,
text: "Gauge chart with datalabels plugin"
},
layout: {
padding: {
bottom: 30
}
},
valueLabel: {
formatter: Math.round,
display: false // hide the label in center of gauge
},
plugins: {
beforeInit: function(chart, options) {
chart.legend.afterFit = function() {
this.height = this.height + 50;
};
},
outlabels: {
display: true,
//text: '%l %v %p',//(label value percentage)the percentage automatically roundoff
//hide chart text label for last section-https://github.com/Neckster/chartjs-plugin-piechart-outlabels/issues/10#issuecomment-716606369
text: function(label) {
console.log(label);
highest_index = label['labels'].length - 1; //get highest index from the labels array
current_index = label['dataIndex']; //current index
value = label['dataset']['data'][label['dataIndex']]; //value of current index
const v = parseFloat(label['percent']) * 100;
if (current_index != highest_index) //to hide last section text label on chart.
{
//return value + ' , ' + `${v.toFixed(2)}%`;
return value+',\n'+`${v.toFixed(2)}%`;
} else {
return false;
}
},
color: 'white',
stretch: 12, //length of stretching
font: {
resizable: true,
minSize: 10,
maxSize: 14
},
padding: {
/*left:25,
right: 0
top:0,
bottom:0*/
}
},
//inner label:
datalabels: { //label on arc section
display: false,
formatter: function(value, context) {
if (value <= data[(colour_array.length - 2)]) //hide datalabel for last section
{
id = data.indexOf(value);
perc = perc_array[id];
return value + ' , ' + perc + '%';
} else {
return '';
}
},
color: function(context) {
return 'black';
},
borderWidth: 0,
borderRadius: 10,
font: {
weight: "bold",
},
anchor: "end" //'center' (default): element center, 'start': lowest element boundary, 'end': highest element boundary
}
},
legend: { //filter last section from legend chart labels
display: true,
//position: 'right',
labels: {
filter: function(legendItem, data) {
//ori-return legendItem !=1;
return !legendItem.text.includes('Others');
},
boxWidth: 20
}
},
rotation: 1 * Math.PI,
circumference: 1 * Math.PI,
tooltips: {
enabled: true,
mode: 'single',
filter: function(tooltipItem, data) { //disable display tooltip in last section
var label = data.labels[tooltipItem.index];
if (label == "Others") {
return false;
} else {
return true;
}
},
callbacks: { //custom tooltip text to show percentage amount (by default,showing real amount)
label: function(tooltipItem, data) {
var dataset = data.datasets[tooltipItem.datasetIndex];
hovered_index = tooltipItem.index;
data_length = data.datasets[0].data.length;
var total = dataset.data.reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
var currentValue = dataset.data[tooltipItem.index];
var percentage = (currentValue / total * 100).toFixed(2);
return currentValue + ' , ' + percentage + "%";
}
}
}
}
};
window.onload = function() {
var ctx = document.getElementById("chartJSContainer").getContext("2d");
window.myGauge = new Chart(ctx, config);
};
<html>
<head>
<script src="https://unpkg.com/chart.js#2.8.0/dist/Chart.bundle.js"></script>
<script src="https://unpkg.com/chartjs-gauge#0.3.0/dist/chartjs-gauge.js"></script>
<script src="https://unpkg.com/chartjs-plugin-datalabels#0.7.0/dist/chartjs-plugin-datalabels.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-piechart-outlabels"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="canvas-holder" style="width:50% align:center">
<canvas id="chartJSContainer"></canvas>
</div>
</body>
</html>
I need to create a div container for a highcharts graphic. This should be done by means of code, but I can not make it work.
The reason to create divs by code is because I have to show many graphics.
Currently I first create the div, then the id and finally the properties.
Error on graphic:
Example :
http://jsfiddle.net/povyq7em/1/
My code is:
var nombre="container-speed";
var div = document.createElement('div');
div.setAttribute("style", "width: 580px; height: 400px; float: left");
div.setAttribute("id", nombre);
var gaugeOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme &&
Highcharts.theme.background2) || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
var chartSpeed = Highcharts.chart(nombre, Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 200,
title: {
text: 'Speed'
}
},
credits: {
enabled: false
},
series: [{
name: 'Speed',
data: [80],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:25px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y}</span><br/>' +
'<span style="font-size:12px;color:silver">km/h</span></div>'
},
tooltip: {
valueSuffix: ' km/h'
}
}]
}));
.highcharts-yaxis-grid .highcharts-grid-line {
display: none;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/solid-gauge.js"></script>
<!--<div id="container-speed" style="width: 300px; height: 200px; float: left"></div>-->
Thank you very much for your help.
You're just missing one step. You need to append the element after you create it. Here's the beginning of your code:
var nombre="container-speed";
var div = document.createElement('div');
div.setAttribute("style", "width: 580px; height: 400px; float: left");
div.setAttribute("id", nombre);
// APPEND ELEMENT TO document.body
document.body.appendChild(div);
Also, I updated your fiddle
Per your request, I updated the fiddle once more. I made 3 changes. Only one of which were really important.
declare and value name to be used as element id and as argument for grafica()
var name = "chart-" + i;
alter setAttribute to div.setAttribute("id", name);
***MOST IMPORTANTLY, you changed the variable nombre to name in every place but here var chartSpeed = Highcharts.chart(name, Highcharts.merge(gaugeOptions, {... which you can tell, I've updated.
Hi I am using the following scatter chart code
https://www.tutorialspoint.com/highcharts/highcharts_scatter_basic.htm
In this I need no negative values. when I pass only positive values data it is solved.
I need to make my y axis value reversed. That is Y axis should start with zero.
x axis same.
Kindly help me to do it. My code is as below
<html>
<head>
<title>User Interaction </title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="ourgraph.js"></script>
</head>
<body>
<div id="container" style="width: 550px; height: 400px; margin: 0 auto"></div>
<script language="JavaScript">
var edata;
var i;
//a = new Array();
$(document).ready(function() {
var chart = {
type: 'scatter',
zoomType: 'xy'
};
var title = {
text: 'User Interaction Touch points'
};
var subtitle = {
text: 'Source: charmboard database'
};
var xAxis = {
//range = [0,320]
title: {
enabled: true,
text: 'Height (px)'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true
};
var yAxis = {
//range = [0,180]
title: {
text: 'Width (px)'
}
};
var legend = {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF',
borderWidth: 0.1
}
var plotOptions = {
scatter: {
marker: {
radius: 0.5,
states: {
hover: {
enabled: true,
lineColor: 'rgb(100,100,100)'
}
}
},
states: {
hover: {
marker: {
enabled: false
}
}
},
tooltip: {
headerFormat: '<b>{series.name}</b><br>',
pointFormat: '{point.x} x-px, {point.y} y-px'
}
}
};
// http call for data
$.ajax({
url: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
type: 'GET',
context: document.body,
success: function(data){
//console.log(data[0]);
//console.log(data[1]);
//console.log(data);
// http call for end
//writeing a data to file starts with removed time slot colum, negatvie values , x axis 0-320 ,y axis 0-180 alone
// data.forEach(function(i)
//{
// if (i[0]> 0 && i[0] < 320 && i[1] >0 && i[1] <180)
// {
//
// edata = data.slice(2);
//}
//});
//writeing a data to file ends with removed time slot colum, negatvie values , x axis 0-320 ,y axis 0-180 alone
var series= [{
name: 'Touches',
color: 'rgba(223, 83, 83, .5)',
data: data
}
];
var json = {};
json.chart = chart;
json.title = title;
json.subtitle = subtitle;
json.legend = legend;
json.xAxis = xAxis;
json.yAxis = yAxis;
json.series = series;
json.plotOptions = plotOptions;
$('#container').highcharts(json);
}
});
});
</script>
</body>
</html>
Since the tutorial is using HighCharts it would be good idea to open there docs.
As for answer you need to change this:
var yAxis = {
title: {
text: 'Weight (kg)'
}
};
To this:
var yAxis = {
title: {
text: 'Weight (kg)'
},
min: 0 // Make sure you add this.
};
Hope that helps!
This question already has an answer here:
Highcharts Donut Chart text in center change on hover
(1 answer)
Closed 8 years ago.
I am trying to dynamic update the text in the centre of my piechart when my tooltip mouses over the series.
By using the formatter inside the tooltip field of the chart I am able to call a separate function but it seems like the text is not updating.
Here is my fiddle Pie Chart
$(function () {
var chartTitle = "Text in the Pie";
var colors = Highcharts.getOptions().colors;
var chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type: 'pie'
},
title: {
text: 'Pie Pie Pie',
y: 20,
verticalAlign: 'top'
},
tooltip: {
//pointFormat: '{series.name}: <b>{point.percentage}%</b>'
formatter: function () {
chartTitle = this.series.name + '/n' + this.point.percentage.toFixed(2) + '%';
refreshText(this);
return '<b>' + this.series.name + '</b>: ' + this.point.percentage;
}
},
plotOptions: {
pie: {
borderColor: 'white',
innerSize: '60%',
dataLabels: {
enabled: false
}
}
},
series: [{
data: [{
y: 59,
color: '#005C7F',
name: 'Chrome'
}, {
y: 41,
color: '#4CCDFF'
}, {
y: 61,
color: '#00B8FF'
}, {
y: 52,
color: '#26677F'
}],
size: '80%',
innerSize: '60%'
}]
},
function (chart1) { // on complete
var xpos = '50%';
var ypos = '50%';
var circleradius = 130;
// Render the circle
chart1.renderer.circle(xpos, ypos, circleradius).attr({
fill: '#0093CC'
}).add();
// Render the text
//chart1.renderer.text(chart1.series[0].data[0].percentage.toFixed(2) + '%', 270, 200).css({
chart1.renderer.text(chartTitle + '%', 230, 200).css({
width: circleradius * 2,
color: '#FFFFFF',
fontSize: '16px',
textAlign: 'center'
}).attr({
// why doesn't zIndex get the text in front of the chart?
zIndex: 999
}).add();
}
);
function refreshText(chart1) {
alert("inside refreshText() function");
var xpos = '50%';
var ypos = '50%';
var circleradius = 130;
// Render the circle
chart1.renderer.circle(xpos, ypos, circleradius).attr({
fill: '#0093CC'
}).add();
chart1.renderer.text(chartTitle + '%', 270, 200).css({
width: circleradius * 2,
color: '#FFFFFF',
fontSize: '16px',
textAlign: 'center'
}).attr({
// why doesn't zIndex get the text in front of the chart?
zIndex: 999
}).add();
}
});
FYI, you were calling refreshChart(this) in your tooltip. You just needed to call refreshChart(chart1) to get the refresh to work, although you weren't clearing out the renderer.
tooltip: {
//pointFormat: '{series.name}: <b>{point.percentage}%</b>'
formatter: function () {
chartTitle = this.series.name + '/n' + this.point.percentage.toFixed(2) + '%';
refreshText(chart1);
return '<b>' + this.series.name + '</b>: ' + this.point.percentage;
}
},
http://jsfiddle.net/2qV9K/
I've been asked to do this kind of graph (40,9% and 16,4% are examples, they should indicate something like -6% and 9%):
Any idea on how I can get that kind of result, using a javascript library, if possible (but it is not a must) Highcharts?
Thanks
It's possible with HighCharts, Documentation
e.g.
$(function () {
data = [{
valSecond: 25,
valFirst: 62.5
}];
// Build the data arrays
var secondData = [];
var firstData = [];
for (var i = 0; i < data.length; i++) {
// add second data
secondData.push({
name: "Second",
y: data[i].valSecond,
color: "#00FF00"
});
// add first data
firstData.push({
name: "First",
y: data[i].valFirst,
color:'#FF0000'
});
}
// Create the chart
$('#container').highcharts({
chart: {
type: 'pie'
},
title: {
text: ''
},
plotOptions: {
pie: {
animation: false,
shadow: false,
center: ['50%', '50%']
}
},
tooltip: {
valueSuffix: '%'
},
series: [{
name: 'second',
data: secondData,
size: '30%',
startAngle: 270,
endAngle: 360,
innerSize: '20%'
}, {
name: 'first',
color:'#FFFFFF',
data: firstData,
size: '80%',
startAngle: 0,
endAngle: 225,
innerSize: '60%',
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 600px; height: 400px; margin: 0 auto"></div>
Jsfiddle
In the highcharts you can adapt donut chart http://www.highcharts.com/demo/pie-donut, remove connectors, set useHTML for dataLabels and rotate by css / rotation SVG element. Missing elements can by added by renderer.