2017-06-26 3 views
1

ヒストグラム1をブラシしようとしていて、サブチャート#histogram2を再描画しようとしています。D3.jsグラフ遷移エラー

私の例では、113行目で再描画が正しく機能していません。

コンソールは時折、「高さ」と「Y」のエラーを示している属性 -

Error: <rect> attribute height: Expected length, "NaN". 
Error: <rect> attribute y: Expected length, "NaN". 

私が悪いの値がどこから来ているかを決定することができませんか。

私が間違っていることを理解するのに役立つことがありますか?

おかげ

var data = [ 
 
{"yr":1940,"type":"E","rate":40},{"yr":1947,"type":"A","rate":20},{"yr":1943,"type":"B","rate":30},{"yr":1950,"type":"B","rate":25}, 
 
{"yr":1943,"type":"C","rate":20},{"yr":1941,"type":"A","rate":30},{"yr":1945,"type":"E","rate":40},{"yr":1948,"type":"A","rate":20}, 
 
{"yr":1947,"type":"B","rate":30},{"yr":1950,"type":"B","rate":25},{"yr":1945,"type":"C","rate":20},{"yr":1941,"type":"A","rate":30}, 
 
{"yr":1944,"type":"B","rate":10},{"yr":1949,"type":"C","rate":20},{"yr":1940,"type":"E","rate":10},{"yr":1940,"type":"E","rate":40}, 
 
{"yr":1940,"type":"E","rate":40},{"yr":1947,"type":"A","rate":20},{"yr":1943,"type":"B","rate":30},{"yr":1950,"type":"B","rate":25}, 
 
{"yr":1943,"type":"C","rate":20},{"yr":1941,"type":"A","rate":30},{"yr":1945,"type":"E","rate":40},{"yr":1948,"type":"A","rate":20}, 
 
{"yr":1947,"type":"B","rate":30},{"yr":1950,"type":"D","rate":25},{"yr":1945,"type":"C","rate":20},{"yr":1941,"type":"A","rate":30}, 
 
{"yr":1944,"type":"B","rate":10},{"yr":1949,"type":"C","rate":20},{"yr":1940,"type":"E","rate":10},{"yr":1947,"type":"E","rate":40} 
 
]; 
 

 
// CROSSFILTER Dimensions // 
 
var cfdata = crossfilter(data) 
 
    , all = cfdata.groupAll() 
 
    , year = cfdata.dimension(function(d) {return d.yr;}) 
 
    , type = cfdata.dimension(function(d) {return d.type;}) 
 
    , years= year.group() 
 
    , types= type.group().reduceCount() 
 
    , typeKeys = types.all() 
 
    , keyMap = typeKeys.map (function(d) {return d.key}) ; 
 

 
// General CHART Dimensions // 
 
var margin = {top: 10, right: 20, bottom: 10, left: 10} 
 
    , height = 200 - margin.top - margin.bottom 
 
    , width = 400 - margin.left - margin.right 
 
    , barPadding = 5 ; 
 

 
// Setup TOOLTIPS // 
 
var tip = d3.tip() 
 
     .attr('class', 'd3-tip') 
 
     .html(function(d){return d.value}); 
 
    
 
// HISTOGRAM 1 : TOTAL BY YEAR // 
 
var min1 = d3.min(years.all(), function(d) {return d.key;}) 
 
    , max1 = d3.max(years.all(), function(d) {return d.key;}) 
 
    , range1 = max1 - min1 ; 
 
    
 
var xScale1 = d3.scale.linear() 
 
     .domain([min1, max1]) 
 
     .range([0, width]) ; 
 

 
var yScale1 = d3.scale.linear() 
 
     .domain([0, d3.max(years.all(), function(d) {return d.value;})]) 
 
     .range([height/2, 0]) ; 
 

 
var xAxis1 = d3.svg.axis() 
 
     .scale(xScale1) 
 
     .ticks(5).tickFormat(d3.format("d")) 
 
     .orient("bottom") ; 
 

 
var histogram1 = d3.select("#histogram1").append("svg:svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g"); 
 

 
    histogram1.call(tip); 
 

 
    histogram1.append("g") 
 
     .attr("class", "axis") 
 
     .call(xAxis1) 
 
     .attr("transform", "translate(" + margin.left + "," + height/2 + ")") ; 
 

 
    histogram1.selectAll("rect") 
 
     .data(years.all()) 
 
     .enter().append("rect") 
 
     .attr("x", function(d) {return xScale1(d.key) + 0.5 * (width/range1)}) 
 
     .attr("width", width/range1) 
 
     .attr("y", function(d) {return yScale1(d.value);}) 
 
     .attr("height", function(d) {return (height/2 - yScale1(d.value));}) 
 
     .attr("fill", "green") 
 
     .attr("stroke", "white") 
 
     .on("mouseover", tip.show) 
 
     .on("mouseout", tip.hide); 
 

 
var brush = d3.svg.brush() 
 
     .x(xScale1) 
 
     .extent([1945, 1946]) 
 
     .on("brush", brushmove) ; 
 

 
var brushg = histogram1.append("g") 
 
     .attr("class", "brush") 
 
     .call(brush) ; 
 

 
    brushg.selectAll("rect") 
 
     .attr("height", height/2) ; 
 

 
    brushg.selectAll(".resize") 
 
     .append("path") 
 
     .attr("d", resizePath) ; 
 

 
function brushmove() { 
 
    var s = brush.extent() 
 
     , lower = parseInt(s[0]) 
 
     , upper = parseInt(s[1]); 
 
    
 
    histogram1.selectAll("rect") 
 
     .style("opacity", function(d) {return lower <= d.key && d.key <= upper ? "1" : ".2";}) ; 
 

 
    var filt = year.filterRange([lower,upper]); 
 
    
 
    console.log(filt.top(Infinity)); 
 

 
    histogram2.selectAll("rect") 
 
     .data(filt.top(Infinity)) 
 
     .transition() 
 
     .attr("y", function(d){ return height - yScale2(d); }) 
 
     .attr("height", function(d){ return yScale2(d); }) 
 
}; 
 

 
// HISTOIGRAM 2 : TOTAL BY TYPE // 
 
var keys2 = typeKeys.map(function(d) {return d.key;}) 
 
    , min2 = d3.min(types, function(d) {return d.key;}) 
 
    , max2 = d3.max(types, function(d) {return d.key;}) 
 
    
 
var xScale2 = d3.scale.ordinal() 
 
     .domain(keys2) 
 
     .rangeBands([0, width]); 
 

 
var yScale2 = d3.scale.linear() 
 
     .domain([0, d3.max(types.all(), function(d) {return d.value;})]) 
 
     .range([height/2, 0]); 
 

 
var xAxis2 = d3.svg.axis() 
 
     .scale(xScale2) 
 
     .orient("bottom"); 
 

 
var histogram2 = d3.select("#histogram2").append("svg:svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g"); 
 

 
    histogram2.call(tip); 
 
    
 
    histogram2.append("g") 
 
     .attr("class", "axis") 
 
     .call(xAxis2) 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .selectAll("text") 
 
     .style("text-anchor", "end") 
 
     .attr("dx", "-.8em") 
 
     .attr("dy", ".15em") 
 
     .attr("transform", function(d) {return "rotate(-65)"}); 
 

 
    histogram2.selectAll("rect") 
 
     .data(types.all()) 
 
     .enter().append("rect") 
 
     .attr("x", function(d) {return xScale2(d.key);}) 
 
     .attr("width", width/keyMap.length - barPadding) 
 
     .attr("y", function(d) {return yScale2(d.value); }) 
 
     .attr("height", function(d) {return height - yScale2(d.value);}) 
 
     .attr("fill", "steelblue") 
 
     .on("mouseover", tip.show) 
 
     .on("mouseout", tip.hide); 
 

 

 

 
function resizePath(d) { 
 
    var e = +(d == "e") 
 
     , x = e ? 1 : -1 
 
     , y = height/4; 
 
    return "M" + (.5 * x) + "," + y + "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) + "V" + (2 * y - 6) + "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y) + "Z" + "M" + (2.5 * x) + "," + (y + 8) + "V" + (2 * y - 8) + "M" + (4.5 * x) + "," + (y + 8) + "V" + (2 * y - 8); 
 
}
/*** d3-tip styles */ 
 
.d3-tip { 
 
    line-height: 1.5; 
 
    padding: 8px; 
 
    background: rgba(0, 0, 0, 0.8); 
 
    color: #fff; 
 
    border-radius: 0px; 
 
    text-align: center; 
 
} 
 
.d3-tip:after { 
 
    box-sizing: border-box; 
 
    display: inline; 
 
    font-size: 10px; 
 
    width: 100%; 
 
    line-height: 1; 
 
    color: rgba(0, 0, 0, 0.8); 
 
    content: "\25BC"; 
 
    position: absolute; 
 
    text-align: center; 
 
} 
 
.d3-tip.n:after { 
 
    top: 100%; 
 
    left: 0; 
 
    margin: -1px 0 0; 
 
} 
 
/*** D3 brush */ 
 
.brush .extent { 
 
    stroke: #222; 
 
    fill-opacity: .125; 
 
    shape-rendering: crispEdges; 
 
}
<script src="https://d3js.org/d3.v3.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script> 
 
<div id="histogram1"></div> 
 
<div id="histogram2"></div>

答えて

1

ブラシに応答して、第2のヒストグラムを更新するときあなたが最初にグラフを描いたときから、異なるデータを使用しています。通常、どちらの場合も同じグループのデータ(.all())を使用することをお勧めします。特に

.data(filt.top(Infinity)) 

チャートにデータの生の行を供給し、あろう

.attr("y", function(d){ return height - yScale2(d); }) 
    .attr("height", function(d){ return yScale2(d); }) 

次いでスケールである場合、スケールに、それらの行オブジェクトを通過しようとし番号が必要です。 (オブジェクトは、「非数」文字通りです。)

あなたが関連付けられているcrossfilter基の全てが、再集計・フィルタを再しますフィルタ

year.filterRange([lower,upper]); 

を適用します。 (それは非常に不可欠ではなく、関数型プログラミング、インターフェースだfilter方法は、ちょうど同じ次元オブジェクトを返します。。)

あなたが最初の場所でそれを描いたとおりにyheightを更新した場合:

.attr("y", function(d){ return height - yScale2(d.value); }) 
    .attr("height", function(d){ return yScale2(d.value); }) 

次にpresto!それはフィルタリングします。

wonderful cross filtering

修正されたコードをいじる:http://jsfiddle.net/gordonwoodhull/hjL6rf9u/5/

+0

は答えの優れた解説をありがとうございました。 – Colin

関連する問題