2014-05-15 20 views
1

我已经使用框架工作D3线图这里概述:http://bost.ocks.org/mike/chart/D3图表与常用代码分离出来

由于我建立了大量的图表我想以分离出公共元件(宽度和身高)例如)到一个单独的文件,但我真的不知道如何在可重用框架内做到这一点。

这里是调用JavaScript文件:

var common = commonChart() 
    .main_height(400) 
    .main_width(600); 

var chart = multiLineChart() 
    .x(function(d) { return d.date; }) 
    .y(function(d) { return d.number; }) 
    .yLabel("Number") 
    .dimKey(function(d) { return d._id.env; }) 
    .yTickFormat(function(d) { return d3.round(d); }) 
    .yScale(d3.scale.sqrt()) 
    .color(d3.scale.category10()); 

d3.json('data/datafile.json', function(data) { 
    d3.select("#graph") 
     .datum(data) 
     .call(common) 
     .call(chart); 
}); 

通用文件是这样的:

function commonChart() { 

    var main_width, main_height; 

    function chart(selection) { 

     console.log(main_height); 

    } 

    // Get/set main_width 
    chart.main_width = function(value) { 
     if (!arguments.length) return main_width; 
     main_width = value; 
     return chart; 
    } 

    // Get/set main_height 
    chart.main_height = function(value) { 
     if (!arguments.length) return main_height; 
     main_height = value; 
     return chart; 
    } 

} 

的multiLineChart具有全部为线图本身的核心逻辑。当我运行这个时,我结束了Cannot read property 'main_height' of undefined。有没有办法使用可重复使用的图表框架与D3做到这一点?

谢谢!

+1

如果我明白你正确地做什么,这是不可能的。你想要在组件中的所有内容必须位于相同的函数/闭包中。但是,您可以使用其他组件内的组件来实现重复功能。 –

+0

好的,我怀疑它是否会起作用。你能详细说说把组件放在其他组件里面吗?谢谢! – JamesE

+1

你不会把它们放在彼此之中,而是在另一个组件中使用一个组件。例如,您可以使用内部使用轴组件的条形图组件。 –

回答

1

我最近有同样的问题。构建一个图表库,并且当我制作新的图表类型时,不想复制 - 粘贴所有常用属性。

这里是我已经提出了解决方案:

Chart = function module() { 
 
     // properties 
 
     this._width = 800; 
 
     this._height = 600; 
 
     this._margin = { 
 
      top: 10, 
 
      bottom: 10, 
 
      left: 20, 
 
      right: 5 
 
     }; 
 
     this._title = ''; 
 
    } 
 

 
    // doing stuff 
 
    Chart.prototype.plot = function() { 
 
     console.log('The plot function has not been defined.'); 
 
    } 
 

 
    // setting the properties 
 
    Chart.prototype.width = function (_x) { 
 
     if (!arguments.length) return this._width; 
 
     this._width = _x; 
 
     return this; 
 
    } 
 
    Chart.prototype.height = function (_x) { 
 
     if (!arguments.length) return this._height; 
 
     this._height = _x; 
 
     return this; 
 
    } 
 
    Chart.prototype.margin = function (_x) { 
 
     if (!arguments.length) return this._margin; 
 
     this._margin = _x; 
 
     return this; 
 
    } 
 
    Chart.prototype.title = function (_x) { 
 
     if (!arguments.length) return this._title; 
 
     this._title = _x; 
 
     return this; 
 
    } 
 

 
    // creating a new type of chart, which inherits from Chart. 
 
    BarChart.prototype = new Chart(); // Here's where the inheritance occurs 
 
    BarChart.prototype.constructor = BarChart; 
 
    BarChart.prototype.parent = Chart.prototype; 
 

 
    function BarChart() { 
 
    } 
 
    // 'overriding' the .plot function 
 
    BarChart.prototype.plot = function (_selection) { 
 
     var myTitle = this.parent.title.call(this); 
 
     _selection.each(function (_data) { 
 
      console.log('Plotting ' + _data.length + ' bars of data. The chart is called: ' + myTitle); 
 
     }); 
 
    } 
 

 
    
 
    
 
    // usage 
 
    var myBarChart1 = new BarChart(); 
 
    myBarChart1.width(250) 
 
     .height(200) 
 
     .title('Population Growth'); 
 
    myBarChart1.plot(d3.select("#chart").datum([1, 2, 3, 4, 5, 6])); // Plotting 6 bars of data. The chart is called: Population Growth 
 

 
    var myBarChart2 = new BarChart(); 
 
    myBarChart2.width(50) 
 
     .height(500) 
 
     .title('Music Sales'); 
 
    myBarChart2.plot(d3.select("#chart").datum([1, 2, 3, 4])); // Plotting 4 bars of data. The chart is called: Music Sales
<div id="chart"></div>

这意味着我只需要创建通用的属性,诸如宽度和高度,一次,而不是在我创建的每一种类型的图表。结果的对象调用可以链接,就像d3.js.唯一不符合d3.js用法的是你必须调用.plot()函数来真正绘制图表。我一直无法弄清楚如何直接从BarChart函数中调用这个函数(我试过从BarChart返回一个绘图函数,但那不起作用)。

如果要围绕主题阅读,这里是在JavaScript上继承一个真正伟大的文章:http://phrogz.net/JS/classes/OOPinJS2.html