퇴근5분전

ChartFX Version : 7.0.3754.18555


ChartFX로 챠트가 지정되었고 이를 좀더 쉽게 데이타를 맵핑하기 위해 확장 클래스를 만들었음.

Vs2010으로 작업하니 편한점이 많다.

우선 옛날 VB를 번역하면서 보던 파라미터에 기본값을 설정하는 부분이 맘에 든다.

자바스크립트 하는 맛?

CalcEngine을 만들때 사용했던 dynamic객체와 또다른 매력이랄까? 

사용 순서는 DataTable객체를 넘겨주면서 시리즈의 데이타를 구해서
ChartEX.SeriesData 로 변환하여 갯수만큼 List화 한다.
이때 Y2 로 사용될 시리즈가 존재 시
IsAxisY2 값을 true로 주면 된다.
MinMax값을 계산해서 넣어줘야 하니 적절한 LINQ문을 사용한다.

2010 10 15 수정
 내용 : SeriesDataList  추가
        시리즈 관리 객체를 만들어서 Y축관련 스텝, 최소값 최대값을 자동 계산해주도록 추가해주었음.

//챠트 사용 소스

  ChartEX.SeriesDataList datas = new ChartEX.SeriesDataList();
            EnumerableRowCollection<double> BM_DURATION = dt.AsEnumerable().Select(c => Convert.ToDouble(c.Field<object>("BM_DURATION")) * cboDurationValue ); // Secondary AxisY
            datas.Add(new ChartEX.SeriesData()
            {
                Name = "벤치마크",
                Values = BM_DURATION.ToArray(),
                Color = ChartEX.DefaultColors[datas.Count],
                Gallery = Gallery.Lines,
                IsAxisY2 = false
            });

            EnumerableRowCollection<double> PF_DURATION = dt.AsEnumerable().Select(c => Convert.ToDouble(c.Field<object>("PF_DURATION")) * cboDurationValue); // Secondary AxisY
            datas.Add(new ChartEX.SeriesData
            {
                Name = "채권",
                Values = PF_DURATION.ToArray(),
                Color = ChartEX.DefaultColors[datas.Count],
                Gallery = Gallery.Lines,
                IsAxisY2 = false
            });

            EnumerableRowCollection<double> RF_RATE = dt.AsEnumerable().Select(c => Convert.ToDouble(c.Field<object>("RF_RATE")) ); // Secondary AxisY
            datas.Add(new ChartEX.SeriesData
            {
                Name = "시장이자율",
                Values = RF_RATE.ToArray(),
                Color = ChartEX.DefaultColors[datas.Count],
                Gallery = Gallery.Lines,
                IsAxisY2 = true
            });

            datas.ClacMaxMin();

            //챠트 셋팅
            chart.ChartSetting(
                    dt.AsEnumerable().Select(c => c.Field<string>("WORKDAY")).ToArray(),
                    datas.ToArray(),
                //null,
                    Legend =>
                    {
                        Legend.Dock = DockArea.Top;
                    },
                //null,
                    (X, Y) =>
                    {
                        X.AutoScale = true;
                        X.Step = 3;
                        X.FirstLabel = 0;
                        X.LabelsFormat.Format = AxisFormat.Date;
                        X.LabelsFormat.CustomFormat = "yyyy-MM-dd";
                        X.Step = 0;

                        Y.AutoScale = false;
                        Y.ForceZero = false;
                        Y.LabelsFormat.Format = AxisFormat.Number;
                        Y.LabelsFormat.CustomFormat = "N2";

                        Y.Max = datas.YMax;
                        Y.Min = datas.YMin;
                        Y.Step = datas.YStep; //0=Auto
                        Y.Title.Text = "벤치마크/채권";
                    },
                // null
                    AxisY2 =>
                    {
                        AxisY2.AutoScale = false;
                        AxisY2.ForceZero = false;
                        AxisY2.Max = datas.Y2Max ;
                        AxisY2.Min = datas.Y2Min;
                        AxisY2.Step = datas.Y2Step;
                        AxisY2.LabelsFormat.CustomFormat = "N2";
                        AxisY2.Title.Text = "시장이자율";
                    }
            );
            datas.Clear();
            datas = null;
            #endregion


// 추가된 챠트 소스
        public class SeriesDataList : IList<SeriesData>
        {
            /// <summary>
            /// Y좌표축 표시 갯수 ( 10d )
            /// </summary>
            public readonly double STEP_INCREEMENT = 10d;
            /// <summary>
            /// Min, Max값 계산시 여백 계산 값. ( 0.3d )
            /// </summary>
            public readonly double STEP_SEED = 0.2d;

            /// <summary>
            /// 시리즈 데이타 리스트
            /// </summary>
            private List<SeriesData> lst = null;
            public SeriesDataList()
            {
                lst = new List<SeriesData>();
                YMax1 = double.MinValue;
                YMin1 = double.MaxValue;

                YMax2 = double.MinValue;
                YMin2 = double.MaxValue;
            }

            /// <summary>
            /// Y축 Min, Max를 계산해줌. 셋팅전에 반드시 호출해주어야 함.
            /// </summary>
            public void ClacMaxMin()
            {
                YMax1 = double.MinValue;
                YMin1 = double.MaxValue;

                YMax2 = double.MinValue;
                YMin2 = double.MaxValue;

                foreach (SeriesData item in lst)
                {
                    if (item.IsAxisY2 == true)
                    {
                        if (YMax2 < item.Values.Max())
                            YMax2 = item.Values.Max();

                        if (YMin2 > item.Values.Min())
                            YMin2 = item.Values.Min();
                    }
                    else
                    {
                        if (YMax1 < item.Values.Max())
                            YMax1 = item.Values.Max();

                        if (YMin1 > item.Values.Min())
                            YMin1 = item.Values.Min();
                    }
                }
            }

            /// <summary>
            /// Y 축 Max
            /// </summary>
            private double YMax1 {get; set;}
            /// <summary>
            /// Y 축 Min
            /// </summary>
            private double YMin1 {get; set;}
            /// <summary>
            /// Y2 축 Max
            /// </summary>
            private double YMax2 { get; set; }
            /// <summary>
            /// Y2 축 Min
            /// </summary>
            private double YMin2 { get; set; }
            /// <summary>
            /// Y축 Max값
            /// </summary>
            public double YMax { get { return YMax1 + Math.Abs(YMax1) * STEP_SEED; } }
            /// <summary>
            /// Y축 Min값
            /// </summary>
            public double YMin { get { return YMin1 - Math.Abs(YMin1) * STEP_SEED; } }

            /// <summary>
            /// Y2 축 Max값
            /// </summary>
            public double Y2Max { get { return YMax2 + Math.Abs(YMax2) * STEP_SEED; } }
            /// <summary>
            /// Y2 축 Min값
            /// </summary>
            public double Y2Min { get { return YMin2 - Math.Abs(YMin2) * STEP_SEED; } }

            /// <summary>
            ///  Y축 스탭 계산해서 나옴.
            /// </summary>
            public double YStep
            {
                get { return Math.Abs((YMax1 - Math.Abs(YMin1)) / STEP_INCREEMENT); }
            }
            /// <summary>
            /// Y2축 스탭 계산해서 나옴.
            /// </summary>
            public double Y2Step {
                get { return Math.Abs((YMax2 - Math.Abs(YMin2)) / STEP_INCREEMENT); ; }
            }

            #region   IList 구현
            public int IndexOf(SeriesData item)
            {
                return lst.IndexOf(item);
            }

            void IList<SeriesData>.Insert(int index, SeriesData item)
            {
                lst.Insert(index, item);
            }

            void IList<SeriesData>.RemoveAt(int index)
            {
                lst.RemoveAt(index);
            }

            SeriesData IList<SeriesData>.this[int index]
            {
                get
                {
                    return lst[index];
                }
                set
                {
                    lst[index] = value;
                }
            }

            public void Clear()
            {
                lst.Clear();
            }

            public bool Contains(SeriesData item)
            {
                return lst.Contains(item);
            }

            public void CopyTo(SeriesData[] array, int arrayIndex)
            {
                lst.CopyTo(array, arrayIndex);
            }

            public int Count
            {
                get { return lst.Count; }
            }

            public bool IsReadOnly
            {
                get { return true; }
            }

            public bool Remove(SeriesData item)
            {
                return lst.Remove(item);
            }

            public IEnumerator<SeriesData> GetEnumerator()
            {
                return lst.GetEnumerator();
            }

            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
            {
                return lst.GetEnumerator();
            }

            public void Add(SeriesData item)
            {
                lst.Add(item);
            }
            #endregion
        }

        /// <summary>
        /// 챠트 데이타 셋팅&lt;T&gt;
        /// </summary>
        /// <typeparam name="T">double, int 등 바인딩 데이타 타입</typeparam>
        /// <param name="chart"> 챠트 </param>
        /// <param name="SeriesAxisX_Datas"> X축 Header 문자열[]</param>
        /// <param name="ToDatas">데이타 클래스&lt;T&gt;[]</param>
        public static void AddSeries<T>(this Chart chart, SeriesData<T> ToDatas)
        {
            try
            {
                chart.Data.Series++;
                chart.Series[chart.Series.Count - 1].Color = ToDatas.Color;
                chart.Series[chart.Series.Count - 1].Gallery = ToDatas.Gallery;
                chart.Series[chart.Series.Count - 1].MarkerShape = MarkerShape.None;
                chart.Series[chart.Series.Count - 1].Text = ToDatas.Name;
                chart.Series[chart.Series.Count - 1].AxisX.Labels.AddRange(ToDatas.Labels);
                if (ToDatas.IsAxisY2) chart.Series[chart.Series.Count - 1].AxisY = chart.AxisY2;
                // Y축 2를 사용하는 필드로 SeriesData 내에 IsAxisY2가 True인것은 이 좌표계를 사용함.

                int cnt = 0;
                foreach (T _data in ToDatas.Values)
                {
                    chart.Data.Y[chart.Series.Count - 1, cnt++] = Convert.ToDouble(_data);
                }
                Debug.Write(string.Format("chart.SeriesCount : {0}", chart.Series.Count - 1));

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 챠트 데이타 셋팅&lt;T&gt;
        /// </summary>
        /// <typeparam name="T">double, int 등 바인딩 데이타 타입</typeparam>
        /// <param name="chart"> 챠트 </param>
        /// <param name="SeriesAxisX_Datas"> X축 Header 문자열[]</param>
        /// <param name="ToDatas">데이타 클래스&lt;T&gt;[]</param>
        public static void AddSeries(this Chart chart, SeriesData ToDatas)
        {
            try
            {
                chart.Data.Series++;
                chart.Series[chart.Series.Count - 1].Color = ToDatas.Color;
                chart.Series[chart.Series.Count - 1].Gallery = ToDatas.Gallery;
                chart.Series[chart.Series.Count - 1].MarkerShape = MarkerShape.None;
                chart.Series[chart.Series.Count - 1].Text = ToDatas.Name;
                chart.Series[chart.Series.Count - 1].AxisX.Labels.AddRange(ToDatas.Labels);
                if (ToDatas.IsAxisY2) chart.Series[chart.Series.Count - 1].AxisY = chart.AxisY2;
                // Y축 2를 사용하는 필드로 SeriesData 내에 IsAxisY2가 True인것은 이 좌표계를 사용함.

                int cnt = 0;
                foreach (double _data in ToDatas.Values)
                {
                    chart.Data.Y[chart.Series.Count - 1, cnt++] = Convert.ToDouble(_data);
                }
                Debug.Write(string.Format("chart.SeriesCount : {0}", chart.Series.Count - 1));

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


##############################################  이하 기존 소스 .......................

// 챠트 생성 

 ## 우선 DataTable에서 챠트에 Series로 등록될 데이타를 구한다.

   #region   챠트
           // Series 1개가 됨.
            List<ChartEX.SeriesData> datas = new List<ChartEX.SeriesData>();
            EnumerableRowCollection<double> BM_DURATION = dt.AsEnumerable().Select(c => Convert.ToDouble(c.Field<object>("BM_DURATION")) ); 

            datas.Add(new ChartEX.SeriesData()
            {
                Name = "벤치마크",
                Values = BM_DURATION.ToArray(),
                Color = ChartEX.DefaultColors[datas.Count],
                Gallery = Gallery.Lines,
                IsAxisY2 = false
            });  

            EnumerableRowCollection<double> PF_DURATION = dt.AsEnumerable().Select(c => Convert.ToDouble(c.Field<object>("PF_DURATION")) ); 

            datas.Add(new ChartEX.SeriesData
            {
                Name = "채권",
                Values = PF_DURATION.ToArray(),
                Color = ChartEX.DefaultColors[datas.Count],
                Gallery = Gallery.Lines,
                IsAxisY2 = false
            });

            EnumerableRowCollection<double> RF_RATE = dt.AsEnumerable().Select(c => Convert.ToDouble(c.Field<object>("RF_RATE")) ); // Secondary AxisY

            datas.Add(new ChartEX.SeriesData
            {
                Name = "시장이자율",
                Values = RF_RATE.ToArray(),
                Color = ChartEX.DefaultColors[datas.Count],
                Gallery = Gallery.Lines,
                IsAxisY2 = true
            });

            ## 챠트 Y 좌표계 Max Min 구하기. 이때 챠트에 사용되는 Y2 좌표계 데이타를 제외한다.
         RF_RATE를 제외했음.
            double AxisYMax = BM_DURATION.Max();
            if (AxisYMax < PF_DURATION.Max())
                AxisYMax = PF_DURATION.Max();

            double AxisYMin = BM_DURATION.Min();
            if (AxisYMin > PF_DURATION.Min())
                AxisYMin = PF_DURATION.Min();

            ##챠트 초기화
            //chart.ChartInit();
            ##챠트 셋팅
            chart.ChartSetting(
                    dt.AsEnumerable().Select(c => c.Field<string>("WORKDAY")).ToArray(), //##X축 Heaer 문자열[]
                    datas.ToArray(),   //##시리즈 데이타클래스[] 를 넘겨준다.
                //null,
                    Legend => //##LegendBox 셋팅
                    {
                        Legend.Dock = DockArea.Top;
                    },
                //null,
                    (X, Y) => //##X,Y좌표계 셋팅
                    {
                        X.AutoScale = true;
                        X.Step = 3;
                        X.FirstLabel = 0;
                        X.LabelsFormat.Format = AxisFormat.Date;
                        X.LabelsFormat.CustomFormat = "yyyy-MM-dd";
                        X.Step = 0;

                        Y.AutoScale = false;
                        Y.ForceZero = false;
                        Y.LabelsFormat.Format = AxisFormat.Number;
                        Y.LabelsFormat.CustomFormat = "N2";
                        Y.Max = AxisYMax;
                        Y.Min = AxisYMin;
                        Y.Step = (AxisYMax - AxisYMin) / 10d; //0=Auto
                    },
                // null
                    AxisY2 => //## Y2 좌표계에 대한 셋팅
                    {
                        AxisY2.AutoScale = true;
                        AxisY2.ForceZero = false;
                        AxisY2.Min = RF_RATE.Min();
                        AxisY2.Max = RF_RATE.Max();
                        AxisY2.Step = (AxisY2.Max - AxisY2.Min) / 10d;
                        AxisY2.LabelsFormat.CustomFormat = "N2";
                        AxisY2.Title.Text = "RF_RATE";
                    }
            );
            datas.Clear();
            datas = null;
            #endregion

여기까지 하면 챠트가 그려진다. ###############################################################



// 챠트 FX 확장 클래스 전체 소스
    /// <summary>
    /// 챠트 확장 클래스
    /// </summary>
    public static class ChartEX
    {
        /// <summary>
        /// 데이타 클래스
        /// </summary>
        public class SeriesData : SeriesData<Double>
        {
        }
        /// <summary>
        /// 데이타 클래스
        /// </summary>
        public class SeriesData<T>
        {
            public string Name { get; set; }
            public T[] Values { get; set; }
            public System.Drawing.Color Color { get; set; }
            public Gallery Gallery { get; set; }
            public bool IsAxisY2 { get; set; }
        }
        /// <summary>
        /// 기본 컬러값 빨주노초파남보?
        /// </summary>
        public static System.Drawing.Color[] DefaultColors = new System.Drawing.Color[] {
                 System.Drawing.Color.Red
                ,System.Drawing.Color.Orange
                ,System.Drawing.Color.Yellow
                ,System.Drawing.Color.Green
                ,System.Drawing.Color.Blue
                ,System.Drawing.Color.DarkBlue // 남색이 맞으려나?
                ,System.Drawing.Color.Violet
        };
        /// <summary>
        /// 좌표계 셋팅 대리자
        /// </summary>
        /// <param name="x">X축</param>
        /// <param name="Y">Y축</param>
        public delegate void __Settings_Axis(Axis x, Axis Y);
        /// <summary>
        /// 레젼드 셋팅 대리자
        /// </summary>
        /// <param name="legendBox">레젼드박스</param>
        public delegate void __Settings_LegendBox(LegendBox legendBox);
        /// <summary>
        /// 좌표계 Y축2  셋팅 대리자
        /// </summary>
        /// <param name="ay2">Y2축</param>
        public delegate void __SetAxisY2(AxisY ay2);

        /// <summary>
        /// 레젼드 박스 셋팅
        /// <para>람다식사용</para>
        /// <para> ( L ) => {</para>
        /// <para>   L 셋팅;</para>
        /// <para> }</para>
        /// </summary>
        /// <param name="chart">챠트</param>
        /// <param name="DoSetting"> 셋팅 대리자로 레젼드 노출 </param>
        private static void ChartLegendBoxSetting(this Chart chart, __Settings_LegendBox DoSetting = null)
        {
            chart.LegendBox.Visible = true;
            chart.LegendBox.Dock = DockArea.Bottom;
            chart.LegendBox.AutoSize = true;

            if (DoSetting != null)
                DoSetting(chart.LegendBox);
        }

        /// <summary>
        /// 챠트 좌표계 셋팅
        /// <para>람다식사용</para>
        /// <para> ( X, Y ) => {</para>
        /// <para>   X 셋팅;</para>
        /// <para>   Y 셋팅;</para>
        /// <para> }</para>
        /// </summary>
        /// <param name="chart">챠트</param>
        /// <param name="DoSetting"> 좌표계 셋팅 대리자로 X축 Y축 노출</param>
        private static void ChartAxisSetting(this Chart chart, __Settings_Axis DoSetting = null)
        {
            chart.AxisX.AutoScale = true;
            chart.AxisX.Step = 3;
            chart.AxisX.FirstLabel = 0;
            chart.AxisX.LabelsFormat.Format = AxisFormat.Date;
            chart.AxisX.LabelsFormat.CustomFormat = "yyyy-MM-dd";
            chart.AxisX.Step = 0;

            chart.AxisY.AutoScale = true;
            chart.AxisY.ForceZero = false;
            chart.AxisY.LabelsFormat.Format = AxisFormat.Number;
            chart.AxisY.LabelsFormat.CustomFormat = "N2";
            chart.AxisY.Step = 0.5d; //0=Auto

            if (DoSetting != null)
                DoSetting(chart.AxisX, chart.AxisY);
        }

        /// <summary>
        /// 챠트 데이타 셋팅&lt;T&gt;
        /// </summary>
        /// <typeparam name="T">double, int 등 바인딩 데이타 타입</typeparam>
        /// <param name="chart"> 챠트 </param>
        /// <param name="SeriesAxisX_Datas"> X축 Header 문자열[]</param>
        /// <param name="ToDatas">데이타 클래스&lt;T&gt;[]</param>
        private static void ChartDataSetting<T>(this Chart chart, string[] SeriesAxisX_Datas, params SeriesData<T>[] ToDatas)
        {
            try
            {
                /* 각 시리즈 별로 데이타를 넣음
                 * 데이타 클래스에 담겨진 데이타를(SeriesData)
                 * chart.Data.Y[SeriesCnt, cnt++] = Convert.ToDouble(_data); 를 통해 각 씨리즈의 Y축에 뿌려줌.
                 *  chart.AxisX.Labels.AddRange(SeriesAxisX_Datas); X축에 헤더를 뿌림.
                 */
                int SeriesCnt = 0;
                int cnt = 0;
                foreach (var Series in chart.Series)
                {
                    chart.Series[SeriesCnt].Color = ToDatas[SeriesCnt].Color;
                    chart.Series[SeriesCnt].Gallery = ToDatas[SeriesCnt].Gallery;
                    chart.Series[SeriesCnt].MarkerShape = MarkerShape.None;
                    chart.Series[SeriesCnt].Text = ToDatas[SeriesCnt].Name;

                    if (ToDatas[SeriesCnt].IsAxisY2) chart.Series[SeriesCnt].AxisY = chart.AxisY2;
                    // Y축 2를 사용하는 필드로 SeriesData 내에 IsAxisY2가 True인것은 이 좌표계를 사용함.

                    cnt = 0;
                    foreach (T _data in ToDatas[SeriesCnt].Values)
                    {
                        chart.Data.Y[SeriesCnt, cnt++] = Convert.ToDouble(_data);
                    }

                    Debug.Write(string.Format("chart.SeriesCount : {0}", SeriesCnt));
                    SeriesCnt++;
                }
                chart.AxisX.Labels.AddRange(SeriesAxisX_Datas);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 챠트 셋팅
        /// </summary>
        /// <typeparam name="T">double, int 등 바인딩 데이타 타입</typeparam>
        /// <param name="chart">챠트</param>
        /// <param name="SeriesAxisX_ColumnName">X축 Header 문자열[]</param>
        /// <param name="ToSeriesDatas">데이타 클래스&lt;T&gt;[]</param>
        /// <param name="legendBox">레젼드 셋팅 대리자</param>
        /// <param name="AxisXY">좌표계x,y 셋팅 대리자</param>
        /// <param name="setay2">좌표계Y2 셋팅 대리자</param>
        public static void ChartSetting<T>(this Chart chart, string[] SeriesAxisX_ColumnName, SeriesData<T>[] ToSeriesDatas, __Settings_LegendBox legendBox = null, __Settings_Axis AxisXY = null, __SetAxisY2 setay2 = null)
        {
            chart.Reset();                                                      // 리셋
            chart.Data.Series = ToSeriesDatas.Length;                           // 시리즈 갯수지정
            chart.AxesStyle = AxesStyle.FlatFrame;                              // 좌표계프레임 설정인데... FlatFrame이 가장 보기 좋음.
            chart.ChartLegendBoxSetting(legendBox);                             // 디폴트 설정후 -> 대리자 처리로 덮어쓰기..
            chart.ChartAxisSetting(AxisXY);                                     // 디폴트 설정후 -> 대리자 처리로 덮어쓰기..
            if (setay2 != null) setay2(chart.AxisY2);                           // 좌표계Y2 셋팅 대리자로 노출시킴[ AxisY2는 추가된 좌표계가 적을시 새로 생성해서 리턴하므로 따로 추가할 필요없음.
            chart.ChartDataSetting<T>(SeriesAxisX_ColumnName, ToSeriesDatas);   // 데이타 셋팅
            chart.RecalculateScale();                                           // 챠트 다시 계산함.
        }

        /// <summary>
        /// 챠트 초기화
        /// </summary>
        /// <param name="chart">챠트</param>
        public static void ChartInit(this Chart chart)
        {
            chart.Reset();
            chart.AxesX.Clear();
            chart.AxesY.Clear();
            chart.LegendBox.Visible = false;
            for (int i = chart.Series.Count - 1; i >= 0; i--)
            {
                chart.Series.Remove(chart.Series[i]);
            }
            chart.Data.Clear();    // 실제 데이타를 초기화 하여 데모에 따라오는 챠트를 숨김.
            chart.Data.Series = 0;
            chart.Titles.Clear();
        }
    }

'# 4) .Net ( Vs 2010 ) > C#' 카테고리의 다른 글

[IPC] Event 추가 ~~  (0) 2011.05.14
LINQ] 로또 구하기?  (1) 2011.04.25
[C#]Box 그리기...  (0) 2010.11.29
[C#]TabControl에서 특정 TabPage를 안보이게 감추기..  (0) 2010.11.26
[LINQ] 콤마 구분자 넣기?  (0) 2010.11.24



요렇게 디자인 하는것...  ( 훈스 게시판에 이런 모양의 디자인을 하고 싶어하는 분이 계셔서.. 잠깐..

Text 를 없애고 FormStyleBorder를 none이 아닌 다른걸로 했음. 그래야 사이즈 조정이 되니까!!



 

'# 3) .Net ( Vs 2008 ) > C#' 카테고리의 다른 글

[LINQ] group by 여러조건 넣기.  (0) 2010.11.08
MS-Chart Demo  (0) 2010.11.05
Ms Access 사용하기 예제소스.  (0) 2010.08.11
WebClient와 WebBrowser의 차이는??  (3) 2010.07.30
LINQ 그룹바이... 훌...  (0) 2010.07.30

"문자"를 "_"로 변경할때 그냥 문자열에 Replace를 하면 조건에 걸리는것 모두를 변경..

훈스 게시판에 처음 조건에 걸리는것만 바꾸는 메서드가 자바에서 지원이 된다기에... 

만들어봤다. 

// 사용예!
   string ss = "바뀔문자,바뀐문자,바꿔봐요!".ReplaceFirst("문자", "_");

결과 : 바뀔_,바뀐문자,바꿔봐요!".
  

// 확장 메서드 구현

  public static class StringEX
    {
        public static string ReplaceFirst(this string s, string re, string ch)
        {
            int offsetIndex = s.IndexOf(re) + re.Length;
            string first = s.Substring(0, s.IndexOf(re));
            string midle = ch;
            string last = s.Substring(s.IndexOf(re) + re.Length, s.Length - offsetIndex);
            return string.Concat(first, midle, last);
        }
    }


'# 1) 프로그래밍' 카테고리의 다른 글

ActiveDirectory] Query  (0) 2011.04.19
HWP 바이너리 파일...  (0) 2011.03.23
일자가 해당 월에 몇주차인지 구하는 법.  (0) 2010.09.30
DateTime관련..  (0) 2010.09.09
피벗 메서드  (0) 2010.08.26


 제목 달기 어렵네.. 

    // 테스트용도.
     for (int day = 1; day <= 31; day++)
     {
         int wcnt1 = GetWeeksOfYear(new DateTime(2010, 10, day));
         int wcnt2 = GetWeeksOfMonth(new DateTime(2010, 10, day));
         textBox1.AppendText(string.Format("{0} : {1}주차 / {0} : {2}주차" + Environment.NewLine,
                                                              day, wcnt1,             wcnt2));

     }

     // 내가 만든 것.
     private static int GetWeekCnt(DateTime dt)
        {
            int week =  Enum.GetValues( typeof( DayOfWeek) ).Length;
            int dayOffset = (int)dt.AddDays(-(dt.Day - 1)).DayOfWeek;
            int weekCnt = (dt.Day + dayOffset) / week ;
            weekCnt += ((dt.Day + dayOffset) % week ) > 0 ? 1 : 0;
            return weekCnt;
        }

   // 훈스에 몬난아님이 검색하신걸 내가 수정한것.
   // 이건 해당 년도에 주차 수를 구한다.
        public int GetWeeksOfYear(DateTime date)
        {
            System.Globalization.CultureInfo cult_info = System.Globalization.CultureInfo.CreateSpecificCulture("ko");
            System.Globalization.Calendar cal = cult_info.Calendar;
            int weekNo = cal.GetWeekOfYear(date, cult_info.DateTimeFormat.CalendarWeekRule, cult_info.DateTimeFormat.FirstDayOfWeek);
            int week1day = cal.GetWeekOfYear(date.AddDays( -( date.Day+1 )), cult_info.DateTimeFormat.CalendarWeekRule, cult_info.DateTimeFormat.FirstDayOfWeek);
            return weekNo - week1day + 1;
        }

음...

'# 1) 프로그래밍' 카테고리의 다른 글

HWP 바이너리 파일...  (0) 2011.03.23
문자열 첫번째 검색 문자만 Replace  (0) 2010.09.30
DateTime관련..  (0) 2010.09.09
피벗 메서드  (0) 2010.08.26
새로운 프로젝트 & 6월에 나의 프로젝트!  (0) 2010.06.03


 -> TextBox 2개 , 버튼 1개
 
  변환 대상 문자열 : "<div>나&너&우리</div>"

  음 훈스에 올렸는데 더 간단한것이..

소류님 글...
01. 참조에 System.Web을 추가합니다.
02. MessageBox.Show(System.Web.HttpUtility.HtmlEncode("<>&"));


// 이하 소스~~~ 

    private void button1_Click(object sender, EventArgs e)
        {
            string pttr = "<|&|>";
            Regex rx = new Regex(pttr);

            this.textBox2.Text = rx.Replace(this.textBox1.Text, new MatchEvaluator(ReplaceString));

        }

        //http://msdn.microsoft.com/en-us/library/cft8645c.aspx
        static string ReplaceString(Match m)
        {
            string mString = m.ToString();

            switch (mString)
            {
                case "<":
                    mString = "&lt;";
                    break;
                case ">":
                    mString = "&gt;";
                    break;
                case "&":
                    mString = "&amp;";
                    break;

            }

            return mString;
       
        }

'# 2) .Net ( Vs 2005 ) > 기타' 카테고리의 다른 글

IPC... 리모트 객체 수명이 5~6분?  (0) 2011.06.24
이미지 미리보기~  (0) 2010.08.31
글꼴 폰트 관련 MSDN 링크  (0) 2010.08.10
소수 구하기 소스...  (0) 2010.08.06
[GDI+] Matrix 객체 사용해보기...  (0) 2010.07.27



DECLARE
    DT1 DATE := TO_DATE( '201001' , 'YYYYMM');
    DT2 DATE := TO_DATE( '201002' , 'YYYYMM');
    CNT INT := MONTHS_BETWEEN( DT2, DT1) + 1;
    IDX INT := 0;
    DT  DATE;
BEGIN

    WHILE IDX <= CNT LOOP
   
      DBMS_OUTPUT.PUT_LINE( IDX );
  
      DT := ADD_MONTHS( DT1, IDX );
      
      INSERT INTO 임시테이블
      VALUES ( DT );
      
      IDX := IDX + 1;
     
      EXIT WHEN IDX > CNT;

    END LOOP;

    SELECT YMD FROM 임시테이블; COMMIT;              -- INTO를 요구한다.

END;

    SELECT YMD FROM 임시테이블;  COMMIT;              -- 정상적인 위치

 

 위 쿼리는 작업 중 MS-SQL에 익숙해진 생각에서 시작했다. 

 항목별 기간 데이타를 만들기 위해 사용 될 기간테이블로 항목별 테이블과 크로스 조인을 통해 데이타를 생성하려는 목적으로 임시테이블을 토드에서 테스트 하기 위해 만들어진 스크립트 임.

 팀장님께서 말씀하시는 데로는 INTO요구하는 곳에서 나오는것은 맞다고 한다. 어딘가 담아야 된다고??  하심.

오라클이 1개의 쿼리만을 허용한다고 얘기는 얼핏 들었지만... 위 같은 상황일거란 생각은...

정상적인 위치로 옮겼을경우 F5를 통해 결과를 얻을수 있지만.  F9를 통해서는 여전히 문법 오류를 반환한다.

아 특이해...

이번 플젝 성패는 오라클을 얼마나 빨리 습득하느냐에 따라 결판날듯 한뎁... 오라클 검색하면 왜케 어렵게 보이는지...

MS-SQL이 쉽다는걸 다시 느꼈다.

 


DROP TABLE 임시테이블명 CASCADE CONSTRAINTS;

CREATE GLOBAL TEMPORARY TABLE 임시테이블명
(
  YMD  DATE
)
ON COMMIT DELETE ROWS   -- Commit 시 임시 데이타는 모두 사라짐.

NOCACHE;

임시테이블 만드는 스트립트임.


옵션이 하나 더 있는데 오라클 임시테이블 치면 블로그 글이 많이 뜸.






프로시져 실행시... F5나 F9로 제대로 실행이 안되서 토드에서 번개아이콘 클릭해서 파라미터 설정후에 콜했었으나...


EXEC 프로시져명( 1 ,:VAR ) [ 음 이건 다시 해보니 안됨? 그때 뭔가에 씌였었나... ]

프로시져명( 1 ,:VAR ) [ 이건 되는걸 확인했음 ]


쿼리문 선택후 F5나 F9 또는 Ctrl + Enter를 클릭시 파라미터를 설정하는 다일로그 하나가 뜬다.

Var는 Cursor 타입으로 지정하면 된다.

: 김영삼씨 덕분에 알게 되었음... 감솨!


DateTime fromDT = DateTime.ParseExact("201011", "yyyyMM", null);

위처럼 하면 포멧 기준을 뒤에 적어주면 날자값으로 변경해서 반환 해준다.


참고로 기간중 Month 개월수 구하는 로직..

    DateTime fromDT = DateTime.ParseExact("201011", "yyyyMM", null);
    DateTime toDT = DateTime.ParseExact("201012", "yyyyMM", null);

            int month = 0;
            try
            {
                while (true)
                {
                    if (fromDT.AddMonths(month).CompareTo(toDT) >= 0)
                    {
                        break;
                    }
                    month++;
                }
            }
            catch
            {
                month = 0;
            }



WPF용 플렉스 그리드에서 콤보박스형태로 데이타를 나타나게 하려면...

해당 컬럼에 ValueConverter에 
1.  new ColumnValueConvert(    [] 타입 , false );
2.  new ColumnValueConvert(  Dictionary  );
   ? 여기서 문제가 발생

  코드값 Y  , Name 값 Y인경우... 
 dic["Y" ] = "Y"; 로 해서 바인딩 시켰을 시 문제가 생긴다.

이를 해결하기 위한 방법을 아래 설명하였다.

( 삽질 신공으로 투자한 시간은 2일정도 된것 같음.. )
덕분에 바인딩을 모두 다시 공부했다...

/********************************************************************************************************

플렉스 그리드에서 기본 제공되는 컨버터로는 해결이 안된다.
예제 샘플을 보면 Dictionary로 선언해서 객체에서 받아서 넘겨주면
Key를 int로 검색하여 코드의 경우 문자열을 코드로 사용하는 경우
문제시 된다. : 예외로 지정한 캐스팅이 어쩌고 저쩌고...

이를 해결하기 위한 방법은 아래처럼 하면 된다.

1. AutoGenerateColumns  = false를 준다. ( true일경우 똑같은 컬럼들이 새로 생성된다 )
2. ItemSource 속성에 {Binding} 설정
3. DataContext에 데이타 테이블을 넘겨준다.
4. 컬럼.Binding = new Binding( Path명 ); 으로 설정해준다.
5. 컬럼.ValueConverter 에 새로 만든 UsedColumnValueConvert를 넘겨주자.
 : 컨버터에는 코드키와 값을 셋팅한 Dictionary<object, string>으로 구성해서 넘겨준다.

**********************************************************************************************************/
.cs 


    DataTable dt = new DataTable();

                dt.Columns.Add("NO");
                dt.Columns.Add("YN");

                dt.Rows.Add(1, "Y");
                dt.Rows.Add(1, "N");

                Dictionary<object, string> lst = new Dictionary<object, string>();

                lst["Y"] = "Y";
                lst["N"] = "N";
                lst["K"] = "K";

                Fx.DataContext = dt;
                Fx.AutoGenerateColumns = false;

                   Column c = new Column();
                c.Binding = new Binding("NO");

                Column c1 = new Column();
                c1.Binding = new Binding("YN");

                Fx.Columns.Add(c);
                Fx.Columns.Add(c1);

                Fx.Columns[1].ValueConverter = new UsedColumnValueConverter(lst);

// Fx.Rows.Add <== 하면 데이타 안늘어남. 참 뭐같음.
// 고로 원본을 꺼내 직접 Add 시켜야 함. 


                for (int i = 201001; i < 201012; i++)
                {
                    DataRow dr = dt.NewRow();
                    foreach (Column c in dt.Columns)
                    {
                        dr[c.ColumnName] = 0;
                    }
                    dr[0] = i;

                    dt.Rows.Add(dr);
                }
             
              //  Fx.Rows.Add(new Row());    // Row증가가 되지 않음.



.xaml

<c1Flex:C1FlexGrid  Grid.Row="1" Grid.Column="2" Name="Fx"  ItemsSource="{Binding}"  >
c1Flex:C1FlexGrid>



여기서 필요한건 새로 만든 UsedColumnValueConverter

 public class UsedColumnValueConverter : IValueConverter, IEditValueConverter
   
{
        IDictionary<object, string> dic = null;
        bool Ex = true;

        public UsedColumnValueConverter(IDictionary<object, string> idic)
        {
            dic = idic;
        }

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (dic.Keys.Contains(value))
                return dic[value];
            else
                return value;
             //
return null;     //널값 주면 값이 사라져버림.

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;

           // return DependencyProperty.UnsetValue;
        }

        public bool Exclusive
        {
            get { return Ex; }
        }

        public ICollection Values
        {
            get {
              return  dic.Values.ToList();
           
            }
        }
    }



PS : 컨트롤에 대한 스터디 시간이 없으므로 다른 컨트롤로 교체됨.

'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글

WPF Textbox의 Numeric!  (0) 2015.09.05
WPF 에서 Keyboard 입력 하기 Winfom SendKeys 같은..  (0) 2011.09.08
IValueConverter 사용 데모  (0) 2010.09.06
WPF 쓰레드 ( 프로그래스바 )  (0) 2010.08.10
[WPF] Tab 순환코드  (0) 2010.07.27