Nulllinie auf selber Höhe mit mehreren y-Achsen aber verschiedenen (+/-)Min/Maxwerten

N

Nanatsusaia

Hallo Allerseits.
wie soviele hier suche ich auch Lösungen für das ein oder andere kleine aber entscheidenes Problem ^^

Also, ich habe ein seeehr klenies mxml welches eine .as-Datei aufruft. In diesem Actionscript wird eine XML eingelesen, welche Daten für mehrere Serien und Konfigurationsdaten für ein LineChart, ColumnChart und PieChart beinhaltet.
Das gesamte Script zeig ich mal lieber nicht, ist mit 2000 LoC wohl ein wenig zu viele ^^'. Kurzzusammenfassung vom Skript:
Nachdem eine XML-Datei auf Fehler untersucht wurde, werden dynamisch mehrere Elemente wie VBox und Canvas u.s.w. erstellt. Anschließend werden je nachdem, welche Diagramme gewünscht sind (steht in der XML) diese erzeugt. In einer weiteren Methode "fülle ich die Diagramme mit den Wert aus der XML auf". Man kann dann im Flash durch anklicken von Bildern zwischen den einzelnen Diagrammen hin und her schalten.
Das zur Grundidee des Progs.

Nun zu meinem Problem: Für jede Serie erstelle ich im Line-/ColumnChart eine separate y-Achse (erste links, zweite rechts, dritte links, ...). Das funktioniert auch soweit gut. Die min- und maxWerte der einzelnen y-Achsen sind gleich der Min-und MaxWerte der zugehörigen Serien. Wenn ich nun aber eine (oder mehrere) Serie habe mit negativen Werten, dann möchte ich gerne die Nulllinie auf allen y-Achsen auf der selben Höhe haben. Denn sonst ist die Anzeige sehr verschoben (eine Serie beginnt "unten" die andere mitten im Diagramm), sodass man Mühe hat die Werte richtig zu verstehen.
Der Codeteil für das bisherige LineChart as Bsp:

Code:
// datenausgabe ist die verwendete XML


private function TabellenMitWertenAuffuellen(y:String):void{
					/* In dieser Funktion werden die Diagramme mit Werten aus der XML gefüllt */
	var tmp1:Array = Lchart.series;
	var tmp2:Array = Cchart.series;
					// Dieses Arrays werden mit den Serien der Diagramme gefüllt um anschließend den Diagrammen hinzugefügt. 
 	var VertikalStellung:Number = 0;
 					// HilfsVariable: Hier wird sich gemerkt, ob eine vertikale Achse Links oder Rechts postiert wird. 
	var hAxisDate:DateTimeAxis = new DateTimeAxis();
					// DateTimeAxis wird verwendent, wenn die Horizontale Achse eine Datumsachse sein soll.
	var hAxisCategory:CategoryAxis = new CategoryAxis();
					// CategoryAxis wird verwendent, wenn die Horizontale Achse Zahlen oder Strings anzeigen sein soll.
 	var SerienName:Array = new Array();
					// HilfsArray, in der die Namen der einzellnen Serien der Reihenfolge nach gespeichert werden.
	var l:Number = new Number();
					// HilfsVariable für Styles 
	for ( var i:Number = 0; i < SerienAnzahl; i++ ) {
					// Merkt sich die Namen der Serien für den "displayName".
		SerienName[i] = datenausgabe.data.series[i].@name;
	}
	if ( xAchsenType_art == "date" ) {
					// Wenn die Horizontalachse vom Type "date" ist, wird hier die hAxisDate formatiert.
		if ( dateformat_sollGeaendertWerden == true ) {
					// In der Funktion FormatDate wird das Datum nach der im XML angegebenen Art formatiert.
			hAxisDate.labelFunction = FormatDate;
		}
		hAxisDate.dataUnits = "days";
		hAxisDate.labelUnits = "days";
		if ( datenausgabe.data.series[laengsteSerie].item.length() <= 10 ) {
			hAxisDate.alignLabelsToUnits = false;
		}
		else {
			hAxisDate.alignLabelsToUnits = true;
		}
		if ( achsenName_sollAngezeigtWerden == true ) {
					// Hier wird die Achsenüberschrift zugewiesen, wenn sie erwünscht ist
			hAxisDate.title = datenausgabe.configuration.axis_name.x;
		}
	}
 	if ( ( yAchsenType_art == "number" ) || ( yAchsenType_art == "text" ) ) {
					// Wenn die Horizontalachse vom Type "number" oder "text" ist, wird hier die hAxisCategory formatiert.
		if ( achsenName_sollAngezeigtWerden == true ) {
			hAxisCategory.title = datenausgabe.configuration.axis_name.x;
		}
	}

	/* -- Horizontalachsenstyle -- */
					// Hier wird das Style der Horizontalachse geändet
	if ( ( style_horizontalAchseFarbe_sollGeaendertWerden == true ) || ( style_horizontalAchseBreite_sollGeaendertWerden == true ) ) {
        var axisr:AxisRenderer = new AxisRenderer();
	        var axisStorke:Stroke = new Stroke();
	        if ( style_horizontalAchseFarbe_sollGeaendertWerden == true ) {
	        	axisStorke.color = datenausgabe.configuration.style.horizontalachse.color;
	        }
	        if ( style_horizontalAchseBreite_sollGeaendertWerden == true ) {
	        	axisStorke.weight = datenausgabe.configuration.style.horizontalachse.weight;
	        }
            axisr.setStyle('axisStroke', axisStorke);
            axisr.setStyle('originStroke', axisStorke);
        axisr.setStyle("canDropLabels", "true");
        			// canDropLabels: alle Daten (jedes Datum) angezeigt werden, oder nur Teile 
        axisr.placement="bottom";
        			// Wo soll die Horizontalachse stehen. Top, Bottom etc.
        axisr.setStyle("tickPlacement", "none");
        			// tickPlacement: Striche der Horizontalachse innen oder außen oder aus (none)
        axisr.axis = hAxisDate;
	 	if ( xAchsenType_art == "date" ) {
			axisr.axis = hAxisDate;
		}
		else {
			axisr.axis = hAxisCategory;
		}
  	}


	/* - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - */
	/* - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - */
	/* - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - LINE - */

	if ( y == "line" ) {
					// Hier wird ein Liniendiagramm mit Werten gefüllt.
		Lchart.dataProvider = datenausgabe.data;
	
	/* -- Horizontalachse -- */
	 	if ( xAchsenType_art == "date" ) {
	 				// Wenn die Horizontalachse vom Type "date" ist, verwendet Lchart die hAxisDate .
			Lchart.horizontalAxis = hAxisDate;
		}

	 	if ( ( xAchsenType_art == "number" ) || ( xAchsenType_art == "text" ) ) {
					// Wenn die Horizontalachse vom Type "number" oder "text" ist, verwendet Lchart die hAxisCategory.
	 		hAxisCategory.dataProvider = datenausgabe.data.series[laengsteSerie].item.x;
			Lchart.horizontalAxis = hAxisCategory;
		}
		if ( ( style_horizontalAchseFarbe_sollGeaendertWerden == true ) || ( style_horizontalAchseBreite_sollGeaendertWerden == true ) ) {
        	Lchart.horizontalAxisRenderers = [axisr];
  		}

		for (var j:Number=0; j<SerienAnzahl; j++) {
					// In dieser Schleife wird jede Serie und deren Achsen einzelln dem Array hinzugefügt.

	/* -- Vertikalachse -- */
			var lSvAxis:LinearAxis = new LinearAxis;
			lSvAxis.labelFunction = FormatDecimal;
			var lSSerienItemLaenge:Number = datenausgabe.data.series[j].item.length();
			var lSmax:Number = 0;
					// Größter Wert der Vertiaklachse
			var lSmin:Number = 0;
					// Kleinster Wert der Vertiaklachse
			var lSHilfsVari:Number = 0;
			for (var n:Number=0; n<lSSerienItemLaenge; n++) {
					// Suchen der größten und kleinsten Werte für die Vertikalachse.
				if ( lSmax <= datenausgabe.data.series[j].item[n].y ) {
					lSmax = datenausgabe.data.series[j].item[n].y;
				}
				if ( lSHilfsVari == 0 ) {
					lSHilfsVari = 1;
					lSmin = datenausgabe.data.series[j].item[n].y;
				}
				else {
					if ( lSmin >= datenausgabe.data.series[j].item[n].y) {
						lSmin = datenausgabe.data.series[j].item[n].y;
					}
				}
			}
			if ( diagrammbeginntBeiNull == true ) {
						// Falls es gewünscht wird, dass das Diagramm immer bei Null beginnen soll, wird dies hier gesetzt. 
				lSmin = 0;
			}
			else {
				if ( lSmin == lSmax ) {
						// Falls der größte Wert gleich dem Kleinsten ist, wird das Diagramm automatisch auf Start 0 gesetzt.
					lSmin = 0;
				}				
			}
			lSvAxis.maximum = lSmax;
			lSvAxis.minimum = lSmin;
			if ( ( achsenName_sollAngezeigtWerden == true ) && ( j == 0 ) ) {
					// Hier die vertikale Achsenüberschrift einmal (!) zugewiesen, wenn sie erwünscht ist. Eventuell auch als heightletter.
				lSvAxis.title = datenausgabe.configuration.axis_name.y;
			}

	/* -- Vertikalachsenstyle -- */
			var lSVAxisRenderer:AxisRenderer = new AxisRenderer();
			lSVAxisRenderer.axis = lSvAxis;

			lSVAxisRenderer.setStyle("verticalAxisTitleAlignment", "vertical");
			if (VertikalStellung == 0) {
					// Vertikalachse links oder rechts setzen.
				lSVAxisRenderer.placement = "left";
				VertikalStellung = 1;
			}
			else {
				lSVAxisRenderer.placement = "right";
				VertikalStellung = 0;
			}
			lSVAxisRenderer.setStyle("labelGap", 1);
					// Abstand zwischen Vertikalachse und deren Beschriftung.
			for (l = 0; l<datenausgabe.configuration.style.series_style.serie.length(); l++) {
				if ( style_serieVertikalAchsenFarbe_sollGeaendertWerden2[l] == SerienName[j] ) {
					var s1:Stroke = new Stroke();
					s1.color = datenausgabe.configuration.style.series_style.serie[l].verticalachse.color;
					lSVAxisRenderer.setStyle("axisStroke", s1);
				}
				if ( style_serieVertikalAchsenSchriftFarbe_sollGeaendertWerden2[l] == SerienName[j] ) {
					lSVAxisRenderer.setStyle("color", datenausgabe.configuration.style.series_style.serie[l].verticalachse.font.fontcolor);
				}
				if ( style_serieVertikalAchsenSchriftGroesse_sollGeaendertWerden2[l] == SerienName[j] ) {
					lSVAxisRenderer.setStyle("fontSize", datenausgabe.configuration.style.series_style.serie[l].verticalachse.font.fontsize);
				}
				if ( style_serieVertikalAchsenSchriftFamilie_sollGeaendertWerden2[l] == SerienName[j] ) {
					lSVAxisRenderer.setStyle("fontFamily", datenausgabe.configuration.style.series_style.serie[l].verticalachse.font.fontfamily);
				}
				if ( style_serieVertikalAchsenSchriftBreite_sollGeaendertWerden2[l] == SerienName[j] ) {
					lSVAxisRenderer.setStyle("fontWeight", datenausgabe.configuration.style.series_style.serie[l].verticalachse.font.fontweight);
				}
			}
			Lchart.verticalAxisRenderers.push(lSVAxisRenderer);

Nächter Post gehts weiter
 
Code:
	/* -- Serienwerte -- */
					// Der aktuellen Serie werden die Werte zugewiesen
			var lS:LineSeries = new LineSeries();
			lS.dataProvider = datenausgabe.data.series[j].item;
			lS.xField = "x";
			lS.yField = "y";
			lS.displayName = SerienName[j];

	/* -- Serienstyle -- */
			lS.interpolateValues = true;
			lS.setStyle("form","segment");
			for (l = 0; l<datenausgabe.configuration.style.series_style.serie.length(); l++) {
				if ( style_serieFarbe_sollGeaendertWerden2[l] == SerienName[j] ) {
					// Mit lineStroke1 ist die Hauptfarbe und die Breite der Kurve angegeben. Die Daten erhält die Vari direkt aus dem XML.
					var lineStroke1:Stroke = new Stroke();
					lineStroke1.color = datenausgabe.configuration.style.series_style.serie.(@name == SerienName[j]).color;
					lS.setStyle("lineStroke",lineStroke1);
				}
			}

	/* -- Hinzufügen der Serie -- */
			lS.verticalAxis = lSvAxis;
			tmp1.push(lS)
			Lchart.series = tmp1;
		}
	}

	.
	.
	.
	// Hier stehen nun die anderen Diagramme
	.
	.
}

Wie kann ich nun also das LineChart so formatieren, dass die Nulllinie auf der selben Ebene (bzw. Höhe) ist, aber die Min- und MaxWerte für jede y-Achse dennoch gleich dem Min- und MaxWerten Serie sind?

Darüberhinaus habe ich noch das eine oder andere Problem:

- Wie kann ich die Schrift der Legende dynamisch ändern? Ich habe es über LegendItem versucht. Habe diesem via .setStyle(...) neue Werte gegeben und mit leg.addChild(legItem); der Legende übergeben wollen. Aber irgendwie geht das nicht o_O.
- Genauso macht mir das Formatieren der Achsenüberschrift (z.B. hAxisDate.title ) sorgen. Bisher weis ich nicht, wie man diese dynamisch ändern kann und habe es über feste Werte in der MXML mit <mx:Style>..CSScode..</mx:Style> gemacht. Aber eigentlich sollte das auch dynmaisch gemacht werden.
- Außerdem funktioniert (wieso auch immer) das Rotieren der y-Achsenbeschriftung nicht und ich weis nicht wieso? Bisher habe ich es immer über mit dem Befehl lSVAxisRenderer.setStyle("rotation", 45); probiert, und es hat nie funktioniert. Kann mir da jemand einen ratschlag geben?


So, dass wars aber fürs erste. Ich würde mich riesig freuen wenn mir jemand ein paar Ratschläge für mein Problem (vorallem mein Hauptprob mit der 0-Linie) geben könnte


Grüße
Nana
 

Neue Beiträge

Zurück