1

既にgithubで閲覧できるGoogle Visualization / Charts API用の Dart ベースのラッパーを開発しています。利用可能なすべてのチャートに対して、チャート固有のラッパー クラスを作成しました。

現在、基礎となるクラスのイベントを調べています。問題は、すべてのチャートで共有されていないさまざまなイベントがあることです。したがって、特定のイベント タイプを対応するチャートに割り当てる方法を見つける必要があります。私がすでにやったことは次のとおりです。

  1. Events APIのラッパーを作成しました。

    abstract class Events {
      static JsObject addListener(source_visualization, event_name, Function handling_function) {
        return vis['events'].callMethod('addListener', [source_visualization, event_name, new JsFunction.withThis(handling_function)]);
      }
    
      static JsObject addOneTimeListener(source_visualization, event_name, handling_function(e)) {
        return vis['events'].callMethod('addOneTimeListener', [source_visualization, event_name, new JsFunction.withThis(handling_function)]);
      }
    
      static void removeListener(listener_handler) {
        return vis['events'].callMethod('removeListener', [listener_handler]);
      }
    
      /// TODO(rh): removeAllListeners
    }
    
  2. 1 つのイベントのすべてのコードをカプセル化するラッパー クラスを作成しました。コードは次のようになります。

    class EventWrapper<E extends Event> {
      JsObject _jsChart;
      String _eventName;
      JsObject _handler;
      Stream<E> get onEvent => _streamController.stream;
      StreamController<E> _streamController;
      ...
      EventWrapper(this._jsChart, this._eventName, E reviver(p)) {
        _streamController = new StreamController.broadcast(onListen: () => _onListen(_eventName), onCancel: () => _onCancel(_eventName));
      }
    
      void _onListen(String event) {
        _handler = Events.addListener(_jsChart, event, ...);
      }
    
      void _onCancel(String event) {
        Events.removeListener(_handler);
      }
    }
    
  3. チャートでは、次のようなコードを使用できます。

    class PieChart ... {
      Stream<SelectEvent> get onSelect => _selectEventHandler.onEvent;
      EventWrapper _selectEventHandler;
    
      PieChart(Element e) : super._(e, "PieChart", vis) {
        _selectEventHandler = new EventWrapper<SelectEvent>(jsChart, 'select', (p) => new SelectEvent());
        // Other Events
      }
      // ...
    }
    

問題は次のとおりです。Eventsインターフェイスには、source_visulizationイベントを登録するチャートである引数が必要です。しかし、これを使用すると、これは ( )dart:jsを介してオブジェクトを作成するため、チャートでコンストラクターを呼び出した後にのみ使用できます。通常はコンストラクター内でインスタンスを作成しますが、いくつかのクラスでイベントを使用する必要があるため、#3 で示されている現在のもの以外に 2 つの解決策を考えました。JsObjectjsChart = new JsObject(ctx[chartName], [element])EventWrapper

  1. ミックスインを作成します - これは実際には機能しません。コンストラクターがなく、エラーが発生してインスタンス メソッドを指定できないためです。

    abstract class SelectEventMixin {
      Stream<SelectEvent> get onSelect => _selectEventHandler.stream;
      final StreamController _selectEventHandler = new StreamController.broadcast(onListen: _onListen);
    
      void _onListen() {
        // jsChart is available here
      }
    }
    
  2. 見られるイベントの組み合わせごとに BaseClasses を作成します。これにより、最も一般的なコードを共有できます。いくつかの BaseClass は次のようになります: NoEventsSelectEventSelectReadyEventsSelectReadyAnimationFinishEvents...

あなたの誰かがより良い解決策を持っていますか?または、誰かが私の問題#1を修正する方法を教えてもらえますか? #2はすでに最善の解決策ですか?いくつかのメソッドを組み合わせるだけで済み、コードが少し重複するだけでよいのでしょうか?

4

0 に答える 0