How to fix labels clashing problem in RGraph pie chart? - rgraph

I'm creating RGraph pie chart in which labels are clashing. Though I am using labels.sticks property to fix this issue but it has no effect on the output.
Here's my code to draw pie chart:
<script type="text/javascript">
$(document).ready(function(){
// Some data that is to be shown on the pie chart. It should be an array of numbers.
var data = [6.3, 2.1, 1.1, 3.2, 7.4, 10.5, 5.3, 27.4, 1.1, 4.2];
var labels = ['Data Loggers 6', 'Data Translation 2', 'Energy Loggers 1', 'Hobo 3', 'iButton 7', 'ICP 10', 'MCC 5', 'Monnit 26', 'Orchestrator 1', 'Sensors 4'];
for(var i = 0; i < data.length; i++)
{
labels[i] = labels[i] + ', ' + data[i] + '%';
}
var colors_arr = new Array('#00FFFF', '#7FFFD4', '#FFE4C4', '#0000FF', '#8A2BE2', '#A52A2A', '#7FFF00', '#FF7F50', '#B8860B', '#A9A9A9', '#8B008B', '#FF1493', '#228B22', '#DAA520', '#20B2AA', '#87CEFA', '#6B8E23', '#FF0000', '#FFFF00', '#F5DEB3');
var colors = new Array();
for(var i = 0; i < data.length; i++)
{
colors[i] = colors_arr[i];
}
// Create the Pie chart
var pie = new RGraph.Pie({
id: 'report_prospects_qty_products_canvas' ,
data: data,
options: {
labels: {
self: labels,
sticks: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
},
tooltips: {
self: labels,
//event: 'onmousemove',
},
shadow: false,
strokestyle: 'transparent',
title: {
self: 'Products',
bold: false,
y: 10
},
radius: 70,
colors: colors,
text: {
size: 8,
color: "red",
angle: 45
},
},
}).roundRobin();
$('#report_prospects_qty_products_wrapper').mouseout(function(){
// Hide the tooltip
RGraph.hideTooltip();
// Redraw the canvas so that any highlighting is gone
RGraph.redraw();
});
});
</script>
HTML
<!-- Put this where you want the chart to show up: -->
<div id="cvs_wrapper">
<!-- An example of using CSS to resize the canvas tag. -->
<canvas id="report_prospects_qty_products_canvas" width="600" height="250" style="width:100%;">[No canvas support]</canvas>
</div>
Output:
To fix labels clashing issue, I am using following option:
options: {
labels: {
self: labels,
sticks: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
},
According to RGraph docs:
labels.sticks Stipulates that sticks for the labels are shown. This
can also be an array of stick lengths - which may be useful if you're
experiencing the labels clashing. Default: false
FYI, I am using // version: 2015-05-24

Judging by the configuration snippet that you posted then I'm guessing that you might be using an older version. The current version (5.0 at this time) uses a far better way of arranging labels so there's no clashing (unless you have oodles of labels).
There's a demo page that shows this new method quite nicely here:
https://www.rgraph.net/demos/pie-basic.html
And the code for this is no different to what you might be used to:
labels = [ 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ];
new RGraph.Pie({
id: 'cvs',
data: [20,1,1,1,1,1,1],
options: {
tooltips: labels,
labels: labels,
shadow: false,
colorsStroke: 'rgba(0,0,0,0)',
exploded: 0
}
}).roundRobin();

Related

Chart.js how to highlight a part of a label

i am trying to highlight part of a label from the axis labels based on what the user has searched for.
However the label is being rendered as text so the html tags are shown like plain text. any ideas on how to achieve this?
You can use the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code snippet, I use the afterDraw hook to draw text of different styles underneath each bar.
When drawing your own tick labels, probably want to define the text rotation. Further you need to instruct Chart.js not to display the default labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false,
rotation: 40
}
}],
You also need to define some padding for the bottom of the chart, otherwise you won't see your custom tick labels.
layout: {
padding: {
bottom: 60
}
},
Please take a look at below code sample and see how it works. Tick labels that need to be drawn with two different styles are separated with a semicolon inside data.labels.
new Chart(document.getElementById('myChart'), {
type: 'bar',
plugins: [{
afterDraw: chart => {
let ctx = chart.chart.ctx;
let xAxis = chart.scales['x-axis-0'];
let yAxis = chart.scales['y-axis-0'];
chart.data.labels.forEach((l, i) => {
let labelTokens = l.split(';');
let rotation = xAxis.options.ticks.rotation * -Math.PI / 180;
let x = xAxis.getPixelForValue(l);
if (labelTokens.length == 2) {
ctx.save();
let width = ctx.measureText(labelTokens.join(' ')).width;
ctx.translate(x, yAxis.bottom + 10);
ctx.rotate(rotation);
ctx.font = 'italic 12px Arial';
ctx.fillStyle = 'blue';
ctx.fillText(labelTokens[0], -width, 0);
ctx.restore();
}
ctx.save();
let labelEnd = labelTokens[labelTokens.length - 1];
let width = ctx.measureText(labelEnd).width;
ctx.translate(x, yAxis.bottom + 10);
ctx.rotate(rotation);
ctx.font = '12px Arial';
ctx.fillText(labelEnd, -width, 0);
ctx.restore();
});
}
}],
data: {
labels: ['NASTY!!;Errors', 'Warnings'],
datasets: [{
label: 'Result',
data: [30, 59],
fill: false,
backgroundColor: ['rgba(255, 99, 132, 0.2)', 'rgba(255, 159, 64, 0.2)'],
borderColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)'],
borderWidth: 1
}]
},
options: {
layout: {
padding: {
bottom: 60
}
},
legend: {
display: false
},
tooltips: {
callbacks: {
title: tooltipItem => tooltipItem[0].xLabel.split(';').join(' ')
}
},
scales: {
xAxes: [{
ticks: {
display: false,
rotation: 40
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" width="10" height="8"></canvas>

RGraph V5 Upgrade - error getting context

I had a working 3d chart using version 2107-10-1 that used images for the y axis.
I'm now trying to use the version 5 libraries but I'm getting an error:
"Cannot read property 'getContext' of null at new RGraph.Drawing.Image (RGraph.drawing.image.js:64)
Which is:
"context = this.canvas.getContext('2d');"
I change the line in the library to 3d to match the chart variant setting of 3d and the error is resolved. However I then get the following errors:
"Cannot set property 'shadowColor' of null
at Object.RG.noShadow.RG.NoShadow (RGraph.common.core.js:5155)
at RGraph.Drawing.Image.draw.Draw (RGraph.drawing.image.js:490)"
I've been going through the API to try and find any differences to the property names but my skill and understanding is not great.
Any help or advice would be greatly appreciated.
:-)
new RGraph.Bar({
id: 'cvs',
data: [ [0,5,5],[0,5,5],[0,5,5] ],
options: {
/******/
variant: '3d',
variantThreedAngle: 0,
hmarginGrouped: 2,
/*****/
textFont: '"Courier New", Courier, monospace',
titleFont: '"Courier New", Courier, monospace',
labels:['Monday', 'Saturday', 'Sunday'] ,
colors: [ '#3cb44b','#5484ed','#fbd75b' ],
textSize: 11,
title: 'Test Learner1: T1C1 W/B 22nd April 2019',
titleSize: 11,
titleColor:'#338833',
titleX: 50,
titleY: 25,
titleHalign: 'Left',
textAccessible: false,
key: ['LabelOne','LabelTwo','LabelThree'], //['One','Two','Three','Four','Five'],
keyPositionY: 470,
keyPositionX: 0,
gutterBottom: 65,
gutterRight: 10,
gutterTop: 40,
gutterLeft: 70,
keyPosition: 'gutter',
keyTextSize: 9,
numyticks: 2,
ylabelsCount: 2,
ymax: 10,
ymin: 0,
backgroundColor: 'white',
labelsColor: 'green'
// end options
}
}).draw().exec(function (obj)
{
var images = [
'smileyimages/graphimages/smiley5.png','smileyimages/graphimages/smiley10.png','smileyimages/graphimages/smiley1.png',
];
var index = 0;
obj.coordsText.forEach(function (val, key, arr)
{
if (val.tag === 'scale') {
var x = val.x,
y = val.y,
text = val.text;
var img = new RGraph.Drawing.Image({
id: 'cvs',
x: x,
y: y,
src: images[index],
options: {
halign: 'right',
valign: 'center'
}
}).draw();
index++;
}
});
obj.set({
ylabels: true
});
RGraph.redraw();
}).on('beforedraw', function (obj)
{
RGraph.clear(obj.canvas, 'white');
});
I've adjusted your code for the new property names. With this code remember to update the paths to the images.
<script src="/libraries/RGraph.drawing.image.js"></script>
<script src="/libraries/RGraph.common.core.js"></script>
<script src="/libraries/RGraph.common.key.js"></script>
<script src="/libraries/RGraph.bar.js"></script>
And the code that makes the chart:
new RGraph.Bar({
id: 'cvs',
data: [ [1,5,5],[1,5,5],[1,5,5] ],
options: {
variant: '3d',
hmargin: 20,
hmarginGrouped: 2,
textFont: '"Courier New", Courier, monospace',
titleFont: '"Courier New", Courier, monospace',
xaxis: false,
xaxisLabels:['Monday', 'Saturday', 'Sunday'] ,
colors: [ '#3cb44b','#5484ed','#fbd75b' ],
title: 'Test Learner1: T1C1 W/B 22nd April 2019',
titleX: 120,
titleY: 25,
titleHalign: 'Left',
textAccessible: false,
key: ['LabelOne','LabelTwo','LabelThree'], //['One','Two','Three','Four','Five'],
keyPositionY: 435,
keyPositionX: 100,
marginBottom: 95,
marginRight: 10,
marginTop: 40,
marginLeft: 100,
keyPosition: 'margin',
keyLabelsSize: 9,
yaxis: false,
yaxisLabelsCount: 2,
yaxisScaleMax: 10,
yaxisScaleMin: 0,
backgroundColor: 'white',
xaxisLabelsColor: 'green'
}
}).draw().exec(function (obj)
{
var images = [
'/images/alex.png',
'/images/alert.png',
'/images/facebook.png'
];
var index = 0;
obj.coordsText.forEach(function (val, key, arr)
{
if (val.tag === 'scale') {
var x = val.x,
y = val.y,
text = val.text;
var img = new RGraph.Drawing.Image({
id: 'cvs',
x: x,
y: y + 10,
src: images[index++],
options: {
halign: 'right',
valign: 'center'
}
}).draw();
}
});
});

Adding tooltip to legend in highcharts

I am trying to add a tooltip to the legend in highcharts. I am using a pie chart. Using angular js framework.
The legend code is as below
legend: {
useHTML: true,
layout: 'vertical',
align: 'left',
itemMarginTop: 10,
itemMarginBottom: 15,
title: {
style: {
fontSize: "14px",
fontWeight: "600",
color: "#404040"
}
},
itemStyle: {
fontWeight: 'normal',
color: '#404040',
fontSize: '14px'
},
//x : 70,
//y: 110,
labelFormatter: function() {
return ` <md-icon>
<md-tooltip md-direction="top">Hello</md-tooltip>
<i class="material-icons help_icon">info_outline</i>
</md-icon>`
}
},
I do not get the expected results. it just displays the letter H and no icon. If i use a standalone icon like
<i class="material-icons help_icon">info_outline</i>
It just displays the icon. But I am unable to add any tooltip. I searched online and found a solution using the jquery UI plugin. Is there any other way without the plugin and using the angular material icons? Please suggest.
Ps: I have also tried with single quotes / double quotes instead of inverted ticks.
Unfortunately, tooltip in a legend is not supported. However, you can create it using Highcharts.SVGRenderer. Check code and demo posted below.
Code:
var chart = Highcharts.chart('container', {
chart: {
type: 'column',
events: {
load: function() {
var chart = this,
legend = chart.legend,
legendItems = legend.allItems,
group,
rectElem,
textElem,
box,
i;
group = chart.renderer.g('legend-tooltip').attr({
transform: 'translate(-9999, -9999)',
zIndex: 99
}).add();
textElem = chart.renderer.text().attr({
class: 'legend-tooltip-text',
zIndex: 7
}).add(group);
rectElem = chart.renderer.rect().attr({
'class': 'legend-tooltip',
'stroke-width': 1,
'stroke': '#c5c5c5',
'fill': 'rgba(245, 245, 245, 0.95)',
}).add(group);
for (i = 0; i < legendItems.length; i++) {
(function(i) {
var item = legend.allItems[i].legendItem.parentGroup;
item.on('mouseover', function(e) {
// Define legend-tooltip text
var str = chart.series[i].userOptions.fullName;
textElem.element.innerHTML = str;
// Adjust rect size to text
box = textElem.getBBox()
rectElem.attr({
x: box.x - 8,
y: box.y - 5,
width: box.width + 15,
height: box.height + 10
});
// Show tooltip
group.attr({
transform: `translate(${e.clientX + 7}, ${e.clientY + 7})`
})
}).on('mouseout', function(e) {
// Hide tooltip
group.attr({
transform: 'translate(-9999,-9999)'
})
});
})(i);
}
}
}
},
series: [{
data: [10, 12, 5],
fullName: 'Series 1 tooltip'
}, {
data: [6, 10, 7],
fullName: 'Series 2 tooltip'
}]
});
Demo:
https://jsfiddle.net/BlackLabel/3cbpe0mn/
API reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer
https://api.highcharts.com/class-reference/Highcharts.SVGElement#on

Set font sizes on individual labels in anychart

I have a pie chart that I'm creating using anychart.
The pie chart labels are all using the correct font-family and color, but what I want to do is be able to set different font sizes for each piece. I want to set the font size to be larger on the largest slice.
Here is my Fiddle
Here is my javascript
<script type="text/javascript">
var chart;
var labels;
anychart.onDocumentReady(function () {
//dataset
var data = anychart.data.set([
{ name: "$0-$50,000", value: 68, labelText: "68%", toolTip: "68%", title: "$0-$50,000" },
{ name: "$50,000-$100,000", value: 13, labelText: "13%", toolTip: "13%", title: "$50,000-$100,000" },
{ name: "$100,000-$150,000", value: 6, labelText: "6%", toolTip: "6%", title: "$100,000-$150,000" },
{ name: "$150,000-$250,000", value: 6, labelText: "6%", toolTip: "6%", title: "$150,000-$250,000" },
{ name: "$250,000 - plus", value: 7, labelText: "7%", toolTip: "7%", title: "$250,000 - plus" }
])
//set chart variable
chart = anychart.pie(data);
//Set labels to pull from data
labels = chart.labels();
labels.textFormatter('{%labelText}');
//Format tooltip content and styles
var tooltip = chart.tooltip();
tooltip.textFormatter('{%toolTip}');
tooltip.titleFormatter('{%title}');
tooltip.separator(true);
tooltip.fontFamily('PT Sans');
tooltip.fontSize(18);
tooltip.title().fontFamily('PT Sans');
tooltip.title().fontSize(18);
tooltip.title().align('center');
//adjust legend
var legend = chart.legend();
legend.enabled(true);
legend.position("left");
legend.align("center");
legend.itemsLayout("vertical");
legend.fontFamily('PT Sans');
//adjust font
var labels = chart.labels();
labels.fontColor('white');
labels.fontFamily('PT Sans');
labels.fontSize(36);
//create title
var title = chart.title();
title.text("68% of Rollovers Involve Less Than $50,000");
title.enabled(true);
title.fontColor('Red');
title.fontSize('48');
title.fontFamily('PT Sans');
title.fontWeight('700');
//inner radius makes this a doughnut chart instead of pie
chart.innerRadius("30%");
//define the container
chart.container("Container");
chart.animation(true);
//set delay to recall draw ch art to
chart.draw();
});
</script>
And here is a photo I've created in photoshop to show what I'm trying to achieve
The easiest way to do that is to put label object right into the data:
anychart.onDocumentReady(function() {
//dataset
var data = anychart.data.set([{
name: "$0-$50,000",
value: 68,
labelText: "68%",
toolTip: "68%",
title: "$0-$50,000",
label: {
fontColor: "Blue",
fontSize: 20
}
}, {
name: "$50,000-$100,000",
value: 13,
labelText: "13%",
toolTip: "13%",
title: "$50,000-$100,000",
label: {
fontColor: "Blue",
fontSize: 10
}
}, {
name: "$100,000-$150,000",
value: 6,
labelText: "6%",
toolTip: "6%",
title: "$100,000-$150,000",
label: {
fontColor: "Blue",
fontSize: 9
}
}, {
name: "$150,000-$250,000",
value: 6,
labelText: "6%",
toolTip: "6%",
title: "$150,000-$250,000",
abel: {
fontColor: "Green",
fontSize: 8
}
}, {
name: "$250,000 - plus",
value: 7,
labelText: "7%",
toolTip: "7%",
title: "$250,000 - plus",
label: {
fontColor: "Red",
fontSize: 7
}
}]);
//set chart variable
chart = anychart.pie(data);
chart.overlapMode(true);
//Set labels to pull from data
labels = chart.labels();
labels.textFormatter('{%labelText}');
//Format tooltip content and styles
var tooltip = chart.tooltip();
tooltip.textFormatter('{%toolTip}');
tooltip.titleFormatter('{%title}');
tooltip.separator(true);
tooltip.fontFamily('PT Sans');
tooltip.fontSize(18);
tooltip.title().fontFamily('PT Sans');
tooltip.title().fontSize(18);
tooltip.title().align('center');
//adjust legend
var legend = chart.legend();
legend.enabled(true);
legend.position("left");
legend.align("center");
legend.itemsLayout("vertical");
legend.fontFamily('PT Sans');
//adjust font
//var labels = chart.labels();
labels.fontColor('white');
labels.fontFamily('PT Sans');
//create title
var title = chart.title();
title.text("68% of Rollovers Involve Less Than $50,000");
title.enabled(true);
title.fontColor('Red');
title.fontSize('48');
title.fontFamily('PT Sans');
title.fontWeight('700');
//inner radius makes this a doughnut chart instead of pie
//chart.innerRadius("30%");
//define the container
chart.container("container");
chart.animation(true);
//set delay to recall draw ch art to
chart.draw();
});
<script src="https://cdn.anychart.com/js/7.12.0/anychart-bundle.min.js"></script>
<div id="container"></div>
Label object goes like this:
label: {
fontColor: "Blue",
fontSize: 20
}
Here is a sample on jsfiddle: http://jsfiddle.net/g3r57cee/
Some more information on labels can be found at http://docs.anychart.com/latest/Common_Settings/Labels

Angular-chart / line chart with multiple horizontal lines (margins)

I am trying to create an agular line chart that has four horizontal lines (margins - two upper margins and two lower margins). Please see this fiddle - https://jsfiddle.net/CypressMountain/arq34fcu/30/
My objective is to define the properties (value,color,label) of these lines inside angular controller, but not inside JQuery line chart extension, as it is currently done in the fiddle. The graph properties, as well as the margin line properties will come from the back end, and the margin lines will be drawn independently from the graph.
I am not sure how to achieve something like $scope.margins = [] in controller, similar to what we have for $scope.data = [] or $scope.labels... Any help is appreciated.
This is the HTML:
<canvas id="line" class="chart chart-linebis" chart-data="data"
chart-labels="labels" chart-legend="true" chart-series="series"
chart-click="onClick">
</canvas>
The margin lines are now defined in draw function, when the line chart type is being extended
draw: function () {
Chart.types.Line.prototype.draw.apply(this, arguments);
var lines =
[
{
label: 'Upper margin 1',
value: 90,
color: 'rgba(255, 0, 0, .9)'
},
{
label: 'Upper margin 2',
value: 75,
color: 'rgba(255, 165, 0, .8)'
},
{
label: 'Lower margin 1',
value: -10,
color: 'rgba(0, 165, 255, .8)'
},
{
label: 'Lower margin 2',
value: -25,
color: 'rgba(0, 0, 255, .8)'
}
]
.............................
This is the controller:
angular.module('test', ['chart.js']);
angular.module('test').controller('TestCtrl', function ($scope) {
$scope.labels = ["January", "February", "March", "April", "May", "June", "July"];
$scope.series = ['Series A'];
$scope.data = [
[-5, 48, 40, -19, 86, 27, 90]
];
});
Two previous posts were referenced
angular-chart add horizontal line
and
Chart.js - draw horizontal line
I finally got it resolved and hope this will help someone else who might have a similar task.
$scope.options is the place inside the angular controller where the margin lines' properties will be received from the back end and assigned to $scope.options (you would replace the current hard coded label, value, and color for each horizontal line with the dynamic values).
$scope.options = {
limitLines: [
{
label: 'Upper margin 1',
value: 90,
color: 'rgba(255, 0, 0, .9)'
},
{
label: 'Upper margin 2',
value: 75,
color: 'rgba(255, 165, 0, .8)'
},
{
label: 'Lower margin 1',
value: -10,
color: 'rgba(0, 165, 255, .8)'
},
{
label: 'Lower margin 2',
value: -25,
color: 'rgba(0, 0, 255, .8)'
}
]
}
Then the canvas tag in HTML will have the options added:
chart-options="options"
Finally, in the line chart extension code, in the draw function 'lines' will be bridged to 'limitLines' via options:
draw: function () {
Chart.types.Line.prototype.draw.apply(this, arguments);
var lines = this.options.limitLines;

Resources