wavesjs / waves-ui

A library to display and edit audio data and timeseries data in the browser.
http://wavesjs.github.io/waves-ui/
BSD 3-Clause "New" or "Revised" License
122 stars 16 forks source link

Shape visibility filter #18

Open echo66 opened 9 years ago

echo66 commented 9 years ago

Greetings!

It would be nice to control the visibility of the shapes with a filter function. For example, the updateShapes method could accept an optional argument, the filter function.

Use case: You have a list of segments, each one can be a silent or non-silent segment. Instead of cloning the list and associating the clone with the Layer.data field, you could use the same list and a filter function.

I changed the Layer class in order to support this feature. I added an additional argument in render, update and updateShapes methods, filterFn.

In the render function, I have the following change:

...
// enter
this.data.forEach((datum) => {
      for (let value of values) { if (value === datum) { return; } }
      if (filterFn && !filterFn(datum)) return;
...

In the update function:

update(items, filterFn) {
  this.updateContainer();
  this.updateShapes(items, filterFn);
}

In the updateShapes function:

updateShapes($el, filterFn) {
  $el = ($el == undefined)? null : $el;
  this._updateRenderingContext();
  // update common shapes
  this._$itemCommonShapeMap.forEach((shape, $item) => {
    shape.update(this._renderingContext, this.data);
  });

  for (let [$item, datum] of this._$itemDataMap.entries()) {
    const shape = this._$itemShapeMap.get($item);
    if (filterFn && !filterFn(datum)) return;
    shape.update(this._renderingContext, datum);
  }
}
b-ma commented 9 years ago

Hey @echo66 ,

Sorry for the late reply, I don't really see what could the use case for that feature, I mean from an application point of view. As presented, it looks like a very particular need we could handle quite easily without the need of modifying the library. Something like this (which is just a matter of creating a new array, each datum would be passed by reference with no duplication) would work quite well in my opinion:

const visibleData = data.filter((datum) => { /* ... */ });
layer.data = visibleData;
layer.render();
layer.update();

It could also be done without the need to modify the layer, but just by overriding your shape to handle a given data attribute with some visibility: hidden style.

Could explain your application use case ? Thanks