我有D3製作的sunburst圖表。每個'花瓣'代表數據的一個子集。當用戶點擊「花瓣」之一,我想它過渡,扇出,只顯示該子集(見圖片):D3 - Sunburst圖中的轉換弧
我遇到麻煩代碼正常過渡。
點擊後,所有'花瓣'(除了選定的花瓣)應該消失,剩餘的路徑應該沿着圓圈生成動畫(使用attrTween,arcTween和interpolate?)。將改變的主要值是angleSize(var angleSize = (2 * Math.PI)/theData.length;
)。
我試過使用this,this,this和this作爲參考沒有太大的成功。處理動畫的最佳方式是什麼?
謝謝你的時間!
- >見Plunker Here。 < -
代碼如下:
var colors = {
'Rank1' : '#3FA548',
'Rank2' : '#00B09E',
'Rank3' : '#8971B3',
'Rank4' : '#DFC423',
'Rank5' : '#E74341'
};
var $container = $('.chart'),
m = 40,
width = $container.width() - m,
height = $container.height() - m,
r = Math.min(width, height)/2;
var study = null;
var arc = d3.svg.arc();
d3.csv('text.csv', ready);
function ready(err, data) {
if (err) console.warn('Error', err);
var svg = d3.select('.chart')
.append('svg')
.attr({
'width' : (r + m) * 2,
'height' : (r + m) * 2,
'class' : 'container'
})
.append('g')
.attr('transform', 'translate(' + (width/4) + ', ' + (height/2) + ')');
var slice = svg.selectAll('.slice');
function updateChart(study) {
if (study) {
var theData = data.filter(function(d) {
return d.study_name === study;
});
} else {
var theData = data;
}
slice = slice.data(theData);
slice.enter()
.append('g')
.attr('class', 'slice');
var angleSize = (2 * Math.PI)/theData.length;
var startRadArr = [],
endRadArr = [];
for (var i = 0; i < data.length; i++) {
var startRadius = (width/20),
endRadius = startRadius;
for (var x = 0; x < 4; x++) {
startRadArr.push(startRadius);
if (x == 0) {
endRadius += Number(data[i].group1_score) * (width/500);
} else if (x == 1) {
endRadius += Number(data[i].group2_score) * (width/500);
} else if (x == 2) {
endRadius += Number(data[i].group3_score) * (width/500);
} else {
endRadius += Number(data[i].group4_score) * (width/500);
}
endRadArr.push(endRadius);
startRadius = endRadius + 0.3;
}
}
var startRadGroup = [],
endRadGroup = [];
for (i = 0; i < startRadArr.length; i += 4) {
startRadGroup.push(startRadArr.slice(i, i + 4));
}
for (i = 0; i < endRadArr.length; i += 4) {
endRadGroup.push(endRadArr.slice(i, i + 4));
}
slice.selectAll('path')
.remove();
for (var x = 0; x < 4; x++) {
slice.append('path')
.attr({
'class' : function(d, i) {
if (x == 0) {
return d.group1_class;
} else if (x == 1) {
return d.group2_class;
} else if (x == 2) {
return d.group3_class;
} else {
return d.group4_class;
}
},
'company' : function(d, i) {
return d.brand_name;
},
'cat' : function(d, i) {
if (x == 0) {
return 'Group1';
} else if (x == 1) {
return 'Group2';
} else if (x == 2) {
return 'Group3';
} else {
return 'Group4';
}
},
'study' : function(d, i) {
return d.study_name;
},
'companyid' : function(d, i) {
return d.brand_id;
},
'startradius' : function(d, i) {
return startRadGroup[i][x];
},
'endradius' : function(d, i) {
return endRadGroup[i][x];
},
'startangle' : function(d, i) {
return angleSize * i;
},
'endangle' : function(d, i) {
return angleSize * (i + 1);
}
})
.on('click', selectStudy);
}
slice.exit()
.remove();
slice.selectAll('path')
.attr({
'd' : function(d) {
return arc({
innerRadius : +d3.select(this)[0][0].attributes.startradius.nodeValue,
outerRadius : +d3.select(this)[0][0].attributes.endradius.nodeValue,
startAngle : +d3.select(this)[0][0].attributes.startangle.nodeValue,
endAngle : +d3.select(this)[0][0].attributes.endangle.nodeValue
})
}
});
}
function selectStudy(d) {
study = $(this).attr('study');
updateChart(study);
}
updateChart();
}
編輯
更新的代碼(基於this)包括一個正常輸入,更新和退出模式。但仍然不確定轉型。我鏈接的大多數示例都使用類似d3.interpolate(this._current, a);
的東西,在不同的數據之間進行補間。
在此圖表中,this._current和a是相同的,angleSize(var angleSize = (2 * Math.PI)/theData.length;
),startAngle和endAngle是唯一發生更改的事物。
有幾件事情使得這一點變得複雜 - 首先,最重要的是,在嘗試轉換它們之前刪除了所有的切片,但是您需要重新創建切片以便開始切換。還要考慮將數據重新格式化爲更深的結構,因此您無需在每個點上循環4次。 – Owen
@歐文呀。 remove()是一些奇怪行爲的臨時修復(新數據會附加在舊數據上)。註釋掉remove - > [LINK](https://plnkr.co/edit/JwCy84YBVSxDERZOp1z0?p=preview)。至於數據,我不幸對格式沒有任何控制。將尋找一個JS解決方案(任何建議?)。不希望在Excel中手動更改。 – BastionGamma
還有什麼理由使用d3 v3而不是v4? – Owen