Nevron Forum

Bar chart with legend combined with axis labels

https://www.nevron.com/Forum/Topic6383.aspx

By Lucy Clarke - Wednesday, May 9, 2012

Hi,

I am trying to repeat an Excel chart option which allows you to display a datatable of the values alongside the legend key under a bar chart. This looks particularly good for clustered charts.

The closest I can get so far with Nevron Chart is to display the label with the values under them by formatting the label. I cannot add the legend key.

I wondered if there is any way to display this chart option in Nevron Chart ?

Thanks

Lucy

 

By Nevron Support - Wednesday, May 9, 2012

Hi Lucy,

There is no build in table scale yet, however it can be emulated to a large degree using a hierarchical scale - the following code shows how to achieve this:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Nevron.GraphicsCore;
using Nevron.Chart;

namespace WindowsFormsApplication1
{
 public partial class Form1 : Form
 {
  public Form1()
  {
   InitializeComponent();
  }

  class NTableLevel
  {
   public NTableLevel(string name, NArgbColor color, List<NHierarchicalScaleNode> nodes)
   {
    m_Name = name;
    m_Color = color;
    m_Nodes = nodes;
   }

   public string m_Name;
   public NArgbColor m_Color;
   public List<NHierarchicalScaleNode> m_Nodes;
  }

  private void Form1_Load(object sender, EventArgs e)
  {
   NChart chart = nChartControl1.Charts[0];

   NBarSeries bar1 = new NBarSeries();
   bar1.MultiBarMode = MultiBarMode.Clustered;
   bar1.DataLabelStyle.Visible = false;

   NBarSeries bar2 = new NBarSeries();
   bar2.MultiBarMode = MultiBarMode.Clustered;
   bar2.DataLabelStyle.Visible = false;

   bar1.Labels.Add("Bar1");
   bar1.Labels.Add("Bar2");
   bar1.Labels.Add("Bar3");

   bar1.Values.Add(10);
   bar1.Values.Add(20);
   bar1.Values.Add(30);

   bar2.Values.Add(20);
   bar2.Values.Add(24);
   bar2.Values.Add(35);

   chart.Series.Add(bar1);
   chart.Series.Add(bar2);

   NStyleSheet.CreatePredefinedStyleSheet(PredefinedStyleSheet.Nevron).Apply(chart);

   NHierarchicalScaleConfigurator hierarchicalScale = new NHierarchicalScaleConfigurator();

   // create a structure that resembles a table
   List<NTableLevel> levels = new List<NTableLevel>();
   List<NHierarchicalScaleNode> levelNodes;
   int maxRowWidth = 0;
   NTableLevel categoryLevel;

   for (int levelIndex = 0; levelIndex < chart.Series.Count; levelIndex++)
   {
    NSeries series = (NSeries)chart.Series[levelIndex];

    // if this is the first series, add the category level to the table
    if (levelIndex == 0)
    {
     List<NHierarchicalScaleNode> categoryLevelNodes = new List<NHierarchicalScaleNode>();
     categoryLevel = new NTableLevel(series.Name, new NArgbColor(255, 255, 255), categoryLevelNodes);

     for (int category = 0; category < series.Labels.Count; category++)
     {
      NHierarchicalScaleNode categoryNode = new NHierarchicalScaleNode(1, ((string)series.Labels[category]).Trim());
      categoryNode.LabelStyle.TextStyle.TextFormat = TextFormat.XML;
      categoryLevelNodes.Add(categoryNode);
     }

     levels.Add(categoryLevel);
    }

    levelNodes = new List<NHierarchicalScaleNode>();
    NTableLevel level = new NTableLevel(series.Name, (NArgbColor)series.FillStyle.GetPrimaryColor(), levelNodes);
    levels.Add(level);

    for (int i = 0; i < series.Values.Count; i++)
    {
     string color = "#" + level.m_Color.R.ToString("X2") + level.m_Color.G.ToString("X2") + level.m_Color.B.ToString("X2");
     string text = "<shape shape='bar' size = '9pt, 9pt' color = '" + color + "' borderwidth = '0pt'/> " + ((double)series.Values[i]).ToString("00.00");

     NHierarchicalScaleNode node = new NHierarchicalScaleNode(1, text);
     node.LabelStyle.TextStyle.TextFormat = TextFormat.XML;

     levelNodes.Add(node);
    }

    maxRowWidth = Math.Max(series.Values.Count, maxRowWidth);
   }

   // then fill that table inside the hierarchical scale
   NHierarchicalScaleNodeCollection parentNodes = hierarchicalScale.Nodes;

   for (int i = 0; i < maxRowWidth; i++)
   {
    for (int levelIndex = levels.Count - 1; levelIndex >= 0; levelIndex--)
    {
     NHierarchicalScaleNode node;
     NTableLevel level = levels[levelIndex];

     if (level.m_Nodes.Count < i)
     {
      node = new NHierarchicalScaleNode(1, string.Empty);
     }
     else
     {
      node = level.m_Nodes[i];
     }

     // link node to parent node
     if (levelIndex == levels.Count - 1)
     {
      hierarchicalScale.Nodes.Add(node);
     }
     else
     {
      levels[levelIndex + 1].m_Nodes[i].ChildNodes.Add(node);
     }
    }
   }

   hierarchicalScale.FirstRowGridStyle = FirstRowGridStyle.Separators;
   hierarchicalScale.CreateSeparatorForEachLevel = true;
   hierarchicalScale.GroupRowGridStyle = GroupRowGridStyle.Grid;

   chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = hierarchicalScale;
  }
 }
}

The general idea of the above code is to first build a table and then export that table to a hierarchical scale. Hope this helps - let us know if you meet any problems.