Javascript 可重用的d3.js组件和继承

Javascript 可重用的d3.js组件和继承,javascript,d3.js,Javascript,D3.js,我正试图按照Mike Bostock的思路创建一个可重用d3.js组件库,但在创建内部重用代码的可重用组件时遇到了一些困难 库及其第i个组件的外观如下所示: d3.library = {} d3.library.component_i = function module() { var width = 800, height = 800; function exports(_selection) { ... } exports

我正试图按照Mike Bostock的思路创建一个可重用d3.js组件库,但在创建内部重用代码的可重用组件时遇到了一些困难

库及其第i个组件的外观如下所示:

d3.library = {}

d3.library.component_i = function module() {
    var width = 800,
        height = 800;

    function exports(_selection) {
        ...
    }

    exports.width = function(_width) {
        if(!arguments.length) 
            return width;
        width = _width;
        return this;
    }
    exports.height = function(_height) {
        if(!arguments.length) 
            return height;
        height = _height;
        return this;
    }

    ....

    return exports
}
一些代码,例如“成员”和“方法”
height
width
,本质上是样板代码,我正在复制粘贴任何组件I。相反,我希望重用代码

在“经典”的OO语言(例如Python)中,编写一些
\u BaseComponent
基类并将其子类化是很自然的。此基类将包含公共成员:

class _BaseComponent(object):
   ...  

   @property
   def width(self):
       ...

   @width.setter
   def width(self, width_):
       ...


class ComponentI(_BaseComponent):

    ...

    # width and height inherited

    ...
但是,由于它是一个Javascript库,我希望保留Javascript和d3.js的“感觉”:函数链接、选择调用范例等等。我已经读了一些关于Javascript中的原型继承的内容(例如,在中),但是那里的对象似乎没有按照上面的代码定义(例如,对于单个导出函数,局部变量作为“数据成员”的函数,以及作为“数据成员”的访问器的“方法”)

我不知道如何创建一个库,使它同时

  • 在内部具有可重用的层次结构
  • 与d3.js的其余部分很好地啮合,尤其是外部

  • A基本上提出了相同的观点,但在特定的解决方案方向上寻求帮助。解决上述两点的任何解决方案在这里都很好,即使它涉及到更改所有组件的结构

    IMO开发可重用组件的理想方法是将其开发为封装在各个模块中的组件,这些模块相互依赖,生成更高级别的组件

    开发对象的层次结构将很难管理,也会限制库的灵活性

    参考:

    实际的代码重用不是通过继承属性,而是通过将可视化开发为不同组件的组合

    因此,重用发生在组件级别,而不是属性/行为级别

    NVD3是一个遵循这种结构的库


    以上代码使用闭包,而不是依赖于原型继承,并且据我所知,不能以您想要的方式进行扩展

    我最近也遇到了同样的问题。构建图表库,并且在创建新类型的图表时不希望复制粘贴所有常见的
    导出
    属性

    以下是我提出的解决方案:

    Chart=功能模块(){
    //性质
    这个宽度=800;
    这个高度=600;
    此页边距={
    前10名,
    底部:10,
    左:20,,
    右:5
    };
    此项。_title='';
    }
    //做事
    Chart.prototype.plot=函数(){
    log('尚未定义绘图函数');
    }
    //设置属性
    Chart.prototype.width=函数(_x){
    如果(!arguments.length)返回此值。\u width;
    这个。_宽度=_x;
    归还这个;
    }
    Chart.prototype.height=函数(_x){
    如果(!arguments.length)返回此值。\u height;
    这个。_高度=_x;
    归还这个;
    }
    Chart.prototype.margin=函数(_x){
    如果(!arguments.length)返回此值。\u margin;
    这个。_margin=_x;
    归还这个;
    }
    Chart.prototype.title=函数(_x){
    如果(!arguments.length)返回此项。\u title;
    这个。_title=_x;
    归还这个;
    }
    //创建从图表继承的新图表类型。
    BarChart.prototype=新图表();//这里是继承发生的地方
    BarChart.prototype.constructor=条形图;
    BarChart.prototype.parent=Chart.prototype;
    函数条形图(){
    }
    //“重写”.plot函数
    BarChart.prototype.plot=函数(_选择){
    var myTitle=this.parent.title.call(this);
    _选择。每个(函数(_数据){
    console.log('Plotting'+_data.length+'数据条。该图表称为:'+myTitle);
    });
    }
    //用法
    var myBarChart1=新的条形图();
    myBarChart1.宽度(250)
    .身高(200)
    .标题(“人口增长”);
    myBarChart1.绘图(d3.选择(“图表”).数据([1,2,3,4,5,6]);//绘制6条数据。这个图表叫做:人口增长
    var myBarChart2=新的条形图();
    myBarChart2.宽度(50)
    .高度(500)
    .标题(“音乐销售”);
    myBarChart2.绘图(d3.选择(“图表”).基准([1,2,3,4]);//绘制4条数据条。该图表名为:音乐销售
    
    
    谢谢,@prashant,但我不确定这如何回答我的问题。很可能我的术语不准确。您参考的幻灯片建议使用构件构建模块。组件是根据我最初问题中的样式构建的。我的问题是如何在这些组件之间共享代码(使用宽度和高度访问器作为具体示例),而不是在组件之间复制粘贴代码。非常感谢!这是非常详细和有用的!(作为一个非常次要的观点,“运行代码片段”很酷,但对我来说不起作用。)啊,我没有包括对d3.js的引用!现在可以了。如果点击run,然后查看控制台输出,您将看到来自.plot()函数的消息。确实如此!非常感谢您的回答和对运行代码片段的考虑。