ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

react-vis Highlight 组件实战指南:用拖拽与框选(Brush Drag)为图表注入交互

react-vis Highlight 组件实战指南:用拖拽与框选(Brush  Drag)为图表注入交互 数据可视化图表库前端【免费下载链接】react-visData Visualization Components项目地址https://gitcode.com/gh_mirrors/re/react-vis点击查看免费下载说明react-vis 官方已声明弃用见 DEPRECATED.md本文所描述的行为与 API 均以当前仓库实际源码为准适用于仍在维护或基于该库二次开发的项目。Highlight是 react-vis 中用于实现图表直接操作交互的核心组件它让你通过**框选brushing和拖拽dragging**直接在图表空间中划出一个选择区域并把该区域对应的数据坐标回传给应用层。本文基于 docs/highlight.md 展开结合 highlight.js 源码与 highlight.test.js 测试用例完整讲解该组件的用法、事件生命周期、API 参数以及底层实现原理读完你可以在自己的图表中实现缩放、框选过滤、选区移动等交互能力。Highlight 能做什么Highlight 组件本身是**有状态stateful**的它内部维护一个被拖出的选框dragged box的概念并在交互过程中持续跟踪选框位置。它具备两个核心能力框选brush按下鼠标并拖动画出一个矩形选区onBrush/onBrushEnd会回调该选区的数据坐标范围拖拽drag通过传入dragprop 开启。开启后你可以先框选出一个选框然后像拖动一个盒子一样在图表空间内移动它移动过程中onDrag持续回调最新坐标。该组件既可以同时响应 x/y 两个方向也可以只响应其中一个方向通过enableX/enableY控制因此非常适合做选区过滤、缩放浏览、区间高亮等交互场景。快速上手把它塞进现有图表官方文档强调把这个功能接入已有图表非常简单只需在XYPlot内追加一个Highlight子组件即可XYPlot width{300} height{300} VerticalGridLines / HorizontalGridLines / XAxis / YAxis / MarkSeries classNamemark-series-example strokeWidth{2} opacity0.8 sizeRange{[5, 15]} colorTypeliteral getColor{d highlightPoint(d) ? #EF5D28 : #12939A} data{data}/ Highlight drag enableX{false} onBrush{area this.setState({filter: area})} onDrag{area this.setState({filter: area})}/ /XYPlot上述示例中enableX{false}表示关闭 x 方向响应只允许在y 方向上框选/拖拽回调返回的area也只包含top/bottom两个数据坐标onBrush与onDrag都在选区变化时把area写入组件 state驱动getColor对落在选区内的数据点重新着色实现过滤高亮效果。完整可运行的版本可参考 selection-plot-example.jsy 方向过滤 MarkSeries 点与 dragable-chart-example.jsx 方向过滤柱状图区间。方向响应默认开启选择退出OPT OUT官方文档特别强调了一个极易踩坑的设计方向响应direction responsiveness默认是开启的也就是enableX与enableY的默认值都是true源码见 highlight.js 中Highlight.defaultProps。这意味着如果你希望 Highlight只在一个方向上生效必须显式地关闭另一个方向而不是开启你想要的方向。例如只做横向区间选择时必须写enableY{false}只做纵向过滤时必须写enableX{false}。这一点在 highlight.js 的_getDrawArea与_convertAreaToCoordinates中均有体现关闭的方向会用占满整幅的取值兜底详见下文源码级实现剖析。拖拽模式drag与双向交互在XYPlot内传入dragprop 即开启拖拽模式Highlight drag color#829AE3 enableY{false} onDrag{updateDragState} onDragEnd{updateDragState} /拖拽模式下的交互分为两个阶段先框选按下鼠标拖出选区定义选框的尺寸再拖拽在选框内按下并移动鼠标整个选框跟随移动。一个经典的应用是缩放图表用onBrushEnd得到的选区范围去更新XYPlot的xDomain/yDomain再用onDrag平移这个视口配合animation属性即可实现流畅的缩放平移体验。完整实现见 zoomable-chart-example.jsXYPlot animation xDomain{lastDrawLocation [lastDrawLocation.left, lastDrawLocation.right]} yDomain{lastDrawLocation [lastDrawLocation.bottom, lastDrawLocation.top]} width{500} height{300} {/* ...轴线与数据系列... */} Highlight onBrushEnd{area this.setState({lastDrawLocation: area})} onDrag{area { this.setState({ lastDrawLocation: { bottom: lastDrawLocation.bottom (area.top - area.bottom), left: lastDrawLocation.left - (area.right - area.left), right: lastDrawLocation.right - (area.right - area.left), top: lastDrawLocation.top (area.top - area.bottom) } }); }} / /XYPlot同时支持 x、y 两个方向的二维拖拽示例见 2d-dragable-plot.js它用drag 全部六个回调onBrushStart/onBrush/onBrushEnd与onDragStart/onDrag/onDragEnd实现了一个可实时统计框内点数的散点图。事件生命周期牢记回调顺序在设计监听器时必须清楚 Highlight 的生命周期因为存在不少边界情况。官方文档给出的回调顺序是非拖拽模式永远按brushStart brush brushEnd的顺序触发拖拽模式制作选框阶段brushStart brush brushEnd拖动选框阶段dragStart drag dragEnd。也就是说brushStart一定先于brushbrush一定先于brushEnd拖拽序列同理。在 highlight.js 的startBrushing/onBrush/stopBrushing三个方法中状态标志brushing与dragging决定当前处于哪个阶段mousedown触发startBrushing并派发onBrushStart或onDragStartmousemove触发onBrush并派发onBrush/onDragmouseup或mouseleave触发stopBrushing并派发onBrushEnd/onDragEnd。点击清除Click to Clear的常见坑官方文档明确指出最大的坑集中在点击清除这类事件上要实现点击清除必须带上on...End监听器如onBrushEnd/onDragEnd来更新 state在纯点击事件中鼠标没有移动因此不存在 start 与 end 之间的中间状态你只会收到start和end两个回调。源码层面_clickedOutsideDrag见 highlight.js负责判断点击是否落在既有选框之外当点击位置在选框外或尚未建立选框时任意点击startBrushing会以重置方式开启一次新的空框选随后stopBrushing检测到选区宽高都小于 5px判定为空选区于是onBrushEnd/onDragEnd会收到null作为参数。应用层拿到null后即可清除过滤状态。这一行为被 highlight.test.js 的多组测试直接验证例如在DragableExample测试中先框选出选区、再在(0, 0)处点击一次界面文本恢复到selectionStart: 0,selectionEnd: 0,的初始状态。限制不支持非连续尺度官方文档明确警告不能在非连续尺度non-continuous scales上进行框选具体来说就是不能对 category分类或 ordinal序数尺度做 brushing。原因在源码注释中写得很清楚见 highlight.js 的_convertAreaToCoordinatesNOTE only continuous scales are supported for brushing/getting coordinates back因为框选结果依赖xScale.invert(...)/yScale.invert(...)把像素坐标反解为数据坐标而invert只对连续尺度如 linear有意义。如果你的 x/y 轴用了分类或序数尺度Highlight 无法给出有意义的选区坐标。API 参考以下参数全部继承自官方文档并结合源码给出补充说明。Highlight 通过 packages/react-vis/src/index.js 中的export Highlight from plot/highlight对外导出。className可选类型String作用为 Highlight 容器添加 CSS 类。源码中通过getCombinedClassName(className, rv-highlight-container)合并类名见 highlight.js 的render。注意官方文档此处写作Add css class to Voronoi container从源码看实际应用于Highlight 自身的g容器Voronoi 应属文档复制遗留笔误。drag可选类型Boolean作用开启拖拽交互。默认不传时为falsedefaultProps中未包含drag。enableX可选类型Boolean默认值true作用开启 x 方向的框选与拖拽。enableY可选类型Boolean默认值true作用开启 y 方向的框选与拖拽。highlightX可选类型String或Number默认值左边缘源码中leftPos 0作用在 x 坐标空间中指定高亮条的左边缘位置即把交互区域在 x 方向平移/锚定到该数据值处。highlightY可选类型String或Number默认值顶边缘源码中topPos 0作用在 y 坐标空间中指定高亮条的顶边缘位置。highlightHeight可选类型Number默认值整幅图高度作用高亮条的像素高度。源码中用highlightHeight || plotHeight计算plotHeight marginTop marginBottom innerHeight因此不传时交互区域覆盖整个绘图区含边距。highlightWidth可选类型Number默认值整幅图宽度作用高亮条的像素宽度。源码中用highlightWidth || plotWidth计算plotWidth marginLeft marginRight innerWidth。onBrushStart可选类型Function作用框选开始时调用mousedown/touchstart。onBrush可选类型Function作用框选进行中、选框变化时持续调用mousemove/touchmove。注意官方文档将三者都写成called on the start of brushing属于复制粘贴的笔误从源码onBrush方法看onBrush与onBrushStart的触发时机有明确区分。onBrushEnd可选类型Function作用框选结束时调用mouseup/mouseleave/touchend。选区不足 5px 时收到null。onDragStart可选类型Function作用拖拽开始时调用。onDrag可选类型Function作用拖动选框过程中持续调用。onDragEnd可选类型Function作用拖拽结束时调用。选区不足 5px 时收到null。除上述参数外Highlight 还继承自AbstractSeries见 abstract-series.js并声明了color默认rgb(77, 182, 172)与opacity默认0.3两个视觉属性用于控制选框的填充颜色与透明度。源码级实现剖析内部状态机Highlight 的 state见 highlight.js记录了完整的交互状态state { dragging: false, brushArea: {top: 0, right: 0, bottom: 0, left: 0}, brushing: false, startLocX: 0, startLocY: 0, dragArea: null };brushing当前是否处于框选过程中dragging当前是否处于拖拽过程中startLocX/startLocY手势起始的像素坐标brushArea当前选框的像素矩形top/right/bottom/leftdragArea拖拽模式中已经固化的选框用于计算位移增量。选区计算框选 vs 拖拽_getDrawArea(xLoc, yLoc)负责框选场景对开启的方向取min/max生成矩形对关闭的方向则用整幅兜底——bottom用touchHeight、right用touchWidth、left/top用0。这就是方向响应默认全开、关闭方向自动占满的底层实现。_getDragArea(xLoc, yLoc)负责拖拽场景基于既有的dragArea加上xLoc - startLocXx 方向与yLoc - startLocYy 方向的位移增量关闭的方向增量为 0选框在该方向不随拖动改变。像素坐标 → 数据坐标的转换_convertAreaToCoordinates(brushArea)是 Highlight 能否与数据联动的关键它通过getAttributeScale(this.props, x | y)拿到尺度对象该函数定义于 scales-utils.js 的getAttributeScale再用scale.invert()把像素反解成数据值。转换规则严格遵循enableX/enableY双向开启返回{top, right, bottom, left}四个数据坐标其中 x 方向减去marginLeft、y 方向直接 invert仅 y返回{top, bottom}减去marginTop仅 x返回{left, right}减去marginLeft两者都关返回空对象。源码注释还专门说明这种按方向分别求值的逻辑是为了保证在混合了分类尺度与线性尺度的图表上也能正常框选——分类轴一侧不参与坐标反解。5px 最小选区阈值stopBrushing中有一段关键逻辑const noHorizontal Math.abs(brushArea.right - brushArea.left) 5; const noVertical Math.abs(brushArea.top - brushArea.bottom) 5; const isNulled noVertical || noHorizontal;只要选框在任一方向的跨度小于 5pxonBrushEnd/onDragEnd就会收到null而非坐标对象。这正是点击清除能够工作的机制基础同时也能过滤掉手抖产生的微小误选区。拖拽模式下只有非空选区!isNulled才会被保留为dragArea供下一次拖拽使用。渲染细节render方法输出一个g容器类名rv-highlight-container内部包含两个矩形rv-mouse-target一个黑色填充、opacity0的透明矩形尺寸为touchWidth × touchHeight负责捕获onMouseDown / onMouseMove / onMouseUp / onMouseLeave等事件rv-highlightpointerEventsnone的可见高亮矩形位置与尺寸由brushArea计算得出并用Math.min(Math.max(0, ...), touchWidth/Height)把选区裁剪在图表范围内。组件还做了完整的触屏与右键处理touchstart时使用pageX/pageY取坐标见getLocstouchend/touchcancel通过preventDefault()阻止浏览器模拟鼠标事件造成双重触发同时对contextmenu右键菜单调用preventDefault()以避免长按/右键干扰框选手势。测试验证highlight.test.js 对上述行为提供了系统性验证包括DragableExample框选出选区后显示selectionStart: 0.93, selectionEnd: 2.47点击(0, 0)后恢复初始状态验证拖拽模式 点击清除ZoomableChartExample框选后展示Top / Right / Bottom / Left四个数据坐标验证坐标反解SelectionPlotExample垂直框选后There are 4 selected points点击清除后恢复 0 selected points验证过滤联动BidirectionDragChart框选后选中 5 个点再拖动选框后选中 6 个点点击选框外清除验证二维拖拽全生命周期。这些测试可以直接在仓库中运行packages/react-vis目录下的 jest 配置是理解 Highlight 交互契约最可靠的参考。小结Highlight 是 react-vis 中实现图表内直接操作的通用组件方向响应默认全开、可选择性关闭drag让选区可被二次拖拽六个回调覆盖完整的框选/拖拽生命周期像素到数据坐标的转换依赖连续尺度分类/序数轴不支持框选5px 阈值与null回调用作点击清除的协议。结合 docs/highlight.md 的示例与仓库中四个 showcase 示例zoomable-chart-example.js、selection-plot-example.js、dragable-chart-example.js、2d-dragable-plot.js你可以在自己的图表中快速落地缩放、区间过滤与选区平移等交互能力。赞分享数据可视化图表库前端【免费下载链接】react-visData Visualization Components项目地址https://gitcode.com/gh_mirrors/re/react-vis点击查看免费下载相关推荐使用 visx/drag 为图表与界面元素添加拖拽交互Drag 组件与 useDrag Hook 完全指南使用 visx/drag 为图表与界面元素添加拖拽交互Drag 组件与 useDrag Hook 完全指南 visx/drag 是 visx 可视化组件库数据可视化前端图表库visx/brush 使用指南为 visx 图表实现 Brush 框选与区域缩放交互visx/brush 使用指南为 visx 图表实现 Brush 框选与区域缩放交互 visx 是 Airbnb 开源的一套基于 React D3 的可数据可视化前端图表库Vue3拖拽调整组件为现代Web应用注入交互活力Vue3拖拽调整组件为现代Web应用注入交互活力 在当今快速发展的前端技术领域用户对Web应用的交互体验要求越来越高。传统的静态页面已经无法满足用户对动态、UI组件前端上一篇YYCategories 开源项目指南下一篇NPU加速实战jeffding/xlm-roberta-large-openmind推理性能提升300%的秘诀创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表