heavysixer / d4

A friendly reusable charts DSL for D3

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Better series indexing

yanofsky opened this issue · comments

When you use beforeRender to filter data and plot different features in the same chart, the classes applied to the series containers are linked to the index in relation to the filtered data not in the original data.

For instance both the bars and the line are classed series0 in this http://visible.io/charts/column/multi-dimension.html

We've been binding an index to the data and accessing it in the afterRender which is less than ideal

line.afterRender(function() {
    this.container.selectAll(".lines g.line")
        .each(function(d,i) {
            d3.select(this).classed("mixed-series-" + d.index, true);
        });
})

Can you reference them by their feature name which is already injected in?

For example: http://visible.io/charts/column/multi-dimension.html

You get each series wrapped inside their feature name .bars, .lineSeries. Then it doesn't matter if the index resets because you still have a way of scoping for the item you are looking for.

Oh the issue is not that there are duplicate classes, it's that there is no way to target a series by it's index without knowing what type of feature it is.

The benefit of this is to allow for a consistent color progression on charts that share a stylesheet but display data differently. i.e. The first series is always red the second is always blue the third is always green, irrespective of the type of series.

Got it ok, thank you for the explanation; let me think this one over. It seems like a solvable problem.

@yanofsky would applying an index of the render order help so:

<g class="chartArea">
  <g class="bars"><g class="series0 value">...</g>
  <g class="lines"><g class="series0 value">...</g>
</g>

would become:

<g class="chartArea">
  <g class="bars" data-render-index='0'><g class="series0 value">...</g>
  <g class="lines" data-render-index='1'><g class="series0 value">...</g>
</g>

The index needs to be applied to the series's g not the feature's g there could be multiple line/column/dot series and each should have their index

<g class="chartArea">
  <g class="bars>
    <g class="series0 value render0">...</g>
    <g class="series1 value render2">...</g>
  </g>
  <g class="lines" data-render-index='1'>
    <g class="series0 value render1">...</g>
    <g class="series1 value render3">...</g>
  </g>
</g>

The way you have described above would also be inconsistent with the way D4 indicates series index and item index, right?

ok how about this, what if I add a generic css class for feature and series to each element.

<g class="chartArea">
  <g class="bars feature">
    <g class="series series0 value render0">...</g>
    <g class="series series1 value render2">...</g>
  </g>
  <g class="lines feature" data-render-index='1'>
    <g class="series series0 value render1">...</g>
    <g class="series series1 value render3">...</g>
  </g>
</g>

then you could guarantee the same colors per series regardless of the returned data index using CSS like this:

first series is always red:

.feature .series:nth-of-type(1)
{
    border:5px solid red;
}

second series is always blue:

.feature .series:nth-of-type(2)
{
    border:5px solid blue;
} 

Would something like that work for you?

did you intend to leave the renderX class in the example above?

wouldn't .feature .series:nth-of-type(2) select render2?

The intention is to able select in order render0, render1, render2, render3

@yanofsky sorry no i didn't mean to leave renderx in.

the idea was that using CSS you could select the first element within a feature for example. This would mean that you could get consistent color across features if the series order is consistent.

Does that make sense?

I am trying to keep the series themselves unaware of the larger ordering within the data array. Their responsibility i believe is to order based on the data they are provided only. Otherwise I believe there is a violation in the separation of concerns.

Thats probably true. Like I said in the first post, this can be achieved in afterRender, so not a big deal, if you don't want to roll into D4

@yanofsky ok will add the generic "feature" and "series" classes to each feature this way you can still style things with CSS and without the need of an afterRender call. I'll update an example on the demo site as well.