Pan/zoom ordinal scale?

一个人想着一个人 提交于 2019-12-03 03:09:46

Expanding slightly from my previous answer as I have been contacted privately to explain how I did this.

First, a screenshot of the app in question, whos emain job is aggregating and displaying planning data gathered from various sources (PowerPoint files, corporate databases, etc.).

The relevant bit is the right vertical axis with the colored dots, where each dot represents a project's effort and involved organization. The gray area on the axis is a d3.js brush, and can be panned/resized to change the chart/table data in real time.

// the axis is a regular ordinal axis, with a brush
y2 = d3.scale.ordinal(),
brush = d3.svg.brush().y(y2).on('brush', brushReact),
// [...]
// brush event handler
function brushReact() {
    if (tasksSlice == null)
        return;
    var yrb = y2.rangeBand(),
        extent = brush.extent(),
        s0 = Math.round(extent[0]/yrb),
        s1 = Math.round(extent[1]/yrb);
    if (s0 == tasksSlice[0] && s1 == tasksSlice[1])
        return;
    tasksSlice = [s0, s1];
    inner.refresh();
}

What happens inside the handler is pretty simple:

  • get the brush extent
  • transpose it to indexes in my data array
  • slice my data array and set the result as the data to display
  • refresh the chart and table

I hope this clears it up.

Turns out it's not that hard, I had to:

  • write a custom scale, mostly identical to d3.scale.ordinal, except that it stores the full range of domain values and implements a slice([min, max]) method that sets the range of visible domain values
  • track the y translation delta in the zoom event callback, and add it to a variable that stores total y translation
  • check if the total translation amount is >= than the y delta between two range values, if it is check that we are not already on one of the (visible or non-visible) domain bounds (0 or length), and if we are not increment or decrement the slice indexes by 1, reset the total translation variable, then redraw the axis
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!