• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] d3 javascript- Problem beim Mausklick

d3js

New member
Hallo zusammen,

ich arbeite gerade an einem Programm, der einen Graphen mit Daten übergibt.
Man kann mit der Maus bestimmte Stellen auf den Graphen wählen, sodass der Bereich in einem zweiten
Graph gezoomt wird.

Beim zoomen gibt es keinerlei Probleme.
das Problem liegt darin, dass beim weiteren Mausklick auf den Graphen der alte Position bleibt.
Ich möchte aber, dass bei jedem Mausklick eine neue Position erstellt wird. Ist das einigermaßen verständlich?
Sieht ihr vielleicht ein fehler im Code? Ich drehe durch,bitte um Hilfe :S

Code(zum teil):

Code:
<!DOCTYPE html>
	<html lang="en">
<head>
		<meta charset="utf-8">
		<title>d3.js Learning csv data</title>
		<script type="text/javascript" src="js/d3.v3.min.js"></script>
		<style>
		/* svg styles!! */

		.axis text {
			font-family: sans-serif;
			font-size: 11px;	
		}
		
		.brush .extent {
		  fill-opacity: .2;							
		  stroke: #fff;
		  shape-rendering: crispEdges;
		}
		</style>
	</head>

		<body>
			<script>
.
.
.
.
	}	

	//hier müsste der fehler liegen. Auch ohne extent ist es genauso

		var brush = d3.svg.brush() //Constructs a new brush
			.x(xScale)
			.y(yScale)
			.extent([[Laenge/3,0.2],[2*Laenge/3,0.5]]) 	
			.on("brushend",function(){
				var dataset_filtered = mydataset.filter(myfilter);
		
				x2Scale.domain([brush.extent()[0][0],brush.extent()[1][0]]);
				y2Scale.domain([brush.extent()[0][1],brush.extent()[1][1]]);
				x2.transition().call(x2Axis);
				y2.transition().call(y2Axis);
.
.
.

Ich bedanke mich im Voraus!

Gruß
 
Ich hab' keine Ahnung von d3, aber wahrscheinlich muss du vor dem Ganzen den Graphen zurücksetzen.

Aber der Code ist definitiv zu Lückenhaft (man kann nur raten, was die einzelnen Variablen beinhalten) um da etwas Konkretes zu sagen.
 
Vielen Dank erstmal für eure Hilfsbereitschaft.
Ich füge den kompletten Code hier ein mit paar Kommentare. Ich Hoffe so könnt ihr durchsteigen.

Auf der Fehlerkonsole erscheint nur dies:
Unerwarteter Wert NaNpx beim Parsen des Attributs x. d3.v3.min.js:1
Unerwarteter Wert NaNpx beim Parsen des Attributs y. d3.v3.min.js:1
Unerwarteter Wert NaNpx beim Parsen des Attributs width. d3.v3.min.js:1
Unerwarteter Wert NaNpx beim Parsen des Attributs height. d3.v3.min.js:1

Das hat aber nichts mit meinem Problem zu tun:/
Ich möchte die Stelle , beim Mausklick neu erstellen können(je nachdem wo der Maus steht).
Das komische noch daran ist, dass sich diese Fläche mit der maus nur von der rechten und von der unteren Seite vegrößern o. verkleinern lässt.

Im Anhang findet ihr das als Bild(Ausschnitt). Es geht um die graue Fläche,die dann gezoomt wird.


Danke im Voraus!

Gruß


Ps:code im nächsten Beitrag, konnte dies nicht löschen :/
 

Anhänge

  • graph.JPG
    graph.JPG
    6,2 KB · Aufrufe: 5
Zuletzt bearbeitet:
Auf der Fehlerkonsole erscheint nur dies:
Unerwarteter Wert NaNpx beim Parsen des Attributs x. d3.v3.min.js:1
Unerwarteter Wert NaNpx beim Parsen des Attributs y. d3.v3.min.js:1
Unerwarteter Wert NaNpx beim Parsen des Attributs width. d3.v3.min.js:1
Unerwarteter Wert NaNpx beim Parsen des Attributs height. d3.v3.min.js:1



Code:
	<!DOCTYPE html>
	<html lang="en">

	<head>
		<meta charset="utf-8">
		<title>d3.js Learning csv data</title>
		<script type="text/javascript" src="js/d3.v3.min.js"></script>
		<style>
		/* svg styles!! */
		.axis path,
		.axis line {
			fill: none;
			stroke: black;
			shape-rendering: crispEdges;
		}
		.axis text {
			font-family: sans-serif;
			font-size: 11px;	
		}
		
		.brush .extent {
		  fill-opacity: .2;							/* auf .1 zurücksetzten */
		  stroke: #fff;
		  shape-rendering: crispEdges;
		}
		</style>
	</head>

		<body>
			<script>
window.onload = function(){			
 			// define dimensions of canvas
			        var margin = {top: 80, right: 80, bottom: 80, left: 80},
 				width = 800 - margin.left - margin.right,
				 height = 300 - margin.top - margin.bottom,
				
				 width2 = 800 - margin.left - margin.right,
				  height2 = 400 - margin.top - margin.bottom;
			
			var mydataset = {};//global verfügbar  machen
			
			// Add an SVG element with the desired dimensions and margin.
			var svg = d3.select("#container")
						.append("svg")
						.attr("float", "left")
						.attr("width", width + margin.left + margin.right)
						.attr("height", height + margin.top + margin.bottom)
						.append("g") //Elemente gruppieren
						.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
	
			// Add an second SVG element with the desired dimensions and margin.
			var svg2 = d3.select("#container2")
						.append("svg")
						.attr("width", width2 + margin.left + margin.right)
						.attr("height", height2 + margin.top + margin.bottom)
						.append("g")
						.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
	

	
			//erzeuge Bereiche scales
			
			var xScale = d3.scale.linear().range([0, width]); 
			var yScale = d3.scale.linear().range([height, 0]);	

			var x2Scale = d3.scale.linear().range([0, width2]);
			var y2Scale = d3.scale.linear().range([height2, 0]);				
			
			//erzeuge achsen
			var	xAxis = d3.svg.axis().scale(xScale).tickSize(-height).tickSubdivide(true), //sets the scale and returns the axis
				yAxis = d3.svg.axis().scale(yScale).ticks(4).orient("right"); //orientation right

			var	x2Axis = d3.svg.axis().scale(x2Scale).tickSize(-height2).tickSubdivide(true),
				y2Axis = d3.svg.axis().scale(y2Scale).ticks(4).orient("right");	
				

			// Bereich zum rendern der Achsen festlegen
			// Add the x-axis.

			var x = svg.append("g") 
			   .attr("class", "x axis")
			  .attr("transform", "translate(0," + height + ")");

			// Add the y-axis.
			var y = svg.append("g")
			  .attr("class", "y axis")
			  .attr("transform", "translate(" + width + ",0)");
			  
			var x2 = svg2.append("g")
			  .attr("class", "x axis")
			  .attr("transform", "translate(0," + height2 + ")");

 			// Add the y-axis.
			var y2 = svg2.append("g")
			  .attr("class", "y axis")
			   .attr("transform", "translate(" + width2 + ",0)");  
			  
			//domain wird festgelegt
var Breite = 1.274;
var Laenge = 2191.094;
xScale.domain([0,Laenge]); 
yScale.domain([0,Breite]);
x.call(xAxis); //aufrufen
y.call(yAxis);
			
//die daten besorgen, csv datei aufrufen		
var drawDefects = function(id){
d3.csv("data/"+id+"_OS.csv", dataconvert,   //dataconvert wird aufgerufen
 function(error, dataset){

//bereits bestehende Elemente mit Daten versorgen
//zusätzliche Elemente hinzufügen

				mydataset = dataset; // gelesene Daten global verfügbar machen
			                        	svg.selectAll("rect").data(dataset)
                                                        .enter()
							.append("rect")
							.attr("x", function(d){return xScale(d.Y_START) +"px"})
							.attr("y", function(d){return yScale(d.X_START)+"px"})
							.attr("width", function(d){ return Math.ceil(d.DIM_LAENGE/width)+"px"})
							.attr("height", function(d){return Math.ceil(d.DIM_BREITE/height)+"px";})
							.attr("fill","none")
							.style("pointer-events","none")
							.attr("stroke", function(d){return d.INFO_SCHWEREGRAD})
							.attr("stroke-width", "1px")
							.attr("stroke-opacity",0.4);


				})
			}	



	//Es ensteht eine transparente fläche auf dem Graphen, diese Position wird im zweiten Graph gezoomt dargestellt

	var brush = d3.svg.brush() //Constructs a new brush
		                .x(xScale)
		                .y(yScale)
 			        .extent([[Laenge/3,0.2],[2*Laenge/3,0.5]]) //sets the extent to the specified values and returns the brush.
 			        .on("brushend",function(){
				  var dataset_filtered = mydataset.filter(myfilter);
				
	//var extent = d3.event.target.extent()
				x2Scale.domain([brush.extent()[0][0],brush.extent()[1][0]]);
				y2Scale.domain([brush.extent()[0][1],brush.extent()[1][1]]);
				x2.transition().call(x2Axis);
				y2.transition().call(y2Axis);
			
	

//Hier Daten aus der Übersicht in die Detailsicht einfügen, zweiter Graph
//select bereits bestehende Elemente für Update
				svg2.selectAll("rect").data([]).exit().remove(); // Alles erst mal raus
				var defects = svg2.selectAll("rect").data(dataset_filtered);  //The result of the data operator is the update selection
			
				//Elemente für zusätzliche Daten einfügen
				defects.enter()		//placeholder nodes for each data element 
						.append("rect")
						.attr("x", function(d){return x2Scale(d.Y_START) +"px"})
						.attr("y", function(d){return y2Scale(d.X_START)+"px"})
						.attr("width", function(d){ 
								return Math.ceil(d.DIM_LAENGE*width2/(brush.extent()[1][0]-brush.extent()[0][0]))+"px"
								}) 
						.attr("height", function(d){
								return Math.ceil(d.DIM_BREITE*height2/(brush.extent()[1][1]-brush.extent()[0][1]))+"px";
								})
						.attr("fill","none")
						.style("pointer-events","none")
						.attr("stroke", function(d){return d.INFO_SCHWEREGRAD})
						.attr("stroke-width", "1px")
						.attr("stroke-opacity",0.4);
				//überflüssige Elemente entfernen
		
				
				}
				);
		
		
		svg.append("g")
			.attr("class", "brush")
			.call(brush);		
				
		var dataconvert = function(d){ //Die gelesenen Daten werden hier konvertiert, falls notwendig
	//je nach Schweregrad enstehen farbige Punkte im Graph
			switch (d.INFO_SCHWEREGRAD){
				case "1": d.INFO_SCHWEREGRAD = "mediumturquoise"; break;
				case "2": d.INFO_SCHWEREGRAD = "forestgreen"; break;
				case "3": d.INFO_SCHWEREGRAD = "orange"; break;
				case "4": d.INFO_SCHWEREGRAD = "lightcoral"; break;
				default:  d.INFO_SCHWEREGRAD = "darkred"; break;
			}
			return d;
		}
		
		var myfilter = function(d){	
		//var upper = brush.extent()[1][1],
		//	lower = brush.extent()[0][1],
		//	left = brush.extent()[0][0],
		//	right = brush.extent()[1][0]
		
		return (
		(d.Y_START > brush.extent()[0][0] && d.Y_START < brush.extent()[1][0] && d.X_START > brush.extent()[0][1] && d.X_START < brush.extent()[1][1]) ||
		(d.Y_START+d.DIM_LAENGE > brush.extent()[0][0] && d.Y_START+d.DIM_LAENGE < brush.extent()[1][0] && d.X_START > brush.extent()[0][1] && d.X_START < brush.extent()[1][1]) ||
		(d.Y_START > brush.extent()[0][0] && d.Y_START < brush.extent()[1][0] && d.X_START+d.DIM_BREITE > brush.extent()[0][1] && d.X_START+d.DIM_BREITE < brush.extent()[1][1]) ||
		(d.Y_START+d.DIM_LAENGE > brush.extent()[0][0] && d.Y_START+d.DIM_LAENGE < brush.extent()[1][0] && d.X_START+d.DIM_BREITE > brush.extent()[0][1] && d.X_START+d.DIM_BREITE < brush.extent()[1][1])
		);
		//return (d.INFO_SCHWEREGRAD == "lightcoral" || d.INFO_SCHWEREGRAD == "orange");
		}

		drawDefects("1146741");

}			
			</script>
			<div id="container"></div>
			<div id="container2"></div>
		</body>
	</html>

das ist eine Menge Code ich weiß, aber der erste Teil ist ja nicht so wichtig, da werden ja erstmal scales und achsen erzeugt.
Sieht ihr vielleicht was im Code noch fehlt?
Danke im Voraus!

Gruß
 
Zuletzt bearbeitet:
Ich gebe kkapsner Recht. Ohne eine Live Ansicht, ist es wirklich schwer durch den Code zu steigen.

Bist du sicher, dass die Fehler nichts mit dem Problem zu haben?
 
Ich gebe kkapsner Recht. Ohne eine Live Ansicht, ist es wirklich schwer durch den Code zu steigen.

Bist du sicher, dass die Fehler nichts mit dem Problem zu haben?

Die Fehlermeldung ist jetzt behoben. Das war auch nur ein Fehler im Datei, kein Codefehler:)

Aber das problem habe ich leider immer noch:/
Soll ich den Code hier als Datei hochladen oder was meint ihr mit testlink?

Gruß
 
danke mikdoe;)

Hier ist der Link dafür:
https://googledrive.com/host/0B4aSDPFCbIYqSHhJb1BhdXctX3c/OIS plot brush.htm

Also nochmal: die graue Fläche(.brush) lässt sich ja bewegen und nur durch die rechte und untere seite kann man es vergrößern oder verkleinern.
Ich möchte aber, dass man den Rechteck von jeder Seite vergrößern bzw. verkleinern kann und ich möchte es auch neu positionieren können.

Wie soll ich es im Code ändern? Hoffe ihr könnt mir jetzt helfen.
Vielen Dank im Voraus!!
 
Das sieht mir, erhlich gesagt, nach einem Bug in dem d3 aus...

... was passiert denn, wenn du die .extent()-Zeile beim Erzeugen des "brush" entfernst?
 
Das sieht mir, erhlich gesagt, nach einem Bug in dem d3 aus...

... was passiert denn, wenn du die .extent()-Zeile beim Erzeugen des "brush" entfernst?

habe ich auch schon versucht, dann ist beim Laden erstmal die graue Fläche nicht da. Sobald ich mit der Maus
eine Fläche fokussiere, dann erscheint es immer ganz oben links. Ich kann also trotzdem nicht irgendwo anders zeichnen. :/

Was ich dazu noch ergänzen möchte: Ich habe festgestellt, dass die brush-funktion nur dann gut klappt wenn die Daten nicht gelesen werden.
Also, sobald die csv-Datei gelesen wird, habe ich das Problem mit brush.
 
Zuletzt bearbeitet:
Ich glaube, wir kommen dem Problem näher.

Kannst du mal die Erzeugung des "brush" in die Callbackfunktion des d3.csv packen? Also dass zuerst die Daten geholt werden und dann erst der "brush" erzeugt wird.
 
Ich glaube, wir kommen dem Problem näher.

Kannst du mal die Erzeugung des "brush" in die Callbackfunktion des d3.csv packen? Also dass zuerst die Daten geholt werden und dann erst der "brush" erzeugt wird.

erstmal Danke für deine Hilfe kkapsner!

Ich habe es so wie du es gesagt hast versucht, dann klappt es schon ABER diesmal kommt eine fehlermeldung das brush(von der Letzte Funktion ganz unten) nicht definiert ist und deswegen wird auch der zweite Graph nicht erstellt.. :confused:

+Die Deklaration von brush sieht auch in d3.csv nicht gut aus und wenn ich es außerhalb deklariere, dann erkennt er das nicht
 
Da du myfilter auch nur beim "brush" verwendest, kannst du das auch im Callback von d3.csv erst deklarieren.

Kannst du dann bitte den geänderten Code im Livebeispiel zeigen.

PS: kannst du deinen Code mal sauber formatieren... das ist echt schwer zu lesen. Bei kann dir z.B. Online JavaScript beautifier helfen.
 
Zurück
Oben