0

I have three identical objects that I'd like to define in three slightly different ways. The only difference is that I'm accessing a different property within my source data (via Bracket Notation) for each object as shown below

The object I'm using is not a function. For example Object1 is defined by

var Object1  = dc.lineChart("#chart-line-hitsperday"); 


var D = "Dimension1"
Object1
    .width(200).height(200)
    .dimension(SourceData.dimension(function (d) {return d[D];}))
    .group(SourceData.dimension(function (d) {return d[D];}).group().reduceSum(function (d) {return d.Amount;}))


var D = "Dimension2"
Object2
    .width(200).height(200)
    .dimension(SourceData.dimension(function (d) {return d[D];}))
    .group(SourceData.dimension(function (d) {return d[D];}).group().reduceSum(function (d) {return d.Amount;}))


var D = "Dimension3"
Object3
    .width(200).height(200)
    .dimension(SourceData.dimension(function (d) {return d[D];}))
    .group(SourceData.dimension(function (d) {return d[D];}).group().reduceSum(function (d) {return d.Amount;}))

Is there a way that I can define each with 1 line of code as oppose to three lines of code. In other words, I'd like to convert above into the following

Object1.definition("Dimension1")
Object2.definition("Dimension2")
Object3.definition("Dimension3")

by defining 'definition' as something like :

definition(D) =         
    .width(200).height(200)
    .dimension(SourceData.dimension(function (d) {return d[D];}))
    .group(SourceData.dimension(function (d) {return d[D];}).group().reduceSum(function (d) {return d.Amount;}))

Is this possible?

See JSFiddle Here: http://jsfiddle.net/chrisguzman/juhaoem2/

I've tried the following with no luck:

var definition = function(D){     
    this.width(200).height(200)
    .dimension(SourceData.dimension(function (d) {return d[D];}))
    .group(SourceData.dimension(function (d) {return d[D];}).group().reduceSum(function (d) {return d.Amount;}))
}


Object1.definition("Dimension1")

Second Try

Object1.prototype.definition = function(dim){
    this.width(200).height(200)
        .dimension(SourceData.dimension(function (d) {return d[dim];}))
        .group(SourceData.dimension(function (d) {return d[dim];}).group().reduceSum(function (d) {return d.Amount;}))
};
Chris
  • 5,444
  • 16
  • 63
  • 119
  • Your code as posted won't work anyway because of the way you re-use "D". – Pointy Aug 16 '14 at 14:10
  • Right, that's kind of the point. This is the code that I wish could work, but doesnt work. But do you get what I'm trying to do? Is there a way to re-use D so that it works? – Chris Aug 16 '14 at 14:11
  • 1
    No, your second try had some mistakes, please see my updated answer – frogatto Aug 16 '14 at 14:27
  • Code after `I've tried the following with no luck` would work if you call it the following way: `Object1.definition.call(Object1,"Dimension1");` as in Vinz243's answer, I've updated it with how to use it. – HMR Aug 16 '14 at 17:16

3 Answers3

2

Try this:

SuperObject.prototype.definition = function(dim){
    this.width(200).height(200)
        .dimension(SourceData.dimension(function (d) {return d[dim];}))
        .group(SourceData.dimension(function (d) {return d[dim];}).group().reduceSum(function (d) {return d.Amount;}))
};

Also you should define the following functions as well:

SuperObject.prototype.width()
SuperObject.prototype.height()
SuperObject.prototype.dimenstion()
SuperObject.prototype.group()

Or put them in the SuperObject prototype chain.

Note that SuperObject is the constructor of Object1, Object2,...

UPDATE #1

Usage:

var obj = new SuperObject();
obj.definition("Dimension1");
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • This will only make sense if "Object1" is a function, and there's no indication that that's the case in the OP. – Pointy Aug 16 '14 at 14:15
  • I am prototypr! Resistence is futile! – Rudie Aug 16 '14 at 14:21
  • The object I'm using is not a function, so prototype doesnt seem to be working for me. var Object1 = dc.lineChart("#chart-line-hitsperday"); – Chris Aug 16 '14 at 14:43
  • @Chris No, prototype is available for all JavaScript objects, your objects is not going to be `SuperObject`. rather that `SuperObject` is a factory/constructor of your objects. type of your objects and what they should to do is specified by you in the SuperObject definiftion – frogatto Aug 16 '14 at 14:47
  • @Chris for clarification, could you please create a [jsfiddle.net](http://www.jsfiddle.net)? – frogatto Aug 16 '14 at 14:50
  • Here is one I I'd like to apply this to: http://jsfiddle.net/chrisguzman/juhaoem2/ – Chris Aug 16 '14 at 14:59
  • Here's the one with the same properties as above: http://jsfiddle.net/chrisguzman/suvac7fg/ – Chris Aug 16 '14 at 15:05
  • @Chris Seems this pattern can't be applied on your codes, because those objects isn't yours, they'll be created by `d3.js`, unless you want to edit that library – frogatto Aug 16 '14 at 15:19
1

Using this?

definition = function(D){     
    this.width(200).height(200)
    .dimension(SourceData.dimension(function (d) {return d[D];}))
    .group(SourceData.dimension(function (d) {return d[D];}).group().reduceSum(function (d) {return d.Amount;}))
}

Use:

definition.call(Object1,"Dimension1");
HMR
  • 37,593
  • 24
  • 91
  • 160
Vinz243
  • 9,654
  • 10
  • 42
  • 86
0

The code as you posted is highly unreadable so I'll try with a simpler example:

var o1={},o2={},o3={}
,dimensions = ['Dimension1','Dimension2','Dimension3']
,objects=[o1,o2,o3]
,len=dimensions.length,i=-1;
while(++i<len){
  //function returning function creating a closure
  //  in a while loop
  objects[i].somefn=(function(d){
    return function(){
      console.log(d);
    }
  }(dimensions[i]));
  objects[i].sameForAll='anything';
}
o1.somefn();
o2.somefn();
o3.somefn();

When a variable name starts with a capital it usually means it's a constructor so I'd advice not to use capitals unless they are all caps to indicate they are constants.

[update]

Here is what it looks like applied to your code:

//wrap in IIFE
(function(dimensions,objects){
  var i=-1,len=dimensions.length;
  //for every object and dimension
  while(++i<len){
    //wrap in IIFE for closure
    (function(object,D){//see later what object and D is
      object
        .width(200).height(200)
        .dimension(
          SourceData.dimension(
            function (d) {
              return d[D];
            }
          )
        )
        .group(
          SourceData.dimension(
            function (d) {
              return d[D];
            }
          )
          .group()
          .reduceSum(
            function (d) {
              return d.Amount;
            }
          )
        );
    }(objects[i],dimensions[i]));//pass object and D
  }
}(['Dimension1','Dimension2','Dimension3'],[Object1,Object2,Object3]))
HMR
  • 37,593
  • 24
  • 91
  • 160