简介

Brushing是一个通过点击或触摸来选择一个一维或二维区域的交互操作,比如可以通过点击鼠标并移动. brush经常被用来选择离散的元素比如散点图中的点或桌面上的文件等。它也可以被用来放大选中的区域。

d3-brush模块的实现基于鼠标和触控事件以及SVG. 点击并拖动来对选中的区域进行变换,点击并拖拽brush边缘来改变选中的范围大小. 点击并拖拽选中区域外侧时开始一个新的brush区域,点击并在按下META键或 ALT键拖动时会以点击区域为中心进行区域选取,按下SPACE时或锁定当前区域大小,此时仅允许移动变换.

安装引用

如果你使用NPM, npm install d3-brush. 也可以从 d3js.org直接下载 最新版. 可以作为单独的模块D3 4.0一部分使用. 也支持AMD, CommonJS, 和 vanilla环境. 在使用时,会创建d3全局变量:

<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src="https://d3js.org/d3-ease.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-timer.v1.min.js"></script>
<script src="https://d3js.org/d3-selection.v1.min.js"></script>
<script src="https://d3js.org/d3-transition.v1.min.js"></script>
<script src="https://d3js.org/d3-drag.v1.min.js"></script>
<script src="https://d3js.org/d3-brush.v1.min.js"></script>
<script> var brush = d3.brush(); </script>

在你的浏览器中测试brush.

API 参考

# d3.brush()

创建一个二维的brush.

# d3.brushX()

创建一个一维的 x-方向的brush.

# d3.brushY()

创建一个一维的 y-方向的brush.

# brush(group)

为指定的 group 应用brush, 一定是一个 选择集,选择集为SVG的G 元素. 这个方法可以间接调用, 也可以通过使用 selection.call来调用. 例如:

svg.append("g")
.attr("class", "brush")
.call(d3.brush().on("brush", brushed));

d3.brush on jsbin.com

在内部,brush会使用 selection.on来绑定需要的拖拽事件监听器,事件监听器使用 .brush来表示这个事件监听器是用来brush的, 你可以使用如下方法来取消brush的事件监听器:

group.on(".brush", null);

brush会创建SVG元素来显示选中的区域,你可以添加、删除或按需改变这些元素的样式,也可以通过样式表来修改外观. 二维的brush元素结构如code list 1所示:

<!--code list 1:-->
<g class="brush" fill="none" pointer-events="all" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
<rect class="overlay" pointer-events="all" cursor="crosshair" x="0" y="0" width="960" height="500"></rect>
<rect class="selection" cursor="move" fill="#777" fill-opacity="0.3" stroke="#fff" shape-rendering="crispEdges" x="112" y="194" width="182" height="83"></rect>
<rect class="handle handle--n" cursor="ns-resize" x="107" y="189" width="192" height="10"></rect>
<rect class="handle handle--e" cursor="ew-resize" x="289" y="189" width="10" height="93"></rect>
<rect class="handle handle--s" cursor="ns-resize" x="107" y="272" width="192" height="10"></rect>
<rect class="handle handle--w" cursor="ew-resize" x="107" y="189" width="10" height="93"></rect>
<rect class="handle handle--nw" cursor="nwse-resize" x="107" y="189" width="10" height="10"></rect>
<rect class="handle handle--ne" cursor="nesw-resize" x="289" y="189" width="10" height="10"></rect>
<rect class="handle handle--se" cursor="nwse-resize" x="289" y="272" width="10" height="10"></rect>
<rect class="handle handle--sw" cursor="nesw-resize" x="107" y="272" width="10" height="10"></rect>
</g>

整个brush是被包含在一个g元素内部。使用class为overlay矩形来表示brush的范围 brush.extent,即在这个区域内可绘制bursh,超出这个范围就不能绘制bursh了。class为selection的矩形部分覆盖了由 brush selection定义的区域. handle矩形表示四个边框和四个角落(不可见),当鼠标接近区域边缘时候可以拖动,实际上是鼠标移到了这些矩形上. 使用 brush.move来对brush进行编程设置.

# brush.move(group, selection)

为指定的group设置选中范围,它通常用来初始化brush的范围大小,这个group必须是一个选择集 或一个SVG G元素的过渡 . selection 为一个数值类型的数组。对于, 对于 二维 brush,必须由 [[x0, y0], [x1, y1]]定义, x0y0 表示最小x和y值, x1y1 表示最大x和y值,如上面code list 1中brush的范围就是:[[289,189],[299,282]]. 对于 x-brush, 一定由 [x0, x1]定义; 对于 y-brush, 一定定义为 [y0, y1]. selection也可以是一个返回数组类型方法. 如果是一个方法则会为每个选中的元素调用,并传递当前的数据d 和索引i, this 表示当前的DOM元素节点.

let brush = d3.brush();
let brushG = svg.append("g");
brushG.call(brush)
.call(brush.move,[[100,100],[250,250]]);//为brush定义一个初始的大小。 //也可以写成
//brush.move(brushG,[[100,100],[250,250]]);

d3.brush on jsbin.com

# brush.extent([extent])

如果 extent 指定,则设置可刷取的范围,它必须在 brush(group) 调用,否则没有效果,extent由 [[x0, y0], [x1, y1]]指定, [x0, y0] 表示左上角坐标, [x1, y1] 表示右下角坐标, 并返回brush. extent 也可以使用返回类似数组的函数; 如果是方法,则会为每个选中的元素调用,并传递当前的数据 d 和索引i, this 表示当前的DOM元素节点. 如果没有指定 extent 则返回当前的范围,默认如下:

function extent() {
var svg = this.ownerSVGElement || this;
return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
}

设置可刷取的范围

brush.extent([[100,50],[500,550]]);

d3.brush on jsbin.com

brush的范围为应用了brush的分组的最大覆盖范围,不能选中分组以外的元素。

# brush.filter([filter])

如果指定过滤器,则设置过滤器,以指定的函数返回的brush。如果未指定过滤器,返回当前的过滤器,其默认值为::

function filter() {
return !event.button;
}

如果返回false,则会忽略起始事件并不会启动brush。这样可以用来区别哪些事件不作为brush操作。默认的过滤器会忽略第二层按下鼠标事件,因为这些事件可能被用作其他目的。

# brush.handleSize([size])

如果指定了size 则设置brush柄的大小并返回brush,如果没有指定则返回当前的handle尺寸,默认为6.这个是前面提到的handle rect的宽度或高度,当鼠标位于边缘3之内的时候会启动边缘拖拽功能. 这个方法一定要在 应用brush到一个选择集之前设置,即brush4个边和4个角的缓冲区。改变handlesize不会对之前的brush有影响。

brush.handleSize(100);

# brush.on(typenames, [listener])

如果指定了 listener 则为brush设置指定类型的事件监听器并返回brush. 如果之前已经指定过事件监听器,则会覆盖之前的事件监听器. 如果listener 为 null, 则移除响应类型的时间监听器. 如果 listener 没有指定则返回第一个与事件类型匹配的事件监听器.

typenames 是一个表示事件类型的字符串,多个类型可以使用空格隔开. 每个 typename 都是一个 type, 可以使用*.*指定类 brush.foobrush.bar; 这样可以为相同的事件类型指定不同的监听器. 事件类型必须为如下中的一个:

  • start - 开始brush操作,比如鼠标按下.
  • brush -当拖动brush区域进行选取时,比如鼠标拖动.
  • end - 在选取结束时,比如鼠标抬起.

listener中的this为承载brush的G元素。
参考dispatch.onBrush Events 获取更多信息.

# d3.brushSelection(node)

返回指定节点的brush选择,在内部元素的brush或以 element.__brush形式存储; 但是你应该使用d3.brushSelection而不是通过直接访问内部存储来调用,如果给定的node没有附加brush操作,则返回null. 此外 selection 被定义为一个数值数组. 对于 二维 brush, 它是[[x0, y0], [x1, y1]]这种形式, x0y0 表示最小x和y值, x1y1 表示最大x和y值, 对于x-brush, 表示为[x0, x1]; 对于 y-brush, 表示为[y0, y1].

Brush 事件

brush 事件监听器 被调用时, d3.event 被设置为当前的brush事件. brush event 对象包括以下几个属性:

  • target - brush 事件的目标元素.就是brush本身
  • type - 事件类型 “start”, “brush” or “end”;参考 brush.on.
  • selection - 当前的 brush 选择集.即,brush的范围
  • sourceEvent - 底层输入事件, 比如 mousemove 或 touchmove.
    //创建一个brush
let brush = d3.brush();
//brush.handleSize(100);
brush.on("end",()=>{
console.log(d3.event);
});
//创建一个G元素用于存放brush
let brushG = svg.append("g");
brush(brushG); //还可以为brush设置一个初始的大小
brush.move(brushG,[[100,100],[250,250]]);
enter description here

通过事件便可以通过编程方式控制Brush. 比如添加end 事件监听器, 然后使用brush.move来设置brush范围:

d3.brush on jsbin.com

brush的更多相关文章

  1. 【转】c#、wpf 字符串,color,brush之间的转换

    转自:http://www.cnblogs.com/wj-love/archive/2012/09/14/2685281.html 1,将#3C3C3C 赋给background this.selec ...

  2. 【转】C# 的Brush 及相关颜色的操作

    // (实心刷) Rectangle rect1 = , , , ); SolidBrush sbrush1 = new SolidBrush(Color.DarkOrchid); SolidBrus ...

  3. 背水一战 Windows 10 (13) - 绘图: Stroke, Brush

    [源码下载] 背水一战 Windows 10 (13) - 绘图: Stroke, Brush 作者:webabcd 介绍背水一战 Windows 10 之 绘图 Stroke - 笔划 Brush ...

  4. GDI+图形图像处理技术中Pen和Brush的简单使用和简单图形的绘制(C#)

    1.Graphics Graphics对象是GDI+绘图表面,因此在Windows窗体应用程序中要使用GDI+创建绘图,必须要先创建Graphics.在给窗体注册一个Paint事件后,Graphics ...

  5. 绘图: Stroke, Brush

    Stroke - 笔划 Brush - 画笔 示例1.演示“Stroke”相关知识点Drawing/Stroke.xaml <Page x:Class="Windows10.Drawi ...

  6. C#中Brush、Color、String相互转换WPF/Silverlight

    //部分方法只适用于WPF,在SL中不能用 using System.Windows.Media; 1.String转换成Color Color color = (Color)ColorConvert ...

  7. C# 的Brush 及相关颜色的操作 (并不是全转)

    C# 的Brush 及相关颜色的操作 2013-12-13 14:08             4977人阅读             评论(0)             收藏             ...

  8. UE4 在C++ 动态生成几何、BSP体、Brush ---- Mesh_Generation

    截至UE4  4.10 runtime 无法生成BSP类 ,只能通过自定义的Mesh的Vertex 进行绘制 ( Google 考证,能改UE4源码的请忽略 ) 可用到的 UE4 集成的Render ...

  9. (状压) Brush (IV) (Light OJ 1018)

    http://www.lightoj.com/volume_showproblem.php?problem=1018   Mubashwir returned home from the contes ...

  10. Unity3D-terrain brush地形画刷无法出现在Scene中,无法刷地图2

    原因大概是 画刷brush 太小了,地图也太小了,没出出现. 如图,非正常状态: 解决方法: tag: terrain brush not working unity

随机推荐

  1. C#基础之并行编程

    并行编程从业务实现的角度可分为数据并行与任务并行,也就是要解决的问题是以数据为核心还是以要处理的事情为核心.基于任务的并行编程模型TPL(任务并行库)是从业务角度实现的并行模型,它以System.Th ...

  2. 试用一下markdown

    1 2 3 4 5 6 Blog

  3. ubuntu的学习教程(常用操作)

    摘要 最近在学习linux,把自己学习过程中遇到的常用操作以及一些有助于理解的内容记录下来.我主要用的是ubuntu系统 命令提示符 '~' 这个是指用户的家目录,用户分为root用户和普通用户,ro ...

  4. 八月暑期福利,10本Python热门书籍免费送!

    八月第一周,网易云社区联合博文视点为大家带来Python专场送书福利,10本关于Python的书籍内容涉及Python入门.绝技.开发.数据分析.深度学习.量化投资等.以下为书籍简介,送书福利请见文末 ...

  5. 用Micro:bit做浇灌系统

    利用Micro:bit结合[土壤湿度感测棒]做一个简单的浇灌系统 一.测试土壤湿度感测棒 •材料:土壤湿度感测棒 (万能的淘宝上可以找到) •连接:将[土壤湿度感测棒]的一端接P0.另一端接GND 简 ...

  6. 「日常训练」Jongmah(Codeforces-1110D)

    题意 你有n个数字,范围[1, m],你可以选择其中的三个数字构成一个三元组,但是这三个数字必须是连续的或者相同的,每个数字只能用一次,问这n个数字最多构成多少个三元组? 分析 根据官方Editori ...

  7. 11-Dockerfile构建镜像

    用 Dockerfile 创建上节的 ubuntu-with-vi,其内容则为: FROM ubuntu RUN apt-get update && apt-get install v ...

  8. 网络通讯中 bind函数的作用

    面向连接的网络应用程序分为客户端和服务器端.服务器端的执行流程一般为4步,客户端程序相对简单,一般需要两个步骤. 服务器端执行流程4步如下: (1)调用socket函数,建立一个套接字,该套接字用于接 ...

  9. Phaser3 场景Scene之间的传值 -- HTML JAVASCRIPT 网页游戏开发

      PHASERJS3 一.首先当然得有至少有二个场景sceneA.js,sceneB.js 二.从场景A传值到场景B二种方法 1)通过事件this.events.emit('event key',{ ...

  10. 在Office 365 的如何给管理员赋予查看所有人邮箱的权限的Powershell

    连接至Office365 的Powershell Get-MsolUser -UserPrincipalName admin@***.partner.onmschina.cn //Get-MsolUs ...