在Webview中使用D3 Canvas图形缩放和平移慢速重绘

时间:2017-09-05 19:44:31

标签: javascript d3.js canvas ionic-framework ionic2

我有一个我在Canvas中实现的d3图。 Chrome中的图表性能非常好,但是当我使用Ionic(webview)进行部署时,缩放和平移重绘在Android上实际上是惊人的,在iOS上甚至更慢。

我最初使用SVG开发了图形,但在确信画布运行更顺畅之后切换到画布。

设置代码

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();

绘制代码

画布绘制代码如下所示:

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();

}

缩放代码

我的缩放代码如下所示:

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;
  }
}

当从画布中排除区域路径(根本没有绘制它)时,性能似乎会增加。

代码

我正在附加repository的链接。要使其运行,请执行以下操作:

  1. git clone https://github.com/airasheed/canvas-d3-test.git
  2. npm install
  3. ionic serve&lt; - 用于浏览器查看图表
  4. 离子cordova构建ios / android&lt; - 选择您的测试平台
  5. OR - ion cordova模拟android / ios
  6. 我想知道它是否存在代码性能问题,或者我使用的数据量是导致问题的原因。

    对于第一个缩放级别,只有只有21点,这是令人惊讶的情节。重绘时似乎很惊人。

    基准

    在chrome中,line(data)方法需要0.5毫秒,但在iOS网页浏览中,它可能需要15毫秒到40毫秒。它看起来像是滞后而没有反应。

1 个答案:

答案 0 :(得分:2)

尝试添加Crosswalk WebView Engine插件性能似乎有所提升:

我已使用Cordova Version : 6.5.0

测试了我的代码

我在Android物理设备(Nexus -6)中测试了这个。您可以使用GithubRepo

中的代码找到完整代码

只有我需要在Android版4.4.4上方验证

在设备中安装后,将更新iOS的基准状态。

更新

在安装WKwebview之前,最初的构建是相当迟缓的。从ionic-team安装WKwebview之后(原始的Apache回购非常错误,离子团队修改了这个插件以适应它们,所以最好从这里添加)repo我可以使它工作顺利过渡

所以Repo可以在这里找到:

https://github.com/Webrusterkk/Canvas-With-ionic

ionic-WKWebview Cordova插件:

https://github.com/ionic-team/cordova-plugin-wkwebview-engine