سؤال

I am using asp.net to produce a chart which is similar to what's produced by the code below. Notice that each legend entry occupies three lines, but the symbol is vertically aligned centrally, which I think looks unclear:

Chart legend with vertically central alignment

Is it possible to align the symbols vertically so that it sits alongside the first line of text (e.g. the first blue line should sit next to "Some name - 1")? Or, can some kind of separator be configured? Either way I'd prefer to align vertically, but both options together would be excellent.

Full demo code:

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim chart1 As New Chart
    Page.Controls.Add(chart1)
    chart1.ChartAreas.Add(New ChartArea)
    Dim l As New Legend
    chart1.Legends.Add(l)
    Dim dt As New DataTable
    dt.Columns.Add(New DataColumn With {.ColumnName = "ColA", .DataType = GetType(System.String)})
    dt.Columns.Add(New DataColumn With {.ColumnName = "ColB", .DataType = GetType(System.Int32)})
    dt.Columns.Add(New DataColumn With {.ColumnName = "ColC", .DataType = GetType(System.Int32)})
    dt.Columns.Add(New DataColumn With {.ColumnName = "ColD", .DataType = GetType(System.Int32)})
    Dim rnd As New Random
    For i As Integer = 1 To 5
        Dim dr As DataRow = dt.NewRow
        dr.Item("ColA") = String.Format("{0} {1}", "Some name - ", i.ToString)
        dr.Item("ColB") = rnd.Next(0, 100)
        dr.Item("ColC") = rnd.Next(0, 100)
        dr.Item("ColD") = rnd.Next(0, 100)
        dt.Rows.Add(dr)
    Next
    Dim gv As New GridView
    Page.Form.Controls.Add(gv)
    gv.DataSource = dt
    gv.DataBind()
    For Each dr As DataRow In dt.Rows
        Dim s As New Series
        s.Name = dr.Item("ColA").ToString
        s.ChartType = SeriesChartType.Line
        s.LegendText = s.Name & Environment.NewLine & "Line 2" & Environment.NewLine & "Line 3"
        chart1.Series.Add(s)
        For i As Integer = 1 To dt.Columns.Count - 1
            Dim p As New DataPoint
            p.SetValueY(Convert.ToInt32(dr.Item(i)))
            p.AxisLabel = dt.Columns(i).ColumnName
            Trace.Warn(dt.Columns(i).ColumnName & " = " & Convert.ToInt32(dr.Item(i)).ToString)
            s.Points.Add(p)
        Next
    Next
    chart1.DataBind()
End Sub
هل كانت مفيدة؟

المحلول

You can use the Chart.CustomizeLegend event to customize the alignment and separators for the legend items:

Imports System.Drawing

Protected Sub Chart_CustomizeLegend(sender As Object, e As CustomizeLegendEventArgs)
    For Each item As LegendItem In e.LegendItems
        ' Align the series symbol.
        item.Cells(0).Alignment = ContentAlignment.TopCenter

        ' Add a separator.
        item.SeparatorType = LegendSeparatorStyle.Line
        item.SeparatorColor = Color.LightGray
    Next
End Sub

Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    Dim chart1 As New Chart

    ' Bind to the CustomizeLegend event.
    AddHandler chart1.CustomizeLegend, AddressOf Chart_CustomizeLegend

    Page.Controls.Add(chart1)
    chart1.ChartAreas.Add(New ChartArea)
    Dim l As New Legend

    ' ... The rest of your code...
End Sub

نصائح أخرى

Deleted my previous answer, you were obviously right in your comment.

Can I try again? What about this: since the line is placed in the middle of the row, what about three empty lines in the beginning of the legend? This way the line would appear next to "Some name".

s.LegendText = Environment.NewLine & Environment.NewLine & Environment.NewLine & s.Name & Environment.NewLine & "Line 2" & Environment.NewLine & "Line 3"
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top