D3 Canvas图形缩放和平移Webview中的慢速重绘

Abd*_*eed 5 javascript canvas d3.js 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>
Run Code Online (Sandbox Code Playgroud)

画布初始化

  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();
Run Code Online (Sandbox Code Playgroud)

抽奖代码

画布绘制代码如下所示:

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

}
Run Code Online (Sandbox Code Playgroud)

缩放码

我的缩放代码如下所示:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

从画布中排除区域路径(根本不绘制)时,性能似乎有所提高。

代码

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

  1. git clone https://github.com/airasheed/canvas-d3-test.git
  2. npm安装
  3. 离子服务<-供浏览器查看图表
  4. 离子Cordova构建ios / android <-选择测试平台
  5. 或-离子cordova模拟android / ios

我想知道这是代码性能问题还是我正在使用的数据量是引起问题的原因。

对于第一个缩放级别,只有21个点可以绘制,这令人惊讶。重绘时似乎令人st异。

标杆管理

在chrome中,此line(data)方法需要0.5毫秒,但在iOS Web视图中,则可能需要15毫秒-40毫秒。它看起来像是滞后的,没有响应。