将附加数据设置为highcharts系列

时间:2022-12-04 15:29:08

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

是否有办法将一些附加的数据传递给series对象,以便在图表“工具提示”中显示?

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?

这里我们只能使用series.name, this。x和。y系列。假设我需要通过数据集传递另一个动态值,并可以通过series对象访问。这是可能的吗?

Thank you all in advance.

提前谢谢大家。

5 个解决方案

#1


184  

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

是的,如果您像下面这样设置series对象,其中每个数据点都是一个散列,那么您可以传递额外的值:

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:

在工具提示中,您可以通过传入的对象的“point”属性访问它:

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

Full example here: http://jsfiddle.net/japanick/dWDE6/314/

完整的例子:http://jsfiddle.net/japanick/dWDE6/314/

#2


12  

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.

谢谢你,尼克。

#3


8  

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:

对于时间序列数据,特别是有足够的数据点来激活turbo阈值,以上所提出的解决方案将不起作用。在turbo阈值的情况下,这是因为highcart期望数据点是一个数组,比如:

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:

为了不失去turbo阈值的好处(这在处理大量数据点时很重要),我将数据存储在图表之外,并在tooltip格式化程序函数中查找数据点。这里有一个例子:

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.

这种方法适用于所有的图表类型。

#4


2  

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:

我使用AJAX从SQL Server获取数据,然后准备一个js数组,作为我的图表中的数据。AJAX成功后的JavaScript代码:

...,
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.

我使用一个DataRow迭代我的结果集,然后我使用一个类在返回Json格式之前分配值。这是Ajax调用的控制器动作中的c#代码。

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.

我知道在c#中有一种更有效和可接受的编码方式,但是我继承了这个项目。

#5


1  

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 :

这样做是为了生成包含10个类别的堆叠列图表的数据。我想为每一个类别4数据系列,并想要显示额外的信息(图像,问题,干扰和期望答案)为每一个数据系列:

<?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:

在highcharts部分:

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.

希望它能帮助一些人。

#1


184  

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

是的,如果您像下面这样设置series对象,其中每个数据点都是一个散列,那么您可以传递额外的值:

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:

在工具提示中,您可以通过传入的对象的“point”属性访问它:

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

Full example here: http://jsfiddle.net/japanick/dWDE6/314/

完整的例子:http://jsfiddle.net/japanick/dWDE6/314/

#2


12  

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.

谢谢你,尼克。

#3


8  

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:

对于时间序列数据,特别是有足够的数据点来激活turbo阈值,以上所提出的解决方案将不起作用。在turbo阈值的情况下,这是因为highcart期望数据点是一个数组,比如:

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:

为了不失去turbo阈值的好处(这在处理大量数据点时很重要),我将数据存储在图表之外,并在tooltip格式化程序函数中查找数据点。这里有一个例子:

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.

这种方法适用于所有的图表类型。

#4


2  

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:

我使用AJAX从SQL Server获取数据,然后准备一个js数组,作为我的图表中的数据。AJAX成功后的JavaScript代码:

...,
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.

我使用一个DataRow迭代我的结果集,然后我使用一个类在返回Json格式之前分配值。这是Ajax调用的控制器动作中的c#代码。

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.

我知道在c#中有一种更有效和可接受的编码方式,但是我继承了这个项目。

#5


1  

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 :

这样做是为了生成包含10个类别的堆叠列图表的数据。我想为每一个类别4数据系列,并想要显示额外的信息(图像,问题,干扰和期望答案)为每一个数据系列:

<?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:

在highcharts部分:

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.

希望它能帮助一些人。