Пример #1
1
        private void Annotation_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            Chart1.Annotations.Clear();

            AnnotationStyle.Items.Clear();
            AnnotationStyle.Enabled = false;

            AnnotationStyle1.Items.Clear();
            AnnotationStyle1.Enabled = false;
            AnnotationStyle2.Items.Clear();
            AnnotationStyle2.Visible = false;

            if(Annotation.SelectedItem.ToString() == "Line")
            {
                LineAnnotation annotation = new LineAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Height = -25;
                annotation.Width = -25;
                annotation.LineWidth = 2;

                Chart1.Annotations.Add(annotation);

                SetLineControls(true);

            }
            else if(Annotation.SelectedItem.ToString() == "Vertical Line")
            {
                VerticalLineAnnotation annotation = new VerticalLineAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Height = -25;
                annotation.LineWidth = 2;

                Chart1.Annotations.Add(annotation);

                SetLineControls(true);

            }
            else if(Annotation.SelectedItem.ToString() == "Horizontal Line")
            {
                HorizontalLineAnnotation annotation = new HorizontalLineAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Width = -25;
                annotation.LineWidth = 2;

                Chart1.Annotations.Add(annotation);

                SetLineControls(true);
            }
            else if(Annotation.SelectedItem.ToString() == "Polyline")
            {
                PolylineAnnotation annotation = new PolylineAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];

                // explicitly set the relative height and width
                annotation.Height = 50;
                annotation.Width = 30;

                PointF [] points = new PointF[5];
                points[0].X = 0;
                points[0].Y = 0;

                points[1].X = 100;
                points[1].Y = 0;

                points[2].X = 0;
                points[2].Y = 100;

                points[3].X = 100;
                points[3].Y = 100;

                points[4].X = 0;
                points[4].Y = 50;

                annotation.GraphicsPath.AddPolygon(points);

                Chart1.Annotations.Add(annotation);

                SetLineControls(false);
            }
            else if(Annotation.SelectedItem.ToString() == "Text")
            {
                TextAnnotation annotation = new TextAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Text = "I am a TextAnnotation";
                annotation.ForeColor = Color.Black;
                annotation.Font = new Font("Arial", 12);;

                Chart1.Annotations.Add(annotation);
                SetTextControls();

            }
            else if(Annotation.SelectedItem.ToString() == "Rectangle")
            {
                RectangleAnnotation annotation = new RectangleAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Text = "I am a\nRectangleAnnotation";
                annotation.ForeColor = Color.Black;
                annotation.Font = new Font("Arial", 12);;
                annotation.LineWidth = 2;

                Chart1.Annotations.Add(annotation);

                SetTextControls();
                SetColorLineControls();
                AnnotationStyle1.SelectedIndex = 2;
            }
            else if(Annotation.SelectedItem.ToString() == "Ellipse")
            {
                EllipseAnnotation annotation = new EllipseAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Text = "I am an EllipseAnnotation";
                annotation.ForeColor = Color.Black;
                annotation.Font = new Font("Arial", 12);;
                annotation.LineWidth = 2;
                annotation.Height = 35;
                annotation.Width = 60;

                Chart1.Annotations.Add(annotation);

                SetTextControls();
                SetColorLineControls();
                AnnotationStyle1.SelectedIndex = 2;

            }
            else if(Annotation.SelectedItem.ToString() == "Arrow")
            {
                ArrowAnnotation annotation = new ArrowAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Height = -25;
                annotation.Width = -25;
                annotation.LineWidth = 2;

                Chart1.Annotations.Add(annotation);

                SetArrowControls();

            }
            else if(Annotation.SelectedItem.ToString() == "Border3D")
            {
                Border3DAnnotation annotation = new Border3DAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Text = "I am a Border3DAnnotation";
                annotation.ForeColor = Color.Black;
                annotation.Font = new Font("Arial", 12);
                annotation.Height = 40;
                annotation.Width = 50;

                Chart1.Annotations.Add(annotation);

                SetBorder3DControls();

            }
            else if(Annotation.SelectedItem.ToString() == "Callout")
            {
                CalloutAnnotation annotation = new CalloutAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Text = "I am a\nCalloutAnnotation";
                annotation.ForeColor = Color.Black;
                annotation.Font = new Font("Arial", 10);;
                annotation.Height = 35;
                annotation.Width = 50;

                Chart1.Annotations.Add(annotation);

                SetCalloutControls();

            }
            else if(Annotation.SelectedItem.ToString() == "Polygon")
            {
                PolygonAnnotation annotation = new PolygonAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];

                // explicitly set the relative height and width
                annotation.Height = 50;
                annotation.Width = 30;

                annotation.BackColor = Color.FromArgb(128, Color.Orange);

                // define relative value points for a polygon
                PointF [] points = new PointF[5];
                points[0].X = 0;
                points[0].Y = 0;

                points[1].X = 100;
                points[1].Y = 0;

                points[2].X = 100;
                points[2].Y = 100;

                points[3].X = 0;
                points[3].Y = 100;

                points[4].X = 50;
                points[4].Y = 50;

                annotation.GraphicsPath.AddPolygon(points);

                Chart1.Annotations.Add(annotation);

                SetColorControl();
                SetColorLineControls();

            }
            else if(Annotation.SelectedItem.ToString() == "Image")
            {
                if(Chart1.Images.IndexOf("MyBmp") < 0)
                {
                    Bitmap Bmp = new Bitmap(200, 75);
                    Graphics g = Graphics.FromImage(Bmp);
                    g.FillRectangle(new SolidBrush(Color.Transparent), 0, 0, Bmp.Width, Bmp.Height);
                    g.FillRectangle(new SolidBrush(Color.PaleGoldenrod), Bmp.Width/2, 0, Bmp.Width/2, Bmp.Height);
                    g.FillRectangle(new SolidBrush(Color.PaleVioletRed), 0, 0, Bmp.Width/2, Bmp.Height);
                    g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.DarkOrange)), 0, Bmp.Height/2, Bmp.Width, Bmp.Height/2);
                    g.DrawString("I am an ImageAnnotation", new Font("Arial", 12),
                        new SolidBrush(Color.Black),
                        new Rectangle( 0, 0, Bmp.Width, Bmp.Height));

                    g.Dispose();

                    Chart1.Images.Add(new NamedImage("MyBmp", Bmp));
                }

                ImageAnnotation annotation = new ImageAnnotation();
                annotation.AnchorDataPoint = Chart1.Series[0].Points[1];
                annotation.Image = "MyBmp";

                Chart1.Annotations.Add(annotation);
                StyleLabel1.Text = "";
                StyleLabel2.Text = "";
            }
        }
Пример #2
0
        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                chart1.Series[0].Points.AddXY(i, i);
            }
            RectangleAnnotation annotation = new RectangleAnnotation();
            annotation.BackColor = Color.ForestGreen;
            annotation.ToolTip = "rectangle annotation";
            annotation.Width = 2.5;
            annotation.Height = 5;
            annotation.AnchorOffsetY = -(annotation.Height / 2);

            annotation.SetAnchor(chart1.Series[0].Points[5]);
            chart1.Annotations.Add(annotation);
        }
        /// <summary>
        /// Draw a rectangle on chart.
        /// </summary>
        /// <param name="sender">Source Chart.</param>
        /// <param name="x">XAxis value</param>
        /// <param name="y">YAxis value</param>
        /// <param name="width">rectangle width using XAis value.</param>
        /// <param name="height">rectangle height using YAis value.</param>
        /// <param name="lineColor">Outline color.</param>
        /// <param name="name">Annotation name.</param>
        /// <param name="lineWidth">Line width</param>
        /// <param name="lineStyle">Line style</param>
        public static void DrawRectangle(this Chart sender, double x, double y,
            double width, double height,
            Drawing.Color lineColor, string name = "",
            int lineWidth = 1, ChartDashStyle lineStyle = ChartDashStyle.Solid)
        {
            RectangleAnnotation rect = new RectangleAnnotation();
            string chartAreaName = sender.ChartAreas[0].Name;
            rect.ClipToChartArea = chartAreaName;
            rect.AxisXName = chartAreaName + "\\rX";
            rect.YAxisName = chartAreaName + "\\rY";
            rect.BackColor = Drawing.Color.Transparent;
            rect.ForeColor = Drawing.Color.Transparent;
            rect.IsSizeAlwaysRelative = false;

            rect.LineColor = lineColor;
            rect.LineWidth = lineWidth;
            rect.LineDashStyle = lineStyle;

            //Limit rectangle within chart area
            Axis ptrAxis = sender.ChartAreas[0].AxisX;
            if (x < ptrAxis.Minimum)
            {
                width = width - (ptrAxis.Minimum - x);
                x = ptrAxis.Minimum;
            }
            else if (x > ptrAxis.Maximum)
            {
                width = width - (x - ptrAxis.Maximum);
                x = ptrAxis.Maximum;
            }
            if ((x + width) > ptrAxis.Maximum) width = ptrAxis.Maximum - x;

            ptrAxis = sender.ChartAreas[0].AxisY;
            if (y < ptrAxis.Minimum)
            {
                height = height - (ptrAxis.Minimum - y);
                y = ptrAxis.Minimum;
            }
            else if (y > ptrAxis.Maximum)
            {
                height = height - (y - ptrAxis.Maximum);
                y = ptrAxis.Maximum;
            }
            if ((y + height) > ptrAxis.Maximum) height = ptrAxis.Maximum - y;

            rect.X = x;
            rect.Y = y;
            rect.Width = width;
            rect.Height = height;
            rect.LineColor = lineColor;
            sender.Annotations.Add(rect);

            if (!string.IsNullOrEmpty(name)) rect.Name = name;
        }
Пример #4
0
        /// <summary>
        /// Draw a rectangle on chart.
        /// </summary>
        /// <param name="sender">Source Chart.</param>
        /// <param name="x">XAxis value</param>
        /// <param name="y">YAxis value</param>
        /// <param name="width">rectangle width using XAis value.</param>
        /// <param name="height">rectangle height using YAis value.</param>
        /// <param name="lineColor">Outline color.</param>
        /// <param name="name">Annotation name.</param>
        /// <param name="lineWidth">Line width</param>
        /// <param name="lineStyle">Line style</param>
        public static void DrawRectangle(this Chart sender, double x, double y,
                                         double width, double height,
                                         Drawing.Color lineColor, string name = "",
                                         int lineWidth = 1, ChartDashStyle lineStyle = ChartDashStyle.Solid)
        {
            RectangleAnnotation rect = new RectangleAnnotation();
            string chartAreaName     = sender.ChartAreas[0].Name;

            rect.ClipToChartArea      = chartAreaName;
            rect.AxisXName            = chartAreaName + "\\rX";
            rect.YAxisName            = chartAreaName + "\\rY";
            rect.BackColor            = Drawing.Color.Transparent;
            rect.ForeColor            = Drawing.Color.Transparent;
            rect.IsSizeAlwaysRelative = false;

            rect.LineColor     = lineColor;
            rect.LineWidth     = lineWidth;
            rect.LineDashStyle = lineStyle;

            //Limit rectangle within chart area
            Axis ptrAxis = sender.ChartAreas[0].AxisX;

            if (x < ptrAxis.Minimum)
            {
                width = width - (ptrAxis.Minimum - x);
                x     = ptrAxis.Minimum;
            }
            else if (x > ptrAxis.Maximum)
            {
                width = width - (x - ptrAxis.Maximum);
                x     = ptrAxis.Maximum;
            }
            if ((x + width) > ptrAxis.Maximum)
            {
                width = ptrAxis.Maximum - x;
            }

            ptrAxis = sender.ChartAreas[0].AxisY;
            if (y < ptrAxis.Minimum)
            {
                height = height - (ptrAxis.Minimum - y);
                y      = ptrAxis.Minimum;
            }
            else if (y > ptrAxis.Maximum)
            {
                height = height - (y - ptrAxis.Maximum);
                y      = ptrAxis.Maximum;
            }
            if ((y + height) > ptrAxis.Maximum)
            {
                height = ptrAxis.Maximum - y;
            }

            rect.X         = x;
            rect.Y         = y;
            rect.Width     = width;
            rect.Height    = height;
            rect.LineColor = lineColor;
            sender.Annotations.Add(rect);

            if (!string.IsNullOrEmpty(name))
            {
                rect.Name = name;
            }
        }
Пример #5
0
        private void AddRectangleAnnotation()
        {
            // create a rectangle annotation
            RectangleAnnotation annotation = new RectangleAnnotation();

            // setup visual attributes
            annotation.Text = "Attached to\nChart Picture";
            annotation.BackColor = Color.FromArgb(255,255,192);
            annotation.AnchorX = 30;
            annotation.AnchorY = 25;

            // prevent moving or selecting
            annotation.AllowMoving = false;
            annotation.AllowAnchorMoving = false;
            annotation.AllowSelecting = false;

            // add the annotation to the collection
            Chart1.Annotations.Add(annotation);
        }
Пример #6
0
        private void AddThresholdAnnotation(Charting.Chart chart, string name, double threshold,
            System.Drawing.Font font)
        {
            Charting.Axis axisX = chart.ChartAreas[0].AxisX;
            Charting.Axis axisY = chart.ChartAreas[0].AxisY2;

            Charting.StripLine stripLine = new Charting.StripLine ();
            stripLine.StripWidth = 0.0;
            stripLine.Interval = 0;
            stripLine.BorderColor = System.Drawing.Color.Red;
            stripLine.BorderDashStyle = Charting.ChartDashStyle.DashDotDot;
            stripLine.IntervalOffset = threshold * 100.0;
            axisY.StripLines.Add (stripLine);

            Charting.RectangleAnnotation ta = new Charting.RectangleAnnotation ();
            ta.Text = name;
            ta.IsSizeAlwaysRelative = false;
            ta.AxisX = axisX;
            ta.AxisY = axisY;
            ta.AnchorX = axisX.Maximum * (15.0 / 16.0);
            ta.AnchorY = threshold * 100.0;
            ta.Alignment = System.Drawing.ContentAlignment.MiddleCenter;
            ta.AnchorAlignment = System.Drawing.ContentAlignment.MiddleCenter;
            ta.ShadowOffset = 2;
            ta.Font = font;
            chart.Annotations.Add (ta);
        }
Пример #7
0
        /// <summary>
        /// Adds an aspect ratio vertical line annotation.
        /// </summary>
        /// <param name="chart">The <see cref="Charting.Chart "/>.</param>
        /// <param name="name">The annotation text.</param>
        /// <param name="aspectRatio">The aspect ratio.</param>
        /// <param name="font">The font.</param>
        /// <param name="plotThresholds">if set to <c>true</c> plot threshold info.</param>
        /// <param name="isCrossover">if set to <c>true</c> is a crossover annotation.</param>
        private void AddARAnnotation(Charting.Chart chart, string name, double aspectRatio, 
            System.Drawing.Font font,
            bool plotThresholds,
            bool isCrossover = false)
        {
            Charting.StripLine stripLine = new Charting.StripLine();

            stripLine.StripWidth = 0.0;
            stripLine.Interval = 0;
            if (isCrossover)
                {
                stripLine.BorderColor = System.Drawing.Color.Red;
                stripLine.BorderDashStyle = Charting.ChartDashStyle.DashDotDot;
                }
            else
                {
                stripLine.BorderColor = System.Drawing.Color.Black;
                stripLine.BorderDashStyle = Charting.ChartDashStyle.Dash;
                }
            stripLine.IntervalOffset = aspectRatio;

            Charting.Axis axisX = chart.ChartAreas[0].AxisX;
            Charting.Axis axisY = chart.ChartAreas[0].AxisY;
            axisX.StripLines.Add (stripLine);

            double yRange = (axisY.Maximum - axisY.Minimum);

            Charting.RectangleAnnotation ta = new Charting.RectangleAnnotation();
            ta.Text = name;
            ta.IsSizeAlwaysRelative = false;
            ta.AxisX = axisX;
            ta.AxisY = axisY;
            ta.AnchorX = aspectRatio;
            ta.AnchorY = axisY.Minimum + yRange * (15.0/16.0);
            ta.ShadowOffset = 2;
            ta.Font = font;
            if (isCrossover)
                ta.ForeColor = System.Drawing.Color.Red;
            chart.Annotations.Add (ta);
        }
        private void addErrorPoint(SkeletonJoint series, int x, double y, Statistics.MarkerType markerType)
        {
            String seriesName = JointDictionary.GetTranslation(series).name;
            DataPoint newPoint = new DataPoint(x, y);

            if (markerType == Statistics.MarkerType.FalseNegative)
            {
                EllipseAnnotation marker = new EllipseAnnotation();
                marker.AnchorDataPoint = newPoint;
                marker.AnchorAlignment = ContentAlignment.MiddleCenter;
                marker.Width = 0.8;
                marker.Height = 1.6;
                marker.BackColor = markerColorFalsePositive;
                marker.LineColor = Color.Black;
                marker.LineWidth = 1;

                AnnotationSmartLabelStyle markerLocation = new AnnotationSmartLabelStyle();
                markerLocation.IsMarkerOverlappingAllowed = true;
                markerLocation.IsOverlappedHidden = false;
                markerLocation.MaxMovingDistance = 0;
                markerLocation.MinMovingDistance = 0;
                marker.SmartLabelStyle = markerLocation;
                chartErrors.Annotations.Add(marker);
                annotations[series].Add(marker);
            }
            if (markerType == Statistics.MarkerType.FalsePositive)
            {
                RectangleAnnotation marker = new RectangleAnnotation();
                marker.AnchorDataPoint = newPoint;
                marker.AnchorAlignment = ContentAlignment.MiddleCenter;
                marker.Width = 0.8;
                marker.Height = 1.6;
                marker.BackColor = markerColorFalseNegative;
                marker.LineColor = Color.Black;
                marker.LineWidth = 1;

                AnnotationSmartLabelStyle markerLocation = new AnnotationSmartLabelStyle();
                markerLocation.IsMarkerOverlappingAllowed = true;
                markerLocation.IsOverlappedHidden = false;
                markerLocation.MaxMovingDistance = 0;
                markerLocation.MinMovingDistance = 0;
                marker.SmartLabelStyle = markerLocation;
                chartErrors.Annotations.Add(marker);
                annotations[series].Add(marker);
            }
            if (markerType == Statistics.MarkerType.NotAvailable)
            {
                EllipseAnnotation marker = new EllipseAnnotation();
                marker.AnchorDataPoint = newPoint;
                marker.AnchorAlignment = ContentAlignment.MiddleCenter;
                marker.Width = 0.8;
                marker.Height = 1.6;
                marker.BackColor = markerColorNA;
                marker.LineColor = Color.Black;
                marker.LineWidth = 1;

                AnnotationSmartLabelStyle markerLocation = new AnnotationSmartLabelStyle();
                markerLocation.IsMarkerOverlappingAllowed = true;
                markerLocation.IsOverlappedHidden = false;
                markerLocation.MaxMovingDistance = 0;
                markerLocation.MinMovingDistance = 0;
                marker.SmartLabelStyle = markerLocation;
                chartErrors.Annotations.Add(marker);
                annotations[series].Add(marker);
            }
            Series insertionSeries = chartErrors.Series[seriesName];
            int insertion_index = 0;
            for (int index = 0; index < insertionSeries.Points.Count; index++)
            {
                if (insertionSeries.Points[index].XValue > x) break;
                else insertion_index++;
            }

            chartErrors.Series[seriesName].Points.Insert(insertion_index, newPoint);
        }
Пример #9
0
        /// <summary>
        /// Initialises the chart
        /// </summary>
        private void InitChart()
        {
            _mainChartArea.AxisX.ScaleView.Zoomable = true;
            _mainChartArea.AxisY.ScaleView.Zoomable = true;
            _mainChartArea.CursorX.AutoScroll = true;
            _mainChartArea.CursorY.AutoScroll = true;
            //_mainChartArea.AxisY2.Enabled = AxisEnabled.True;

            _priceAnnotation = new RectangleAnnotation();
            _priceAnnotation.ForeColor = Color.Black;
            _priceAnnotation.Font = new Font("Arial", 9); ;
            _priceAnnotation.LineWidth = 1;
            _priceAnnotation.BackColor = Color.LemonChiffon;

            chartCtrl.Annotations.Add(_priceAnnotation);

            _maxPriceAnnotation = new CalloutAnnotation();
            _maxPriceAnnotation.ForeColor = Color.Black;
            _maxPriceAnnotation.Font = new Font("Arial", 9); ;
            _maxPriceAnnotation.LineWidth = 1;
            _maxPriceAnnotation.CalloutStyle = CalloutStyle.SimpleLine;
            _maxPriceAnnotation.AnchorAlignment = ContentAlignment.BottomRight;
            chartCtrl.Annotations.Add(_maxPriceAnnotation);

            _minPriceAnnotation = new CalloutAnnotation();
            _minPriceAnnotation.ForeColor = Color.Black;
            _minPriceAnnotation.Font = new Font("Arial", 9); ;
            _minPriceAnnotation.LineWidth = 1;
            _minPriceAnnotation.CalloutStyle = CalloutStyle.SimpleLine;
            _minPriceAnnotation.AnchorAlignment = ContentAlignment.MiddleRight;
            _minPriceAnnotation.AxisX = _mainChartArea.AxisX;
            _minPriceAnnotation.AxisY = _mainChartArea.AxisY;

            chartCtrl.Annotations.Add(_minPriceAnnotation);

            _currentPriceAnnotation = new ArrowAnnotation();
            _currentPriceAnnotation.ForeColor = Color.Black;
            _currentPriceAnnotation.Font = new Font("Arial", 9);
            _currentPriceAnnotation.LineWidth = 1;
            _currentPriceAnnotation.Width = 1;
            _currentPriceAnnotation.Height = 1;
            _currentPriceAnnotation.ArrowSize = 1;
            _currentPriceAnnotation.AxisX = _mainChartArea.AxisX;
            _currentPriceAnnotation.AxisY = _mainChartArea.AxisY;
            _currentPriceAnnotation.ArrowSize = 3;
            _currentPriceAnnotation.Height = 0;
            _currentPriceAnnotation.AnchorAlignment = ContentAlignment.MiddleLeft;
            //_currentPriceAnnotation.AnchorAlignment = ContentAlignment.MiddleRight;

            chartCtrl.Annotations.Add(_currentPriceAnnotation);

            // _mainChartArea.BackSecondaryColor = _mainChartArea.BackColor = Color.Black;
            chartCtrl.Series[Constants.PriceSerieName]["PriceUpColorUp"] = "Green";
        }
        /// <summary>
        /// Displays the history variation for the current statistics.
        /// </summary>
        /// <param name="history">The views history.</param>
        /// <param name="axisX">The X axis.</param>
        /// <param name="axisY">The Y axis.</param>
        private void DisplayHistoryVariation(AjaxViewsHistory history, string axisX, string axisY)
        {
            if (null == history) return;

            this.chart.Series.Clear();
            this.chart.Annotations.Clear();
            this.listViewDiscovery.Items.Clear();

            // Update the chart.
            Series series = new Series("Video {0}".FormatWith(this.textBox));
            series.ChartType = SeriesChartType.Line;
            series.XValueType = ChartValueType.DateTime;
            series.YValueType = ChartValueType.Int32;
            series.Font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);
            series.MarkerStyle = MarkerStyle.Circle;

            DateTime[] time = new DateTime[history.Series.Length - 1];
            double[] popularity = new double[history.Series.Length - 1];
            for (int index = 1; index < history.Series.Length; index++)
            {
                TimeSpan dx = history.Series[index].Time - history.Series[index - 1].Time;
                time[index - 1] = new DateTime((history.Series[index].Time.Ticks + history.Series[index - 1].Time.Ticks) / 2);
                double dy = history.Series[index].Value - history.Series[index - 1].Value;
                popularity[index - 1] = dy / dx.TotalDays;

                series.Points.AddXY(time[index - 1], popularity[index - 1]);
            }

            this.chart.Series.Add(series);
            this.chart.ChartAreas[0].AxisX.Title = axisX;
            this.chart.ChartAreas[0].AxisY.Title = axisY;

            AjaxHistoryMarker? lastMarker = null;
            RectangleAnnotation lastAnnotation = null;

            // For all markers.
            foreach (AjaxHistoryMarker marker in history.Markers)
            {
                // Get the history point closest to the marker.
                AjaxHistoryPoint? point = history.GetPointAt(marker);

                // If the point does not exist, continue.
                if (null == point) continue;

                // Get index of the point.
                int index = Array.IndexOf<AjaxHistoryPoint>(history.Series, point.Value);

                // If the index is not found, skip the point.
                if (-1 == index) continue;

                // If the index is greater than the number of popularity points, limit the index to the size of the popularity array.
                if (index >= popularity.Length) index = popularity.Length - 1;

                // If the last marker and last annotation exist.
                if ((lastMarker != null) && (lastAnnotation != null))
                {
                    // If the last marker has the same date with the current one, only update the annotation text.
                    if (lastMarker.Value.Time == marker.Time)
                    {
                        lastAnnotation.Text += " " + marker.Name;
                        continue;
                    }
                }

                RectangleAnnotation rect = new RectangleAnnotation();
                rect.Text = marker.Name;
                rect.ForeColor = Color.Black;
                rect.AxisX = this.chart.ChartAreas[0].AxisX;
                rect.AxisY = this.chart.ChartAreas[0].AxisY;
                rect.AnchorX = time[index].ToOADate();
                rect.AnchorY = popularity[index];
                rect.AnchorOffsetX = 0;
                rect.AnchorOffsetY = 5;
                rect.ShadowColor = Color.Gray;
                rect.ShadowOffset = 5;

                VerticalLineAnnotation line = new VerticalLineAnnotation();
                line.AxisX = this.chart.ChartAreas[0].AxisX;
                line.AxisY = this.chart.ChartAreas[0].AxisY;
                line.AnchorX = time[index].ToOADate();
                line.AnchorY = popularity[index];
                line.Height = -5;

                this.chart.Annotations.Add(line);
                this.chart.Annotations.Add(rect);
                this.chart.ResetAutoValues();

                lastAnnotation = rect;
                lastMarker = marker;
            }

            // Add discovery events.
            foreach (KeyValuePair<string, AjaxViewsHistoryDiscoveryEvent> evt in history.DiscoveryEvents)
            {
                ListViewItem item = new ListViewItem(new string[] {
                        evt.Value.Name,
                        evt.Value.Marker != null ? evt.Value.Marker.Value.Time.ToString() : "Unknown",
                        AjaxViewsHistoryDiscoveryEvent.GetTypeDescription(evt.Value.Type),
                        evt.Value.Extra != null ? evt.Value.Extra : string.Empty }, 0);
                item.Tag = evt.Value;

                this.listViewDiscovery.Items.Add(item);
            }
        }
        /// <summary>
        /// Displays the history for the current statistics.
        /// </summary>
        /// <param name="history">The views history.</param>
        /// <param name="axisX">The X axis.</param>
        /// <param name="axisY">The Y axis.</param>
        private void DisplayHistory(AjaxViewsHistory history, string axisX, string axisY)
        {
            if (null == history) return;

            this.chart.Series.Clear();
            this.chart.Annotations.Clear();
            this.listViewDiscovery.Items.Clear();

            // Update the chart.
            Series series = new Series("Video {0}".FormatWith(this.textBox));
            series.ChartType = SeriesChartType.Line;
            series.XValueType = ChartValueType.DateTime;
            series.YValueType = ChartValueType.Int32;
            series.Font = new Font(this.Font.FontFamily, this.Font.Size, this.Font.Style);
            series.MarkerStyle = MarkerStyle.Circle;

            foreach (AjaxHistoryPoint point in history.Series)
                series.Points.AddXY(point.Time, point.Value);

            this.chart.Series.Add(series);
            this.chart.ChartAreas[0].AxisX.Title = axisX;
            this.chart.ChartAreas[0].AxisY.Title = axisY;

            AjaxHistoryMarker? lastMarker = null;
            RectangleAnnotation lastAnnotation = null;

            // For all markers.
            foreach (AjaxHistoryMarker marker in history.Markers)
            {
                // Get the history point closest to the marker.
                AjaxHistoryPoint? point = history.GetPointAt(marker);

                // If the point does not exist, continue.
                if (null == point) continue;

                // If the last marker and last annotation exist.
                if ((lastMarker != null) && (lastAnnotation != null))
                {
                    // If the last marker has the same date with the current one, only update the annotation text.
                    if (lastMarker.Value.Time == marker.Time)
                    {
                        lastAnnotation.Text += " " + marker.Name;
                        continue;
                    }
                }

                RectangleAnnotation rect = new RectangleAnnotation();
                rect.Text = marker.Name;
                rect.ForeColor = Color.Black;
                rect.AxisX = this.chart.ChartAreas[0].AxisX;
                rect.AxisY = this.chart.ChartAreas[0].AxisY;
                rect.AnchorX = marker.Time.ToOADate();
                rect.AnchorY = point.Value.Value;
                rect.AnchorOffsetX = 0;
                rect.AnchorOffsetY = 5;
                rect.ShadowColor = Color.Gray;
                rect.ShadowOffset = 5;

                VerticalLineAnnotation line = new VerticalLineAnnotation();
                line.AxisX = this.chart.ChartAreas[0].AxisX;
                line.AxisY = this.chart.ChartAreas[0].AxisY;
                line.AnchorX = marker.Time.ToOADate();
                line.AnchorY = point.Value.Value;
                line.Height = -5;

                this.chart.Annotations.Add(line);
                this.chart.Annotations.Add(rect);
                this.chart.ResetAutoValues();

                lastAnnotation = rect;
                lastMarker = marker;
            }

            // Add discovery events.
            foreach (KeyValuePair<string, AjaxViewsHistoryDiscoveryEvent> evt in history.DiscoveryEvents)
            {
                ListViewItem item = new ListViewItem(new string[] {
                        evt.Value.Name,
                        evt.Value.Marker != null ? evt.Value.Marker.Value.Time.ToString() : "Unknown",
                        AjaxViewsHistoryDiscoveryEvent.GetTypeDescription(evt.Value.Type),
                        evt.Value.Extra != null ? evt.Value.Extra : string.Empty }, 0);
                item.Tag = evt.Value;

                this.listViewDiscovery.Items.Add(item);
            }
        }