Chart.js2 Radar, how to configure the label padding/spacing? - charts

I have the following Radar chart using Chart.js v2.
My configuration:
legend: false,
scale: {
pointLabels :{
fontSize: 16,
fontStyle: "bold",
}
}
The problem here is the "Communication" label has 0 padding between the label and the number 100. How can I configure this padding and/or fix this issue?

Spent an hour and still can't find the proper label padding options.
My workaround is padding the labels with newlines and spaces:
['行業競爭情況', ''],
['擁有專利', ''],
' 成本控制',
' 現金流',
['', '回本期'],
['', '營運能力'],
['', '行業潛力'],
'行業網絡 ',
'團隊經驗 ',
['計劃的完整性', ''],
The outcome is acceptable:
Make it auto if you wish:
scale: {
pointLabels: {
callback: function (label, i, labels) {}...

I have the same problem as described in the question and also was unable to find a solution using known chart options.
However, here is another workaround to achieve a behaviour similar to the desired padding (although not exactly):
ticks: {
display: false,
max: 11, // notice how this is +1 more than what you actually want
},
gridLines: {
display: true,
color: [
"#dddddd", "#dddddd", "#dddddd", "#dddddd", "#dddddd",
"#dddddd", "#dddddd", "#dddddd", "#dddddd", "#dddddd",
"transparent" ], // notice how the last (additional) line is set to transparent
},
angleLines: {
display: true,
color: "#dddddd",
},
The idea is to add one additional grid line with a transparent color. While this does not cause any padding between the pointLabels and the angleLines, it does cause there to be one gridLine worth of space between the label and the next gridLine. To me, this at least looks a little better.
Note that this is only feasible if you do not need to display ticks (or if you are ok with your scale showing one additional tick value that you don't actually use).

I use chart.js 2.6.0.
I suffered from the same problem as you.
I use only the radar type chart and amended as follows.
// chart.js v2.6.0
function adjustPointPositionForLabelHeight(angle, textSize, position) {
console.log(position.y);
if (angle === 90 || angle === 270) {
position.y -= (textSize.h / 2);
} else if (angle > 270 || angle < 90) {
position.y -= textSize.h;
position.y -= 7; //add source
}
}

Whenever my PR will be merged, pointLabels.padding option will be added ;)

The PR request mentioned by #ketysek was finally merged as of March 2021.
pointLabels.padding
options: {{
scale: {
pointLabels: {
padding: 10, // Enter number here
},
}};

Usually problem occurs with the first pointLabel when it is single liner you can add the callback in options as follows
pointLabels: {
callback: function (label, index) {
/* Hack to add spacing between first pointLabel item and radar graph */
return index == 0 && label.length == 1? [''].concat(label): label;
}
Making pointLabel multi line text solves the problem.
EDIT:
Current version of chartjs is 2.7.3. Upcoming version will probably solves this problem.

var pointLabelPosition = scale.getPointPosition(i, outerDistance + 5);
-> var pointLabelPosition = scale.getPointPosition(i, outerDistance + 15);

Related

How to color individual boxes of an echarts boxplot based on function

How do I color each boxes individually in an echarts box-plot based on a function?
The following function works on a simple bar chart and colors the bars appropriately:
series: [{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar',
showBackground: true,
itemStyle: {
color: function(seriesIndex) {
return ProfessionColor[seriesIndex.name.split("_", 1).toString()]
},
},
}]
However, it does not work on a box-plot:
series: [{
name: 'boxplot',
type: 'boxplot',
datasetIndex: 1,
itemStyle: {
color: function(seriesIndex) {
return ProfessionColor[seriesIndex.name.split('_', 1)];
}
},
encode: {
tooltip: [1, 2, 3, 4, 5]
}
},
{
name: 'outlier',
type: 'scatter',
encode: {
x: 1,
y: 0
},
datasetIndex: 2
}
]
If I provide color: "red" rather than a function all boxes are colored red. This leads me to believe that it needs to happen in the transform.config which I can't find in the documents or tutorial.
Echarts Box-Plot currently
The link is the complete charts in its current form.
Apparently, echarts only allows scripting (i.e., using a function for) either the line color -- option itemStyle.borderColor or the fill color -- option itemStyle.color.
The difference between the two appears to be made by the value of the internal property BoxplotSeriesModel#visualDrawType. It is now set to "stroke", which means that borderColor can be set via a function.
Since you wanted to set the fill color, its value should be set to "fill". I searched a way to change that property - it was rather difficult for echarts don't document an API for extensions. Still, navigating the source code I came up with this hacky solution:
const BoxplotSeriesModel = echarts.ComponentModel.getClassesByMainType('series').find(cls=>cls.type==='series.boxplot');
const BoxplotSeriesModelFill = function(...args){
const _this = new BoxplotSeriesModel(...args);
_this.visualDrawType = 'fill';
return _this;
}
BoxplotSeriesModelFill.type = BoxplotSeriesModel.type;
echarts.ComponentModel.registerClass(BoxplotSeriesModelFill);
That's a "patch" to be applied at the beginning of your script, immediately after you have the echarts global defined.
Here's a forked version of your code that uses that patch. The only other change I made was to set a borderColor (can now only be a fixed value) to black.
This will not get you all the way, but if you add colorBy: "data" to your options and remove the itemStyle, it will look like this:

ECharts - Looking for the ability to make the last point of a line graph blink

I have a line graph that receives and displays real-time data. I would like to have the last point of the line be a circle that blinks slowly to reinforce the idea that the graph is real-time. Note that the showSymbol attribute of the series is false.
Is there any way to do this on echarts?
To display a point on the last point of your data, you can use a markPoint.
But it doesn't have an option to make it blink so you can instead use a trick like changing its itemStyle.opacity periodically.
Here is an example : (you can copy the following code at the end of this echart example to try it out)
var v = 0
setInterval(function () {
v = v + 0.01
if(v >= 1) {
v = 0.2
}
myChart.setOption({
series: [
{
markPoint: {
animation: false,
symbol: 'circle',
data: [
{
xAxis: data[data.length-1].value[0],
yAxis: data[data.length-1].value[1],
symbolSize: 10,
itemStyle: {
opacity: v
},
}
]
},
}
]
});
}, 20);
There you have a blinking point on the last point of a real-time graphe. You can easily change the way the markPoint looks (shape, color, position ...) : see markPoint doc.

How can I add a title to c3.js chart

Can any one suggest me the way of adding title to the C3.js line and bar charts ? I have got the following sample but it is for gauge chart. For any c3 chart is there any option to set the chart title?
donut: {
title: 'Title'
}
This was a top google result, so I thought I'd add that this is now part of the library:
title: {
text: 'My Title'
}
More info # https://github.com/masayuki0812/c3/pull/1025
You'd need to fall back to using D3 to add a chart title. Something like:
d3.select("svg").append("text")
.attr("x", 100 )
.attr("y", 50)
.style("text-anchor", "middle")
.text("Your chart title goes here");
I am using this code for my chart.
Code:
var chart = c3.generate({
data: {
columns: [
['Monday', 70],
['TuesDay', 20],
['Wednesday', 30],
['Thursday', 50],
['Friday', 100]
],
type: 'donut'
},
donut: {
title: "usage "
}
});
Result :
also couldn't find a way and ended up writing the title as the unit and editing the label.
gauge: {
label: {
format: function(value, ratio) {
return "%"+value;
},
show: true // to turn off the min/max labels.
},
min: 0,
max: 100,
units: "Overall Profit"
// width: 39 // for adjusting arc thickness
},

Show legend of "Indicator plot" in dojo charts

Is there a way to create a Legend control for series that belong to Indicator Plot with Dojo Charting.
I've tried some standard well described ways from the documentation. But with no success! Legend are not appearing for Indicator Plot.
Maybe somebody know is it possible to draw legend for this case or not?
Thanks in advance!
EDIT(my code added):
1. id - id of chart dom element.
2. opts.chartOpts - chart options from outside js.
3. legname - id of legend dom element.
4. scale.avg - is just a double value.
this.chart = new Chart(id, this.opts.chartOpts);
this.chart.addPlot("default", {
animate: { duration: 1000, easing: easing.linear },
type: ColumnsPlot,
markers: true,
gap: 1
});
this.chart.addPlot("avgline", {
type: IndicatorPlot,
vertical: false,
lineStroke: { color: "#00ff00", style: "ShortDash" },
stroke: { width: '1.2px' },
fill: '#eeeeee',
font: 'normal normal normal 11px Arial',
labels: 'none',
offset: { x: 32, y: 4 },
values: [scale.avg],
precision: this.opts.precision
});
//Add axis code goes here... cutted for clearance
this.chart.addSeries('Power', chartOptions.data);
this.chart.addSeries('Average', [scale.avg], { plot: 'avgline' });
var tip = new Tooltip(this.chart, "default", { 'class' : 'kaboom' });
var mag = new Magnify(this.chart, "default");
var hightlight = new Highlight(this.chart, "default");
this.chart.render();
this.leg = new Legend({ chart: this.chart, horizontal: false }, this.legName);
And as result of this code I see legend for 'default' plot 'Power' series only. And nothing for 'Average' series.

Embed bubble charts on a web site

I'm looking for a way to create what come to know to be called a "bubble chart" for a website I'm building. It needs to be compatible with IE7 and above, and of course all the good browsers like Firefox, Chrome and Safari. And no flash since this thing will need to run on iOS.
The chart needs to look like this, http://www.flickr.com/photos/jgrahamthomas/5591441300/
I've browse online and tried a few things, including:
Google Scatter Charts. This doesn't work as it seems Google Charts limits the size of a point to something smaller than I need. And Venn Diagrams are limited to three circles.
Protovis Dots. Great library, but isn't compatible with IE8.
Raphael Javascript. This one might be my best bet, but there's no explicit support for bubble charts.
Thanks for your help.
It looks like Raphael javascript is the way to go. It's compatible with IE6. I found a great tutorial at http://net.tutsplus.com/tutorials/javascript-ajax/an-introduction-to-the-raphael-js-library/ and am able to get the example working on my rails site with this code:
# window.onload = function() {
# var paper = new Raphael(document.getElementById('canvas_container'), 500, 500);
# var circle = paper.circle(100, 100, 80);
# for(var i = 0; i < 5; i+=1) {
# var multiplier = i*5;
# paper.circle(250 + (2*multiplier), 100 + multiplier, 50 - multiplier)
# }
# var rectangle = paper.rect(200, 200, 250, 100);
# var ellipse = paper.ellipse(200, 400, 100, 50);
# }
You can give Protovis a chance, the library looks good for your needs: http://vis.stanford.edu/protovis/ex/
Another charting library is Highcharts, but I haven't tried it yet: http://www.highcharts.com/
Have you had a look at flot?
It's a plotting library for jQuery. While it technically doesn't have any "native" support for bubble charts it is possible to create bubble charts with it by using a few tricks, the simplest one probably being to simply put each point in its own data series (thus allowing you to control the radius of each individual point.
By defining your points similar to this you'll be able to create a bubble chart:
var dataSet = [{
color:"rgba(0,0,0,0)", // Set the color so it's transparent
shadowSize:0, // No drop shadow effect
data: [[0,1],], // Coordinates of the point, normally you'd have several
// points listed here...
points: {
show:true,
fill:true,
radius: 2, // Here we set the radius of the point (or rather, all points
// in the data series which in this case is just one)
fillColor: "rgba(255,140,0,1)", // Bright orange :D
}
},
/* Insert more points here */
];
There is a bubble chart available for flot here
Note that you need to scale your bubbles size yourself if you don't want them to coverup the graph. Documentation is here.
To use it, add the following at the beggining of your html page:
and call it from a json result or any data object like in this sample:
$.getJSON('myQuery.py?'+params, function(oJson) {
// ... Some validation here to see if the query worked well ...
$.plot('#myContainer',
// ---------- Series ----------
[{
label: 'Line Sample',
data: oJson.lineData,
color: 'rgba(192, 16, 16, .2)',
lines: { show: true },
points: { show: false }
},{
label: 'Bubble Sample',
data: oJson.bubbleData, // arrays of [x,y,size]
color: 'rgba(80, 224, 80, .5)',
lines: { show: false },
points: { show: false },
},{
label: 'Points sample',
data: oJson.pointsData,
color: 'rgba(255, 255, 0, 1)',
lines: { show: false },
points: { show: true, fillColor: 'rgba(255, 255, 0, .8)' }
},{
...other series
}],
// ---------- Options ----------
{ legend: {
show: true,
labelBoxBorderColor: 'rgba(32, 32, 32, .2)',
noColumns: 6,
position: "se",
backgroundColor: 'rgba(224, 224, 224, .2)',
backgroundOpacity: .2,
sorted: false
},
series: {
bubbles: { active: true, show: true, fill: true, linewidth: 2 }
},
grid: { hoverable: true, clickable: true } },
xaxis: { tickLength: 0 }
}); // End of plot call
// ...
}); // End of getJSON call
I tried to do the same thing with jqPlot which has some advantages but doesn't work with bubbles and other kind of series on the same graph. Also Flot does a better job to synchronise common axis scale with many series. Highchart does a really good job here (mixing bubble chart with other kind of series) but isn't free for us (government context).