这是一个黑客,但它解决了一个棘手的问题:我的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();
}