Valeur non valide pour <cercle> attribut cx=“NaN” à l'aide de D3.js
Je suis en train de créer une forme de nuage de points. J'ai une coutume de l'axe des x et une échelle spécifique à la fois sur un axe. J'ai mis en place une fonctionnalité de zoom pour elle aussi. Jusqu'à présent, tout est bien, mais quand j'ai enfin essayez de tracer mes données sous la forme de cercles-je obtenir deux erreurs:
.
Mon graphe peuvent être consultés sur ce site: http://servers.binf.ku.dk/hemaexplorerbeta/
(les cercles sont énormes, parce que je veux être sûr que je connais approximativement à l'endroit où ils sont avant de style)
- Je créer mes cercles de connaissances fondées sur des données lues à partir d'un serveur MYSQL. J'ai vérifié toutes mes données et les chiffres sont corrects. Ils sont soit en cours de traçage à tort ou à mon échelles de zoom sont défectueux.
Aussi, vous remarquerez peut-être je crée mon axe et de l'échelle de quelques valeurs initialement et de le modifier, dans certaines fonctions juste après. Cela est dû au fait que je suis sur la planification du chargement d'un graphique vide sur le site web où l'utilisateur peut décider de ce jeu de données à charger, où les fonctions ont pour personnaliser les deux échelles et les axes pour le chargement de données.
Je l'ai collé mon code source ci-dessous:
//Setting generic width and height values for our SVG.
var margin = {top: 60, right: 0, bottom: 70, left: 40},
genWidth = 1024;
genHeight = 768;
width = genWidth - 70 - margin.left - margin.right,
height = genHeight - 100 - margin.top - margin.bottom;
//Other variable declarations.
var valueY = 0;
var graphData = Array();
//Creating scales used to scale everything to the size of the SVG.
var xScale = d3.scale.linear()
.domain([0, genWidth])
.range([0, width-margin.right]);
var yScale = d3.scale.linear()
.domain([0, genHeight])
.range([height, margin.bottom]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
//Zoom command ...
var zoom = d3.behavior.zoom()
.x(xScale)
.y(yScale)
.scaleExtent([1,10])
.on("zoom", zoomTargets);
//The mark '#' indicates an ID. IF '#' isn't included argument expected is a tag such as "svg" or "p" etc..
var SVG = d3.select("#mainSVG")
.attr("class", "SVG")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("pointer-events", "all")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//This creates a body with a clippath inside the svg where all element in the graph will be. This prevents elemnts on the graph to go past the axis.
var SVGbody = SVG.append("g")
.attr("clip-path", "url(#clip)")
.call(zoom);
//Create background. The mouse must be over an object on the graph for the zoom to work. The rectangle will cover the entire graph.
var rect = SVGbody.append("rect")
.attr("width", width)
.attr("height", height);
//Showing the axis that we created earlier in the script for both X and Y.
SVG.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("transform", function(d) {
return "rotate(-30)"
});;
SVG.append("g")
.attr("class", "y axis")
.call(yAxis);
d3.json("getdata.php?type=load&gene=CCL5&data=human", function(error, data) {
var arrayValues = [];
if(error){ return console.log(error); }
data.forEach( function(d) {
arrayValues.push(d.gene_name);
valueY = getValueY(d.gene_data);
var string = JSON.stringify(d.gene_data);
graphData.push(string.split(" "));
});
//console.log(graphData);
arrayValues = removeDuplicatesInPlace(arrayValues);
updateScaleX(arrayValues.length);
updateAxisX(arrayValues);
//console.log(arrayValues);
updateScaleY(valueY);
//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.
for(var i = 0;i <= graphData.length;i++){
var circle = SVGbody
.selectAll("circle")
.data(graphData[i])
.enter()
.append("circle")
.attr("cx",function(d){return xScale((i*100)+100);})
.attr("cy",function(d){return yScale(d)})
.attr("r",20);
}
});
//Clipping is defined here used to prevent elements from the graph from going past the axis.
var clip = SVG.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("id", "clip-rect")
.attr("x", "0")
.attr("y", "0")
.attr("width", width)
.attr("height", height);
//Resets zoom when click on circle object. Zoom work now, should be changed to a button instead of click on circle though.
SVG.selectAll("circle").on("click", function() {
zoom.scale(1);
zoom.translate([0,0]);
zoomTargets();
});
//The function handleling the zoom. Nothing is zoomed automatically, every elemnt must me defined here.
function zoomTargets() {
var translate = zoom.translate(),
scale = zoom.scale();
tx = Math.min(0, Math.max(width * (1 - scale), translate[0]));
ty = Math.min(0, Math.max(height * (1 - scale), translate[1]));
//This line applies the tx and ty which prevents the graphs from moving out of the limits. This means it can't be moved until zoomed in first.
zoom.translate([tx, ty]);
SVG.select(".x.axis").call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("transform", function(d) {
return "rotate(-30)"
});
SVG.select(".y.axis").call(yAxis);
SVG.selectAll("circle").attr("cx",function(d){return xScale(d)}).attr("cy",function(d){return yScale(d)});
}
function resetZoom() {
zoom.scale(1);
zoom.translate([0,0]);
zoomTargets();
}
function updateAxisX(arr) {
var formatAxis = function(d, i) { return arr[i]; }
xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickValues(createTickValuesArray(arr.length))
.tickFormat(formatAxis);
SVG.select(".x.axis")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("transform", function(d) {
return "rotate(-30)"
});
}
function updateScaleX(newWidth){
genWidth = newWidth;
xScale = d3.scale.linear()
.domain([0, (newWidth*100)+50])
.range([0, width-margin.right]);
SVG.selectAll("circle").attr("cx",function(d){return xScale(d)}).attr("cy",function(d){return yScale(d)});
zoom.x(xScale);
}
function updateScaleY(newHeight){
console.log(newHeight);
var yScale = d3.scale.linear()
.domain([0, newHeight])
.range([height, margin.bottom]);
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
SVG.select(".y.axis").call(yAxis);
SVG.selectAll("circle").attr("cx",function(d){return xScale(d)}).attr("cy",function(d){return yScale(d)});
zoom.y(yScale);
}
function createTickValuesArray(amountOfTicks){
var tickValuesArr = [];
for(var i = 1;i<=amountOfTicks;i++){
tickValuesArr[i-1] = 100*i;
}
return tickValuesArr;
}
function getValueY(coordinates){
return d3.max(coordinates, Number);
}
//Custom functions used for specific uses.
var removeDuplicatesInPlace = function (arr) {
var i, j, cur, found;
for (i = arr.length - 1; i >= 0; i--) {
cur = arr[i];
found = false;
for (j = i - 1; !found && j >= 0; j--) {
if (cur === arr[j]) {
if (i !== j) {
arr.splice(i, 1);
}
found = true;
}
}
}
return arr;
};
yScale
, qui est mis en place comme une échelle linéaire pour les nombres.J'ai essayé d'utiliser
parseint()
mais il ne fait aucune différence. J'obtiens toujours la même erreur.
OriginalL'auteur Vanquiza | 2014-04-03
Vous devez vous connecter pour publier un commentaire.
Le premier et le dernier élément de chaque tableau dans
graphData
provoquer des erreurs lors de analysée comme des numéros, car d'un autre devisPar exemple, le septième tableau de
graphData
ressemble à ceci:La cause de ce qui semble être inutile
JSON.stringfiy()
appel lors de l'extraction de donnéesd.gene_data
est déjà une chaîne de caractères, donc ça devrait marcher comme prévu, lorsque vous retirez laJSON.stringify()
gene_data[0]
- je obtenir des nombres entiers variant autour de 4-9. Pourquoi est-ce possible?? Par exemple, si je imprimerd.gene_data[0]
il écrit simplement UN nombre entier :SEn tout cas je l'ai corrigé en supprimant tous les " à partir d'éléments dans les tableaux. Mais je suis toujours bloqué avec le message d'erreur
Uncaught TypeError: Cannot read property 'length' of undefined
je ne comprends vraiment pas où l'enfer qu'elle vient de...Mon changement de boucle de
i<=arr.length
ài<arr.length
résolu le problème.. Mais ça ne fonctionne toujours pas dessiner les cercles correctement. pour une raison quelconque..Pour votre premier commentaire: Comme je l'ai déjà écrit.
d.gene_data
est une chaîne de chiffres séparés par un espace. Doncd.gene_data[0]
vous donnera le premier caractère de la chaîne. La deuxième: il suffit de retirer leJSON.stringify()
comme mentionné - ou beaucoup mieux: correction de lagetdata.php
script de retour JSON valide. Pour la troisième commentaire: les tableaux JavaScript sont zéro indexé: le premier élément d'un tableau est à l'indice 0, et le dernier élément est à l'indice égal à la valeur de la longueur du tableau de propriété moins 1. Avec<= arr.length
la dernière itération est en dehors des limitesD'accord merci beaucoup 🙂
OriginalL'auteur Andreas