D3 Canvas图形缩放和平移在Webview中慢速重绘 [英] D3 Canvas graph zooming and panning slow redraw in Webview
问题描述
我有一个我在Canvas中实现的d3图。 Chrome中的图表性能非常好,但是当我使用Ionic(webview)进行部署时,缩放和平移重绘在Android上实际上是惊人的,在iOS上甚至更慢。
I have a d3 graph that I implemented in Canvas. The graphs performance is great in Chrome, but when I deploy it with Ionic(webview), zoom and pan redrawing are really staggering on android and even slower on iOS.
I最初使用SVG开发了图形,但在确信画布运行更顺畅之后切换到画布。
I originally developed the graph with SVG, but switched to canvas after being convinced that canvas would run smoother.
HTML
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<canvas width="300" height="300"></canvas>
</ion-content>
画布初始化
mode = 'monthly';
canvas = document.querySelector("canvas");
context = canvas.getContext("2d");
margin = { top: 20, right: 20, bottom: 30, left: 50 },
width = canvas.width - margin.left - margin.right,
height = canvas.height - margin.top - margin.bottom;
var parseTime = d3.timeParse("%d-%b-%y");
// setup scales
x = d3.scaleTime()
.range([0, width]);
x2 = d3.scaleTime().range([0, width]);
y = d3.scaleLinear()
.range([height, 0]);
// setup domain
x.domain(d3.extent(data, function (d) { return moment(d.usageTime); }));
y.domain(d3.extent(data, function (d) { return d.kWh; }));
x2.domain(x.domain());
// get day range
dayDiff = daydiff(x.domain()[0], x.domain()[1]);
// line generator
line = d3.line()
.x(function (d) { return x(moment(d.usageTime)); })
.y(function (d) { return y(d.kWh); })
.curve(d3.curveMonotoneX)
.context(context);
area = d3.area()
.curve(d3.curveMonotoneX)
.x(function (d) { return x(moment(d.usageTime)); })
.y0(height)
.y1(function (d) { return y(d.kWh); })
.context(context);
// zoom
zoom = d3.zoom()
.scaleExtent([1, dayDiff * 12])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on("zoom", zoomed);
d3.select("canvas").call(zoom)
context.translate(margin.left, margin.top);
draw();
抽取代码
画布绘制代码如下所示:
Draw Code
The canvas draw code looks like this:
function draw() {
// remove everything:
context.clearRect(-margin.left, -margin.top, canvas.width, canvas.height);
// draw axes:
xAxis();
yAxis();
// save the context without a clip path
context.save();
// create a clip path:
context.beginPath()
context.rect(0, 0, width, height);
context.lineWidth = 0;
context.strokeStyle = "none";
context.stroke();
context.clip();
// draw line in clip path
line(data);
context.lineWidth = 1.5;
context.strokeStyle = "steelblue";
context.stroke();
context.beginPath();
area(data);
context.fillStyle = 'steelblue';
context.strokeStyle = 'steelblue';
context.fill();
// restore without a clip path
context.restore();
}
放大代码
我的缩放代码如下所示:
Zoom Code
My zoom code looks like this:
function zoomed() {
var t = d3.event.transform;
x = t.rescaleX(x2);
draw();
var diff = daydiff(x.domain()[0], x.domain()[1]);
if (diff < 366 && diff > 120 && mode !== 'monthly') {
mode = 'monthly';
data = monthlyData;
y.domain(d3.extent(data, function (d) { return d.kWh; }));
return;
}
if (diff <= 120 && diff > 2 && mode !== 'daily') {
mode = 'daily';
data = dailyData;
y.domain(d3.extent(data, function (d) { return d.kWh; }));
return;
}
}
排除区域路径时性能似乎会提高(从画布上完全不画画。
The performance seems to increase when excluding the area path(not drawing it at all) from the canvas.
我正在附加链接到 repository
。要使它运行,请执行以下操作:
I'm attaching a link to the repository
. To make it run do the following:
- git clone https://github.com/airasheed/canvas-d3-test.git
- npm install
- ionic serve< - 浏览器查看图表
- ionic cordova build ios / android< - 选择您的测试平台
- OR - 离子cordova模拟android / ios
- git clone https://github.com/airasheed/canvas-d3-test.git
- npm install
- ionic serve <--for browser to see graph
- ionic cordova build ios/android <--choose your testing platform
- OR - ionic cordova emulate android/ios
我想知道它是否存在代码性能问题或是否我正在使用的数据量是造成这个问题的原因。
I'd like to know if its a code performance issue or if the amount of data i'm using is what's causing the issue.
对于第一个缩放级别,只有21点,要绘制的是奇怪。重绘时似乎令人震惊。
For the first zoom level there are only 21 points, to plot which is surprising. It seems its staggering when redrawing.
在chrome中 line(data)
方法需要.5ms,但在iOS webview中,它可能需要15ms到40ms。它看起来像是滞后而没有响应。
In chrome the line(data)
method takes .5ms, but in the iOS webview it can take anywhere from 15ms - 40ms. It looks like its lagging and not responsive.
推荐答案
尝试添加 Crosswalk WebView引擎
插件性能似乎有所改善:
Try to add the Crosswalk WebView Engine
Plugin Performance seems to be improved :
我用 Cordova版本测试了我的代码:6.5.0
我在Android物理设备(Nexus -6)中测试了这个。您可以使用 GithubRepo
I have Tested this in Android Physical Devices (Nexus -6) . You can find the Full Code with the code in the GithubRepo
仅我需要在Android版本中验证 4.4.4
以上
Only case i need to verify in the Android version 4.4.4
above
在设备中安装后,将更新 iOS
的基准状态。
Will update the benchmark status of the iOS
after installing in the device.
更新:
在安装 WKwebview
之前,最初构建是相当迟缓的。从 WKwebview 后>离子团队(原始的Apache回购非常错,离子团队已经修改了这个插件以适应他们所以最好从这里添加)repo我可以让它顺利过渡
Initially build was quite delay before installing the WKwebview
. after installing the WKwebview
from the ionic-team (Original Apache repo is quite buggy and ionic-team has modified this plugin to fit for them so it is better to add from here ) repo i can make it work with smooth transition
所以可以在这里找到回购:
So Repo can be found here :
https://github.com/Webrusterkk/Canvas-With-ionic
ionic-WKWebview Cordova插件:
ionic-WKWebview Cordova Plugin :
https:/ /github.com/ionic-team/cordova-plugin-wkwebview-engine
这篇关于D3 Canvas图形缩放和平移在Webview中慢速重绘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!