既にgithubで閲覧できるGoogle Visualization / Charts API用の Dart ベースのラッパーを開発しています。利用可能なすべてのチャートに対して、チャート固有のラッパー クラスを作成しました。
現在、基礎となるクラスのイベントを調べています。問題は、すべてのチャートで共有されていないさまざまなイベントがあることです。したがって、特定のイベント タイプを対応するチャートに割り当てる方法を見つける必要があります。私がすでにやったことは次のとおりです。
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 }
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); } }
チャートでは、次のようなコードを使用できます。
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 つの解決策を考えました。JsObject
jsChart = new JsObject(ctx[chartName], [element])
EventWrapper
ミックスインを作成します - これは実際には機能しません。コンストラクターがなく、エラーが発生してインスタンス メソッドを指定できないためです。
abstract class SelectEventMixin { Stream<SelectEvent> get onSelect => _selectEventHandler.stream; final StreamController _selectEventHandler = new StreamController.broadcast(onListen: _onListen); void _onListen() { // jsChart is available here } }
見られるイベントの組み合わせごとに BaseClasses を作成します。これにより、最も一般的なコードを共有できます。いくつかの BaseClass は次のようになります:
NoEvents
、SelectEvent
、SelectReadyEvents
、SelectReadyAnimationFinishEvents
...
あなたの誰かがより良い解決策を持っていますか?または、誰かが私の問題#1を修正する方法を教えてもらえますか? #2はすでに最善の解決策ですか?いくつかのメソッドを組み合わせるだけで済み、コードが少し重複するだけでよいのでしょうか?