Управление несколькими диаграммами highchart на одной веб-странице

У меня есть несколько диаграмм highchart различных типов (Bar, Pie, Scatter type) на одной веб-странице. В настоящее время я создаю объект конфигурации для каждого графика, например,

{
chart : {},
blah blah,
}

И передать их пользовательской функции, которая просто вызовет HighCharts.chart(). Но это приводит к дублированию кода. Я хочу централизованно управлять всей этой логикой рендеринга диаграмм.

Любая идея о том, как это сделать?


person Selvaraj M A    schedule 24.11.2011    source источник
comment
в чем именно проблема?: Где дублирование кода? Предоставьте свой код.   -  person NT3RP    schedule 26.11.2011


Ответы (3)


Вы можете использовать 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: []
});

Справочник

ПОЛНАЯ ДЕМО

person Ricardo Alvaro Lohmann    schedule 07.03.2012
comment
Отлично! Только вчера наткнулся на этот код, и он очень полезен. Я хотел бы отметить, что вы не должны использовать хэштег при объявлении chartContent, иначе Highcharts выдает ошибку (13). - person WastedSpace; 26.07.2012
comment
У меня похожая ситуация, но с Highstock. +1 за идею - person Hardik Mishra; 31.07.2012
comment
прибыл сюда через вопрос, который вы пометили как потенциальный обман. Мне любопытно - делает ли использование Highcharts.setOptions({...}) в основном то же самое? Я вообще большой поклонник использования jQuery.extend именно для описанной цели, но я (с грустной регулярностью) делаю ошибки, которые тонко перезаписывают значения по умолчанию, поэтому я предпочитаю полагаться на библиотеку (с большим количеством глазных яблок и в этом случае $ s), чтобы сделать это правильно. В настоящее время я не использую Highcharts, но я ищу лучшую библиотеку для построения графиков js, отсюда и любопытство. - person Carl; 06.09.2012

Я знаю, что на этот вопрос уже был дан ответ, но я чувствую, что его можно продвинуть еще дальше. Я все еще новичок в JavaScript и jQuery, поэтому, если кто-то обнаружит что-то не так или считает, что этот подход нарушает какие-то руководящие принципы или практические правила, я был бы признателен за обратную связь.

Основываясь на принципах, описанных Рикардо Ломанном, я создал подключаемый модуль jQuery, который (на мой взгляд) позволяет Highcharts работать более плавно с jQuery (т. е. так же, как jQuery работает с другими объектами HTML).

Мне никогда не нравился тот факт, что вы должны указать идентификатор объекта в Highcharts, прежде чем он нарисует диаграмму. Таким образом, с помощью подключаемого модуля я могу назначить диаграмму стандартному объекту селектора 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/

Критика приветствуется!!

person cartbeforehorse    schedule 20.11.2012

Чтобы добавить к отличному ответу @Ricardo, я также сделал что-то очень похожее. На самом деле, я не ошибусь, если скажу, что пошел еще дальше. Поэтому хотел бы поделиться подходом.

Я создал обертку над библиотекой highchart. Это дает множество преимуществ, следующие из которых являются основными преимуществами, побуждающими идти по этому пути.

  • Развязка: отделяет ваш код от highcharts.
  • Простые обновления: эта оболочка будет единственным кодом, который потребует модификации в случае каких-либо критических изменений в highchart API после обновлений, или даже если кто-то решит вообще перейти на другую библиотеку диаграмм (даже из highchart to highstock может быть исчерпывающим, если ваше приложение широко использует графики)
  • Простота использования: API-интерфейс оболочки остается очень простым, в качестве опций выставляются только те вещи, которые могут различаться (тоже значения которых не будут такими, как у глубокого js-объекта, такого как HC, в основном 1 уровень deep), каждый из которых имеет значение по умолчанию. Таким образом, большую часть времени создание нашей диаграммы очень короткое: конструктор берет 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. Даже если вам нужно установить какое-то свойство, в основном это просто типы true/false, ничего похожего на ужас, который ожидает конструктор highchart (не критикуя их, количество предоставляемых ими опций просто потрясающе с точки зрения настройки, но для каждого разработчика в команде, чтобы понять и освоить это, может потребоваться некоторое время)

Таким образом, создание диаграммы так же просто, как

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