最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - d3.js: Zoom on click event - Stack Overflow

programmeradmin1浏览0评论

I was trying to get same behavior Wil Linssen's implementation but on d3.js version 4. I am quite confused with zoom api in version 4.

The changes that I made in the original implementation is: zoom.translate() replaced with d3.zoomTransform(selection.node()) and appropriate points added instead:

svg.attr("transform",
    "translate(" + t.x + "," + t.y + ")" +
    "scale(" + t.k + ")"
);

This one:

zoom
  .scale(iScale(t))
  .translate(iTranslate(t));

replaced to

var foo = iTranslate(t);
zoom.
  translateBy(selection, foo[0], foo[1]);
zoom
  .scaleBy(selection, iScale(t));

But it's still has a problem, looks like with scale, zoom out...

Example: Example on d3.v4 - jsfiddle

Thanks for the help

I was trying to get same behavior Wil Linssen's implementation but on d3.js version 4. I am quite confused with zoom api in version 4.

The changes that I made in the original implementation is: zoom.translate() replaced with d3.zoomTransform(selection.node()) and appropriate points added instead:

svg.attr("transform",
    "translate(" + t.x + "," + t.y + ")" +
    "scale(" + t.k + ")"
);

This one:

zoom
  .scale(iScale(t))
  .translate(iTranslate(t));

replaced to

var foo = iTranslate(t);
zoom.
  translateBy(selection, foo[0], foo[1]);
zoom
  .scaleBy(selection, iScale(t));

But it's still has a problem, looks like with scale, zoom out...

Example: Example on d3.v4 - jsfiddle

Thanks for the help

Share Improve this question asked Oct 8, 2016 at 12:51 Vladyslav BabenkoVladyslav Babenko 1,36918 silver badges26 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 3

After researching the most easiest way to use d3 v4 api that provides interpolation etc out of box. In original question zoom implemented from scratch, that doesn't make sense in version 4. Solution is similar to @Nixie answers and has few lines of code.

This version includes pan as well, if you do not need, remove svg.call(zoom);

Final example: Zoom D3 v4 - jsfiddle

One interesting note: The function:

function transition() {
  svg.transition()
      .delay(100)
      .duration(700)
      .call(zoom.scaleTo, zoomLevel);
      //.on("end", function() { canvas.call(transition); });
}

call(zoom.ScaleTo, zoomLevel) - will zoom to the center of page. But if you need the center of an image, use this one: call(zoom.transform, transform);

Where transform is a function that sets center of your image. For example of such function:

function transform() {
  return d3.zoomIdentity
      .translate(width / 2.75, height / 2.75)
      .scale(zoomLevel)
      .translate(-width/2.75, -height/2.75);
}

This piece of code does not resolve all the problems, but could be a starting point. In D3 v4 you can transition zoom in one line of code (see also https://github./d3/d3-zoom/blob/master/README.md#zoom_transform)

function interpolateZoom (translate, scale) {
    return selection.transition().duration(350)
              .call(zoom.transform, 
                    d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale))
}

Modified example: https://jsfiddle/2yx1cLrq/. Also, you need to replace selection with selection.node() in all calls to d3.zoomTransform

I've used Angular for this, and it's in my opinion the simplest and cleanest so far. I already had scroll to zoom behavior, adding mouse clicks was easy. Please note I import my d3 functions using ES6 modules. Example:

import { event as d3event, zoom, scaleExtent, selectAll, transition, duration } from 'd3';

My existing zoom (mouse scroll)

this.zoom = zoom().scaleExtent([1, 8]).on('zoom', this.zoomed.bind(this));

// this.chart is my map chart svg created by d3
this.chart.call(this.zoom)

zoomed() {
// this.g is a <g> element appended to the chart that contains all countries in my case.
    this.g
      .selectAll('path') // To prevent stroke width from scaling
      .attr('transform', d3event.transform);
  }

What I added to get zoom buttons:

<!-- My markup -->
<button (click)="zoomClick(1.5)">Zoom in</button>
<button (click)="zoomClick(0.5)">Zoom out</button>
zoomClick(level): void {
  this.chart.transition().duration(200).call(this.zoom.scaleBy, level);
}
发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>