将附加数据设置到highcharts系列

121
有没有办法向系列对象传递一些附加数据,以在图表的“提示信息”中显示?
例如:
 tooltip: {
     formatter: function() {
               return '<b>'+ this.series.name +'</b><br/>'+
           Highcharts.dateFormat('%b %e', this.x) +': '+ this.y;
     }

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

提前感谢大家。


1
JavaScript 对传递的对象并不挑剔,如果它们没有被使用,通常会忽略它们。虽然它们可能会被库的内部代码剥离,但不一定如此,而且通常值得一试。您是否尝试将其他数据附加到您的 series 对象,并在此处理程序中显示它? - Merlyn Morgan-Graham
@MerlynMorgan-Graham - 我是新手,对于 'HighCharts' 不太熟悉。你能否提供任何示例链接?非常感谢你的帮助。 - Sam
@Sam,我的回答有一个完整的工作示例,你可以看一下。如果不太符合您的要求,请告诉我。 - Nick B
在气泡图中,如何添加额外的数据(例如myData),因为数据数组是这样的data : [[12, 43, 13], [74, 23, 44]]?例如,数据值的键是什么,上面的例子有“y”,是否还有“x”,“y”和“z”或“size”? - vishal
5个回答

230

是的,如果您设置了以下这样的系列对象,其中每个数据点都是一个哈希值,那么您就可以传递额外的值:

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

在您的工具提示中,您可以通过传递对象的 "point" 属性来访问它:

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

完整示例在这里:https://jsfiddle.net/burwelldesigns/jeoL5y7s/


1
我知道这是一个旧答案,但是链接到的fiddle不再显示相关示例。 - undefinedvariable
@Nick,太棒了,谢谢。顺便说一句,你的回答很好。我已经没有未使用的默认值可以偷偷地传递信息了。 - undefinedvariable
如果myData是一个数组,如何访问它? - vishal
@user1191081 不太确定我是否理解了你的问题..但是你可以像这样将myData变成一个数组:{ y : 3, myData : [ 'foo', 'bar' ] } 然后你就可以通过this.point.myData[0]和this.point.myData[1]等方式访问它们。 - Nick B
3
谢谢,对于气泡图,如果数据数组是这样的data : [[12, 43, 13], [74, 23, 44]],我该如何添加类似于myData的额外数据?例如上述数据有'y'键,那么有没有'x'、'y'和'z'或者'size'等其他键? - vishal
显示剩余6条评论

17

此外,使用该解决方案,您甚至可以将多个数据任意放置

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'
    }]
}]

谢谢你,尼克。


4
当使用[x, y]非对象格式时,无法添加“附加数据”?我们将datetime用作x值,但希望向工具提示中添加额外的数据。 - Rvanlaak
时间序列数据示例:var serie = {x:Date.parse(d.Value), y:d.Item, method:d.method }; - Arjun Upadhyay
如何在安卓上实现这个? - K Pradeep Kumar Reddy

17

对于时间序列数据,尤其是具有足够数据点以激活turbo 阈值的情况下,上述建议将无法工作。在 turbo 阈值的情况下,这是因为 Highcarts 期望数据点的形式为数组:

series: [{
    name: 'Numbers over the course of time',
    data: [
      [1515059819853, 1],
      [1515059838069, 2],
      [1515059838080, 3],
      // you get the idea
    ]
  }]
为了不失去涉及大量数据点时很重要的 Turbo 阈值的好处,我将数据存储在图表外,并在工具提示 formatter 函数中查找数据点。以下是一个示例:
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])
    }]
})

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


谢谢你的回答,对于在High Stock图表中显示额外数据非常有帮助。 - S Kumar
1
data: _.map(data, row => [row['timestamp'], row['value']]) 应该改为 data: chartData.map(row => [row.timestamp, row.value]),而且你不需要使用 lodash;你可以使用 Array.find。虽然它不被 IE 支持,但你已经在使用 ES6 (const),而且 微软在 2016 年停止支持 IE - Dan Dascalescu
chartData 很好的发现。我习惯使用 lodash,但你是对的。我更新了我的示例,使其与任何库兼容。谢谢。 - Christof

3

我正在使用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);
         },

现在展示额外的元数据在工具提示中:

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

我使用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;
}

我意识到有更高效和更可接受的C#编码方式,但我继承了这个项目。


1

为了增加一些动态效果:

这是为了生成一个包含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"
);
?>

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

希望它能帮助到某个人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接