简体   繁体   English

将附加数据设置为highcharts系列

[英]Set Additional Data to highcharts series

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. 这里我们只能将series.name,this.x和this.y用于该系列。 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. 谢谢大家。

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: 在工具提示中,您可以通过传入的对象的“point”属性访问它:

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

Full example here: https://jsfiddle.net/burwelldesigns/jeoL5y7s/ 这里有完整的例子: https//jsfiddle.net/burwelldesigns/jeoL5y7s/

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. 谢谢尼克。

For time series data, especially with enough data points to activate the turbo threshold , the proposed solutions above will not work. 对于时间序列数据,特别是有足够的数据点来激活turbo阈值 ,上面提出的解决方案将不起作用。 In the case of the turbo threshold, this is because Highcarts expects the data points to be an array like: 在turbo阈值的情况下,这是因为Highcarts期望数据点是一个数组,如:

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. 为了不失去turbo阈值的好处(这在处理大量数据点时很重要),我将数据存储在图表之外,并在工具提示formatter函数中查找数据点。 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. 此方法适用于所有图表类型。

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. 我正在使用AJAX从SQL Server获取数据,然后我准备一个js数组,用作我的图表中的数据。 JavaScript code once the AJAX is successfull: 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. 我使用DataRow迭代我的结果集,然后我使用一个类在以Json格式传回之前分配值。 Here is the C# code in the controller action called by Ajax. 以下是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#,但我继承了该项目。

Just to add some kind of dynamism : 只是为了增加某种活力:

Did this for generating data for a stacked column chart with 10 categories. 这是否为生成10个类别的堆积柱形图的数据。
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 : 我希望每个类别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. 希望它可以帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM