Conditional FastLine

TeeChart for Microsoft Visual Studio .NET, Xamarin Studio (Android, iOS & Forms) & Monodevelop.
Post Reply
QL_member
Newbie
Newbie
Posts: 8
Joined: Fri Oct 05, 2012 12:00 am

Conditional FastLine

Post by QL_member » Mon Feb 04, 2013 11:08 pm

Hi

Can multiple colors be shown FastLine ?

An example image below .

Image



Please provide .net example how this can be achieved using TeeChart?

Thanks

Andy

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Conditional FastLine

Post by Sandra » Tue Feb 05, 2013 1:21 pm

Hello Andy,

I am afraid it is only possible change segments color of FastLine, so pointer property doesn't exist for FastLine Series. You can change the color segments in same way as next code:

Code: Select all

      List<int> valList;
      List<Color> colorList;
      private void InitializeChart()
      {
        tChart1.Aspect.View3D = false
		tChart1.Header.Visible = true;
        tChart1.Panning.Allow = Steema.TeeChart.ScrollModes.Horizontal;
        FastLine myCustomLine = new FastLine(tChart1.Chart);
        myCustomLine.LinePen.Width = 3;
        myCustomLine.Marks.Visible = true;
        myCustomLine.ColorEach = true;
        valList = new List<int>(new int[] { 81, 81, 81, 13, 13, 13, 13, 53 });
        colorList = new List<Color>(new Color[] { Color.Red, Color.Green, Color.Blue, Color.HotPink, Color.Black, Color.Purple, Color.Magenta, Color.Cyan });
        int index = 0;
          foreach (int val in valList)
          {
		   myCustomLine.Add(index, val, "", colorList[index]);
           index++;
          }

      }
But if you want use pointer, I think a good idea for you use Line Series instead of FastLine that allow you achieve the results as you want. You can do somethin as next next lines of code:

Code: Select all

     List<int> valList;
      List<Color> colorList;
      private void InitializeChart()
      {
          tChart1.Aspect.View3D = false;

          tChart1.Header.Visible = true;
          tChart1.Panning.Allow = Steema.TeeChart.ScrollModes.Horizontal;
          Line myCustomLine = new Line(tChart1.Chart);

          myCustomLine.Pointer.Visible = true;
          myCustomLine.Pointer.Style = Steema.TeeChart.Styles.PointerStyles.DownTriangle;
          myCustomLine.Pointer.Color = Color.Red;
          myCustomLine.Pointer.HorizSize = 4;
          myCustomLine.Pointer.VertSize = 4;
          myCustomLine.Pointer.Visible = true;
          myCustomLine.Pointer.Pen.Visible = false;

          myCustomLine.LinePen.Width = 3;
          myCustomLine.LinePen.Width = 3;

          myCustomLine.Marks.Visible = true;
          myCustomLine.ColorEachLine = true;
          ((Steema.TeeChart.Styles.Line)this.tChart1[0]).Color = Color.Green;
          myCustomLine.GetPointerStyle += new Steema.TeeChart.Styles.CustomPoint.GetPointerStyleEventHandler(myCustomLine_GetPointerStyle);

          valList = new List<int>(new int[] { 81, 81, 81, 13, 13, 13, 13, 53 });
          colorList = new List<Color>(new Color[] { Color.Red, Color.Green, Color.Blue, Color.HotPink, Color.Black, Color.Purple, Color.Magenta, Color.Cyan });
          int index = 0;

          foreach (int val in valList)
          {
              myCustomLine.Add(index, val, "", colorList[index]);
              index++;
          }

      }
      void myCustomLine_GetPointerStyle(Steema.TeeChart.Styles.CustomPoint series, Steema.TeeChart.Styles.GetPointerStyleEventArgs e)
      {// Get the Data Quality lists for this series...
          Line dqSeries = series as Line;

          if (dqSeries != null)
          {
              if (e.ValueIndex != -1)
              {
                  int nextIndex = e.ValueIndex;
                  if (nextIndex < (series.LastVisibleIndex + 1))
                  {
                      e.Color = colorList[nextIndex];
                  }
              }
          }
      }
Could you tell us if previous codes work in your end?

I hope will helps.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

QL_member
Newbie
Newbie
Posts: 8
Joined: Fri Oct 05, 2012 12:00 am

Re: Conditional FastLine

Post by QL_member » Tue Feb 05, 2013 5:48 pm

Hi Sandra

Thanks for quick response. Adding points by using following line;

Code: Select all

  myCustomLine.Add(index, val, "", colorList[index]); 

causes issues with

Code: Select all

 
            myCustomLine.DefaultNullValue = double.NegativeInfinity;
            myCustomLine.TreatNulls = TreatNullsStyle.DoNotPaint;
TreatNulls get ignored

Attaching wpf sample code.

How sample can modified so that pointers are visible for start and end point of segment only ;

Thanks

Andy
Attachments
ConditionalLine.zip
WPF SampleCode
(58.69 KiB) Downloaded 421 times

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Conditional FastLine

Post by Sandra » Wed Feb 06, 2013 1:43 pm

Hello andy,

Thanks for your project. I have made a simple code where only appears the pointer in the start and in the end of segment and I think you can adapt it in your application to work with your values:

Code: Select all

        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            _series1 = new Steema.TeeChart.WPF.Styles.Line(tChart1.Chart);
            Random rnd = new Random();
            for (int i = 0; i < 10; i  )
            {
                if (i < 5)
                {
                    _series1.Add(i, rnd.Next(100), Colors.Red);
                }
                else
                {
                    _series1.Add(i, rnd.Next(100), Colors.Black);
                }
            }
            _series1.Pointer.Visible = true;
            BitmapSource bitmap = tChart1.Chart.Bitmap(tChart1.Width, tChart1.Height);
            _series1.GetPointerStyle  =new CustomPoint.GetPointerStyleEventHandler(series1_GetPointerStyle);

        }
        void series1_GetPointerStyle(CustomPoint series, GetPointerStyleEventArgs e)
        {
            
                if (e.ValueIndex == 0 || e.ValueIndex == 4)
                {
                    e.Color = Colors.Red;
                    series.Pointer.Pen.Color = e.Color;
                    e.Style = PointerStyles.Circle;
                }
                else if (e.ValueIndex == 5 || e.ValueIndex == 9)
                {
                    e.Color = Colors.Black;
                    series.Pointer.Pen.Color = e.Color;
                    e.Style = PointerStyles.Circle;
                }
                else 
                {
                    e.Color = Colors.Transparent;
                    series.Pointer.Pen.Color = e.Color;
                }
        }
Could you tell us if previous code help you to solve your problems? If you have any problems please let me know.

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

QL_member
Newbie
Newbie
Posts: 8
Joined: Fri Oct 05, 2012 12:00 am

Re: Conditional FastLine

Post by QL_member » Wed Feb 06, 2013 2:28 pm

Sandra

I think you forget to address the issue I raised about

Code: Select all

series.TreatNulls = TreatNullsStyle.DoNotPaint;
when we add values to series by

Code: Select all

series.Add(x, y, Colors.Red)
About GetPointerStyle; it would be nice I can get hold of "Value Object" from GetPointerStyleEventArgs not only "ValueIndex".

Thanks

Andy

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Conditional FastLine

Post by Sandra » Thu Feb 07, 2013 2:34 pm

Hello Andy,

Sorry I have forgotten add it. I attach again my simple code:

Code: Select all

        Steema.TeeChart.WPF.Styles.Line _series1;
        private void InitializeChart()
        {
            tChart1.Aspect.View3D = false;
            _series1 = new Steema.TeeChart.WPF.Styles.Line(tChart1.Chart);
            _series1.DefaultNullValue = double.NegativeInfinity;
            _series1.TreatNulls = TreatNullsStyle.DoNotPaint;
            Random rnd = new Random();
            for (int i = 0; i < 10; i++)
            {
                if (i < 5)
                {
                    _series1.Add(i, rnd.Next(100), Colors.Red);
                }
                else
                {
                    _series1.Add(i, rnd.Next(100), Colors.Black);
                }
            }
             _series1.SetNull(7);
            _series1.Pointer.Visible = true;
       
            BitmapSource bitmap = tChart1.Chart.Bitmap(tChart1.Width, tChart1.Height);
            _series1.GetPointerStyle +=new CustomPoint.GetPointerStyleEventHandler(series1_GetPointerStyle);

        }
        void series1_GetPointerStyle(CustomPoint series, GetPointerStyleEventArgs e)
        {
            
                if (e.ValueIndex == 0 || e.ValueIndex == 4)
                {
                    e.Color = Colors.Red;
                    series.Pointer.Pen.Color = e.Color;
                    e.Style = PointerStyles.Circle;
                }
                else if (e.ValueIndex == 5 || e.ValueIndex == 9)
                {
                    e.Color = Colors.Black;
                    series.Pointer.Pen.Color = e.Color;
                    e.Style = PointerStyles.Circle;
                }
                else 
                {
                    e.Color = Colors.Transparent;
                    series.Pointer.Pen.Color = e.Color;
                }
              
        }
Could you please tell us, if it works in your end or you consider there are any problems? If you consider there is problems please let me exactly where are these, because we can try to find a solution for you.
You are About GetPointerStyle; it would be nice I can get hold of "Value Object" from GetPointerStyleEventArgs not only "ValueIndex".
Sorry, but I am not sure which behavior you expect of GetPointerStyle. Could you tell us, how you think GetPointerStyle should be worked?

Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

QL_member
Newbie
Newbie
Posts: 8
Joined: Fri Oct 05, 2012 12:00 am

Re: Conditional FastLine

Post by QL_member » Fri Feb 08, 2013 8:59 pm

Hi Sandra

I modified your example a bit. I added 50000 points; added color to each point based on rule and making some as Null.
Added DownSamplingMethod to reduce points. Observed couple of issues

1) tChart ignored the color i'm specifying in point.
2) tChart ignored points.SetNull
3) Example provided earlier about showing first and last point did not work. Is it issue with DownSamplingMethod ? In GetPointerStyle can we check if point associated with e.ValueIndex is visible ?

Code: Select all

             
         
        private void InitializeChart()
        {
            Line lineSeries;
            Points points;
           
            DownSampling downSampling;

            tChart1.Axes.Bottom.Automatic = true;
            tChart1.Axes.Bottom.Labels.ValueFormat = string.Empty;
            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;
            tChart1.Aspect.ClipPoints = false;
            tChart1.Zoom.Allow = false;
            tChart1.Axes.Left.Automatic = true;

            tChart1.Zoom.Direction = ZoomDirections.Horizontal;

            points = new Points(tChart1.Chart);
            lineSeries = new Line(tChart1.Chart);
            downSampling = new DownSampling(tChart1.Chart);

            points.DefaultNullValue = double.NegativeInfinity;

            
            points.ColorEach = true;
            var rnd = new Random();
           
            for (int index = 0; index < 50000; index++)
            {
                //for 1001 to 1999 make Colors.Transparent
                if (index > 1000 & index < 2000)
                    points.Add(index, rnd.Next(20,30), Colors.Transparent);
                //for 5001 to 19999 make Colors.Black
                else if (index > 5000 & index < 20000)
                    points.Add(index, rnd.Next(10, 20), Colors.Black);
                //for rest make Colors.Red
                else
                    points.Add(index, rnd.Next(30, 40), Colors.Red);

            }
            //mark 1001 to 1999 as null
            for (var i = 0; i < 1000; i++)
            {
                points.SetNull(i+1000);
            }
            lineSeries.Pointer.Visible = true;
            points.Active = false;

            downSampling.DisplayedPointCount = 500;
            downSampling.Method = DownSamplingMethod.MinMaxFirstLastNull;
            lineSeries.TreatNulls = TreatNullsStyle.DoNotPaint;
            lineSeries.LinePen.Width = 2;
            lineSeries.ColorEach = true;
            
            
            lineSeries.DataSource = points;
            lineSeries.Function = downSampling;
            var bitmap = tChart1.Chart.Bitmap(tChart1.Width, tChart1.Height);
            lineSeries.GetPointerStyle += new CustomPoint.GetPointerStyleEventHandler(lineSeries_GetPointerStyle);

            

        }

        void lineSeries_GetPointerStyle(CustomPoint series, GetPointerStyleEventArgs e)
        {
            // how to find first and last valueIndex of visible points
            if (e.ValueIndex == 1001 || e.ValueIndex == 1999)
            {
                e.Color = Colors.Red;
                series.Pointer.Pen.Color = e.Color;
                e.Style = PointerStyles.Circle;
            }
            else if (e.ValueIndex == 5001 || e.ValueIndex == 19999)
            {
                e.Color = Colors.Black;
                series.Pointer.Pen.Color = e.Color;
                e.Style = PointerStyles.Circle;
            }
            else
            {
                e.Color = Colors.Transparent;
                series.Pointer.Pen.Color = e.Color;
            }
        }
Thanks

Andy

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Conditional FastLine

Post by Sandra » Mon Feb 11, 2013 11:50 am

Hello Andy,
If you use DisplayedPointCount property, you need know that it specifies how many points the DownSampling function should paint and displays this number as a maximum number of point, that in your case is 500 points. In this point, I have realized that in GetPointerStyle, you define values aren't in the range of 500 points you have fixed to DisplayedPointCount and for this reason doesn't appears the custom pointers.
If you want achieve pointers appear, you can change the range of DisplayPoitnsCount for a biggest value or change the values where you want appear the custom pointer. I have modified your code keeping the fix value you assign to DisplayedPointCount and I have changed the values of GetPointerStyle because the pointers appear and I think you can do something similar.

Code: Select all

        public MainWindow()
        {
            InitializeComponent();
            InitializeChart();
        }

        private void InitializeChart()
        {
            Steema.TeeChart.WPF.Styles.Line lineSeries;
            Points points;

            Steema.TeeChart.WPF.Functions.DownSampling downSampling;

            tChart1.Axes.Bottom.Automatic = true;
            tChart1.Axes.Bottom.Labels.ValueFormat = string.Empty;
            tChart1.Aspect.View3D = false;
            tChart1.Legend.Visible = false;
            tChart1.Aspect.ClipPoints = false;
            tChart1.Zoom.Allow = false;
            tChart1.Axes.Left.Automatic = true;


             tChart1.Zoom.Direction = Steema.TeeChart.ZoomDirections.Horizontal;

            points = new Points(tChart1.Chart);
            lineSeries = new Steema.TeeChart.WPF.Styles.Line(tChart1.Chart);
            downSampling = new Steema.TeeChart.WPF.Functions.DownSampling(tChart1.Chart);

            points.DefaultNullValue = double.NegativeInfinity;


            points.ColorEach = true;
            var rnd = new Random();

            for (int index = 0; index < 50000; index++)
            {
                //for 1001 to 1999 make Colors.Transparent
                if (index > 1000 & index < 2000)
                    points.Add(index, rnd.Next(20, 30), Colors.Transparent);
                //for 5001 to 19999 make Colors.Black
                else if (index > 5000 & index < 20000)
                    points.Add(index, rnd.Next(10, 20), Colors.Black);
                //for rest make Colors.Red
                else
                    points.Add(index, rnd.Next(30, 40), Colors.Red);

            }
            //  points.Visible = true;
            //mark 1001 to 1999 as null
            for (var i = 0; i < 1000; i++)
            {
                points.SetNull(i + 1000);
            }

            lineSeries.DataSource = points;
            lineSeries.Function = downSampling;
            lineSeries.Pointer.Visible = true;
            points.Active = false;

            downSampling.DisplayedPointCount = 500;
            downSampling.Method = Steema.TeeChart.WPF.Functions.DownSamplingMethod.MinMaxFirstLastNull;
            lineSeries.TreatNulls = TreatNullsStyle.DoNotPaint;
            lineSeries.LinePen.Width = 2;
            lineSeries.ColorEach = true;
            lineSeries.GetPointerStyle += new CustomPoint.GetPointerStyleEventHandler(lineSeries_GetPointerStyle);
            var bitmap = tChart1.Chart.Bitmap(tChart1.Width, tChart1.Height);
        }

        void lineSeries_GetPointerStyle(CustomPoint series, GetPointerStyleEventArgs e)
        {
            // how to find first and last valueIndex of visible points
            if (e.ValueIndex == 101 || e.ValueIndex == 199)
            {
                e.Color = Colors.Red;
                series.Pointer.Pen.Color = e.Color;
                e.Style = PointerStyles.Circle;
                series[e.ValueIndex].Color = e.Color;
            }
            else if (e.ValueIndex == 401 || e.ValueIndex == 499)
            {
                e.Color = Colors.Black;
                series.Pointer.Pen.Color = e.Color;
                e.Style = PointerStyles.Circle;

                series[e.ValueIndex].Color = e.Color;
            }
            else
            {
                e.Color = Colors.Transparent;
                series.Pointer.Pen.Color = e.Color;
            }
        }
In the same way, if you want see the result to apply SetNull points, you need change the range you assign to DisplayPointCount property of DownSampling because the NullPoints aren't considered if you fix the display points to 500.


Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

QL_member
Newbie
Newbie
Posts: 8
Joined: Fri Oct 05, 2012 12:00 am

Re: Conditional FastLine

Post by QL_member » Mon Feb 11, 2013 8:10 pm

Sandra

The example provided; did ignore color specified.

Code: Select all

            for (int index = 0; index < 50000; index++)
            {
                //for 1001 to 1999 make Colors.Transparent
                if (index > 1000 & index < 2000)
                    points.Add(index, rnd.Next(20, 300), Colors.Transparent);
                //for 5001 to 19999 make Colors.Black
                else if (index > 5000 & index < 20000)
                    points.Add(index, rnd.Next(10, 200), Colors.Black);
                //for rest make Colors.Red
                else
                    points.Add(index, rnd.Next(30, 100), Colors.Red);

            }
Original points are 50000. Using DownSampling only 500 points will be shown.
From 50000 points we know location of first and last point for each color.
However when "down sampling" reduces points 50000 to 500; which one is first and last point for each color .



Thanks

Andy

Sandra
Site Admin
Site Admin
Posts: 3132
Joined: Fri Nov 07, 2008 12:00 am

Re: Conditional FastLine

Post by Sandra » Wed Feb 13, 2013 1:08 pm

Hello Andy,

Sorry for the delay. I have made a simple example where I calculate the first and last point in the downsampling and I think can help you to achieve as you want.
WpfApplication2.zip
(31.96 KiB) Downloaded 428 times
Could you tell us if previous project works in your end? If you have any problem please let me know.


Thanks,
Best Regards,
Sandra Pazos / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

QL_member
Newbie
Newbie
Posts: 8
Joined: Fri Oct 05, 2012 12:00 am

Re: Conditional FastLine

Post by QL_member » Mon Feb 18, 2013 4:06 pm

Sandra

The sample you provided works fine.

BTW What is difference between Line and FastLine ?

Thanks

Andy

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Re: Conditional FastLine

Post by Narcís » Tue Feb 19, 2013 6:58 am

Hi Andy,

FastLine is more optimized for performance and real-time purposes. It only plots in 2D mode and has less objects and properties associated, for example: no pointers, no brush, etc.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

Post Reply