我##标题##想知道如何在D3图形渲染后立即执行函数。
我正在开发一个动态页面,它显示了给出一些参数的散点图。我想在渲染图表后立即调用函数download_SVG。问题是我从服务器获取数据,因此在散点图加载完成之前总是调用将图表保存为SVG文件的函数,从而导致空的SVG文件。我试过setTimeOut()没有成功。
这个问题有什么好的解决方案吗?
$(document).ready(function() {
//Get list of dataset.
$("#dataset").load('/mysite/php/getDataset.php', function(){
var getSVG;
var urldata = window.location.href;
//console.log(window.location.href);
var data = getParams(urldata);
if(data != null){
var gene = data["gene"];
var dataset = data["dataset"];
var exportSvg = data["exportsvg"];
getSVG = data["SVG"];
var e = document.getElementById("probeSelect");
var probe = e.options[e.selectedIndex].value;
settingSVG(getSVG);
loadGraph(gene, dataset, probe);
getAbbList(dataset);
changeSelectedDataset(dataset);
//setTimeout(download_SVG("mainSVG", "scatter"),6000);
//console.log(data["gene"]);
//console.log(data["dataset"]);
}
});
});
function drawCircles() {
//console.log(datasetChanged);
//This selects 4 circles (non-existent, there requires data-binding) and appends them all below enter.
//The amount of numbers in data is the amount of circles to be appended in the enter() section.
if(datasetChanged){
SVG.selectAll("circle").remove();
}
if(SVG.selectAll("circle").empty() ){
animationNum = 0;
animationNumMedian = 0;
} else if(selectPopulation){
animationNum = 1;
animationNumMedian = 2;
} else if(probeChanged || log2Data){
animationNum = 2;
animationNumMedian = 1;
} else {
animationNum = 3;
animationNumMedian = 0;
//animationNum = randomIntFromInterval(1, 4);
}
var circle = SVGbody
.selectAll("circle")
.data(graphDataY);
circle.exit()
.style("opacity", CIRCLE_OPACITY)
.transition()
.duration(ANIMATION_TIME_MODIFIER*300)
.style("opacity", 0)
.remove();
circle.enter()
.append("circle")
.on("mouseover", function(d) {
div.transition()
.duration(100)
.style("opacity", .9);
div.html(d)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(300)
.style("opacity", 0);
});
var amountOfCircles = d3.selectAll("circle").size();
var iOS = ( navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false );
if(d3.selectAll("circle").size() > 3000 || iOS){
animationNum = 9;
}
switch(animationNum){
case 0:
//Executed on init and when dataset is changed.
circle
.attr("cx",xScale(0))
.attr("cy", yScale(minAxisY))
.attr("r",4)
.style('opacity', 0)
.style("fill", function(d, i){ return graphDataColors[i]; })
.transition()
.duration(ANIMATION_TIME_MODIFIER*1000)
.attr("cx", function(d, i){ return xScale(graphDataX[i]);})
//.attr("cy", function (d, i){ return yScale(i); })
.style('opacity', CIRCLE_OPACITY)
.transition()
.duration(ANIMATION_TIME_MODIFIER*1000)
.attr("cy", function(d){return yScale(parseFloat(d));} );
break;
case 1:
//Executed when select population is changed. Remove all dots below the graph and pulls the new data back up.
circle
.attr("cx", function(d, i){ return xScale(graphDataX[i]);})
.attr("cy", function(d){return yScale(parseFloat(d));} )
.attr("r",4)
.style('opacity', 0)
.style("fill", function(d, i){ return graphDataColors[i]; })
.transition().duration(ANIMATION_TIME_MODIFIER*500)
.style('opacity', CIRCLE_OPACITY);
break;
case 2:
//Executed when probe is changed. Changes the position og circles to quickly update the graph.
circle
.transition()
.duration(ANIMATION_TIME_MODIFIER*1000)
.attr("cx", function(d, i){ return xScale(graphDataX[i]);})
.attr("cy", function(d){return yScale(parseFloat(d));} )
.attr("r",4)
.style('opacity', CIRCLE_OPACITY)
.style("fill", function(d, i){ return graphDataColors[i]; });
break;
case 3:
//Executed when gene is changed. Gathers all circles in the middles, spreads the out at the bottom, and lastly pulls them to their places.
circle
.transition().duration(ANIMATION_TIME_MODIFIER*750)
.style("fill", function(d, i){ return graphDataColors[i]; })
.attr("r",4)
.style('opacity', CIRCLE_OPACITY)
.attr("cx", width/2)
.attr("cy", height/2)
.transition()
.attr("cx", function(d, i){ return xScale(graphDataX[i]);})
.attr("cy", yScale(minAxisY))
.transition()
.attr("cy",function(d){return yScale(parseFloat(d));});
break;
case 9:
circle
.attr("cx", function(d, i){ return xScale(graphDataX[i]);})
.attr("cy", function(d){return yScale(parseFloat(d));} )
.attr("r",4)
.style('opacity', 0)
.style("fill", function(d, i){ return graphDataColors[i]; })
.transition().duration(ANIMATION_TIME_MODIFIER*1000)
.style('opacity', CIRCLE_OPACITY);
break;
case 10:
circle
.attr("cx", function(d, i){ return xScale(graphDataX[i]);})
.attr("cy", function(d){return yScale(parseFloat(d));} )
.attr("r",4)
.style("fill", function(d, i){ return graphDataColors[i]; })
.style('opacity', CIRCLE_OPACITY);
break;
}
//console.log(d3.selectAll("circle").size());
//CSS for circles
$("circle").css({"stroke":"#404040","stroke-width":"1px"});
}
function processDatalol(gene, dataset, probe, data){
initValues();
//If a new gene or dataset is chosen, no probes have been chosen by default. If new probe has been chosen, we ignore this.
//console.log("Current gene: " + currentGene + ", New gene: " + gene);
if(currentGene != gene || datasetChanged){
chosenProbe = "none";
gene = makeUpperCase(gene, dataset);
currentGene = gene;
graphDataProbes = Array();
SVG.selectAll(".graphTitle")
.transition().duration(ANIMATION_TIME_MODIFIER*800)
.attr("x", width/2)
.attr("y", 0)
.style("text-anchor", "middle")
.style("font-size", "16")
.style("font-family", "helvetica")
.style("font-weight", "bold")
.transition().duration(ANIMATION_TIME_MODIFIER*700)
.attr("x", width/2)
.attr("y", 90)
.text(currentGene);
SVG.selectAll(".title")
.transition().duration(ANIMATION_TIME_MODIFIER*1500)
.style("font-size", "500")
.style("opacity", "0")
.remove();
}
if(typeof data !== 'undefined' && data.length > 0) {
//console.log(data);
changeAxisLabel(dataset);
data.forEach( function(d) {
arrayValues.push(d.cell_name);
var cell_data = JSON.stringify(d.cell_data);
var probe_name = JSON.stringify(d.probe_name);
console.log(d);
//console.log(probe_name);
cell_data = cell_data.replace(/"/g,"");
probe_name = probe_name.replace(/"/g,"");
if(chosenProbe == "none"){
chosenProbe = probe_name;
}
if(probeChanged == true){
chosenProbe = probe;
}
if((chosenProbe == probe_name) || (probe == MAX_PROBE)){
graphDataSubValueY.push(cell_data.split(" "));
}
graphDataProbes.push(probe_name);
graphDataFullArray.push(cell_data.split(" "));
});
//console.log(graphDataFullArray);
console.log(graphDataSubValueY);
if(!$("#Log2_scale").is(':checked')){
graphDataSubValueY = convert2DArrayToLog2(graphDataSubValueY);
}
arrayValues = removeDuplicatesInArray(arrayValues);
graphDataProbes = removeDuplicatesInArray(graphDataProbes);
//console.log(arrayValues);
//console.log(graphDataProbes);
chooseSearchedProbe();
calculateMedian();
updateTreeGraph(dataset);
//Open survival plot for probe
$(".survPlot").attr("src","/mysite/surv/survplotsPNG/" + chosenProbe + ".png");
$(".survPlot").error(function () {
$(".survPlot").attr("src","/mysite/surv/survplotsPNG/No_Survival_Data.png");
});
updateCheckboxes();
findBiggestCelltype(probe);
calculateMinMaxValues();
calculateCoordinatesXY();
updateAllAxis();
// Change probes and ttest lists avaliable to user.
refreshProbeSelect(graphDataProbes);
refreshTTestList(arrayValues);
changeSelectedProbe(chosenProbe, gene);
//Draw circles and possibly medians.
drawCircles();
if($("#median").is(':checked')){
drawMedians();
}
//Get correlations from database and create buttons that will link to them.
getCorrelations(dataset, chosenProbe);
//Update global booleans after process is done.
setProbeChanged(false);
setDatasetChanged(false);
setSelectPopulation(false);
setLog2Data(false);
animationNum = 1;
//Take a backup of maxAxisY.
maxAxisY_backup = maxAxisY;
}
}