Benutzer mit den meisten Antworten
MS Chart Farbpalette in der LegendCell verwenden

Frage
-
Moin Forum,
ich komme leider mit einem Problem nicht richtig weiter und hoffe auf eure Hilfe. Ich erzeuge dynamisch Serien in meinem Chart. Jetzt will ich eine Legende erstellen in der ich die einzelnen Serien über eine Checkbox ein- und ausblenden kann. Da gibt es ja auch ein schönes Beispiel in den Chart Samples.
Legende soll so aussehen das erst das bmp mit der Checkbox dargestellt wird, dann eine Linie mit der Farbe und der Name der Serie. Jetzt habe ich das Problem das in meiner Legende keine Farben der Serie angezeigt werden. Ich würde die gerne der Palette verwenden, da ja dynamisch x beliebige erzeugt werden können.
Sobald ich isVisibleInLegend auf True setze, tauchen natürlich alle Einträge doppelt in der Legende auf, die einen mit der richtigen Farbzuordnung und die anderen (Cell) ohne Farbe. Setze ich die Farbe manuell über Color funktioniert es, ist aber nicht das was ich will.
Dim LegendItem1 As LegendItem Dim LegendCell1 As LegendCell Dim LegendCell2 As LegendCell Dim LegendCell3 As LegendCell Dim Legend1 As Legend = New Legend ChartK1Logger.Palette = ChartColorPalette.Berry For Each n As clsK1Logger In myclassIC40.Instance.LogData.K1LoggerElements.Values ChartK1Logger.Series.Add(n.Name.ToString) ChartK1Logger.Series(n.Name.ToString).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line ChartK1Logger.Series(n.Name.ToString).IsVisibleInLegend = False LegendItem1 = New LegendItem LegendCell1 = New LegendCell LegendCell1.CellType = System.Windows.Forms.DataVisualization.Charting.LegendCellType.Image LegendCell1.Image = "C:\subversion\Tools\BCSoft4\trunk\IC40\Resources\chk_checked.png" LegendCell2 = New LegendCell LegendCell2.CellType = System.Windows.Forms.DataVisualization.Charting.LegendCellType.SeriesSymbol LegendCell3 = New LegendCell LegendCell3.Text = n.Name.ToString LegendItem1.Cells.Add(LegendCell1) LegendItem1.Cells.Add(LegendCell2) LegendItem1.Cells.Add(LegendCell3) LegendItem1.ImageStyle = System.Windows.Forms.DataVisualization.Charting.LegendImageStyle.Line LegendItem1.Name = n.Name Legend1.CustomItems.Add(LegendItem1) ChartK1Logger.Series(n.Name).ChartArea = "ChartArea1" Next Me.ChartK1Logger.Legends.Add(Legend1)
Vielleicht kann mir ja jemand helfen und mir sagen was ich hier nicht beachte. Vielen Dank schonmal.
Gruß
Michael
- Bearbeitet MiLampe Donnerstag, 6. Juli 2017 08:53
Antworten
-
und so sieht das im Beispiel aus.
Zunächst im Kopf die Farbtabelle anlegen, damit kannst Du auch schön Deine eigene Farben vorgeben:
Dim lstColors As List(Of Color) = New List(Of Color) lstColors.Add(Color.Red) lstColors.Add(Color.Blue) lstColors.Add(Color.Yellow) lstColors.Add(Color.Green) lstColors.Add(Color.Aqua) lstColors.Add(Color.Cyan)
und dann bei der Farbzuweisung:
' die nächste Zeile durch die übernächste ersetzen 'ser.Color = Color.FromArgb(255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)) ser.Color = lstColors(Offset - 1)
Das Ergebnis sieht bei mir dann so aus:
Grüße
Roland
- Bearbeitet Roland Franz Donnerstag, 13. Juli 2017 12:00
- Als Antwort markiert MiLampe Donnerstag, 13. Juli 2017 12:10
Alle Antworten
-
Hallo Michael,
versuche doch einmal vor der Schleife die bereits im Control enthaltenen Legenden zu löschen.
. . . ChartK1Logger.Palette = ChartColorPalette.Berry ChartK1Logger.Legends.Clear() 'Das sind die zwei neuen Zeilen ChartK1Logger.Series.Clear() ' """ For Each n As clsK1Logger In lstseries . . .
Falls das nicht Dein Problem ist, könntest Du mal bitte einen Screenshot von Deiner legende machen?
Grüße
Roland
-
Hallo Roland,
das hat leider nicht funktioniert.
Habe gerade festgestellt, dass ich noch keine Bilder hochladen darf. Ich versuch das dann mal zu beschreiben. Wie lange dauert das denn, bis ich überprüft wurde?
Wenn ich den Code wie oben verwende, habe ich eine Legende mit allen Einträgen (Series). Ein Legendeneintrag besteht aus einem Legenditem mit jeweils 3 Zellen. 1. Bitmap der Checkbox, 2. Farbe der Serie und 3. der Name. Wenn ich forecolor der 2. Zelle auf Rot setze, wird die Linie auch in Rot dargestellt.
ChartK1Logger.Series(n.Name.ToString).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line ChartK1Logger.Series(n.Name.ToString).IsVisibleInLegend = False
Wenn ich IsVisibleInLegend auf True setze, habe ich quasi 2. Legenden. Es wird aber nur eine Legende mit new von mir erzeugt. Alle Einträge sind jetzt doppelt da. Also eine Legende mit allen Serien, so wie ich es haben will, daneben noch eine komplette Legende so wie sie vom Chart erzeugt wird (Darstellung Linie mit der Farbe der Serie und der entsprechende Text. Ich schaffe es nicht das er sich die Farben aus der Palette nimmt.
Vielleicht gibt es ja noch eine einfachere/bessere Möglichkeit, wie man Serien über eine "Checkbox" ein- und abschalten kann.
Bin leider erst am Montag wieder da und kann mich dann erst wieder um meine Legende kümmern.
Schönes Wochenende
Gruß
Michael
- Bearbeitet MiLampe Donnerstag, 6. Juli 2017 14:04
-
Hallo Michael,
es ist in der tat schwierig Custom Items mit normalen Items in der Legende zu mischen. Dabei müsste man ganz geziehlt einzelen Elemente aus der Legende nachträglich etfernen.
Als Alternative könnte ich Dir eine Selektion über separate Checkboxen z.B. in einer GroupBox zeigen.
Das hat zwar den Nachteil, dass die Legende und die Auswahlcheckbox nicht an einer Stelle liegen, dafür ist der Programmcode relativ einfach.
Zunächst würde ich Dir gerne zeigen wie die Oberfläche damit aussieht.
Zunächst mit allen Reihen ausgewählt:
Und hier nur die erste und fünfte Reihe ausgewählt:
Der komplette Programmcode für das Beispiel sieht so aus:
Dim lstseries As List(Of clsK1Logger) = New List(Of clsK1Logger) '***Nur zum Testen eingebaut Dim cht As Chart Dim ser As Series lstseries.Add(New clsK1Logger("Reihe1")) '*** Nur zum Testen eingebaut lstseries.Add(New clsK1Logger("Reihe2")) lstseries.Add(New clsK1Logger("Reihe3")) lstseries.Add(New clsK1Logger("Reihe4")) lstseries.Add(New clsK1Logger("Reihe5")) cht = ChartK1Logger cht.Palette = ChartColorPalette.Berry cht.Series.Clear() Dim Offset As Integer = 1 For Each n As clsK1Logger In lstseries ser = cht.Series.Add(n.Name) '*** an meine testumgebung angepasst ser.ChartType = SeriesChartType.Line ser.IsVisibleInLegend = True ser.ChartArea = "ChartArea1" For index = 1 To 10 '***Nur zum Testen eingebaut ser.Points.AddXY(index, index * index * Offset) '***Eigene Testdaten Next Offset += 1 cb = New CheckBox() '*** ab hier werden dynamisch die cb.Left = 10 '*** Checkboxen aufgebaut cb.Top = (Offset - 1) * 20 cb.Name = n.Name cb.Text = n.Name cb.Checked = True AddHandler cb.CheckedChanged, AddressOf cb_CheckedChanged gbReihen.Controls.Add(cb) Next End Sub Private Sub cb_CheckedChanged(sender As Object, e As EventArgs) Handles cb.CheckedChanged Dim cb As CheckBox cb = sender ChartK1Logger.Series.Item(cb.Name).Enabled = cb.Checked End Sub
Die Checkboxen werde in dem Beispiel ebenfalls dynamisch mit jeder reieh angelegt.
Gegenüber Deinem Beispiel enhält der Code ein paar Zeilen mit dem ich mir Testdaten erzeuge, das musst Du natürlich wieder an Deine Daten anpassen.
Grüße
Roland
- Bearbeitet Roland Franz Freitag, 7. Juli 2017 11:39
- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Dienstag, 11. Juli 2017 07:35
-
Hallo Roland,
Danke für deine Antwort. Diese Version habe ich in der Vergangenheit auch gehabt. Finde es aber so unglücklich, weil unnötig viel Platz verschwendet wird.
So wie in dem Bild (kommt von den Microsoft Chart samples) würde ich es auch gerne machen, nur in dem Beispiel sind die Farben der einzelnen Serien fest definiert. Ich möchte die gerne aus einer Palette verwenden.
Im 2. Bild ist mein derzeitiger Zustand. Die rechte Hälfte der Legende kann ich über VisibleInLegend = False ausblenden. Links ist so wie ich es gerne hätte, nur leider fehlen die Farben der Serie. Ich denke das muß doch irgendwie gehen. Wenn nicht, muß ich wohl den alten Weg über die Checkboxen machen.
- Bearbeitet MiLampe Mittwoch, 12. Juli 2017 07:55
-
-
-
Hier das Beispiel:
Private Sub btnEigeneLegende_Click(sender As Object, e As EventArgs) Handles btnEigene.Click Dim lstseries As List(Of clsK1Logger) = New List(Of clsK1Logger) '***Nur zum Testen eingebaut Dim cht As Chart Dim ser As Series gbLegende.Visible = True lstseries.Add(New clsK1Logger("Reihe1")) '*** Nur zum Testen eingebaut lstseries.Add(New clsK1Logger("Reihe2")) lstseries.Add(New clsK1Logger("Reihe3")) lstseries.Add(New clsK1Logger("Reihe4")) lstseries.Add(New clsK1Logger("Reihe5")) lstseries.Add(New clsK1Logger("Reihe6")) lstseries.Add(New clsK1Logger("Reihe7")) lstseries.Add(New clsK1Logger("Reihe8")) cht = ChartK1Logger cht.Palette = ChartColorPalette.Berry cht.Series.Clear() Dim Offset As Integer = 1 Dim r As New Random Dim intSeriesCount As Integer = lstseries.Count gbLegende.Height = intSeriesCount * 20 + 25 For Each n As clsK1Logger In lstseries ser = cht.Series.Add(n.Name) '*** an meine testumgebung angepasst 'ser.ChartType = SeriesChartType.Line ser.ChartType = SeriesChartType.Spline ser.Color = Color.DarkRed ser.Color = Color.FromArgb(255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)) ser.IsVisibleInLegend = False ser.ChartArea = "ChartArea1" For index = 1 To 10 '***Nur zum Testen eingebaut ser.Points.AddXY(index, index * index * Offset) '***Eigene Testdaten Next Offset += 1 cb = New CheckBox() '*** ab hier werden dynamisch die cb.Left = 10 '*** Checkboxen aufgebaut cb.Top = (Offset - 1) * 20 cb.Name = n.Name cb.Text = "--- " + n.Name cb.ForeColor = ser.Color cb.Checked = True AddHandler cb.CheckedChanged, AddressOf cb_CheckedChanged gbLegende.Controls.Add(cb) Next End Sub Private Sub cb_CheckedChanged(sender As Object, e As EventArgs) Handles cb.CheckedChanged Dim cb As CheckBox cb = sender ChartK1Logger.Series.Item(cb.Name).Enabled = cb.Checked End Sub
Die GroupBox habe ich in die obere rechte Ecke des Fensters geklebt, die lässt sich aber auch in das Diagramm setzten.
Die Anfangsposition musst Du noch an Deine Form anpassen:
Me.gbLegende.Anchor = CType((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles) Me.gbLegende.BackColor = System.Drawing.Color.White Me.gbLegende.FlatStyle = System.Windows.Forms.FlatStyle.Flat Me.gbLegende.Location = New System.Drawing.Point(1073, 0) Me.gbLegende.Name = "gbLegende" Me.gbLegende.Size = New System.Drawing.Size(134, 495) Me.gbLegende.TabIndex = 3 Me.gbLegende.TabStop = False Me.gbLegende.Text = "Legende"
-
und so sieht das im Beispiel aus.
Zunächst im Kopf die Farbtabelle anlegen, damit kannst Du auch schön Deine eigene Farben vorgeben:
Dim lstColors As List(Of Color) = New List(Of Color) lstColors.Add(Color.Red) lstColors.Add(Color.Blue) lstColors.Add(Color.Yellow) lstColors.Add(Color.Green) lstColors.Add(Color.Aqua) lstColors.Add(Color.Cyan)
und dann bei der Farbzuweisung:
' die nächste Zeile durch die übernächste ersetzen 'ser.Color = Color.FromArgb(255, r.Next(0, 256), r.Next(0, 256), r.Next(0, 256)) ser.Color = lstColors(Offset - 1)
Das Ergebnis sieht bei mir dann so aus:
Grüße
Roland
- Bearbeitet Roland Franz Donnerstag, 13. Juli 2017 12:00
- Als Antwort markiert MiLampe Donnerstag, 13. Juli 2017 12:10
-
Fein, so gehts.
Da hast du dir quasi eine Palette selber erstellt. Das sollte ja auch mit meinen customItems in der Legende funktionieren. Einfach die Farbe der Serie und die Legende auf die eigene Farbpalette abstimmen. Probiere ich gleich mal aus.
Ganz lieben Dank für die Lösung und deinen Einsatz.
Gruß
Michael