【问题标题】:Manage multiple highchart charts in a single webpage在单个网页中管理多个 highchart 图表
【发布时间】:2011-11-24 07:39:13
【问题描述】:

我在一个网页中有多个不同类型的高图(条形图、饼图、散点图)。目前我正在为每个图创建配置对象,例如,

{
chart : {},
blah blah,
}

并将它们提供给一个自定义函数,该函数将调用HighCharts.chart()。但这会导致代码重复。我想集中管理所有这些图表呈现逻辑。

关于如何做到这一点的任何想法?

【问题讨论】:

  • 到底是什么问题?代码重复在哪里?提供您的代码。

标签: highcharts highstock


【解决方案1】:

您可以使用jQuery.extend()Highcharts.setOptions
因此,首先您将创建第一个对象,该对象将被您的所有图表扩展,该对象将包含您的 Highchart 默认函数。

您可以使用命名空间来做到这一点。
当您有非常不同的图表时,以下方法很好。

默认图形:

var defaultChart = {
    chartContent: null,
    highchart: null,
    defaults: {

        chart: {
            alignTicks: false,
            borderColor: '#656565',
            borderWidth: 1,
            zoomType: 'x',
            height: 400,
            width: 800
        },

        series: []

    },

    // here you'll merge the defauls with the object options

    init: function(options) {

        this.highchart= jQuery.extend({}, this.defaults, options);
        this.highchart.chart.renderTo = this.chartContent;
    },

    create: function() {

        new Highcharts.Chart(this.highchart);
    }

};

现在,如果你想制作柱形图,你将扩展 defaultChart

var columnChart = {

    chartContent: '#yourChartContent',
    options: {

        // your chart options
    }

};

columnChart = jQuery.extend(true, {}, defaultChart, columnChart);

// now columnChart has all defaultChart functions

// now you'll init the object with your chart options

columnChart.init(columnChart.options);

// when you want to create the chart you just call

columnChart.create();

如果您有类似的图表,请使用 Highcharts.setOptions,这将在此之后为所有创建的图表应用选项。

// `options` will be used by all charts
Highcharts.setOptions(options);

// only data options
var chart1 = Highcharts.Chart({
    chart: {
        renderTo: 'container1'
    },
    series: []
});

var chart2 = Highcharts.Chart({
    chart: {
        renderTo: 'container2'
    },
    series: []
});

参考

COMPLETE DEMO

【讨论】:

  • 这太棒了!昨天刚看到这段代码,它非常有用。我要说的一点是,在声明 chartContent 时不应使用主题标签,否则 Highcharts 会引发错误 (13)。
  • 我也有类似的情况,但在 Highstock。为这个想法 +1
  • 通过您标记为潜在欺骗的问题到达这里。我很好奇 - 使用 Highcharts.setOptions({...}) 也做同样的事情吗?一般来说,我非常喜欢使用jQuery.extend 来达到所描述的目的,但是我(经常性地)犯的错误会巧妙地覆盖默认值,所以我更喜欢依赖库(有很多眼球,在这个case $'s) 以使其正确。我目前没有使用 Highcharts,但我正在寻找一个更好的 js 绘图库,因此很好奇。
【解决方案2】:

我知道这个问题已经得到解答,但我觉得还可以更进一步。我对 JavaScript 和 jQuery 还很陌生,所以如果有人发现任何错误,或者认为这种方法违反了某种准则或经验法则,我将不胜感激。

基于 Ricardo Lohmann 所描述的原则,我创建了一个 jQuery 插件,(在我看来)它允许 Highcharts 与 jQuery 更无缝地协同工作(即 jQuery 与其他 HTML 对象协同工作的方式)。

我从不喜欢在 Highcharts 绘制图表之前必须向它提供对象 ID 的事实。因此,通过插件,我可以将图表分配给标准的 jQuery 选择器对象,而不必为包含 <div> 的对象指定 id 值。

(function($){
    var chartType = {
        myArea : {
            chart: { type: 'area' },
            title: { text: 'Example Line Chart' },
            xAxis: { /* xAxis settings... */ },
            yAxis: { /* yAxis settings... */ },
            /* etc. */
            series: []
        },
        myColumn : {
            chart: { type: 'column' },
            title: { text: 'Example Column Chart' },
            xAxis: { /* xAxis settings... */ },
            yAxis: { /* yAxis settings... */ },
            /* etc. */
            series: []
        }
    };
    var methods = {
        init:
            function (chartName, options) {
                return this.each(function(i) {
                    optsThis = options[i];
                    chartType[chartName].chart.renderTo = this;
                    optsHighchart = $.extend (true, {}, chartType[chartName], optsThis);
                    new Highcharts.Chart (optsHighchart);
                });
            }
    };
    $.fn.cbhChart = function (action,objSettings) {
        if ( chartType[action] ) {
            return methods.init.apply( this, arguments );
        } else if ( methods[action] ) {
            return methods[method].apply(this,Array.prototype.slice.call(arguments,1));
        } else if ( typeof action === 'object' || !action ) {
            $.error( 'Invalid arguments to plugin: jQuery.cbhChart' );
        } else {
           $.error( 'Action "' +  action + '" does not exist on jQuery.cbhChart' );
        }
    };
})(jQuery);

有了这个插件,我现在可以按如下方式分配图表:

$('.columnChart').cbhChart('myColumn', optionsArray);

这当然是一个简单的例子;对于一个真实的例子,您必须创建更复杂的图表属性。但我们在这里关注的是原则,我发现这种方法解决了最初的问题。它重用了代码,同时仍然允许在彼此之上逐步应用单独的图表更改。

原则上,它还允许您将多个 Ajax 调用组合为一个,将每个图形的选项和数据推送到单个 JavaScript 数组中。

必需的 jFiddle 示例在这里:http://jsfiddle.net/3GYHg/1/

欢迎批评!!

【讨论】:

    【解决方案3】:

    为了补充@Ricardo 的出色答案,我也做了一些非常相似的事情。事实上,如果我说我比这更进一步,我不会错。因此想分享一下方法。

    我在 highchart 库上创建了一个包装器。这带来了多重好处,以下是鼓励走这条路的主要优势

    • 解耦:将您的代码与 highcharts 解耦
    • 轻松升级:此包装器将是唯一需要修改的代码,以防升级后 highchart api 发生任何重大更改,或者即使决定完全迁移到不同的图表库(甚至来自 highchart如果您的应用程序广泛使用图表,to highstock 可能会很详尽)
    • 易于使用: 包装器 api 保持非常简单,只有可能变化的东西作为选项公开(其值也不会像 HC 已经拥有的深度 js 对象,主要是 1 级deep),每个都有一个默认值。所以大多数时候我们的图表创建时间很短,构造函数采用 1 个 options 对象,只有 4-5 个属性,其默认值不适合正在创建的图表
    • 一致的 UX: 整个应用程序的外观和感觉一致。例如:工具提示格式和位置、颜色、字体系列、颜色、工具栏(导出)按钮等
    • 避免重复:当然,作为对所提问题的有效答案,它必须避免重复,而且在很大程度上是这样

    这是options 默认值的样子

    defaults : {
            chartType : "line", 
            startTime : 0,
            interval : 1000,
            chartData : [],
            title : "Product Name",
            navigator : true,
            legends : true,
            presetTimeRanges : [],
            primaryToolbarButtons : true,
            secondaryToolbarButtons : true,
            zoomX : true,
            zoomY : false,
            height : null,
            width : null,
            panning : false,
            reflow : false,
            yDecimals : 2,
            container : "container",
            allowFullScreen : true,
            credits : false,
            showAll : false,
            fontSize : "normal", // other option available is "small"
            showBtnsInNewTab : false,
            xAxisTitle : null,
            yAxisTitle : null,
            onLoad : null,
            pointMarkers : false,
            categories : []
    }
    

    如您所见,大多数情况下,只是chartData 发生了变化。即使您需要设置一些属性,它主要只是真/假类型,与 highchart 构造函数所期望的恐怖完全不同(不是批评它们,它们提供的选项数量从定制的角度来看是惊人的,但对于每个开发人员来说团队理解和掌握它可能需要一些时间)

    所以图表的创建就这么简单

    var chart=new myLib.Chart({
                  chartData : [[1000000,1],[2000000,2],[3000000,1],[4000000,5]]
             });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 2021-10-22
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      相关资源
      最近更新 更多