Set Additional Data to highcharts series

JavascriptJqueryHighcharts

Javascript Problem Overview


is there any way to pass some additional data to the series object that will use to show in the chart 'tooltip'?

for example

 tooltip: {
     formatter: function() {
               return '<b>'+ this.series.name +'</b><br/>'+
           Highcharts.dateFormat('%b %e', this.x) +': '+ this.y;
     }

here we can only use series.name , this.x & this.y to the series. lets say i need to pass another dynamic value alone with the data set and can access via series object. is this possible?

Thank you all in advance.

Javascript Solutions


Solution 1 - Javascript

Yes, if you set up the series object like the following, where each data point is a hash, then you can pass extra values:

new Highcharts.Chart( {
    ...,
    series: [ {
        name: 'Foo',
        data: [
            {
                y : 3,
                myData : 'firstPoint'
            },
            {
                y : 7,
                myData : 'secondPoint'
            },
            {
                y : 1,
                myData : 'thirdPoint'
            }
        ]
    } ]
} );

In your tooltip you can access it via the "point" attribute of the object passed in:

tooltip: {
    formatter: function() {
        return 'Extra data: <b>' + this.point.myData + '</b>';
    }
}

Full example here: https://jsfiddle.net/burwelldesigns/jeoL5y7s/

Solution 2 - Javascript

Additionally, with this solution, you can even put multiple data as much as you want :

tooltip: {
    formatter: function () {
        return 'Extra data: <b>' + this.point.myData + '</b><br> Another Data: <b>' + this.point.myOtherData + '</b>';
    }
},

series: [{
    name: 'Foo',
    data: [{
        y: 3,
        myData: 'firstPoint',
        myOtherData: 'Other first data'
    }, {
        y: 7,
        myData: 'secondPoint',
        myOtherData: 'Other second data'
    }, {
        y: 1,
        myData: 'thirdPoint',
        myOtherData: 'Other third data'
    }]
}]

Thank you Nick.

Solution 3 - Javascript

For time series data, especially with enough data points to activate the turbo threshold, the proposed solutions above will not work. In the case of the turbo threshold, this is because Highcarts expects the data points to be an array like:

series: [{
    name: 'Numbers over the course of time',
    data: [
      [1515059819853, 1],
      [1515059838069, 2],
      [1515059838080, 3],
      // you get the idea
    ]
  }]

In order not to lose the benefits of the turbo threshold (which is important when dealing with lots of data points), I store the data outside of the chart and look up the data point in the tooltip formatter function. Here's an example:

const chartData = [
  { timestamp: 1515059819853, value: 1, somethingElse: 'foo'},
  { timestamp: 1515059838069, value: 2, somethingElse: 'bar'},
  { timestamp: 1515059838080, value: 3, somethingElse: 'baz'},
  // you get the idea
]

const Chart = Highcharts.stockChart(myChart, {
  // ...options
  tooltip: {
    formatter () {
      // this.point.x is the timestamp in my original chartData array
      const pointData = chartData.find(row => row.timestamp === this.point.x)
      console.log(pointData.somethingElse)
    }
  },
  series: [{
      name: 'Numbers over the course of time',
      // restructure the data as an array as Highcharts expects it
      // array index 0 is the x value, index 1 is the y value in the chart
      data: chartData.map(row => [row.timestamp, row.value])
    }]
})

This approach will work for all chart types.

Solution 4 - Javascript

I am using AJAX to get my data from SQL Server, then I prepare a js array that is used as the data in my chart. JavaScript code once the AJAX is successfull:

...,
success: function (data) {
            var fseries = [];
            var series = [];
            for (var arr in data) {
                for (var i in data[arr]['data'] ){
                    var d = data[arr]['data'][i];
                    //if (i < 5) alert("d.method = " + d.method);
                    var serie = {x:Date.parse(d.Value), y:d.Item, method:d.method };
                    series.push(serie);
                }
                fseries.push({name: data[arr]['name'], data: series, location: data[arr]['location']});
                series = [];
            };
            DrawChart(fseries);
         },

Now to show extra meta-data in the tooltip:

...
tooltip: {
    xDateFormat: '%m/%d/%y',
    headerFormat: '<b>{series.name}</b><br>',
    pointFormat: 'Method: {point.method}<br>Date: {point.x:%m/%d/%y } <br>Reading: {point.y:,.2f}',
    shared: false,
},

I use a DataRow to iterate through my result set, then I use a class to assign the values prior to passing back in Json format. Here is the C# code in the controller action called by Ajax.

public JsonResult ChartData(string dataSource, string locationType, string[] locations, string[] methods, string fromDate, string toDate, string[] lstParams)
{
    List<Dictionary<string, object>> dataResult = new List<Dictionary<string, object>>();
	Dictionary<string, object> aSeries = new Dictionary<string, object>();
	string currParam = string.Empty;		
		
	lstParams = (lstParams == null) ? new string[1] : lstParams;
	foreach (DataRow dr in GetChartData(dataSource, locationType, locations, methods, fromDate, toDate, lstParams).Rows)
	{
		if (currParam != dr[1].ToString())
		{
			if (!String.IsNullOrEmpty(currParam))		//A new Standard Parameter is read and add to dataResult. Skips first record.
			{
				Dictionary<string, object> bSeries = new Dictionary<string, object>(aSeries); //Required else when clearing out aSeries, dataResult values are also cleared
				dataResult.Add(bSeries);
				aSeries.Clear();
			}
			currParam = dr[1].ToString(); 
			aSeries["name"] = cParam;
			aSeries["data"] = new List<ChartDataModel>();
			aSeries["location"] = dr[0].ToString();
		}

		ChartDataModel lst = new ChartDataModel();
		lst.Value = Convert.ToDateTime(dr[3]).ToShortDateString();
		lst.Item = Convert.ToDouble(dr[2]);
		lst.method = dr[4].ToString();
		((List<ChartDataModel>)aSeries["data"]).Add(lst);
	}
	dataResult.Add(aSeries);
	var result = Json(dataResult.ToList(), JsonRequestBehavior.AllowGet);  //used to debug final dataResult before returning to AJAX call.
	return result;
}

I realize there is a more efficient and acceptable way to code in C# but I inherited the project.

Solution 5 - Javascript

Just to add some kind of dynamism :

Did this for generating data for a stacked column chart with 10 categories.
I wanted to have for each category 4 data series and wanted to display additional information (image, question, distractor and expected answer) for each of the data series :

<?php 

while($n<=10)
{
    $data1[]=array(
        "y"=>$nber1,
        "img"=>$image1,
        "ques"=>$ques,
        "distractor"=>$distractor1,
        "answer"=>$ans
    );
	$data2[]=array(
        "y"=>$nber2,
        "img"=>$image2,
        "ques"=>$ques,
        "distractor"=>$distractor2,
        "answer"=>$ans
    );
	$data3[]=array(
        "y"=>$nber3,
        "img"=>$image3,
        "ques"=>$ques,
        "distractor"=>$distractor3,
        "answer"=>$ans
    );
	$data4[]=array(
        "y"=>$nber4,
        "img"=>$image4,
        "ques"=>$ques,
        "distractor"=>$distractor4,
        "answer"=>$ans
    );
}

// Then convert the data into data series:

$mydata[]=array(
    "name"=>"Distractor #1",
    "data"=>$data1,
    "stack"=>"Distractor #1"
);
$mydata[]=array(
    "name"=>"Distractor #2",
    "data"=>$data2,
    "stack"=>"Distractor #2"
);
$mydata[]=array(
    "name"=>"Distractor #3",
    "data"=>$data3,
    "stack"=>"Distractor #3"
);
$mydata[]=array(
    "name"=>"Distractor #4",
    "data"=>$data4,
    "stack"=>"Distractor #4"
);
?>

In the highcharts section:

var mydata=<? echo json_encode($mydata)?>;

// Tooltip section
tooltip: {
    useHTML: true,
        formatter: function() {
									
            return 'Question ID: <b>'+ this.x +'</b><br/>'+
				   'Question: <b>'+ this.point.ques +'</b><br/>'+
                   this.series.name+'<br> Total attempts: '+ this.y +'<br/>'+
				   "<img src=\"images/"+ this.point.img +"\" width=\"100px\" height=\"50px\"/><br>"+
				   'Distractor: <b>'+ this.point.distractor +'</b><br/>'+
				   'Expected answer: <b>'+ this.point.answer +'</b><br/>';
               }
           },

// Series section of the highcharts 
series: mydata
// For the category section, just prepare an array of elements and assign to the category variable as the way I did it on series.

Hope it helps someone.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSamView Question on Stackoverflow
Solution 1 - JavascriptNick BView Answer on Stackoverflow
Solution 2 - JavascriptAntoine SubitView Answer on Stackoverflow
Solution 3 - JavascriptChristofView Answer on Stackoverflow
Solution 4 - JavascriptCodingSergeView Answer on Stackoverflow
Solution 5 - JavascriptDK250View Answer on Stackoverflow