C3js customize tooltip of scatter chart - javascript

I created a scatter chartlike this in the JSfiddle (http://jsfiddle.net/q8h39/102/)
which is doing two dimension data analysis.
but I need to contain some extra information (e.g: custom names and a extra count value) in the chart** and give different color for each of the plots.
I tried to create an Array and use the tooltip library like this but i didn't reach the goal yet still.
var nameArr = ['anson','jason','samson','dickson']; // Names
tooltip: {
format: {
title: function (d) { return nameArr; },
}
}
Please see the JSfiddle code for further details, many thanks
The below is the current result and the exception exception after development

i have gone through the jsfiddle link and there were two issue with this:-
c3js library is old
c3js does not provide this functionality out of the box but you can achieve this using trick.
I have fixed both of above given issues and now it is working fine.
jsfiddle:-
http://jsfiddle.net/q8h39/109/
code for setting the tooltip:-
tooltip: {
format: {
title: function(x) {
var indOfVal = engagmentArr.indexOf(x);
return nameArr[indOfVal - 1]
},
name: function() {
return engagmentArr[0];
}
},
},

Related

Highcharts JS- add third variable to tooltip for two series

I've already figured out how to make a chart using highcharts where there are three variables- one on the X axis, one on the Y axis, and one on the tooltip. The way to do this is to add the following to the tooltip:
tooltip: {
formatter () {
// this.point.x is the timestamp in my original chartData array
const pointData = chartData.find(row => row.timestamp === this.point.x)
return pointData.somethingElse
}
}
See this fiddle for the full code:
https://jsfiddle.net/m9e6thwn/
I would simply like to do the same, but with two series instead of one. I can't get it to work. I tried this:
tooltip: {
formatter () {
// this.point.x is the timestamp in my original chartData array
const pointData = chartData1.find(row => row.timestamp === this.point.x)
return pointData.somethingElse
const pointData2 = chartData2.find(row => row.timestamp === this.point.x)
return pointData2.somethingElse
}
}
Here is the fiddle of the above: https://jsfiddle.net/hdeg9x02/ As you can see, the third variable only appears on one of the two series. What am I getting wrong?
There are some issues with the way you are using the formatter now. For one, you cannot have two returns in the same function without any if clauses. That will mean that only the first return will be used.
Anyway, here are some improvements I suggest you do for your code.
Add the extra information for each point to highcharts, that makes it a lot easier to access this information through highcharts. E.g. in a tooltip. You can set the data like this:
chartData1.map(function(row) {
return {
x: row.timestamp,
y: row.value,
somethingElse: row.somethingElse
}
})
If you do that, then returning the correct tooltip for each series is a simple matter of doing this:
tooltip: {
formatter () {
// this.point.x is the timestamp in my original chartData array
return this.point.somethingElse
}
}
Working JSFiddle example: https://jsfiddle.net/ewolden/dq7L64jg/6/
If you wanted more info in the tooltip you could then do:
tooltip: {
formatter () {
// this.point.x is the timestamp in my original chartData array
return this.point.somethingElse + ", time: " + str(this.x) + ", value: " + str(this.y)
}
}
Addtionally, you need to ensure that xAxis elements, i.e. your timestamps are sorted. This is a requirement for highcharts to function properly. As it is, your example is reporting
Highcharts error #15: www.highcharts.com/errors/15
in console, because chartData2 is in reverse order. It looks okay for this example, but more complicated examples can lead to the chart not looking as you expect it to.
For this example using reverse is easy enough: data: chartData2.reverse().map(function(row) {return {x: row.timestamp, y: row.value, somethingElse: row.somethingElse}})
Working JSFiddle example: https://jsfiddle.net/ewolden/dq7L64jg/7/

Highchart stacked area not functioning with missing datapoint

The issue is that the percentage area function does not seem to work when a datetime series is missing a datapoint for some t.
E.g. removing
{
x: new Date("2008-10-31T00:00:00.000Z"),
y: 0,
drilldown: 'my_drilldown'
}
from the series in http://jsfiddle.net/qtoas0jg/3/, giving http://jsfiddle.net/qtoas0jg/4/.
The expected/desired behaviour is that the area should fill for all times t. After going through the documentation I conclude that connectNulls:false, also using step:"left" I can achieve the desire behaviour for one series, the one holding values for all t, but then again not for the second series.
Any ideas?
EDIT:
I was not able to solve the issue using Highcharts functionality. Instead I (quite unrigiously) manipulated the series that I put in by adding value 0 for the missing t. If someone stumbles apon this issue, the following might be useful:
let asd = []
// Firstly finding which t:s that need to be added for respective series
let to_be_added = series.map(arg_a => {
return([arg_a.name,arg_a.data.reduce((acc_b,arg_b) => {
// Adding all available t:s
(asd.indexOf(arg_b.x.toString())>=0?0:asd.push(arg_b.x.toString()))
acc_b.push(arg_b.x.toString())
return acc_b
},[])])
}).map(arg_a => {
return [arg_a[0],asd.filter(arg_b => arg_a[1].indexOf(arg_b)<0)]
})
// Adding the new timestamps with y:0
to_be_added.map(arg_a => {
series.map((arg_b,ind) => {
if (arg_b.name == arg_a[0]) {
arg_a[1].reverse().map(arg_c => {
series[ind].data.unshift({x:new Date(arg_c),y:0})
})
}
})
})
This problem is caused by Highcharts bug: https://github.com/highcharts/highcharts/issues/5634
To workaround use timestamps instead of Date object:
data: [{
x: new Date("2008-10-31T00:00:00.000Z").getTime(),
...
}, ...]
Live demo: http://jsfiddle.net/BlackLabel/0wr3kvt1/

Hiding HighCharts StackLabels when series is large

there are a few questions about stacklables on SO, but I don't see any related to my question.
Right now, I have a pretty standard column chart (built with HighCharts). It has basic stack labels and everything works fine. However, when a user expands the viewset of the data (in essence expanding the size of the series) the StackLabels (labels above individual columns) overlap and look messy.
So, I want to hide the stack labels for all columns when the series is say >= 20.
Right now, my stack labels are shown like this:
yAxis: {
min: 0,
title: {
text: 'My Title'
},
stackLabels: {
enabled: true,
formatter: function () {
//if more than 20 points, hide them
if (this.series.length >= 20) {
return ''
}
//else show them
return this.total
}
},
But this doesn't work because the context for 'this' isnt correct, thus this.series.[anything] returns undefined. It seems 'this' is referring to the point..but I need to reference the chart that contains the point.
Is this possible?
This in the formatter does not refer to the chart object nor the axis. Also, data from the series is not yet available. However, you can get the length of the data from the options.
formatter: function() {
//if more than 20 points, hide them
if (this.axis.series[0].options.data.length >= 20) {
return false
}
//else show them
return this.total
}
example: http://jsfiddle.net/6mmLu3ct/

how to use tool tip to display data that is not part of series in highcharts?

I love tool tip function of highcharts! Yet so far I can only display the data from series to tool tip but not the data outside the series. I was considering to add more series but these added series would end up in the chart, which is not what I want.
Can anyone help me? thanks!
The approach I use to this is adding an additional property to each series datapoint:
series:[{
name:"Example Series",
data:[{x:1,y:2,tt:"Tooltip for point 1"},{x:2,y:3,tt:"Tooltip for point 2"}]
}]
These addition properties are available to the tooltip formatter context
tooltip: {
formatter: function() {
if(typeof this.point.tt != 'undefined'){
return this.point.tt;
}else{
return ''+this.x +' / '+ this.y +'';
}
}
},
If you use two element arrays to convey your data, you'll have to convert to objects with x and y properties.
You can access whatever data you like inside the tooltip formatter, including external variables if they're in scope.
jsFiddle Example
var extraVariable = "This is not part of the chart"
var chart = new Highcharts.Chart({
tooltip: {
formatter: function() {
return 'The value for <b>'+ this.x +
'</b> is <b>'+ this.y +'</b> I\'m also showing this: '+extraVariable;
}
},

Decrease the number of visible labels under Ext JS 4 chart

I'm writing Ext JS 4 line chart component. It works all fine, but when I display labels under axis they are just too dense. I won't the number of visible labels to decrease. How to do that? Here's my code for the axis:
{
type: 'Category',
position: 'bottom',
fields: ['date'],
grid: true,
label: {
field: 'label',
rotate: { degrees:315 },
renderer: function(item) {
var date = new Date(item);
/* parseIntToStringWithZeros is a custom method somewhere else */
var day = parseIntToStringWithZeros(date.getDate());
var month = parseIntToStringWithZeros(date.getMonth());
result = day + '-' + month;
return result;
}
}
}
I think you might need to use a "Numeric" axis instead of a "Category" axis a start (not sure what your data looks like, but you might need to convert times to values to get it to work).
With the numeric axis you are supposed to be able to set the number of major tick values (where the grid lines and labels appear), by setting the steps property in the axis config; however this doesn't always work. A more surefire way is to override the applyData function which isn't documented so you need to search through the dev code to see what it's doing.
Also, to simply not render a particular label you can just return the empty string in the label renderer function. e.g. if you only want an individual "month" to show up once in the above code you could do something like this..
label: {
....
renderer: (function(){
var lastRenderedMonth = '';
return function(item){
... //your code above without the return..
if(month == lastRenderedMonth)
return "";
lastRenderedMonth = month;
return result;
};
})(),
...

Categories

Resources