26

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

{
chart : {},
blah blah,
}

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

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

4

3 回答 3

42

您可以使用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: []
});

参考

完成演示

于 2012-03-07T19:04:44.547 回答
6

我知道这已经得到了回答,但我觉得它可以更进一步。我对 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/

欢迎批评!!

于 2012-11-20T22:13:24.110 回答
4

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

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

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

以下是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]]
         });
于 2012-08-20T17:35:59.143 回答