Click here to Skip to main content
15,896,063 members
Articles / Programming Languages / C#

Reconstruction of Charts from Images

Rate me:
Please Sign up or sign in to vote.
4.92/5 (13 votes)
18 Mar 2010CPOL7 min read 38K   4.1K   42  
Usage of universal framework for chart reconstruction
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.Serialization;

namespace Chart
{
    /// <summary>
    /// Performer of dictionary operations
    /// </summary>
    [Serializable()]
    public class DictionaryPerformer : ISerializable
    {
        #region Fields

        Action<IDictionary<string, object>> add;

 
        Dictionary<string, PenValue> pens = new Dictionary<string, PenValue>();

        Dictionary<string, PenSave> save = new Dictionary<string, PenSave>();


        int bufferSize = 50;

        private Bitmap bmp;

        private Bitmap bmpOld;


        private Bitmap bmpNew;

        private Dictionary<string, Func<object, double>> converters = new Dictionary<string, Func<object, double>>();

        private Brush fonBrush = new SolidBrush(Color.Black);


        double invertedHeight;

        Rectangle oldRect;

        Rectangle newRect;

        Rectangle dRect;

        Control contol;

        private int wNew = 0;

        private List<string> exists = new List<string>();

        #endregion

        #region Ctor

        /// <summary>
        /// Default constructor
        /// </summary>
        public DictionaryPerformer()
        {
            init();
        }



        /// <summary>
        /// Deserialization constructor
        /// </summary>
        /// <param name="info">Serialization info</param>
        /// <param name="context">Streaming context</param>
        protected DictionaryPerformer(SerializationInfo info, StreamingContext context) 
        {
            save = SerializationPerformer.GetObject<Dictionary<string, PenSave>>(info, "Pens");
            foreach (string s in save.Keys)
            {
                PenSave ps = save[s];
                PenValue pv = Transform(ps);
                pens[s] = pv;
            }
            init();
        }


        #endregion

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {

            SerializationPerformer.Serialize(save, info, "Pens");
        }

        #endregion

        #region Members

        /// <summary>
        /// Names of existed series
        /// </summary>
        public ICollection<string> Exists
        {
            get
            {
                List<string> ex = new List<string>(save.Keys);
                foreach (string s in ex)
                {
                    if (!exists.Contains(s))
                    {
                        save.Remove(s);
                        pens.Remove(s);
                    }
                }
                return exists;
            }
        }

        /// <summary>
        /// Removes series
        /// </summary>
        /// <param name="s">Series name</param>
        public void Remove(string s)
        {
            save.Remove(s);
        }

        /// <summary>
        /// Gets pen for series
        /// </summary>
        /// <param name="s">Series name</param>
        /// <returns>The pen</returns>
        public Pen GetPen(string s)
        {
            if (!save.ContainsKey(s))
            {
                return null;
            }
            return new Pen(save[s].color);
        }

        /// <summary>
        /// Gets minimal value for series
        /// </summary>
        /// <param name="s">Series name</param>
        /// <returns>Minimal value</returns>
        public double GetMin(string s)
        {
            if (!save.ContainsKey(s))
            {
                return 0;
            }
            return save[s].min;
        }

        /// <summary>
        /// Gets maximal value for series
        /// </summary>
        /// <param name="s">Series name</param>
        /// <returns>Maximal value</returns>
        public double GetMax(string s)
        {
            if (!save.ContainsKey(s))
            {
                return 1;
            }
            return save[s].max;
        }

        /// <summary>
        /// Sets series to active
        /// </summary>
        /// <param name="s">Series name</param>
        /// <param name="active">True if active and facle otherwise</param>
        public void SetAcive(string s, bool active)
        {
            if (active & save.ContainsKey(s))
            {
                return;
            }
            if (!active & !save.ContainsKey(s))
            {
                return;
            }
            if (!active)
            {
                save.Remove(s);
                pens.Remove(s);
                return;
            }
            PenSave ps = new PenSave();
            ps.color = Color.White;
            PenValue pv = Transform(ps);
            save[s] = ps;
            pens[s] = pv;
        }

        /// <summary>
        /// Sets pen to series
        /// </summary>
        /// <param name="s">Series name</param>
        /// <param name="pen">Pen</param>
        public void SetPen(string s, Pen pen)
        {
            if (!save.ContainsKey(s))
            {
                return;
            }
            save[s].color = pen.Color;
            pens[s].pen = pen;
        }

        /// <summary>
        /// Active seies names
        /// </summary>
        public ICollection<string> Active
        {
            get
            {
                return save.Keys;
            }
        }

        /// <summary>
        /// Resets itself
        /// </summary>
        public void Reset()
        {
            add = AddNew;
        }

        /// <summary>
        /// Sets scale
        /// </summary>
        /// <param name="s">Series name</param>
        /// <param name="min">Minimal value</param>
        /// <param name="max">Maximal value</param>
        public void SetScale(string s, double min, double max)
        {
            if (!save.ContainsKey(s))
            {
                return;
            }
            lock (this)
            {
                PenSave ps = save[s];
                ps.min = min;
                ps.max = max;
                pens[s] = Transform(ps);
                init();
            }
        }

        /// <summary>
        /// Control for paint
        /// </summary>
        public Control Control
        {
            set
            {
                contol = value;
                CreateBitmaps(value);
                value.Resize += Resize;
                value.Paint += Paint;
            }
        }
        /// <summary>
        /// Writes dictionary
        /// </summary>
        /// <param name="d">The dictionary to write</param>
        public void Write(IDictionary<string, object> d)
        {
            add(d);
        }

        /// <summary>
        /// Access to function by name
        /// </summary>
        /// <param name="name">Function name</param>
        /// <returns>The function</returns>
        public Func<object, double> this[string name]
        {
            set
            {
                converters[name] = value;
            }
        }

        /// <summary>
        /// Crates bitmaps
        /// </summary>
        /// <param name="width">Width of bitmaps</param>
        /// <param name="height">Height of bitmaps</param>
        void CreateBitmaps(int width, int height)
        {
            invertedHeight = ((double)height);
            double x = (double)width / 3;
            if (x < 50)
            {
                bufferSize = 50;
            }
            else
            {
                bufferSize = (int)x;
            }
            bmp = new Bitmap(width, height);
            Clear(bmp);
            double res = (double)width / (double)bufferSize;
            wNew = (int)res;
            if (wNew < 1)
            {
                wNew = 1;
            }
            bmpNew = new Bitmap(wNew, height);
            Clear(bmpNew);
            bmpOld = new Bitmap(width - wNew, height);
            Clear(bmpOld);
            oldRect.Height = height;
            oldRect.X = 0;
            oldRect.Y = 0;
            oldRect.Width = width - wNew;
            newRect.Height = height;
            newRect.X = oldRect.Width;
            newRect.Y = 0;
            newRect.Width = wNew;
            dRect.X = 0;
            dRect.Y = 0;
            dRect.Width = oldRect.Width;
            dRect.Height = height;
        }

        /// <summary>
        /// Creates bitmap for control
        /// </summary>
        /// <param name="control">The control</param>
        void CreateBitmaps(Control control)
        {
            CreateBitmaps(contol.Width, contol.Height);
        }

        void CopyBmp(Graphics g)
        {
            g.DrawImage(bmpOld, oldRect, 0, 0, bmpOld.Width, bmpOld.Height, GraphicsUnit.Pixel);
            g.DrawImage(bmpNew, newRect, 0, 0, bmpNew.Width, bmpNew.Height, GraphicsUnit.Pixel);
        }

        void DrawFullBmp()
        {
            Graphics go = Graphics.FromImage(bmpOld);
            go.DrawImage(bmp, dRect, wNew, 0, bmpOld.Width, bmpOld.Height, GraphicsUnit.Pixel);
            Graphics g = Graphics.FromImage(bmp);
            CopyBmp(g);
        }

        void Paint(object sender, PaintEventArgs arg)
        {
            arg.Graphics.DrawImage(bmp, 0, 0);
        }

        void Resize(object s, EventArgs arg)
        {
            CreateBitmaps(contol);
        }


        void SaveOld()
        {
            Graphics g = Graphics.FromImage(bmpOld);
            g.DrawImage(bmp, 0, 0);
        }

        void Clear(Graphics g, int w, int h)
        {
            g.FillRectangle(fonBrush, 0, 0, w, h);
        }

        void Clear(Bitmap bmp)
        {
            Graphics g = Graphics.FromImage(bmp);
            Clear(g, bmp.Width, bmp.Height);
        }

        void AddExist(IDictionary<string, object> d)
        {
            Graphics g = Graphics.FromImage(bmpNew);
            Clear(g, bmpNew.Width, bmpNew.Height);
            foreach (string s in pens.Keys)
            {
                PenValue pv = pens[s];
                if (pv.pen == null)
                {
                    continue;
                }
                int x1 = pv.x;
                if (!converters.ContainsKey(s))
                {
                    continue;
                }
                Func<object, double> conv = converters[s];
                int y = Get(pv, conv(d[s]));
                g.DrawLine(pv.pen, 0, x1, wNew, y);
            }
            DrawControl();
        }

        void DrawControl()
        {
            Graphics g = Graphics.FromHwnd(contol.Handle);
            DrawFullBmp();
            g.DrawImage(bmp, 0, 0);
        }

        void AddNew(IDictionary<string, object> d)
        {
            exists.Clear();
            List<string> l = new List<string>(pens.Keys);
            foreach (string s in l)
            {
                if (!d.ContainsKey(s))
                {
                    pens.Remove(s);
                }
            }
            foreach (string s in d.Keys)
            {
                exists.Add(s);
                if (!pens.ContainsKey(s))
                {
                    continue;
                }
                PenValue pv = pens[s];
                object o = d[s];
                if (!converters.ContainsKey(s))
                {
                    converters[s] = ToDoubleDefault;
                }
                Func<object, double> conv = converters[s];
                Get(pv, conv(o));
            }
            add = AddExist;
        }



 /*       double Get(object o)
        {
            Type t = o.GetType();
            double a = 0;
            if (t.Name.Contains("Int16"))
            {
                short k = (short)o;
                a = (double)k;
            }
            else
            {
                a = (double)o;
            }
            return a;
        }
  */

        int Get(PenValue pv, double d)
        {
            double x = (pv.max - d) * pv.scale * invertedHeight;
            int y = (int)x;
            pv.x = y;
            return y;
        }

        PenValue Transform(PenSave ps)
        {
            PenValue pv = new PenValue();
            pv.pen = new Pen(ps.color);
            pv.min = ps.min;
            pv.max = ps.max;
            pv.scale = 1 / (ps.max - ps.min);
            return pv;
        }


        void Add(string s, PenSave ps)
        {
            PenValue pv = Transform(ps);
            save[s] = ps;
            pens[s] = pv;
        }

 

        void init()
        {
            add = AddNew;
        }

        /// <summary>
        /// Converts object to double
        /// </summary>
        /// <param name="o">Conversion to double</param>
        /// <returns>Result of conversion</returns>
        public static double ToDoubleDefault(object o)
        {
            System.Type t = o.GetType();
            if (t.Equals(typeof(sbyte)))
            {
                sbyte sb = (sbyte)o;
                return (double)sb;
            }
            if (t.Equals(typeof(byte)))
            {
                byte b = (byte)o;
                return (double)b;
            }
            if (t.Equals(typeof(short)))
            {
                short s = (short)o;
                return (double)s;
            }
            if (t.Equals(typeof(ushort)))
            {
                ushort us = (ushort)o;
                return (double)us;
            }
            if (t.Equals(typeof(int)))
            {
                int i = (int)o;
                return (double)i;
            }
            if (t.Equals(typeof(uint)))
            {
                uint ui = (uint)o;
                return (double)ui;
            }
            if (t.Equals(typeof(long)))
            {
                long l = (long)o;
                return (double)l;
            }
            if (t.Equals(typeof(ulong)))
            {
                ulong ul = (ulong)o;
                return (double)ul;
            }
            if (t.Equals(typeof(float)))
            {
                float ul = (float)o;
                return (float)ul;
            }
            return (double)o;
        }


 
      //  public void Perform(Dictionary<string, object>

        #endregion

        #region The Pen - value class
        class PenValue
        {
            internal Pen pen;
            internal double min;
            internal double max;
            internal double scale;
            internal int x;
        }

        #endregion

    }

    /// <summary>
    /// Saved pens
    /// </summary>
    [Serializable()]
    public class PenSave : ISerializable
    {
        internal Color color;
        internal double min;
        internal double max;


        #region Ctor

        internal PenSave()
        {
            color = Color.White;
            min = 0;
            max = 1;
        }

        /// <summary>
        /// Deserialization constructor
        /// </summary>
        /// <param name="info">Serialization info</param>
        /// <param name="context">Streaming context</param>
        protected PenSave(SerializationInfo info, StreamingContext context)
        {
            color = (Color)info.GetValue("Color", typeof(Color));
            min = (double)info.GetValue("Min", typeof(double));
            max = (double)info.GetValue("Max", typeof(double));
        }

        #endregion

        #region ISerializable Members

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Color", color, typeof(Color));
            info.AddValue("Min", min, typeof(double));
            info.AddValue("Max", max, typeof(double));
        }

        #endregion
    }

   // delegate void Paint(Graphics g);

   // delegate void Add(IDictionary<string, object> d);

   // public delegate double ToDouble(object o);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Russian Federation Russian Federation
Ph. D. Petr Ivankov worked as scientific researcher at Russian Mission Control Centre since 1978 up to 2000. Now he is engaged by Aviation training simulators http://dinamika-avia.com/ . His additional interests are:

1) Noncommutative geometry

http://front.math.ucdavis.edu/author/P.Ivankov

2) Literary work (Russian only)

http://zhurnal.lib.ru/editors/3/3d_m/

3) Scientific articles
http://arxiv.org/find/all/1/au:+Ivankov_Petr/0/1/0/all/0/1

Comments and Discussions