Dies ist eine gute Frage, aber leider gibt es keine einfache Lösung wie die beiden Axes
Sperren oder einen Wert einstellen ..
ist, indem man die entsprechenden Spieler beginnen lassen:
Die Chart
Kontrolle hat eine innere Size
namens ClientSize
, die Chart.Size
minus die Grenzen ist. Beide Größen werden in Pixel gemessen.
Im Inneren kann es einen oder mehrere ChartAreas
geben. Jeder hat eine Position
, die vom Typ ElementPosition
ist.
Innerhalb jedes ChartArea
ist das ein Bereich, der für das tatsächliche Zeichnen der Punkte verwendet wird; es heißt InnerPlotPosition
.
Die InnerPlotPosition Eigenschaft definiert, um das Rechteck innerhalb eines Diagramms Flächenelement, das zum Plotten von Daten verwendet wird; Ausgenommen sind Teilstriche, Achsenbeschriftungen und so weiter. Die für diese Eigenschaft verwendeten Koordinaten (0,0 bis 100,100) beziehen sich auf das ChartArea-Objekt und nicht auf das gesamte Diagramm.
Die InnerPlotPosition-Eigenschaft kann zum Ausrichten mehrerer Diagrammbereiche verwendet werden. Wenn jedoch ein Diagrammbereich über Teilstriche und Achsenbeschriftungen verfügt und nicht über einen anderen verfügt, können ihre Achsenlinien nicht ausgerichtet werden.
- Sowohl
ChartArea.Position
und ChartArea.InnerPlotPosition
enthalten nicht nur die Lage aber auch die Größe der Bereiche; Alle Werte sind in Prozent des äußeren Bereichs, dh ChartArea.InnerPlotPosition
ist relativ zu ChartArea.Position
und ChartArea.Position
ist relativ zu Chart.ClientSize
. Alle Prozentsätze gehen von 0-100
.
So ist die ChartArea
umfasst Labels
und Legends
sowie Axes
und TickMarks
..
Was wir wollen, ist, einen Weg zu finden, den InnerPlotArea
Platz zu machen, dh sie haben die gleiche Breite und Höhe in Pixel . Die Prozentsätze reichen nicht!
Beginnen wir mit ein paar einfachen Berechnungen; wenn diese die Daten sind wir haben ..:
// we'll work with one ChartArea only..:
ChartArea ca = chart1.ChartAreas[0];
ElementPosition cap = ca.Position;
ElementPosition ipp = ca.InnerPlotPosition;
.. dann sind dies die Pixelgrößen der beiden Bereiche:
// chartarea pixel size:
Size CaSize = new Size((int)(cap.Width * chart1.ClientSize.Width/100f),
(int)(cap.Height * chart1.ClientSize.Height/100f));
// InnerPlotArea pixel size:
Size IppSize = new Size((int)(ipp.Width * CaSize.Width/100f),
(int)(ipp.Height * CaSize.Height/100f));
Idealerweise würden wir den InnerPlotArea
gerne Platz sein; Da die kleine Seite nicht sehr gut wachsen kann (sonst würde die Grafik überziehen), müssen wir die größere verkleinern. Also ist die neue Pixelgröße des InnerPlotArea
int ippNewSide = Math.Min(IppSize.Width, IppSize.Height);
Was nun? Da die Chart.Size
gerade eingestellt wurde, wollen wir uns nicht damit anlegen. Wir sollten auch nicht mit Zohan an der ChartArea
: Es muss noch Raum der Legend
etc halten ..
Also haben wir die Größe des InnerPlotArea
ändern ..:
zuerst eine Klassenstufe Variable erstellen, um die ursprünglichen Werte zu speichern, die InnerPlotPosition
:
ElementPosition ipp0 = null;
Wir werden es brauchen, um die ursprünglichen Prozentsatz, dh die Margen zu halten, um sie zu verwenden, wenn die neue Berechnung. Wenn wir das Diagramm anpassen werden die dann aktuellen, bereits geändert/verzerrt worden ..
Dann erstellen wir eine Funktion, um die InnerPlotArea
Platz zu machen, die es auf den Packungen:
void makeSquare(Chart chart)
{
ChartArea ca = chart.ChartAreas[0];
// store the original value:
if (ipp0 == null) ipp0 = ca.InnerPlotPosition;
// get the current chart area :
ElementPosition cap = ca.Position;
// get both area sizes in pixels:
Size CaSize = new Size((int)(cap.Width * chart1.ClientSize.Width/100f),
(int)(cap.Height * chart1.ClientSize.Height/100f));
Size IppSize = new Size((int)(ipp0.Width * CaSize.Width/100f),
(int)(ipp0.Height * CaSize.Height/100f));
// we need to use the smaller side:
int ippNewSide = Math.Min(IppSize.Width, IppSize.Height);
// calculate the scaling factors
float px = ipp0.Width/IppSize.Width * ippNewSide;
float py = ipp0.Height/IppSize.Height * ippNewSide;
// use one or the other:
if (IppSize.Width < IppSize.Height)
ca.InnerPlotPosition = new ElementPosition(ipp0.X, ipp0.Y, ipp0.Width, py);
else
ca.InnerPlotPosition = new ElementPosition(ipp0.X, ipp0.Y, px, ipp0.Height);
}
Sie nennen würde die Funktion nach oder während der Größenänderung.
private void chart1_Resize(object sender, EventArgs e)
{
makeSquare(chart1);
}
Hier kann die Funktion bei der Arbeit ist:
Originalgröße: 
Zwängt ein wenig: 
und machte Platz wieder: 
Hinweis wie das grüne ChartArea
reserviert genug Platz für die Labels
und die Legend
und wie die automatische Skalierung für die Achsen noch funktioniert .. Aber die X-Axis Etiketten passen jetzt nicht in eine Zeile. Beachten Sie auch, dass die ChartArea.BackColor
eigentlich nur die Farbe der InnerPlotArea
ist!
Beachten Sie, dass Sie haben können, die Variable ipp0
zu aktualisieren, um die geänderten Prozentsätze beziehen sich, nachdem sie auf die ChartArea
Layout wie Vergrößern oder Verschieben oder Entfernen von Legends
oder Ändern der Größe oder Winkel von Labels
machen Modifikation etc ..
Of Natürlich können Sie die Funktion ändern, um in einem anderen Verhältnis zu übergeben, anstatt die Fläche ein Quadrat zu halten.
Awesome, vielen Dank! Können Sie den Zweck von 'cip0' erklären? –
Wir werden es brauchen, um die ursprünglichen Prozentsätze, d. H. Die Ränder, zu behalten, um sie bei der Berechnung der neuen zu verwenden. Wenn wir das Diagramm anpassen, werden die aktuellen bereits geändert/verzerrt. – TaW
Ich denke, um meine Frage zu klären, wofür steht es/wie soll es initialisiert werden? Ich sehe, was "ipp0" darstellt und wo es initialisiert werden soll, aber nicht "cip0". –