A different suffix for each line on Highstock/Highcharts with Thingspeak source - highcharts

I've got the code for Highcharts in combination with Thingspeak from here:
https://forum.arduino.cc/index.php?topic=213058.0
My problem is, I am not able to implement the different suffix into the code :-(. I've tried a lot, but I dont understand the mechanism behind the Java code.
I've tried some things, but result is, I only have one datafield for the first series but not for the other series...
Formatter function is on line 246.
My different yAxies on line 286.
How can formatter decide which yAxies do actual series use?
Maybe somebody have fun to help me?
http://jsfiddle.net/cbmj8rku/
Best regards, David

Each series is assigned to one yAxis. You can detect which series uses which axis for example by axis title:
tooltip: {
formatter: function() {
var points = this.points,
title,
result = '';
Highcharts.each(points, function(p) {
result += p.y;
title = p.series.yAxis.axisTitle.textStr;
if (title === 'yAxis1') {
result += 'suffix1<br>'
} else if (title === 'yAxis1') {
result += 'suffix2<br>'
} else {
result += 'suffix2<br>'
}
});
return result
}
}
Live demo: http://jsfiddle.net/BlackLabel/ncvtxoke/

I changed the code like this:
http://jsfiddle.net/cbmj8rku/20/
formatter: function() {
var d = new Date(this.x + (myOffset*60000));
var _Min = (d.getMinutes()<10) ? '0' + d.getMinutes() : d.getMinutes();
var _Sec = (d.getSeconds()<10) ? '0' + d.getSeconds() : d.getSeconds();
var s = d.getHours() + ':' + _Min + ':' + _Sec + '<br/>';
$.each(this.points, function () {
s += '<br/>' + this.series.name + ' <b>' + this.y + this.series.yAxis.userOptions.labels.suffix + '</b>';this.series.tooltipOptions.valueSuffix[this.point.index];
});
return s;
}

Related

How to add more attributes in tooltip series in Angular NVD3 line chart

I need to add more attributes in tooltip series in Angular NVD3 line chart, if possible, without modifying the NVD3 source code. I know there are similar posts, but none of them covers this scenario.
Here is my tooltip section in options:
interactiveLayer: {
tooltip: {
contentGenerator: function (d) {
// output is key, value, color, which is the default for tooltips
console.log(JSON.stringify(d.series[0]));
//{"key":"Name","value":1000,"color":"rgba(255,140,0, 1)"}
// and I need more attributes to be added
// into data points, such as label, count, location (see data below)
//{"key":"Name","value":1000,"color":"rgba(255,140,0, 1), "label" : "some label", "count" : 23, "location" : "Paris"}
}
}
}
And here is my data:
$scope.data =
[
{
values: FirstGraphPointsArray,
key: 'Name',
color: 'rgba(255,140,0, 1)'
},
{
values: SecondGraphPointsArray
key: 'City',
color: 'rgba(255,140,0, 1)'
}
]
Finally, the structure of the arrays in data:
FirstGraphPointsArray -> [{ x: xVariable, y: yVariable, label: labelVariable, count: countVariable, location : locationVariable }, {second element...}, {third element...}];
SecondGraphPointsArray -> [a similar array...]
How to get more attributes (label, count, location) from these arrays into the contentGenerator: function (d). As mentioned above, I only receive the default ones from within function parameter (d)
console.log(JSON.stringify(d.series[0]));
//{"key":"Name","value":1000,"color":"rgba(255,140,0, 1)"}
I came up with a solution and wanted to share it, in case someone else comes across the same task. I ended up accessing some of the parameters from d through the default route - function(d), while some of the custom ones - directly from $scope.data.
Important: using the d.index, which indicates the place of the data point in the list is critical hear. This makes sure that for any given index the parameters pulled from the function(d) and those of pulled directly, belong to the same data point (see the code below).
interactiveLayer: {
tooltip: {
contentGenerator: function (d) {
var customTooltipcontent = "<h6 style='font-weight:bold'>" + d.value + "</h6>";
customTooltipcontent += "<table class='custom-tooltip-table'>";
customTooltipcontent += "<tr style='border-bottom: 1px solid green;'><td></td><td>Name</td><td>Value</td><td>Count</td></tr>";
for (var i = 0; i < d.series.length; i++) {
customTooltipcontent += "<tr><td><div style='width:10px; height:10px; background:" + d.series[i].color + "'></div></td><td>" + d.series[i].key + "</td><td>" + d.series[i].value + "</td><td>" + $scope.data[0].values[d.index].count + "</td><td>" + $scope.data[0].values[d.index].location + "</td></tr>"
}
customTooltipcontent += "</table>";
return (customTooltipcontent);
}
}
}

Why Document DB procedure returns only 100 docs on querydocument?

I have below procedure in Document DB. It executes fine from DocumentDb script explorer but the result it returns is partial. I have more than 250 documents satisfying its given where clause which I checked in query explorer. But when I run procedure from script explorer count(defined in procedure) is always 100.
Below is my procedure -
function getInvoice(pageNo, numberOfRecords, member, searchText, customerGroupId,ResellerId) {
var collectionReseller = getContext().getCollection();
var filterquery ;
var count=0, invoiceAmountTotal=0, referalCommissionTotal=0, developerCommissionTotal=0;
var customerIdString='';
var InvoiceList = [];
var whereClause;
if (customerGroupId != "") {
filterquery = 'SELECT c.id from c where c.Type="Customer" and c.CustomerGroupID="' + customerGroupId + '"';
var isAccepted = collectionReseller.queryDocuments(
collectionReseller.getSelfLink(), filterquery,
function (err, documents, responseOptions) {
var docCount = documents.length;
documents.forEach(function (doc) {
docCount--;
if (docCount > 0)
customerIdString = customerIdString + '"' + doc.id + '", '
else
customerIdString = customerIdString + '"' + doc.id + '" '
})
whereClause = 'where r.Type="Invoice" and r.CustomerID IN (' + customerIdString + ')'
var filterquery1 = 'SELECT * FROM root r ';
if (member.length > 0) {
member.forEach(function (val, i) {
whereClause = whereClause + ' and contains(r.' + member[i] + ',"' + searchText[i] + '")';
});
}
isAccepted = collectionReseller.queryDocuments(
collectionReseller.getSelfLink(), filterquery1 + whereClause,
function (err, invoiceDoc) {
var qr = filterquery1 + whereClause;
count = invoiceDoc.length;
invoiceDoc.forEach(function (doc) {
invoiceAmountTotal = parseFloat(invoiceAmountTotal) + parseFloat(doc.InvoiceAmount);
referalCommissionTotal = parseFloat(referalCommissionTotal) + parseFloat(doc.ReferralCommission);
developerCommissionTotal= parseFloat(developerCommissionTotal) + parseFloat(doc.DeveloperCommission);
InvoiceList.push(doc);
});
InvoiceList.sort(SortByID);
InvoiceList = InvoiceList.slice(pageNo * numberOfRecords, pageNo * numberOfRecords + numberOfRecords);
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
getContext().getResponse().setBody(JSON.stringify({ InvoiceList, count, invoiceAmountTotal, referalCommissionTotal, developerCommissionTotal }));
});
});
}
else
{
whereClause = ' where r.Type = "Invoice" and r.ResellerID = "'+ ResellerId + '"';
filterquery = 'SELECT * FROM root r ';
if(member.length > 0) {
member.forEach(function (val, i) {
whereClause = whereClause + ' and contains(r.' + member[i] + ',"' + searchText[i] + '")';
});
}
filterquery = filterquery + whereClause;
var isAccepted = collectionReseller.queryDocuments(
collectionReseller.getSelfLink(), filterquery,
function (err, documents, responseOptions) {
if (err) throw err;
invoiceDoc = documents;
count =invoiceDoc.length;
invoiceDoc.forEach(function (doc) {
InvoiceList.push(doc);
invoiceAmountTotal = parseFloat(invoiceAmountTotal) + parseFloat(doc.InvoiceAmount);
referalCommissionTotal = parseFloat(referalCommissionTotal) + parseFloat(doc.ReferralCommission);
developerCommissionTotal= parseFloat(developerCommissionTotal) + parseFloat(doc.DeveloperCommission);
});
InvoiceList.sort(SortByID);
InvoiceList = InvoiceList.slice(pageNo * numberOfRecords, pageNo * numberOfRecords + numberOfRecords);
// Check the feed and if empty, set the body to 'no docs found',
// else take 1st element from feed
getContext().getResponse().setBody(JSON.stringify({ InvoiceList, count, invoiceAmountTotal, referalCommissionTotal, developerCommissionTotal }));
});
}
function SortByID(a, b) {
var aName = a.UpdatedOn.toLowerCase();
var bName = b.UpdatedOn.toLowerCase();
return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
}
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
Any help will be highly appreciated..
If you want to get all 250 back in one shot, you need to populate the options parameter for queryDocuments() with a pageSize field. It's an optional third parameter for that function call. Without it, this server-side API will default to 100.
You can also set pageSize to -1 to get you all documents. However, for server-side stored procedures, I recommend against this. Rather, you need to handle paging using the continuation token. If you want it to be really robust you also need to deal with premature shutdown of the stored procedure.

Showing tooltip with two or more stack columns

When I select a column, I want to show a tool-tip with only the values for the specific stack selected, but I'm showing all values for the two stacks (2012 and 2013).
Can I configure the tool-tip to show only one stack value?
If I cannot do it, how can I show the stack label into the tool-tip(2012 or 2013)?
I tried to use point.series.stack, but I'm getting a undefined value. Is it possible?
Code to show a tooltip over a stacked chart:
tooltip: {
formatter: function() {
var s = '<b>'+ this.x +'</b>';
$.each(this.points, function(i, point) {
s += '<br/>'+ point.series.name +': '+point.series.stack+':'+ point.y +'m';
});
return s;
},
shared : true
}
The complete code
Thanks for your help.
Hi again
I followed your advice in order to show only the values for the same stack.
I have this formatter code:
tooltip: {
formatter: function() {
var tip = '<b>'+ this.x ;
var stackSelected = this.point.series.options.stack;
tip += '/'+stackSelected+'</b>';
$.each(this.series.chart.series, function(i, s) {
if(s.options.stack == stackSelected){
tip += '<br/><br/>';
tip += '<b>'+s.name+' : </b>'+s.yAxis;
}
});
return tip;
},
shared : false
}
But I have problems in order to get the value for each serie.
Could you help me on this please?
Thanks in advance
I forgot the complete code: http://jsfiddle.net/Kqumw/4/
I can get that i want
Thanks for your tips.
This is my tooltip code:
tooltip: {
formatter: function() {
var tip = '<b>'+ this.x ;
var stackSelected = this.point.series.options.stack;
var categorySelected = this.point.category;
tip += '/'+stackSelected+'</b>';
tip += '<br/><br/>';
var index = 0;
$.each(this.series.chart.series, function(i, s) {
if(s.options.stack == stackSelected){
$.each(s.data, function(j, point){
if(point.category == categorySelected)
tip += '<b>'+s.name+' : </b>'+point.y+'<br>';
});
}
});
return tip;
},
shared : false
}
This is the complete code http://jsfiddle.net/Kqumw/5/
It's not possible to show different tooltip for the same category when shared is set for tooltip. If you want to show stack in tooltip, use point.series.options.stack, see: http://jsfiddle.net/Kqumw/1/
If you want to show only one stack (full stack for hovered point), then disable shared (shared: false) and find on your own corresponding points for the same category and the same stack (by comparing category index/name from points and stack id from series).

Highstock change display format on y-axis when changing comparer

Hi I'm using the following example:
http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/stock/members/axis-setcompare/
How do I a change format of the values on the y-axis. For example when I choose percentage i want the values to be displayed as +25%. I now how to initially set up this up but how do I change it with Jquery script.
formatter: function () {
return (this.value > 0 ? '+' : '') + this.value + '%';
}
/S
If you use formatter in the tooltip, you should have this.y instead of this.value.
formatter: function() {
return (this.y > 0 ? '+' : '') + this.y;
}
http://jsfiddle.net/6neGD/1/
I solved it. Just use
chart.options.yAxis[0].labels.format = '{value} %';
to display label as percentage

Highchart - yAxis - 1,000 should be displayed like 1000

I can't find the settings for my problem in the Highchart API.
I've cerated an example on jsFiddle http://jsfiddle.net/qErT2/
How can I swap 1,000 into 1000 ??
Greetings
HighChart number format is the same like PHP NUMBER FORMATS
you can use this format any where
for tooltip
tooltip: {
formatter: function ()
{
return '<b>' + this.series.name + '</b><br/>' + this.x + ' - <b>' + Highcharts.numberFormat(this.y, 0,'',''); + '</b>';
}
}
for yAxis
yAxis: {
labels: {
formatter: function () {
return Highcharts.numberFormat(this.value, 0,'','');
}
}
},
YOUR EXAMPLE MODIFIED DEMO (tooltip)
AND UPDATED DEMO (tooltip and yAxis labels)
Take look at lang options http://api.highcharts.com/highcharts#lang and obviously you can use Highcharts.numberFormat() http://api.highcharts.com/highcharts#Highcharts.numberFormat() which can be used in tooltip formater / label formatter to display numbers as you need.
http://api.highcharts.com/highcharts#yAxis.labels.formatter

Resources