NVD3图:如何拦截回调中的触摸事件?

时间:2018-02-01 14:58:17

标签: angular d3.js ionic2 nvd3.js

这是一个黑客,但它解决了一个棘手的问题:我的Ionic(3)应用程序显示NVD3图表。当用户点击/点击图表上的值时,必须显示相关详细信息。

工具提示不适用于此。

快速访问:在此页面中查找“hackOfJem_bindTouchToClick”(cmd-f或ctrl-f)。

首先是图表选项

找到“elementClick”:

this.graphOptions = {
  "chart": {
    "type": "lineChart",
    "callback": (chart) => {

      // Listen to click events
      chart.lines.dispatch.on('elementClick', (e) => this.entryClicked(e[0].point.x) );

      // Customize tooltip
      chart.interactiveLayer.tooltip.contentGenerator(this.tooltipContentGenerator);
      return chart;
    },

    "height": 450,
    "margin": { ... },
    "useInteractiveGuideline": true,
    "dispatch": {},
    "xAxis": { .. },
    "yDomain": [-100, 100],
    "yAxis": { ... }
  }
};

然后,将点击转换为点击次数

Rem:不要忘记取消注册听众!

private hackedTouchListener: any[] = [];

  constructor(private elementRef: ElementRef,
              private renderer: Renderer2,
              @Inject(DateService) private dateService: DateService,
              @Inject(I18nService) private _i18n: I18nService) {

    this.initGraphOptions();

    // Hack: As NVD3 only gets click events, convert local touch events to clicks.
    this.hackOfJem_bindTouchToClick(this.elementRef.nativeElement);
  }

  ngOnChanges(changes: any) {
    if(changes){
      const timelineEntries: TimelineEntry[] = changes['values'] && changes['values'].currentValue;
      if(timelineEntries) this.processTimelineEntries(timelineEntries);
    }
  }

  ngOnDestroy(): void {
    console.log('unsubscribing from listeners...');
    this.hackedTouchListener.forEach(unsubscribe => unsubscribe());
  }

  private hackOfJem_bindTouchToClick(elem: ElementRef){
    // Other touch events: touchmove, touchend, touchcancel
    this.hackedTouchListener.push(this.renderer.listen(elem, 'touchstart', this.convertTouchEventsToMouseEvents));
  }

  private convertTouchEventsToMouseEvents(event) {
    const touches = event.changedTouches,
      first = touches[0];
    let type = "";

    switch(event.type){
      case "touchstart" : type = "click"; break;       // note that "mousedown" doesn't work, (NV)D3 explicitly looks for "click"
      case "touchmove"  : type = "mousemove"; break;   // not tested
      case "touchend"   : type = "mouseup";   break;   // not tested
      default           : return;
    }

    const simulatedEvent = document.createEvent("MouseEvent");
    simulatedEvent.initMouseEvent(type, true, true, window, 1,
      first.screenX, first.screenY,
      first.clientX, first.clientY, false,
      false, false, false, 0/*left*/, null);

    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
  }

0 个答案:

没有答案