Profile Picture

Restricting maximum marker size

Posted By Kevin Harrison 11 Years Ago
Author
Message
Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

I am currently setting my series markers as 1.5% proportional, but this means they get very large when the chart is large. Is there a simple way to set them 1.5% proportional up to a maximum pixel size?

Thanks

Kevin



Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 1 days ago @ 1:54 AM
Posts: 3,054, Visits: 4,009
Hi Kevin,

There is no build in property that controls the maximum calculated marker size (however we'll add one in the next SP). For the time being you can use the following workaround:

1. Attach to the chart pre-paint callback.
2. Calculate a marker size based on the current chart plot area.
3. Set that marker size to the series
4. Recalculate the chart again.

The following code shows how to achieve this:

      class NPaintCallback : INPaintCallback
      {
         public NPaintCallback(NChartControl chartControl)
         {
            m_ChartControl = chartControl;
         }

         #region INPaintCallback Members

         void INPaintCallback.OnAfterPaint(NPanel panel, NPanelPaintEventArgs eventArgs)
         {
               
         }

         void INPaintCallback.OnBeforePaint(NPanel panel, NPanelPaintEventArgs eventArgs)
         {
            NChart chart = (NChart)panel;
            NLineSeries line = chart.Series[0] as NLineSeries;

            // compute a new marker size
            float side = Math.Min(chart.PlotArea.Width, chart.PlotArea.Height);
            float maxMarkerSize = 30;

            line.MarkerStyle.Width = new NLength(Math.Min(maxMarkerSize, side * 0.1f), NGraphicsUnit.Pixel);
            line.MarkerStyle.Height = new NLength(Math.Min(maxMarkerSize, side * 0.1f), NGraphicsUnit.Pixel);

            // Recalculate the control
            m_ChartControl.Document.Calculate();
            m_ChartControl.RecalcLayout();
         }

         #endregion

         NChartControl m_ChartControl;
      }

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

         NLineSeries line = new NLineSeries();

         line.MarkerStyle.Width = new NLength(0, NGraphicsUnit.Pixel);
         line.MarkerStyle.Height = new NLength(0, NGraphicsUnit.Pixel);
         line.MarkerStyle.Visible = true;
         line.DataLabelStyle.Visible = false;

         line.Values.Add(10);
         line.Values.Add(20);
         line.Values.Add(30);
         line.InflateMargins = false;

         chart.Series.Add(line);

         chart.PaintCallback = new NPaintCallback(nChartControl1);
      }

Hope this helps - let us know if you meet any problems.

Best Regards,
Nevron Support Team



Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

Thanks for the quick reply and the useful code, an additon to the next SP would be very welcome.

Kevin



Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

Has the new property been added to the just released SP?

Thanks

Kevin



Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 1 days ago @ 1:54 AM
Posts: 3,054, Visits: 4,009
Hi Kevin,

Yes - you can access those settings from the MaxWidth, MaxHeight and MaxDepth properties of the marker style.

Best Regards,
Nevron Support Team



Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

I can confirm this works well for line series, thanks.

What about point series though? I've always been slightly confused by these anyway. They have a MarkerStyle, but the point symbols are determined by the PointShape and the size by Size.

Thanks

Kevin



Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

Because I need to limit the size of both line and point series, sometimes on the same chart, I have resorted to using the PaintCallback method you described earlier. I am attempting to calculate the change point when the % setting should switch over to the fixed pixel size (and vice versa), but I am getting a jump in size at the crossover point. My code is below.

There are several things I am not sure about.

1) I tried using chart panel Width / Height, but the numbers were very small and I do not know how to convert them to pixels.
Instead, I used the size of the chart control. Am I converting the chart control size to pixels correctly? This is not the same as the chart panel size, but, even with no legend, there is still a size discontinuity.
2) When I use ParentPercentage in setting the MarkerSize of a series, what exactly is the Parent?
3) Ideally I would read the size of the marker directly in pixels - can I do this?

Any other help would be most welcome.

     public void OnBeforePaint(NPanel panel, NPanelPaintEventArgs eventArgs)
        {
            NChart chart = (NChart)panel;
            double chartSize = Math.Min(this.chartControl.Width, this.chartControl.Height);

            bool seriesFound = false;
            bool requiresRecalculate = false;
            NLength requiredMarkerSize = NLength.Empty;

            foreach (NSeries series in chart.Series)
            {
                NPointSeries pointSeries = series as NPointSeries;
                NLineSeries lineSeries = series as NLineSeries;
                if (pointSeries != null || lineSeries != null)
                {
                    // Determine if size needs changing for the first series only.
                    if (!seriesFound)
                    {
                        // Set flag so this calculation is only executed once
                        seriesFound = true;

                        // Have to convert the returned chartSize to pixels to compare with the maximum pixel size 
                        NMeasurementUnitConverter converter = new NMeasurementUnitConverter(eventArgs.Graphics.DpiX, eventArgs.Graphics.DpiY);
                        float pixelsPerPointUnit = converter.ConvertX(NGraphicsUnit.Point, NGraphicsUnit.Pixel, 1);

                        // Determine if the point size should be changed
                        bool overMaximum = (chartSize * pixelsPerPointUnit * this.DefaultPercentagePointSize / 100.0) > (double)this.MaximumPointSize;
                        NLength markerSize = pointSeries != null ? pointSeries.Size : lineSeries.MarkerStyle.Width;
                        requiresRecalculate = overMaximum ? markerSize.MeasurementUnit == NRelativeUnit.ParentPercentage : markerSize.MeasurementUnit == NGraphicsUnit.Pixel;
                        requiredMarkerSize = overMaximum ? new NLength((float)this.MaximumPointSize, NGraphicsUnit.Pixel) : new NLength((float)this.DefaultPercentagePointSize, NRelativeUnit.ParentPercentage);
                    }

                    // Reset the point size if required
                    if (requiresRecalculate)
                    {
                        if (pointSeries != null)
                            pointSeries.Size = requiredMarkerSize;
                        else
                        {
                            lineSeries.MarkerStyle.Width = requiredMarkerSize;
                            lineSeries.MarkerStyle.Height = requiredMarkerSize;
                        }
                    }
                }
            }

            // Recalculate the layout only if necessary
            if (requiresRecalculate)
            {
                this.chartControl.Document.Calculate();
                this.chartControl.RecalcLayout();
            }
        }

 



Nevron Support
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)Supreme Being (4,435 reputation)

Group: Forum Members
Last Active: 1 days ago @ 1:54 AM
Posts: 3,054, Visits: 4,009
Hi Kevin,

Probably the best way to do it is to use a points series with markers and hide the points.

Regarding your questions:

1) I tried using chart panel Width / Height, but the numbers were very small and I do not know how to convert them to pixels. Instead, I used the size of the chart control. Am I converting the chart control size to pixels correctly? This is not the same as the chart panel size, but, even with no legend, there is still a size discontinuity.

You need to access the chart panel Bounds (Width / Height are used to specify an aspect of the chart).

2) When I use ParentPercentage in setting the MarkerSize of a series, what exactly is the Parent?

It is generally the a size relative to the parent panel bounds Width or Height, but with some exceptions:
1. When the length is used for X coordinates - it is percentage of the Width.
2. When the length is used for Y coordinates - it is percentage of the Height.
3. When the length is used for both X and Y coordinates - it is calculated as (Width + Height) * Percentage / 200.0;

3) Ideally I would read the size of the marker directly in pixels - can I do this?
No, however the code below shows how to calculate this correctly.

We tested with the following code:

using System;
using System.Windows.Forms;
using Nevron.Chart;
using Nevron.Chart.WinForm;
using Nevron.GraphicsCore;

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

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

         chart.BoundsMode = BoundsMode.Fit;

         NPointSeries point = new NPointSeries();

         point.UseXValues = true;
         point.DataLabelStyle.Visible = false;
         point.MarkerStyle.Visible = false;

         Random rand = new Random();

         for (int i = 0; i < 10; i++)
         {
            double yValue = rand.Next(100);
            double xValue = rand.Next(100);

            point.XValues.Add(xValue);
            point.Values.Add(yValue);
         }

         chart.Series.Add(point);
         chart.PaintCallback = new NPaintCallback(nChartControl1);
      }

      internal class NPaintCallback : INPaintCallback
      {
         public NPaintCallback(NChartControl chartControl)
         {
            m_ChartControl = chartControl;
         }
         NChartControl m_ChartControl;
         float DefaultPercentagePointSize = 10;
         float MaximumPointSize = 10;

         #region INPaintCallback Members

         public void OnAfterPaint(NPanel panel, NPanelPaintEventArgs eventArgs)
         {
            
         }

         public void OnBeforePaint(NPanel panel, NPanelPaintEventArgs eventArgs)
         {
            NChart chart = (NChart)panel;
            bool seriesFound = false;
            bool requiresRecalculate = false;
            NLength requiredMarkerSize = NLength.Empty;

            foreach (NSeries series in chart.Series)
            {
               NPointSeries pointSeries = series as NPointSeries;
               NLineSeries lineSeries = series as NLineSeries;

               if (pointSeries != null || lineSeries != null)
               {
                  // Determine if size needs changing for the first series only.
                  if (!seriesFound)
                  {
                     // Set flag so this calculation is only executed once
                     seriesFound = true;

                     // Determine if the point size should be changed
                     bool overMaximum = ((chart.Bounds.Width + chart.Bounds.Height) * this.DefaultPercentagePointSize / 200.0) > (double)this.MaximumPointSize;
                     NLength markerSize = pointSeries != null ? pointSeries.Size : lineSeries.MarkerStyle.Width;

                     requiresRecalculate = overMaximum ? markerSize.MeasurementUnit == NRelativeUnit.ParentPercentage : markerSize.MeasurementUnit == NGraphicsUnit.Pixel;
                     requiredMarkerSize = overMaximum ? new NLength((float)this.MaximumPointSize, NGraphicsUnit.Pixel) : new NLength((float)this.DefaultPercentagePointSize, NRelativeUnit.ParentPercentage);
                  }

                  // Reset the point size if required
                  if (requiresRecalculate)
                  {
                     if (pointSeries != null)
                        pointSeries.Size = requiredMarkerSize;
                     else
                     {
                        lineSeries.MarkerStyle.Width = requiredMarkerSize;
                        lineSeries.MarkerStyle.Height = requiredMarkerSize;
                     }
                  }
               }
            }

            // Recalculate the layout only if necessary
            if (requiresRecalculate)
            {
               this.m_ChartControl.Document.Calculate();
               this.m_ChartControl.RecalcLayout();
            }
         }

         #endregion
      }

      private void button1_Click(object sender, EventArgs e)
      {
         nChartControl1.ShowEditor();
      }
   }
}

Let us know if you meet any problems.

Best Regards,
Nevron Support Team



Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

Thaks for the speedy response, but there is still a size discontinuity.

Would it be possible to add a maximum size for point series in the next release? Then I can remove all this code (assuming point and line series behave identically)

Thanks

Kevin



Kevin Harrison
Posted 11 Years Ago
View Quick Profile
Supreme Being

Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)Supreme Being (79 reputation)

Group: Forum Members
Last Active: 3 Years Ago
Posts: 176, Visits: 1,865

Can someone reply please?

Thanks

Kevin





Similar Topics


Reading This Topic