HighStock 图表中的多个系列

Multiple series in HighStock charts

我按照以下线程解决了问题,但它对我不起作用。

我有一个简单的要求,即在 page/chart 的负载和初始加载后在单个图表中绘制多个系列(GBP_USD、USD_EUR 和 USD_CHF)完成后,每秒都会调用服务器,其中 returns 一个具有三个值的数组,一个用于 series1 (GBP_USD),第二个用于 series2(EUR_USD),第三个用于 series3 (USD_CHF).

我先从绘制静态图开始,一个图表中的三个系列...

当我在图表中绘制单个系列时,它可以正常工作,但是当我添加更多系列时,它就不起作用了。我可以在三个不同的调用中下载数据(按照 HighStock 的比较示例)并且数据已成功接收,但我得到的不是曲线,而是直线。 [![图像显示数组中有三个名称,绘制直线][1]][1]。 [![此图为names数组只有一个值时的图表-GBP_USD][2]] [2]

JSFiddle link

$(function() {
  console.log('in annynymous()');
  // var names = ['GBP_USD'], // Any One Currency, works [serise is as it should be]
  var names = ['GBP_USD', 'EUR_USD', 'USD_CHF'], // Three currencies [series are flat]
    seriesCounter = 0,
    seriesOptions = [],
    colors = Highcharts.getOptions().colors;

  console.log('starting to retrive data');

  $.each(names, function(i, name) {
    document.getElementById("loading").innerHTML = '<B>Loading please wait.. retrieving data</B>';


    var url = "http://134.213.48.26:8080/apitest/api/v1/ext/jsfiddle/data?callback=?&id=" + name;
    $.getJSON(url, function(data) {
      console.log("success with grabing json data for " + name);

      seriesOptions[i] = {
        name: name + ' Temperature',
        data: data,
        color: colors[i],
        type: 'line'
      };

      // As we're loading the data asynchronously, we don't know what order it will arrive. So
      // we keep a counter and create the chart when all the data is loaded.
      seriesCounter++;

      if (seriesCounter == names.length) {
        createChart();
      }
    });
  });

  // create the chart when all data is loaded
  function createChart() {

    console.log('in createChart()');
    Highcharts.setOptions({
      global: {
        useUTC: false
      }
    });

    // Create a timer, to test how long this takes to load
    var start = +new Date();

    // Create the chart
    $('#container').highcharts('StockChart', {

      chart: {
        events: {
          load: function(chart) {
            this.setTitle(null, {
              text: 'This chart was built on ' + new Date() + ' in ' + (new Date() - start) + 'ms'
            });


          }
        }
      },
      rangeSelector: {
        buttons: [{
          type: 'hour',
          count: 1,
          text: '1hr'
        }, {
          type: 'hour',
          count: 3,
          text: '3hr'
        }, {
          type: 'hour',
          count: 12,
          text: '12hr'
        }, {
          type: 'day',
          count: 1,
          text: '1d'
        }, {
          type: 'day',
          count: 3,
          text: '3d'
        }, {
          type: 'day',
          count: 5,
          text: '5d'
        }, {
          type: 'day',
          count: 7,
          text: '7d'
        }, {
          type: 'month',
          count: 1,
          text: '1m'
        }, {
          type: 'month',
          count: 3,
          text: '3m'
        }, {
          type: 'month',
          count: 6,
          text: '6m'
        }, {
          type: 'year',
          count: 1,
          text: '1y'
        }, {
          type: 'all',
          text: 'All'
        }],
        selected: 2
      },

      yAxis: {
        type: 'linear',
        title: {
          text: 'Prices'
        }
      },

      title: {
        text: 'Historical Instruments Data '
      },

      subtitle: {
        text: 'Built chart at...' // dummy text to reserve space for dynamic subtitle
      },

      tooltip: {
        pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
        valueDecimals: 1
      },

      series: seriesOptions,

      exporting: {
        width: 1000
      }

    }, function(chart) {
      // Last point in graph...
      document.getElementById("loading").style.display = "none"; //hide the loading text

      showLastPointTooltip(chart);
    });
  };

});


function showLastPointTooltip(objHighStockchart) {
  // show tooltip for last point   
  var points = [];
  if (objHighStockchart) {
    for (var i = 0; i < objHighStockchart.series.length; i++)

      points.push(objHighStockchart.series[i].points[objHighStockchart.series[i].points.length - 1]);


    objHighStockchart.tooltip.refresh(points);


  };
  console.log('DONE')

};
<title>Multiple Currencies</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/highcharts-more.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>

<div id="loading" sytle="font-weight:bold;"></div>
<div id="container" style="height: 500px; min-width: 500px">

我可以在服务器端控制 data/format 和频率,并且可以更改为使解决方案正常工作所需的任何最佳方式。

我也按照下面的示例行,但是将 url 更改为我的本地服务器,还更改了 Jquery verion 和 HighStock 图表脚本标签,但出现错误。[![错误当运行下面的例子URL][3]][3]

trouble plotting multiple series of data on highstock

三种货币服务器端数据如下:

GBP_USD = [[[1442485146000,1.55080],[1442485147000,1.55080],[1442485147000,1.55077] ,1.55067],[1442485152000,1.55067],[1442485152000,1.55067],[1442485153000,1.55067],[1442485154000,1.55072],[1442485155000,1.55072],[1442485156000,1.55072],[1442485157000,1.55072],[1442485158000,1.55072 ],[1442485158000,1.55072],[1442485159000,1.55072],[1442485160000,1.55072],[1442485161000,1.55072],[1442485162000,1.55072],[1442485163000,1.55072],[1442485163000,1.55072],[1442485164000,1.55072], [1442485165000,1.55072],[1442485166000,1.55072],[1442485167000,1.55072],[1442485168000,1.55072],[1442485169000,1.55072],[1442485169000,1.55072],[1442485170000,1.55076],[1442485171000,1.55107],[1442485172000 ,1.55107],[1442485173000,1.55107],[1442485174000,1.55107],[1442485174000,1.55107],[1442485175000,1.55107]]

EUR_USD = [[1442485146000,1.13152],[1442485147000,1.13152],[1442485147000,1.13156],[1442485148000,1.13151],[1442485149000,1.13155],[1442485150000,1.13155],[1442485151000 ,1.13153],[1442485152000,1.13155],[1442485152000,1.13155],[1442485153000,1.13155],[1442485154000,1.13155],[1442485155000,1.13155],[1442485156000,1.13155],[1442485157000,1.13155],[1442485158000,1.13155 ],[1442485158000,1.13155],[1442485159000,1.13155],[1442485160000,1.13155],[1442485161000,1.13155],[1442485162000,1.13155],[1442485163000,1.13155],[1442485163000,1.13155],[1442485164000,1.13155], [1442485165000,1.13155],[1442485166000,1.13155],[1442485167000,1.13155],[1442485168000,1.13155],[1442485169000,1.13155],[1442485169000,1.13155],[1442485170000,1.13157],[1442485171000,1.13149],[1442485172000 ,1.13149],[1442485173000,1.13149],[1442485174000,1.13149],[1442485174000,1.13155],[1442485175000,1.13155]]

USD_CHF = [[[1442485146000,0.96951],[1442485147000,0.96951],[1442485147000,0.96948] ,0.96948],[1442485152000,0.96939],[1442485152000,0.96933],[1442485153000,0.96933],[1442485154000,0.96933],[1442485155000,0.96933],[1442485156000,0.96933],[1442485157000,0.96933],[1442485158000,0.96933 ],[1442485158000,0.96933],[1442485159000,0.96933],[1442485160000,0.96933],[1442485161000,0.96933],[1442485162000,0.96933],[1442485163000,0.96933],[1442485163000,0.96933],[1442485164000,0.96933], [1442485165000,0.96933],[1442485166000,0.96933],[1442485167000,0.96933],[1442485168000,0.96933],[1442485169000,0.96933],[1442485169000,0.96933],[1442485170000,0.96933],[1442485171000,0.96940],[1442485172000 ,0.96940],[1442485173000,0.96940],[1442485174000,0.96940],[1442485174000,0.96940],[1442485175000,0.96940]]

任何指点帮助将不胜感激...

发生这种情况是因为与不同系列之间的差异相比,一个系列中的数据变化太小,无法产生任何视觉差异。例如,您在每个系列中的数据变化小于 +/- 0.001,而第二个和第三个系列之间的差异接近 0.16,比 0.001 大 160 倍!您甚至可以在 this updated fiddle 中直观地看到这种效果(看到图表底部的图例了吗?单击系列中的 2 个以隐藏它们,并查看第 3 个如何扩展以填充空白 space ).

有两种方法可以解决这个问题,都涉及多个 y 轴:

1。使用多个重叠的 y 轴

var axisOptions = [];

$.each(names, function(i, name) {
  var url = "http://134.213.48.26:8080/apitest/api/v1/ext/jsfiddle/data?callback=?&id="+ name; 
  $.getJSON(url, function(data) {
    axisOptions.push({
      title: {
      text: name + 'Prices'
    });
    // build seriesOptions and other stuff ...
  });
});

$('#container').highcharts('StockChart', {
    yAxis: axisOptions,
    // other options ...
});

Link to JSFiddle

$(function() {
  console.log('in annynymous()');
  // var names = ['GBP_USD'], // Any One Currency, works [serise is as it should be]
  var names = ['GBP_USD', 'EUR_USD', 'USD_CHF'], // Three currencies [series are flat]
    seriesCounter = 0,
    seriesOptions = [],
    axisOptions = [],
    colors = Highcharts.getOptions().colors;

  console.log('starting to retrive data');

  $.each(names, function(i, name) {
    document.getElementById("loading").innerHTML = '<B>Loading please wait.. retrieving data</B>';


    var url = "http://134.213.48.26:8080/apitest/api/v1/ext/jsfiddle/data?callback=?&id=" + name;
    $.getJSON(url, function(data) {
      console.log("success with grabing json data for " + name);

      seriesOptions[i] = {
        name: name + ' Temperature',
        data: data,
        color: colors[i],
        type: 'line',
        yAxis: i
      };

      axisOptions.push({
        title: {
          text: name + 'Prices'
        },
      });

      // As we're loading the data asynchronously, we don't know what order it will arrive. So
      // we keep a counter and create the chart when all the data is loaded.
      seriesCounter++;

      if (seriesCounter == names.length) {
        createChart();
      }
    });
  });

  // create the chart when all data is loaded
  function createChart() {

    console.log('in createChart()');
    Highcharts.setOptions({
      global: {
        useUTC: false
      }
    });

    // Create a timer, to test how long this takes to load
    var start = +new Date();

    // Create the chart
    $('#container').highcharts('StockChart', {

      chart: {
        events: {
          load: function(chart) {
            this.setTitle(null, {
              text: 'This chart was built on ' + new Date() + ' in ' + (new Date() - start) + 'ms'
            });


          }
        }
      },
      rangeSelector: {
        buttons: [{
          type: 'hour',
          count: 1,
          text: '1hr'
        }, {
          type: 'hour',
          count: 3,
          text: '3hr'
        }, {
          type: 'hour',
          count: 12,
          text: '12hr'
        }, {
          type: 'day',
          count: 1,
          text: '1d'
        }, {
          type: 'day',
          count: 3,
          text: '3d'
        }, {
          type: 'day',
          count: 5,
          text: '5d'
        }, {
          type: 'day',
          count: 7,
          text: '7d'
        }, {
          type: 'month',
          count: 1,
          text: '1m'
        }, {
          type: 'month',
          count: 3,
          text: '3m'
        }, {
          type: 'month',
          count: 6,
          text: '6m'
        }, {
          type: 'year',
          count: 1,
          text: '1y'
        }, {
          type: 'all',
          text: 'All'
        }],
        selected: 2
      },

      // NOTE: I added these lines
      // See the chart legend at the bottom of the chart now?
      // Click on 2 of the series to remove them, and notice how
      // the 3rd one expands to show all the points correctly
      legend: {
        enabled: true
      },

      yAxis: axisOptions,

      title: {
        text: 'Historical Instruments Data '
      },

      subtitle: {
        text: 'Built chart at...' // dummy text to reserve space for dynamic subtitle
      },

      tooltip: {
        pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
        valueDecimals: 1
      },

      series: seriesOptions,

      exporting: {
        width: 1000
      }

    }, function(chart) {
      // Last point in graph...
      document.getElementById("loading").style.display = "none"; //hide the loading text

      showLastPointTooltip(chart);
    });
  };

});


function showLastPointTooltip(objHighStockchart) {
  // show tooltip for last point   
  var points = [];
  if (objHighStockchart) {
    for (var i = 0; i < objHighStockchart.series.length; i++)

      points.push(objHighStockchart.series[i].points[objHighStockchart.series[i].points.length - 1]);


    objHighStockchart.tooltip.refresh(points);


  };
  console.log('DONE')

};
<title>Multiple Currencies</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/highcharts-more.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>

<div id="loading" sytle="font-weight:bold;"></div>
<div id="container" style="height: 500px; min-width: 500px">

这只是将您的 3 个系列中的每一个分配给不同的轴。因此,除了创建 seriesOptions,您现在还为每个创建了 axisOptions

2。使用多个不重叠的 y 轴

var axisOptions = [],
    numAxes = names.length,
    // percentage of height left out for spacing the 3 y-axes
    axisSpacingPercent = 5,
    // percentage of height occupied by each y-axis
    axisHeightPercent = (100 - (numAxes - 1) * axisSpacingPercent) / numAxes;

$.each(names, function(i, name) {
  var url = "http://134.213.48.26:8080/apitest/api/v1/ext/jsfiddle/data?callback=?&id="+ name; 
  $.getJSON(url, function(data) {
    axisOptions.push({
      title: {
        text: name + 'Prices'
      },
      // settings for multiple panes in the chart
      height: '' + axisHeightPercent + '%',
      top: '' + (i * (axisHeightPercent + axisSpacingPercent)) + '%',
      offset: false,
      lineWidth: 1
    });
    // build seriesOptions and other stuff ...
  });
});

$('#container').highcharts('StockChart', {
    yAxis: axisOptions,
    // other options ...
});

Link to JSFiddle

$(function() {
  console.log('in annynymous()');
  // var names = ['GBP_USD'], // Any One Currency, works [serise is as it should be]
  var names = ['GBP_USD', 'EUR_USD', 'USD_CHF'], // Three currencies [series are flat]
    seriesCounter = 0,
    seriesOptions = [],
    axisOptions = [],
    colors = Highcharts.getOptions().colors,
    containerHeight = $('#container').height(),

    numAxes = names.length,
    // percentage of height left out for spacing the 3 y-axes
    axisSpacingPercent = 5,
    // percentage of height occupied by each y-axis
    axisHeightPercent = (100 - (numAxes - 1) * axisSpacingPercent) / numAxes;

  console.log('starting to retrive data');

  $.each(names, function(i, name) {
    document.getElementById("loading").innerHTML = '<B>Loading please wait.. retrieving data</B>';


    var url = "http://134.213.48.26:8080/apitest/api/v1/ext/jsfiddle/data?callback=?&id=" + name;
    $.getJSON(url, function(data) {
      console.log("success with grabing json data for " + name);

      seriesOptions[i] = {
        name: name + ' Temperature',
        data: data,
        color: colors[i],
        type: 'line',
        yAxis: i
      };

      axisOptions.push({
        title: {
          text: name + 'Prices'
        },
        // settings for multiple panes in the chart
        height: '' + axisHeightPercent + '%',
        top: '' + (i * (axisHeightPercent + axisSpacingPercent)) + '%',
        offset: false,
        lineWidth: 1
      });

      // As we're loading the data asynchronously, we don't know what order it will arrive. So
      // we keep a counter and create the chart when all the data is loaded.
      seriesCounter++;

      if (seriesCounter == names.length) {
        createChart();
      }
    });
  });

  // create the chart when all data is loaded
  function createChart() {

    console.log('in createChart()');
    Highcharts.setOptions({
      global: {
        useUTC: false
      }
    });

    // Create a timer, to test how long this takes to load
    var start = +new Date();

    // Create the chart
    $('#container').highcharts('StockChart', {

      chart: {
        events: {
          load: function(chart) {
            this.setTitle(null, {
              text: 'This chart was built on ' + new Date() + ' in ' + (new Date() - start) + 'ms'
            });


          }
        }
      },
      rangeSelector: {
        buttons: [{
          type: 'hour',
          count: 1,
          text: '1hr'
        }, {
          type: 'hour',
          count: 3,
          text: '3hr'
        }, {
          type: 'hour',
          count: 12,
          text: '12hr'
        }, {
          type: 'day',
          count: 1,
          text: '1d'
        }, {
          type: 'day',
          count: 3,
          text: '3d'
        }, {
          type: 'day',
          count: 5,
          text: '5d'
        }, {
          type: 'day',
          count: 7,
          text: '7d'
        }, {
          type: 'month',
          count: 1,
          text: '1m'
        }, {
          type: 'month',
          count: 3,
          text: '3m'
        }, {
          type: 'month',
          count: 6,
          text: '6m'
        }, {
          type: 'year',
          count: 1,
          text: '1y'
        }, {
          type: 'all',
          text: 'All'
        }],
        selected: 2
      },

      // NOTE: I added these lines
      // See the chart legend at the bottom of the chart now?
      // Click on 2 of the series to remove them, and notice how
      // the 3rd one expands to show all the points correctly
      legend: {
        enabled: true
      },

      yAxis: axisOptions,

      title: {
        text: 'Historical Instruments Data '
      },

      subtitle: {
        text: 'Built chart at...' // dummy text to reserve space for dynamic subtitle
      },

      tooltip: {
        pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
        valueDecimals: 1
      },

      series: seriesOptions,

      exporting: {
        width: 1000
      }

    }, function(chart) {
      // Last point in graph...
      document.getElementById("loading").style.display = "none"; //hide the loading text

      showLastPointTooltip(chart);
    });
  };

});


function showLastPointTooltip(objHighStockchart) {
  // show tooltip for last point   
  var points = [];
  if (objHighStockchart) {
    for (var i = 0; i < objHighStockchart.series.length; i++)

      points.push(objHighStockchart.series[i].points[objHighStockchart.series[i].points.length - 1]);


    objHighStockchart.tooltip.refresh(points);


  };
  console.log('DONE')

};
<title>Multiple Currencies</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script src="http://code.highcharts.com/stock/highstock.js"></script>
<script src="http://code.highcharts.com/stock/highcharts-more.js"></script>
<script src="http://code.highcharts.com/stock/modules/exporting.js"></script>

<div id="loading" sytle="font-weight:bold;"></div>
<div id="container" style="height: 900px; min-width: 500px">

这与解决方案 #1 类似,但 space 跨不同的非重叠 y 轴输出数据。