【发布时间】:2014-09-16 15:27:45
【问题描述】:
我使用 D3 创建了以下图表:
(来源:envhealthatlas.co.uk)
这是为了可视化 3 个变量按升序排列的分布,并识别小于和大于 1 的值。
垂直条同步 3 个图表,并在鼠标悬停时相应移动。下面代码中的 mousemove 函数获取特定鼠标坐标对应的 x 值,然后从查找中我可以获得标识符,它允许我将条形移动与所有 3 个图表同步。
var xS = d3.scale.linear()
.range( [ 0, this.width ] )//width 400
.domain( [1, options.data.length]);
var yS = d3.scale.linear()
.range( [ this.height, 0 ] )
.domain( [ 0, this.maxDataPoint ] );
var linename = this.name + "_line";
this.area = d3.svg.area()
//.interpolate( "monotone" )
.x( function( d ) {
return xS( +d[xOrder] );
} )
.y0( function( d ) {
if ( d[ localName ] < 1 ) {
return yS( d[ localName ] );
} else {
return yS( 1 )
}
} )
.y1( function( d ) {
if ( d[ localName ] < 1 ) {
return yS( 1 );
} else {
return yS( d[ localName ] )
}
} );
this.chartContainer = svg.append( "g" )
.attr( 'class', this.name.toLowerCase() )
.attr( "transform", "translate(" + this.margin.left + "," + ( this.margin.top + ( this.height * this.id ) + ( 10 * this.id ) ) + ")" );
/* We've created everything, let's actually add it to the page */
this.chartContainer.append( "path" )
.data( [ options.data ] )
.attr( "class", "chart unadj " + this.name.toLowerCase() )
.attr( "clip-path", "url(#clip-" + this.id + ")" )
.attr( "d", this.area );
var mousemove = function( d ) {
var xValue = Math.round(xS.invert(d3.mouse(this)[0])) ,
gid = null;
var update = function( xVal , txt, set ){
lines[set]
.attr("transform","translate(" + xS(xVal) + "," + 0 + ")");
texts[set]
.text( txt );
};
if( typeof dataSets[localName][xValue] !== 'undefined'){
gid = dataSets[localName][xValue]["gid"];// Sync with other area charts
};
for (var set in dataSets){
var dataLength = dataSets[set].length ;
while(dataLength--){
if(dataSets[set][dataLength]["gid"] === gid){
var xVal = +dataSets[set][dataLength][xOrder],// xOrder is an auto increment field used for sync purpose and for the xs linear scale
yVal = dataSets[set][dataLength][set];
update(xVal, yVal, set);
};
};
};
};
this.chartContainer.append( "rect" )
.attr( "class", "overlayHover" )
.attr( "width", width)
.attr( "height", chartHeight )
.on( "mousemove", mousemove );
/* Highlighter */
lines[localName] = this.chartContainer.append("line")
.attr("class", "lineHover")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", chartHeight)
.attr("height", 2 )
.attr("height", chartHeight )
.attr("id", linename );
this.yAxis = d3.svg.axis().scale( yS ).orient( "left" ).tickValues( [ 0, 1, this.maxDataPoint ]);
this.chartContainer.append( "g" )
.attr( "class", "y axis" )
.attr( "transform", "translate(0,0)" )
.call( this.yAxis );
this.chartContainer.append( "text" )
.attr( "class", "country-title" )
.attr( "transform", "translate(10,20)" )
.text( this.name );
texts[localName] = this.chartContainer.append( "text" )
.attr( "class","areaValue")
.attr ( "id", localName + "_text" )
.attr( "transform", "translate(10,32)" )
.text("0.00");
};
问题: 图表似乎表现良好,但是通过使用包含几千条记录的当前数据集,我意识到某些值从未显示。例如,如果我将鼠标悬停在图表的最左侧或最右侧(最低或最高),我无法让鼠标坐标变为 0.00 和 400(图表宽度),因此无法获得数据集的极端值。
可用宽度和 x 条目数是否存在问题?
数据如下我有大约9000条记录:
gid,rr_unadj,x_order
948,0.751,1
947,0.751,2
6728,0.762,3
950,0.768,4
任何帮助表示赞赏, 谢谢!
【问题讨论】:
-
听起来像 0 和 400 点,因为离边缘太近了,基本上落在用于捕获 mousemove 事件的矩形之外和/或完全在 SVG 之外。如果是这样,您需要使矩形稍微宽一些,以便它可以捕获 400 的 x 坐标(然后将 Math.min/Math.max 值保持在 0 到 400 之间)。而且,由于 SVG 边界会剪裁矩形,因此您还需要增加 SVG 的宽度以在其周围引入一些填充。
-
最大的问题是可用的宽度有限。如果我的 X 是 400px 宽,但我有 8800 个条目,并且执行鼠标悬停效果的线当时只能移动 1px 如果 xS.invert(mouseX) 只能有 400 个唯一的 mouseX 坐标,它如何在整个数据集中移动价值观
标签: javascript d3.js charts