缩短/重构多个插件值的方法

时间:2014-10-31 14:39:01

标签: javascript jquery highcharts refactoring javascript-objects

我在一个页面上有大约15-20个高图(使用滑块,每张幻灯片1-2个图表),一些条形图,一些柱形图,一些饼图,具有不同的显示选项。我使用的是在我的闭包中有多个方法,我有像self.drawColumnChart(xPlotColor, yPlotColor, xPlotLabelSize, yPlotLabelSize, ...10 more arguments)这样的方法。在同一个对象中,我有像'drawRevenueChart(),drawLossChart()'等方法。drawRevenueChart()用15个参数调用self.drawColumnChart(。随着图表数量的增长,我最终将越来越多的论点传递给self.drawColumnChart(所以我认为我可以通过将drawRevenueChart()更改为

来重构这一点
("$id").highcharts(
    {chart: {
        plotOptions: {
            labelSize: '2em'
        },
        xAxis:{
          labelSize: '1.3em',
          formatter: function(){
               return '% ' + this.value;
          }
          ...and so on
        }
    })'

我不再需要self.drawColumnChart(xPlotColor, yPlotColor, xPlotLabelSize, yPlotLabelSize, ...10 more arguments),但我只是将这种复杂性传递给了drawRevenueChart()drawRevenueChart()曾经是2行长,但现在它长25行。与drawLossChart()相同,它曾经是3行,只是调用self.drawColumnChart(,但它在重构后变成了15行长的方法。

你能想到我可以如何重构/缩短这个吗?也许drawRevenueChart()来电self.drawChart("column", [plotOptions.labelSize: '2em', xAxis: {labelSize: '1.e em'}...

似乎我必须不断重复

plotOptions: {
    labelSize: '2em'
    },
    xAxis:{
        labelSize: '1.3em',

我的每个图表的关闭都有不同的选项。有没有办法缩短这个?我已经在使用jQuery extend()来扩展带有自定义选项的默认图表选项。这一切都在关闭之内。但不管我如何重构这个,我发现自己用不同的选项重复相同的行。欢迎任何想法。

更新

按照TrueBlueAussie的要求:

曾经是:

myClosure{

    var self = this;

    self.drawColumnChart = function(selector, xPlotColour, yPlotColour, xAxisName, yAxisName, xPlotOptionsSize....10 more arguments)
    {
          $(selector).highcharts({
              chart: {
                  type: 'column'
              },
              xPlot:{
                  style:{
                     color: xPlotColour
                  }
              },
              yPlot: {
                  labels: {
                      style:{
                          color: yPlotColour
                      }
                  }
              },
              xAxis:{
                  labels: { 
                     name: xAxisName,
                  }
              }    
          })
    }

    drawRevenueChart: function(data){
        self.drawColumnChart("#chartid1", 'blue', 'red', 'profit', 'month', '1.2em', null, false, null....);
    }

    drawLossChart: function(data){
        self.drawColumnChart("#chartid2", 'orange', 'yellow, 'loss', 'month', '2em' ...);
    }
}

重构后

drawRevenueChart: function(data){
        $("#chartid1").highcharts({
              chart: {
                  type: 'column'
              },
            xPlot:{
                  style:{
                     color: 'blue'
                  }
              },
              yPlot: {
                  labels: {
                      style:{
                          color: 'red'
                      }
                  }
              },
              xAxis:{
                  labels: { 
                     name: 'profit',
                  }
              }    
        });
    }

drawLossChart: function(data){
    $("chartid2").highcharts({
        xplot:{
            style:{
               color: 'orange'
            }
        },
        xAxis:{
           labels:{
               name: 'loss',
               color: 'puke'
           }
        }
    }
};

所以我只是将3级深度对象设置从一种方法移动到另一种方法,没有真正的好处。

2 个答案:

答案 0 :(得分:2)

好的,现在更清楚了。这实际上不是代码重构问题,而是数据重构问题。我建议的唯一解决方案是在结构中查找公共数据,将这些分支存储在范围内的变量中,并$.extend()将它们组合在一起构建最终的选项结构。

e.g。

myClosure {
    // Put any common settings in shared vars
    var columnChart = {
        chart: {
            type: 'column'
        }
        // any other common properties for a column chart
    };

    var barChart = {
        chart: {
            type: 'barchart'
        }
        // any other common properties for a bar chart
    }

    var self = this;

    self.drawColumnChart = function (selector, data) {
        $(selector).highcharts($.extend({}, columnChart, data));
    }

    drawRevenueChart: function (data) {
        self.drawColumnChart("#chartid1", {
            xPlot: {
                style: {
                    color: 'blue'
                }
            },
            yPlot: {
                labels: {
                    style: {
                        color: 'red'
                    }
                }
            },
            xAxis: {
                labels: {
                    name: 'month name',
                }
            }
        });
    }

    drawLossChart: function (data) {
        self.drawColumnChart("#chartid2", {
            xPlot: {
                style: {
                    color: 'orange'
                }
            },
            yPlot: {
                labels: {
                    style: {
                        color: 'yellow'
                    }
                }
            },
            xAxis: {
                labels: {
                    name: 'loss',
                }
            });
        }
    }
}

这样做的好处是,如果你知道HighCharts选项结构,每个调用仍然是可读的,因此更容易维护。

除非你使用强类型的JS语言(比如TypeScript),否则使用带有参数的函数是 human -error-prone,所以最好避免使用。

答案 1 :(得分:1)

我最终做的是在插件中创建了一个对象,该对象使用单个drawChart函数处理所有highcharts选项,该函数接受一个对象。即。

var plugin = function(){

    helper.drawChart({
        legendEnabled: true,
        selector: '#divID',
        backgroundColor: '#FF0000', //etc all other options
    });

    var chartHelper = function(){
         var defaults = {
            _common:{
               //common highcharts options
               {
                   legend: false //etc
               }
            },
            _bar:{
               chart: 'bar', //all common bar options
            },
            get bar(){ return $.extend({}, _common, _bar); }
         }

         this.drawChart = function(options){
            var default = {};
            if (options.legendEnabled){
                default.legend = true;
            }

            if (options.yLabelText){
                default.yTitle = { text = options.yLabelText }
            }//and other options here

            $(options.selector).highchart($.extend({}, defaults.bar, default);
         }
    }

    var helper = new chartHelper();
}

我在插件中有20个图表,这为我节省了大约600行。所有的图表逻辑都在帮助器内部,它不会使插件代码混乱,我不需要在每个绘制函数中重复.highcharts({ 20 different options }),这只是我现在需要做的一次。