Char.js - How to show labels by default in pie chart [duplicate] - javascript

This question already has answers here:
Chart.js - Doughnut show tooltips always?
(5 answers)
Closed 7 years ago.
I want to show the labels by default when the page loads. But default chart.js will not show any labels until we do mouseover. I am writing code like below.
var ctx = document.getElementById("chart-area").getContext("2d");
window.myPie = new Chart(ctx).Pie(pieData,{
animationSteps: 100,
animationEasing: 'easeInOutQuart',
scaleShowLabels : true
});
This is my data.
var pieData = [
{
value: 100,
color:"#F7464A",
highlight: "#FF5A5E",
label: "New",
},
{
value: 220,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "In Progress"
}];
What is the property to show the labels by default? I am not able to find under the documentation of chart.js

Actually it is quite easy, you only have to override 2 options properties :
// Draw the tooltips when the animation is completed
onAnimationComplete: function() {
this.showTooltip(this.segments);
},
// Block the mouse tooltip events so the tooltips
// won't disapear on mouse events
tooltipEvents: []
First you force to draw the tooltips when animation is completed, and then you block the mouse events to override the default behaviour as you don't need it anymore (this behaviour is to show only the active tooltip and hide the others)
See my JSFiddle here

You add it in pieData ex:
var pieData = [
{
value : 30,
color : "#F38630",
label : 'Sleep',
labelColor : 'white',
labelFontSize : '16'
},
...
];

Related

Change color of range column chart in ApexCharts

I am trying to implement a waterfall chart for 1 of my projects using ApexCharts. This chart isn't available out of the box with ApexCharts. So, I'm trying to modify the range column chart into a Waterfall chart.
This is pretty much all I need but I need to change the color of the columns where the range is decreasing. Here the middle columns have a blue color, but I need to change it to red. Any leads are appreciated.
I have already checked the fill and the colors property, they don't seem to work properly with range column charts.
CodePen: https://codesandbox.io/s/apx-range-column-forked-8dv67
Thanks in advance.
The closest thing I've been able to get working is setting a fillColor for each data point in a series:
this.chartOptions = {
series: [
{
name: "blue",
data: [
{
x: "Team A",
y: [0, 100],
fillColor: "#FF0000",
},
],
},
],
}
For this to work though, you'd need to do some pre-processing before you add the data points to the series. You would need a function to check if the range is negative and if so sets the color to red.
function barColor(dataPoint1, dataPoint2) {
return (dataPoint1 - dataPoint2) < 0 ? "" : "#FF0000";
}
There's a code Sandbox showing the fillColor in use.

Highcharts Donut Chart customization

I'm working with highcharts and aiming to make a chart similar to this:
Now I've been playing around with the whole ordeal for a while now and I've come been able to reach the following point: http://jsfiddle.net/ccjSy/24/
$(function () {
$(document).ready(function () {
var chart = null;
var categories = ['Body Fat', 'Lean Mass'],
name = 'Body Fat vs. Lean Mass',
data = [{
y: 69,
color: '#F0CE0C',
drilldown: {
name: 'Body Fat',
color: '#F0CE0C'
}
}, {
y: 207,
color: '#23A303',
drilldown: {
name: 'Lean Mass' ,
color: '#23A303'
}
}];
// Build the data array
var browserData = [];
for (var i = 0; i < data.length; i++) {
// add browser data
browserData.push({
name: categories[i],
y: data[i].y,
color: data[i].color
});
}
// Create the chart
chart = new Highcharts.Chart({
chart: {
renderTo: 'donutchart',
type: 'pie',
spacingTop: 0
},
title: {
text: 'Your Body Fat vs Lean Mass',
style: {"color": '#7d7d7d'}
},
series: [{
name: 'Weight',
data: browserData,
dataLabels: {
style: {
fontFamily: 'ArialMT',
fontSize: '15px',
fontWeight: 'bold',
color: '#7d7d7d'
}
},
innerSize: '70%'
}],
tooltip: {
valueSuffix: ' lbs'
},
plotOptions: {
series: {
cursor: 'pointer'
}
}
});
});
});
I am thinking of leaving the space empty in the donut chart and inserting a custom circle with the Weight labeling.
However, I'm not certain how to tackle the following problems:
1) Leave more defined white spaces in between my two columns
2) How to properly align my two data labels? (As you can see in the model, they are in a straight line with neutral lines attached)
3) How to display the data underneath the two labels with both, the pounds and the percentage, as shown in the image.
Answering each of your three questions:
"More white space between columns?" -- add a plotOptions.pie.borderWidth element. The default value is 1. I used 5 to give it more white space.
"Properly align the two data labels?" -- You can compute a custom startAngle based on the two data values which will give you the correct angle to start with. Since you only have two data values in the series, that's easy.
Calculate startAngle for pie chart
var startAngle = 0 - (90 + (180 * (data[0].y / (data[0].y + data[1].y))));
Notice that if you change the y value for the first data object, the "Body Fat" portion of the pie chart will still maintain it's correct position, even as the portion of the chart grows larger or smaller.
"Display data underneath the two labels with custom formatting?" -- use plotOptions.pie.format to apply custom formatting to the pie value labels.
format: '<div style="position: relative; top: -20px; text-align: center">{point.name}<br><b><span style="font-size: 29px">{point.percentage:.0f}%</span></b> ({point.y} lbs)</div>'
Here's a working JSFiddle to see the results. You'll still need to add a dark gray circle behind the pie chart and add the "Total Weight" text but that shouldn't be too difficult.
Since I'm sure you'll be wondering about this, I should mention that there's a lot of white space under the pie chart title because it's leaving enough room for other labels that may appear above or below the pie. Since you're only using two values that will always be on the left/right sides of the pie chart, that doesn't change the fact that HighCharts is preparing to have other labels that may need to be displayed in the surrounding area.

Fill Chart js with $http.get() data

Trying to get some data off of a webservice and display it in a chart. I figured chart js would be a good means to do so. (actually using tc-angular-chartjs). The $http.get( ) call I am using to test is:
$http.get('http://myjson.com/1chr1').success(function(data2) {
data2.forEach(function(r) {
$scope.labels.push(r.name);
$scope.scores.push(r.score);
});
});
and here is the whole js file for just the doughnut chart:
'use strict';
angular
.module( 'app.doughnut', [] )
.controller( 'DoughnutCtrl', function ( $scope ) {
$scope.labels = [];
$scope.scores = [];
$scope.data = [
{
value: 700,
color:'#F7464A',
highlight: '#FF5A5E',
label: 'Red'
},
{
value: 50,
color: '#46BFBD',
highlight: '#5AD3D1',
label: 'Green'
},
{
value: 100,
color: '#FDB45C',
highlight: '#FFC870',
label: 'Yellow'
}
];
$scope.options = {
// Sets the chart to be responsive
responsive: true,
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : '#fff',
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout : 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : 'easeOutBounce',
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
//String - A legend template
legendTemplate : '<ul class="tc-chart-js-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
};
});
The issue I am running into is that most of these examples use the same format to supply the chart with data (static data with the same labels like value/label/color/highlight).
For my needs the colors or highlight dont really matter but I need the data pulled from a wesbervice where the value I need for the chart is called name and the label for the chart is called score.
So I was thinking I could do the $http.get( ) call and put the labels and scores into 2 different arrays and then the data portion in the js would look something like:
$scope.data = {
labels : ["option 1","option 2","option 3"],
values : [ 10, 20, 30 ],
datasets: [ value : values, color : #F7484A, highlight : #FF5A5E, label : labels]
};
I saw something like this done for a Chart.js bar graph, but not for a doughnut graph, and I cannot seem to get it to work. Maybe it isnt possible?
Are there any other alternatives? I mean I cannot be the only person who needs to display dynamic data into a nice responsive chart, but all of the examples use static data.
EDIT ANSWER I took dubhov's advice. Also found out my webservice link was messed up so I wasnt getting any data :p. Here is the new js for future reference:
'use strict';
angular
.module('app.doughnut', [])
.controller('DoughnutCtrl', function($scope, $http) {
$http.get('https://api.myjson.com/bins/1chr1').success(function(data2) {
$scope.data = [];
data2.forEach(function(r) {
$scope.data.push({
'value': r.score,
'color': '#F7464A',
'highlight': '#FF5A5E',
'label': r.name
});
});
});
$scope.options = {
// Sets the chart to be responsive
responsive: true,
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke: true,
//String - The colour of each segment stroke
segmentStrokeColor: '#fff',
//Number - The width of each segment stroke
segmentStrokeWidth: 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout: 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps: 100,
//String - Animation easing effect
animationEasing: 'easeOutBounce',
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
//String - A legend template
legendTemplate: '<ul class="tc-chart-js-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
};
});
Chart.js expects the data to be formatted like it is with the static examples. Can't you just add an object to the data array with the data you need? Like this:
$scope.data.push({'value':r.score,
'label':r.name,
'color':'#RANDOMCOLOR',
'highlight':'#SLIGHTLYSHADEDRANDOMCOLOR'});
As far as the colors, which may or may not be required by the API (I think they will be), you can either go random, or if you know that your dataset is limited, you can select from a static list of colors. Here's some ideas on randoms: https://stackoverflow.com/a/25709983/769971

Incorrect data point value in highcharts navigator series when extending min and max date

I recently updated highstock in which I used a chart that displayed values with an "extended range", i.e. where the min and max date is set outside the boundaries of the chart data.
After the update (which fixed some other bugs) I noticed that the last data point in the navigator series at the bottom is not correct according to the data in the actual series. As can be seen, there's an additional data point at the far right in the bottom that doesn't exist in the actual series.
This can be viewed at http://jsfiddle.net/ab96pnjf/ as well
The code that creates the chart is the following
$(function () {
var fromdate = new Date('2011-04-01');
var todate = new Date('2012-05-21');
var series = [{
color: 'red',
data: MSFT,
name: 'MSFT'
}];
$('#container').highcharts('StockChart', {
navigator: {
series: {
data: series[0].data,
color: '#4572A7',
fillOpacity: 0.05
}
},
xAxis: {
ordinal: false,
min: fromdate.getTime(),
max: todate.getTime()
},
legend: {
enabled: true
},
series: series
});
});
Now, if I change the navigator.series property to
navigator: {
series: series
}
the navigator chart is correct, as in the values are cut off at the right when there is no more data available. This is what I want; the only problem is that the color is the same as the series, and I want it to use my custom color, as in the first example.
So how do I configure HighStock to cut off the last value in the navigator chart while at the same time being able to use a custom color for the series?
Hm, well I have a "quick fix" to this problem, as I am not sure how I would configure highcharts to do it for me.
Using jQuery I can extract the line in the navigator, since highcharts (at least) applies a class to the series. It sets the class name for all series including the one in the "main area", but the last one is the navigator series it seems, or every odd series if there is more than one highcharts chart in the document.
$(function () {
// ... as previous
$('#container').highcharts('StockChart', {
navigator: {
series: series
},
// ... as previous
});
// added code to apply a custom style to the navigator line diagram
var navseries = $('.highcharts-series:last').children();
// can be undefined if the series has no data points
if (navseries) {
navseries.css('stroke', '#4572A7');
navseries.css('strokeWidth', 1);
navseries.css('fillOpacity', 0.05);
}
});

Highcharts dynamically add/change yAxis plotLines

I'm trying to make it possible for my users to add a max plotLine to a chart and have it change the background color of the chart if a plot goes above that line. I can't seem to get a method to update the plotlines. I've tried:
chart.yAxis[0].update({
plotLines: [{
id: 'limit-max',
color: 'blue',
dashStyle: 'LongDashDot',
width: 1,
value: 45000,
zIndex: 0
}]
});
but I get the error:
TypeError: a is undefined
...dBands,function(a){a.render()});n(this.series,function(a){a.isDirty=!0})},setCat...
highcharts.js (line 136)
You can only destroy and create new plotLins, because update() function is not available.
just add this code and then you can use the plotline.update method
//Add support for update method
Highcharts.PlotLineOrBand.prototype.update = function (newOptions){
var plotBand = this;
Highcharts.extend(plotBand.options, newOptions);
if (plotBand.svgElem) {
plotBand.svgElem.destroy();
plotBand.svgElem = undefined;
plotBand.render();
}
}
Here's what worked for me http://jsfiddle.net/tx1kt0bj/2/
var plotBand = tempAxis.plotLinesAndBands[0];
$.extend(plotBand.options, {
color: '#000',
to: 10,
from: 2
});
plotBand.svgElem.destroy();
plotBand.svgElem = undefined;
plotBand.render();
I tried to assign an id to plotLine,
First remove the plotline completely by removePlotLine(id), then added it back by addPlotLine. It works great for me.
function upgradePlotLine(new_line) {
chart.yAxis[0].removePlotLine('my_line');
chart.yAxis[0].addPlotLine(new_line);
}

Categories

Resources