첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

TestProject.zip
0.01MB

▶ MainForm.cs

using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

using ScottPlot;
using ScottPlot.Plottable;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 차트 1 십자선
        /// </summary>
        private Crosshair chart1Crosshair = null;

        /// <summary>
        /// 차트 2 수직선
        /// </summary>
        private VLine chart2VLine = null;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            Random random = new Random(0);

            OHLC[]   chart1OHLCArray = DataGen.RandomStockPrices(null, 60, TimeSpan.FromDays(1));
            double[] chart2XArray    = chart1OHLCArray.Select(OHLC => OHLC.DateTime.ToOADate()).ToArray();
            double[] chart2YArray    = DataGen.Random(random, chart2XArray.Length, 10000, 50);

            #region 차트 컨트롤 1을 설정한다.

            this.chartControl1.Plot.XAxis.DateTimeFormat(true);
            this.chartControl1.Plot.XAxis.Line(false);
            this.chartControl1.Plot.XAxis.TickDensity(5);
            this.chartControl1.Plot.XAxis.TickLabelStyle(rotation : 90);
            this.chartControl1.Plot.XAxis.Ticks(false);

            #endregion
            #region 차트 컨트롤 1에 재무 플롯을 추가한다.

            FinancePlot financePlot = this.chartControl1.Plot.AddCandlesticks(chart1OHLCArray);

            #endregion
            #region 차트 컨트롤 1에 십자선을 추가한다.

            this.chart1Crosshair = this.chartControl1.Plot.AddCrosshair(0, 0);

            this.chart1Crosshair.XAxisIndex                               = 0;
            this.chart1Crosshair.YAxisIndex                               = 0;
            this.chart1Crosshair.LineWidth                                = 1;
            this.chart1Crosshair.LineStyle                                = LineStyle.Solid;
            this.chart1Crosshair.VerticalLine.PositionLabelOppositeAxis   = false;
            this.chart1Crosshair.VerticalLine.PositionFormatter           = position => DateTime.FromOADate(position).ToString("yyyy-MM-dd");
            this.chart1Crosshair.HorizontalLine.PositionLabelOppositeAxis = false;
            this.chart1Crosshair.HorizontalLine.PositionFormatter         = position => position.ToString("#,##0.00");
            this.chart1Crosshair.Color                                    = Color.Red;
            this.chart1Crosshair.IsVisible                                = false;

            #endregion
            #region 차트 컨트롤 2를 설정한다.

            this.chartControl2.Plot.XAxis.DateTimeFormat(true);
            this.chartControl2.Plot.XAxis.TickDensity(5);
            this.chartControl2.Plot.XAxis.TickLabelStyle(rotation : 90);

            #endregion
            #region 차트 컨트롤 2에 막대 플롯을 추가한다.

            BarPlot barPlot = this.chartControl2.Plot.AddBar(chart2YArray, chart2XArray);

            #endregion
            #region 차트 컨트롤 2에 수직선을 추가한다.

            this.chart2VLine = this.chartControl2.Plot.AddVerticalLine(0, Color.Red, 1f, LineStyle.Solid);

            this.chart2VLine.LineWidth = 1;
            this.chart2VLine.IsVisible = false;

            #endregion
            #region 차트 컨트롤 2의 축을 차트 컨트롤 1의 축과 동기화한다.

            this.chartControl2.Plot.SetAxisLimitsX(this.chartControl1.Plot.XAxis.Dims.Min, this.chartControl1.Plot.XAxis.Dims.Max);
            this.chartControl2.Plot.AxisAutoY();

            #endregion
            #region 이벤트를 설정한다.

            this.chartControl1.AxesChanged += chartControl1_AxesChanged;
            this.chartControl1.MouseEnter  += chartControl1_MouseEnter;
            this.chartControl1.MouseMove   += chartControl1_MouseMove;
            this.chartControl1.MouseLeave  += chartControl1_MouseLeave;
            this.chartControl2.AxesChanged += chartControl2_AxesChanged;
            this.chartControl2.MouseEnter  += chartControl2_MouseEnter;
            this.chartControl2.MouseMove   += chartControl2_MouseMove;
            this.chartControl2.MouseLeave  += chartControl2_MouseLeave;

            #endregion

            this.chartControl1.Plot.YAxis.SetSizeLimit(min : 50, max : 50);
            this.chartControl2.Plot.YAxis.SetSizeLimit(min : 50, max : 50);

            this.chartControl1.Refresh();
            this.chartControl2.Refresh();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 차트 컨트롤 1 축 변경시 처리하기 - chartControl1_AxesChanged(sender, e)

        /// <summary>
        /// 차트 컨트롤 1 축 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl1_AxesChanged(object sender, EventArgs e)
        {
            AxisLimits chart1AxisLimits = this.chartControl1.Plot.GetAxisLimits();
            AxisLimits chart2AxisLimits = this.chartControl2.Plot.GetAxisLimits();

            AxisLimits newChart2AxisLimits = new AxisLimits
            (
                chart1AxisLimits.XMin,
                chart1AxisLimits.XMax,
                chart2AxisLimits.YMin,
                chart2AxisLimits.YMax
            );

            this.chartControl2.Configuration.AxesChangedEventEnabled = false;

            this.chartControl2.Plot.SetAxisLimits(newChart2AxisLimits);

            this.chartControl2.Render();

            this.chartControl2.Configuration.AxesChangedEventEnabled = true;
        }

        #endregion
        #region 차트 컨트롤 1 마우스 진입시 처리하기 - chartControl1_MouseEnter(sender, e)

        /// <summary>
        /// 차트 컨트롤 1 마우스 진입시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl1_MouseEnter(object sender, EventArgs e)
        {
            if(this.chart1Crosshair != null)
            {
                this.chart1Crosshair.IsVisible = true;

                this.chart2VLine.IsVisible = true;

                this.chartControl1.Refresh();
                this.chartControl2.Refresh();
            }
        }

        #endregion
        #region 차트 컨트롤 1 마우스 이동시 처리하기 - chartControl1_MouseMove(sender, e)

        /// <summary>
        /// 차트 컨트롤 1 마우스 이동시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl1_MouseMove(object sender, MouseEventArgs e)
        {
            if(this.chart1Crosshair != null)
            {
                (double coordinateX, double coordinateY) = this.chartControl1.GetMouseCoordinates(0, 0);

                this.chart1Crosshair.X = coordinateX;
                this.chart1Crosshair.Y = coordinateY;

                this.chart2VLine.X = coordinateX;

                this.chartControl1.Refresh(lowQuality : true, skipIfCurrentlyRendering : true);
                this.chartControl2.Refresh(lowQuality : true, skipIfCurrentlyRendering : true);
            }
        }

        #endregion
        #region 차트 컨트롤 1 마우스 이탈시 처리하기 - chartControl1_MouseLeave(sender, e)

        /// <summary>
        /// 차트 컨트롤 1 마우스 이탈시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl1_MouseLeave(object sender, EventArgs e)
        {
            if(this.chart1Crosshair != null)
            {
                this.chart1Crosshair.IsVisible = false;

                this.chart2VLine.IsVisible = false;

                this.chartControl1.Refresh();
                this.chartControl2.Refresh();
            }
        }

        #endregion

        #region 차트 컨트롤 2 축 변경시 처리하기 - chartControl2_AxesChanged(sender, e)

        /// <summary>
        /// 차트 컨트롤 2 축 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl2_AxesChanged(object sender, EventArgs e)
        {
            AxisLimits chart1AxisLimits = this.chartControl1.Plot.GetAxisLimits();
            AxisLimits chart2AxisLimits = this.chartControl2.Plot.GetAxisLimits();

            AxisLimits newChart1AxisLimits = new AxisLimits
            (
                chart2AxisLimits.XMin,
                chart2AxisLimits.XMax,
                chart1AxisLimits.YMin,
                chart1AxisLimits.YMax
            );

            this.chartControl1.Configuration.AxesChangedEventEnabled = false;

            this.chartControl1.Plot.SetAxisLimits(newChart1AxisLimits);

            this.chartControl1.Render();

            this.chartControl1.Configuration.AxesChangedEventEnabled = true;
        }

        #endregion
        #region 차트 컨트롤 2 마우스 진입시 처리하기 - chartControl2_MouseEnter(sender, e)

        /// <summary>
        /// 차트 컨트롤 2 마우스 진입시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl2_MouseEnter(object sender, EventArgs e)
        {
            if(this.chart2VLine != null)
            {
                this.chart1Crosshair.IsVisible = true;

                this.chart2VLine.IsVisible = true;

                this.chartControl1.Refresh();
                this.chartControl2.Refresh();
            }
        }

        #endregion
        #region 차트 컨트롤 2 마우스 이동시 처리하기 - chartControl2_MouseMove(sender, e)

        /// <summary>
        /// 차트 컨트롤 2 마우스 이동시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl2_MouseMove(object sender, MouseEventArgs e)
        {
            if(this.chart2VLine != null)
            {
                (double coordinateX, double _) = this.chartControl2.GetMouseCoordinates(0, 0);

                this.chart1Crosshair.X = coordinateX;

                this.chart2VLine.X = coordinateX;

                this.chartControl1.Refresh(lowQuality : true, skipIfCurrentlyRendering : true);
                this.chartControl2.Refresh(lowQuality : true, skipIfCurrentlyRendering : true);
            }
        }

        #endregion
        #region 차트 컨트롤 2 마우스 이탈시 처리하기 - chartControl2_MouseLeave(sender, e)

        /// <summary>
        /// 차트 컨트롤 2 마우스 이탈시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void chartControl2_MouseLeave(object sender, EventArgs e)
        {
            if(this.chart2VLine != null)
            {
                this.chart1Crosshair.IsVisible = false;

                this.chart2VLine.IsVisible = false;

                this.chartControl1.Refresh();
                this.chartControl2.Refresh();
            }
        }

        #endregion
    }
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요