我正在使用d3.js,并想知道如何获得边,宽度,坐标等; 程度.在这样的例子http://bl.ocks.org/mbostock/1667367
Ame*_*aBR 58
使用画笔控件时,可以使用.extent()画笔对象上的方法访问有关画笔状态的信息.
.extent()方法返回的信息取决于您连接到画笔对象的缩放比例.
如果已经一个刻度联(任一的X标尺或 Y形的规模,但不是两者),则程度方法返回形式的两元件阵列[minimum, maximum].
如果有两个 X和Y标尺设置在刷对象,则程度方法返回形式的嵌套阵列[??[xMinimum, yMinimum], [xMaximum, yMaximum]?].
但这些最小值和最大值是多少?这也取决于规模.如果比例具有有效.invert(value)方法,则最小值和最大值将转换为数据域值.对于没有简单invert方法的序数,阈值和其他比例,画笔函数返回对画笔元素有效的坐标系中的值.
要回答您链接到的具体示例的问题,我们需要查看画笔对象并缩放对象.在该示例中,画笔连接到较小的"上下文"图表(x2比例)上的水平刻度:
var x = d3.time.scale().range([0, width]),
x2 = d3.time.scale().range([0, width]),
y = d3.scale.linear().range([height, 0]),
y2 = d3.scale.linear().range([height2, 0]);
var brush = d3.svg.brush()
.x(x2)
.on("brush", brushed);
Run Code Online (Sandbox Code Playgroud)
上面创建的画笔对象仅存在于Javascript中,而不存在于文档中.但是,该对象也是一个可以被调用的函数(类似于轴函数),以便创建一系列矩形,它们将响应鼠标事件(这些是不可见的)和一个"范围"矩形(在本例中)是灰色的,带有白色边框).
context.append("g")
.attr("class", "x brush")
.call(brush) //call the brush function, causing it to create the rectangles
.selectAll("rect") //select all the just-created rectangles
.attr("y", -6)
.attr("height", height2 + 7); //set their height
Run Code Online (Sandbox Code Playgroud)
不可见矩形的默认大小基于X和Y标度的输出范围.由于此画笔没有Y刻度,因此必须明确设置矩形的恒定高度和垂直位置.
范围矩形的初始大小基于画笔对象的范围(默认情况下为零宽度和高度).该矩形的高度也在上面的代码中设置.
当用户与屏幕上的画笔交互时,画笔对象捕获这些事件,(1)更新"范围"矩形的宽度,(2)调用与行中"画笔"事件关联的函数.on("brush", brushed).
该brushed()功能是:
function brushed() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
}
Run Code Online (Sandbox Code Playgroud)
这个画笔的目的是缩放主图表,这是通过设置主图表的X比例的域来完成的.如果画笔的宽度为零,则brush.empty()返回true,主图表X-domain设置为小图表中显示的完整域.
但是,如果画笔具有有效宽度,则空测试返回false,并将域设置为结果brush.extent().因为画笔附加到线性X刻度,而没有Y刻度,所以范围[xMin, xMax](在数据编号中)返回,这正是设置域所需的.
如果你需要知道数据值的宽度,这是一个简单的减法问题:
var extent = brush.extent(); //returns [xMin, xMax]
var width = extent[1] - extent[0]; //data-width = max - min
Run Code Online (Sandbox Code Playgroud)
但是,如果要在屏幕上绘制其他元素,则需要知道SVG中的实际坐标,而不仅仅是数据值.要进行转换,您使用的是始终用于从数据转换为SVG坐标的相同内容:您的缩放功能.记住要使用x2控制小图表的比例,而不是主图表的放大比例,如下所示:
var extent = brush.extent(); //returns [xMin, xMax]
var rangeExtent = [x2( extent[0] ), x2( extent[1] ) ]; //convert
var rangeWidth = rangeExtent[1] - rangeExtent[0];
Run Code Online (Sandbox Code Playgroud)
要重新强调,此示例适用于具有一个(水平/ X)刻度的画笔,这是一个线性刻度.如果您同时使用X和Y线性刻度,则需要使用以下代码分隔X和Y范围值:
function brushed() {
if (brush.empty()) {
//either the height OR the width is empty
x.domain( x2.domain() ); //reset X scale
y.domain( y2.domain() ); //reset Y scale
}
var extent = brush.extent();
x.domain( [extent[0][0] , extent[1][0] ] ); //min and max data X values
y.domain( [extent[0][1] , extent[1][1] ] ); //min and max data Y values
var rangeExtent = [
[x2(extent[0][0]), y2(extent[0][1])],
[x2(extent[1][0]), y2(extent[1][1])]
];
var rangeWidth = rangeExtent[1][0] - rangeExtent[0][0];
var rangeHeight = rangeExtent[1][1] - rangeExtent[0][1];
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
focus.select(".y.axis").call(yAxis);
}
Run Code Online (Sandbox Code Playgroud)
如果您想知道矩形左上角的坐标,您还需要知道Y刻度是否从上到下切换最小值.
或者,您可以从屏幕上的"范围"矩形中获取宽度,高度和左上角坐标,刷子对象会为您修改:
function brushed() {
//use the brush object's values to set the data domains:
if (brush.empty()) {
//either the height OR the width is empty
x.domain( x2.domain() ); //reset X scale
y.domain( y2.domain() ); //reset Y scale
}
var extent = brush.extent();
x.domain( [extent[0][0] , extent[1][0] ] ); //min and max data X values
y.domain( [extent[0][1] , extent[1][1] ] ); //min and max data Y values
//use the brush extent rectangle to get the SVG coordinates:
var extentRect = d3.select("g.x.brush rect.extent");
var rangeWidth = extentRect.attr("width");
var rangeHeight = extentRect.attr("height");
var rangeLeft = extentRect.attr("x");
var rangeTop = extentRect.attr("y");
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
focus.select(".y.axis").call(yAxis);
}
Run Code Online (Sandbox Code Playgroud)
如果使用序数比例,则缩放比较复杂,但查找屏幕坐标的复杂程度较低. 这个答案描述了如何使用带有序数比例的画笔进行缩放.但是,由于返回的值.extent()已经在SVG坐标中,如果需要坐标和宽度,则不必使用比例本身进行转换
画笔控件的API页面在页面顶部有一组缩略图图像; 点击其中任何一个打开一个工作示例.有关更多讨论,您可能会对本教程感兴趣,并提供另一个很好的示例.
| 归档时间: |
|
| 查看次数: |
18460 次 |
| 最近记录: |