Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing a chart in the options of a mixin #66

Open
samselikoff opened this issue Dec 19, 2013 · 7 comments
Open

Passing a chart in the options of a mixin #66

samselikoff opened this issue Dec 19, 2013 · 7 comments

Comments

@samselikoff
Copy link

I was experimenting with passing a chart to its mixin, like so:

this.xAxis = this.mixin('xAxis', this.base.select('g').append('g'), this);

Then, in the xAxis chart (really, more of a component) I could access the main chart's scale and height. The idea would be to build the xAxis component to work as a mixin with any chart that implements a scale and height method.

Do you have any comments on this approach? Would you prefer some other approach, like passing in the height and scale directly? If so, why?

Thanks!

@jugglinmike
Copy link
Member

Chart#mixin is designed specifically in order to namespace charts. I would
recommend explicitly passing the required data structures and methods. As a
brute force approach, you could require that the mixin is initialized with a
reference to its parent, i.e.

this.xAxis = this.mixin('xAxis', this.base.select('g').append('g'), {
  parent: this
});

If your desire to share the same method namespace is a hard requirement,
though, this won't help. In that case, I would recommend re-using the xAxis
chart using the static method Chart.extend:

d3.chart('xAxis').extend('ChartThatHasAnXAxis', {
  // etc.
});

This relationship is kind of the inverse of what you described. I assume you
were planning on having the xAxis chart define a width and height methods
that wrapped the original implementations, which is not possible here. Instead,
you could make this behavior a little more explicit by expanding the contract
of Charts that extend xAxis: they must broadcast set:height and set:width
events.

Will either of those approaches work for you?

@samselikoff
Copy link
Author

Hmm I'm getting a little confused...

  1. What do you mean by namespacing charts?
  2. I wasn't planning on having axis define width or height methods, I'm using it as an axis component i.e. mix the yAxis chart with any chart that has a yScale and height and you'll get an axis added to your chart.

@jugglinmike
Copy link
Member

  1. When you use the Chart#mixin API, the "child" chart (xAxis in your case) is its own Chart instance. The instance follows typical prototypal inheritance: the properties of the prototype are available on the instance (unless shadowed). This behavior is distinct from the functionality you described, where the prototype methods are defined on the "parent" chart instance itself. You're not the first to be confused by this, though, but I'm hoping to clear things up in version 0.2. Along with the changes to the Chart#mixin API, I want to rename the method to Chart#attach to more clearly describe the intent. (A true "mixin" may find its way into version 0.3.)
  2. Sounds like I was a bit too prescriptive then!

@samselikoff
Copy link
Author

Right, I think I understand. So my question was more about conventions. If I asked for the parent chart in the constructor, it's more along the lines of interfaces - something like, "My xAxis component will work with any chart that exposes width and height methods". Alternatively, I could simply ask for both the width and height in the constructor.

The former seems easier for reuse for consumers of the component, but it doesn't really matter to me. More a question of best practices/what you all have been doing at Bocoup.

@samselikoff
Copy link
Author

@jugglinmike I have another question about this. Say I have a bar chart with a height method. If I pass the chart into my xAxis mixin, the xAxis can always get the current height by calling parent.height(). However, if I pass the height in explicitly, it won't get updated if it's changed in the base chart.

What's the best way to accomplish this?

@samselikoff
Copy link
Author

I could get the height from the yScale I pass in, because I believe the axis holds a reference to the object on the original chart. But it still seems like something I'll have to deal with eventually.

@samselikoff
Copy link
Author

@jugglinmike this popped up again. This time I have a 'Legend' component that updates the width of the chart its being mixed into.

Have you encountered situations like this? How could I accomplish this without passing a reference to the parent chart into my component?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants