Пример #1
0
        public void Update(Boolean useTransition)
        {
            LegendAreaWidth = 0;
            D3Data          = new Data()
            {
                List = Data.Select(d => d as Object).ToList()
            };

            CircleData   = Data.SelectMany(l => l.DataPoints).Where(dp => dp.Item2 != null).ToList();
            D3CircleData = new Data()
            {
                List = CircleData.Select(d => d as Object).ToList()
            };

            if (LegendVisibility == Visibility.Visible)
            {
                LegendRectangleElement.Data = D3Data;
                LegendRectangleElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);

                LegendTextElement.Data = D3Data;
                LegendTextElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);
                LegendTextElement.ForceMeasure();

                LegendAreaWidth          = Math.Max(LegendTextElement.MaxActualWidth + Const.LegendPatchWidth + Const.LegendPatchSpace + Const.PaddingRight, Const.MinimumLegendWidth);
                LegendTitleElement.Width = LegendAreaWidth;
                LegendTitleElement.Text  = LegendTitle;
                Canvas.SetTop(LegendTitleElement, LegendPatchYGetter(null, 0) - 30);
            }

            Canvas.SetLeft(LegendPanel, this.Width - LegendAreaWidth);

            if (HorizontalAxisVisibility == Visibility.Visible)
            {
                ChartAreaEndY = this.Height - Const.PaddingBottom - Const.HorizontalAxisHeight - Const.HorizontalAxisLabelHeight;
            }
            else
            {
                ChartAreaEndY = this.Height - Const.PaddingBottom;
            }

            if (LegendVisibility == Visibility.Visible)
            {
                ChartAreaEndX = this.Width - Const.PaddingRight - LegendAreaWidth;
            }
            else
            {
                ChartAreaEndX = this.Width - Const.PaddingRight;
            }

            HorizontalAxisLabelCanvasLeft = Const.PaddingLeft + Const.VerticalAxisWidth + Const.VerticalAxisLabelWidth;
            HorizontalAxisLabelCanvasTop  = ChartAreaEndY + Const.HorizontalAxisHeight;
            HorizontalAxisLabelWidth      = ChartAreaEndX - Const.PaddingLeft - Const.VerticalAxisWidth - Const.VerticalAxisLabelWidth;

            VerticalAxisCanvasLeft      = Const.PaddingLeft + Const.VerticalAxisLabelWidth + Const.VerticalAxisWidth;
            VerticalAxisLabelCanvasLeft = Const.PaddingLeft + Const.VerticalAxisLabelWidth / 2 - (ChartAreaEndY - Const.PaddingTop) / 2;
            VerticalAxisLabelCanvasTop  = Const.PaddingTop + (ChartAreaEndY - Const.PaddingTop) / 2;
            VerticalAxisLabelHeight     = ChartAreaEndY - Const.PaddingTop;


            Double yMin = Math.Min(CircleData.Select(d => (Double)d.EnvelopeItem2).Min(), CircleData.Select(d => (Double)d.Item2).Min()),
                   yMax = Math.Max(CircleData.Select(d => (Double)d.EnvelopeItem2).Max(), CircleData.Select(d => (Double)d.Item2).Max());

            if (YStartsFromZero)
            {
                yMin = 0;
            }
            else if (yMin == yMax)
            {
                if (yMin == 0.0)
                {
                    yMin = -1; yMax = 1;
                }
                else if (yMin < 0)
                {
                    yMin *= 1.2;
                    yMax *= 0.8;
                }
                else
                {
                    yMin *= 0.8;
                    yMax *= 1.2;
                }
            }
            else
            {
                if (yMin > 0)
                {
                    yMin *= 0.9;
                }
                else
                {
                    yMin *= 1.1;
                }
            }

            YScale = new Linear()
            {
                DomainStart = yMin,
                DomainEnd   = yMax,
                RangeStart  = ChartAreaEndY,
                RangeEnd    = Const.PaddingTop
            };

            YScale.Nice();

            XScale = new Ordinal()
            {
                RangeStart = VerticalAxisCanvasLeft,
                RangeEnd   = ChartAreaEndX + Const.PaddingLeft
            };

            foreach (Object item1 in CircleData.OrderBy(dp => dp.Order)
                     .Select(cd => cd.Item1).Distinct())
            {
                XScale.Domain.Add(item1);
            }

            HandleLineElement.Data   = D3Data;
            EnvelopeLineElement.Data = D3Data;
            LineElement.Data         = D3Data;

            EnvelopeCircleElement.Data = D3CircleData;
            CircleElement.Data         = D3CircleData;

            HorizontalAxis.Scale = XScale;
            Canvas.SetTop(HorizontalAxis, ChartAreaEndY);
            HorizontalAxis.Visibility = HorizontalAxisVisibility;

            Canvas.SetTop(HorizontalAxisTitleElement, HorizontalAxisLabelCanvasTop);
            Canvas.SetLeft(HorizontalAxisTitleElement, HorizontalAxisLabelCanvasLeft);
            HorizontalAxisTitleElement.Width      = HorizontalAxisLabelWidth;
            HorizontalAxisTitleElement.Visibility = HorizontalAxisVisibility;
            HorizontalAxisTitleElement.Text       = HorizontalAxisTitle;

            VerticalAxis.Scale = YScale;
            Canvas.SetLeft(VerticalAxis, VerticalAxisCanvasLeft);

            Canvas.SetTop(VerticalAxisTitleElement, VerticalAxisLabelCanvasTop);
            Canvas.SetLeft(VerticalAxisTitleElement, VerticalAxisLabelCanvasLeft);
            VerticalAxisTitleElement.Width = VerticalAxisLabelHeight;
            VerticalAxisTitleElement.Text  = VerticalAxisTitle;

            LegendHandleRectangleElement.Data       = D3Data;
            LegendHandleRectangleElement.Visibility = LegendVisibility;

            IndicatorTextElement.Data = D3CircleData;

            HandleLineElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);
            LineElement.Update(useTransition ? TransitionType.Opacity & TransitionType.Color: TransitionType.None);
            EnvelopeCircleElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);
            EnvelopeLineElement.Update(useTransition ? TransitionType.Opacity & TransitionType.Color : TransitionType.None);
            CircleElement.Update(TransitionType.None);        // useTransition ? TransitionType.Opacity : TransitionType.None);
            LegendHandleRectangleElement.Update(TransitionType.None);
            IndicatorTextElement.Update(TransitionType.None); // useTransition ? TransitionType.Opacity : TransitionType.None);
            HorizontalAxis.Update(useTransition);
            VerticalAxis.Update(useTransition);
        }
Пример #2
0
        public void Update(Boolean useTransition)
        {
            LegendAreaWidth = 0;
            D3Data          = new Data()
            {
                List = Data.Select(d => d as Object).ToList()
            };

            firstColumnViewModel  = Data[0].ColumnViewModel;
            secondColumnViewModel = Data[0].Children[0].ColumnViewModel;

            // chart data 수정
            ChartData   = Data.SelectMany(d => d.Children).ToList();
            D3ChartData = new Data()
            {
                List = ChartData.Select(d => d as Object).ToList()
            };

            /*
             *  기존 데이터를 여러 각도로 수정해야함
             *  1. 레전드용 데이터: 두번째 키만 모아야함. 이것은 색깔을 배치할때도 쓰임
             *  2. 사각형 그리기용 데이터: 왜냐하면 hierarchical하게 있으면 안되므로
             */

            // legend 데이터 수정

            if (LegendVisibility == Visibility.Visible)
            {
                LegendData.Clear();
                foreach (GroupedBarChartDatum gbcd in Data)
                {
                    foreach (BarChartDatum bcd in gbcd.Children)
                    {
                        if (LegendData.Select(d => d.Key).Count(d => d == bcd.Key) == 0)
                        {
                            LegendData.Add(bcd);
                        }
                    }
                }

                LegendData = LegendData.OrderBy(d => d.Order).ToList();

                LegendRectangleElement.Data = new Data()
                {
                    List = LegendData.Select(d => d as Object).ToList()
                };
                LegendRectangleElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);

                LegendTextElement.Data = new Data()
                {
                    List = LegendData.Select(d => d as Object).ToList()
                };
                LegendTextElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);
                LegendTextElement.ForceMeasure();

                LegendAreaWidth          = Math.Max(LegendTextElement.MaxActualWidth + Const.LegendPatchWidth + Const.LegendPatchSpace + Const.PaddingRight, Const.MinimumLegendWidth);
                LegendTitleElement.Width = LegendAreaWidth;
                LegendTitleElement.Text  = LegendTitle;
                Canvas.SetTop(LegendTitleElement, LegendPatchYGetter(null, 0) - 30);
            }

            Canvas.SetLeft(LegendPanel, this.Width - LegendAreaWidth);

            if (HorizontalAxisVisibility == Visibility.Visible)
            {
                ChartAreaEndY = this.Height - Const.PaddingBottom - Const.HorizontalAxisHeight - Const.HorizontalAxisLabelHeight;
            }
            else
            {
                ChartAreaEndY = this.Height - Const.PaddingBottom;
            }

            if (LegendVisibility == Visibility.Visible)
            {
                ChartAreaEndX = this.Width - Const.PaddingRight - LegendAreaWidth;
            }
            else
            {
                ChartAreaEndX = this.Width - Const.PaddingRight;
            }

            HorizontalAxisLabelCanvasLeft = Const.PaddingLeft + Const.VerticalAxisWidth + Const.VerticalAxisLabelWidth;
            HorizontalAxisLabelCanvasTop  = ChartAreaEndY + Const.HorizontalAxisHeight;
            HorizontalAxisLabelWidth      = ChartAreaEndX - Const.PaddingLeft - Const.VerticalAxisWidth - Const.VerticalAxisLabelWidth;

            VerticalAxisCanvasLeft      = Const.PaddingLeft + Const.VerticalAxisLabelWidth + Const.VerticalAxisWidth;
            VerticalAxisLabelCanvasLeft = Const.PaddingLeft + Const.VerticalAxisLabelWidth / 2 - (ChartAreaEndY - Const.PaddingTop) / 2;
            VerticalAxisLabelCanvasTop  = Const.PaddingTop + (ChartAreaEndY - Const.PaddingTop) / 2;
            VerticalAxisLabelHeight     = ChartAreaEndY - Const.PaddingTop;

            isSelectionEnabled = ChartData.Any(bcd => bcd.BarState == BarState.FullySelected || bcd.BarState == BarState.PartiallySelected);

            // 최솟 최댓값 모두 envelope의 값은 고려해야함
            // 그냥 값은 선택되어 있을때만 고려해야함
            Double yMin = ChartData.Select(d => d.EnvelopeValue).Min(),
                   yMax = ChartData.Select(d => d.EnvelopeValue).Max();

            if (isSelectionEnabled) // 선택된게 하나라도 있으면
            {
                IEnumerable <Double> selected = ChartData.Where(cd => cd.BarState == BarState.FullySelected || cd.BarState == BarState.PartiallySelected).Select(cd => cd.Value);
                yMin = Math.Min(yMin, selected.Min());
                yMax = Math.Max(yMax, selected.Max());
            }

            if (YStartsFromZero)
            {
                yMin = 0;
            }
            else if (yMin == yMax)
            {
                if (yMin == 0.0)
                {
                    yMin = -1; yMax = 1;
                }
                else if (yMin < 0)
                {
                    yMin *= 1.2;
                    yMax *= 0.8;
                }
                else
                {
                    yMin *= 0.8;
                    yMax *= 1.2;
                }
            }
            else
            {
                if (yMin > 0)
                {
                    yMin *= 0.9;
                }
                else
                {
                    yMin *= 1.1;
                }
            }

            YScale = new Linear()
            {
                DomainStart = yMin,
                DomainEnd   = yMax,
                RangeStart  = ChartAreaEndY,
                RangeEnd    = Const.PaddingTop
            };

            YScale.Nice();

            XScale = new Ordinal()
            {
                RangeStart = VerticalAxisCanvasLeft,
                RangeEnd   = ChartAreaEndX + Const.PaddingLeft
            };

            foreach (GroupedBarChartDatum datum in Data)
            {
                XScale.Domain.Add(datum);
            }

            MaxBarCountInAGroup = Data.Select(d => d.Children.Count()).Max();


            // update 시 재대입 할 것들 대입

            HandleRectangleElement.Data   = D3ChartData;
            EnvelopeRectangleElement.Data = D3ChartData;
            RectangleElement.Data         = D3ChartData;

            HorizontalAxis.Scale = XScale;
            Canvas.SetTop(HorizontalAxis, ChartAreaEndY);
            HorizontalAxis.Visibility = HorizontalAxisVisibility;

            Canvas.SetTop(HorizontalAxisTitleElement, HorizontalAxisLabelCanvasTop);
            Canvas.SetLeft(HorizontalAxisTitleElement, HorizontalAxisLabelCanvasLeft);
            HorizontalAxisTitleElement.Width      = HorizontalAxisLabelWidth;
            HorizontalAxisTitleElement.Visibility = HorizontalAxisVisibility;
            HorizontalAxisTitleElement.Text       = HorizontalAxisTitle;

            VerticalAxis.Scale = YScale;
            Canvas.SetLeft(VerticalAxis, VerticalAxisCanvasLeft);

            Canvas.SetTop(VerticalAxisTitleElement, VerticalAxisLabelCanvasTop);
            Canvas.SetLeft(VerticalAxisTitleElement, VerticalAxisLabelCanvasLeft);
            VerticalAxisTitleElement.Width = VerticalAxisLabelHeight;
            VerticalAxisTitleElement.Text  = VerticalAxisTitle;

            LegendHandleRectangleElement.Data = new Data()
            {
                List = LegendData.Select(d => d as Object).ToList()
            };
            LegendHandleRectangleElement.Visibility = LegendVisibility;

            LegendRectangleElement.Data = new Data()
            {
                List = LegendData.Select(d => d as Object).ToList()
            };
            LegendRectangleElement.Visibility = LegendVisibility;

            LegendTextElement.Data = new Data()
            {
                List = LegendData.Select(d => d as Object).ToList()
            };
            LegendTextElement.Visibility = LegendVisibility;

            IndicatorTextElement.Data = new Data()
            {
                List = ChartData.Select(d => d as Object).ToList()
            };

            LegendHandleRectangleElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);
            HandleRectangleElement.Update(TransitionType.None);
            EnvelopeRectangleElement.Update(useTransition ? TransitionType.All : TransitionType.None);
            RectangleElement.Update(useTransition ? TransitionType.All : TransitionType.None);
            IndicatorTextElement.Update(useTransition ? TransitionType.All : TransitionType.None);
            HorizontalAxis.Update(useTransition);
            VerticalAxis.Update(useTransition);
        }
Пример #3
0
        public void Update(Boolean useTransition)
        {
            LegendAreaWidth = 0;
            D3Data          = new Data()
            {
                List = Data.Select(d => d as Object).ToList()
            };

            if (LegendVisibility == Visibility.Visible)
            {
                LegendRectangleElement.Data = D3Data;
                LegendRectangleElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);

                LegendTextElement.Data = D3Data;
                LegendTextElement.Update(useTransition ? TransitionType.Opacity : TransitionType.None);

                LegendTextElement.ForceMeasure();
                LegendAreaWidth = Math.Max(LegendTextElement.MaxActualWidth + Const.LegendPatchWidth + Const.LegendPatchSpace + Const.PaddingRight, Const.MinimumLegendWidth);

                LegendTitleElement.Width = LegendAreaWidth;
                LegendTitleElement.Text  = LegendTitle;
                Canvas.SetTop(LegendTitleElement, LegendPatchYGetter(null, 0) - 30);
            }

            Canvas.SetLeft(LegendPanel, this.Width - LegendAreaWidth);

            if (HorizontalAxisVisibility == Visibility.Visible)
            {
                ChartAreaEndY = this.Height - Const.PaddingBottom - Const.HorizontalAxisHeight - Const.HorizontalAxisLabelHeight;
            }
            else
            {
                ChartAreaEndY = this.Height - Const.PaddingBottom;
            }

            if (LegendVisibility == Visibility.Visible)
            {
                ChartAreaEndX = this.Width - Const.PaddingRight - LegendAreaWidth;
            }
            else
            {
                ChartAreaEndX = this.Width - Const.PaddingRight;
            }

            HorizontalAxisLabelCanvasLeft = Const.PaddingLeft + Const.VerticalAxisWidth + Const.VerticalAxisLabelWidth;
            HorizontalAxisLabelCanvasTop  = ChartAreaEndY + Const.HorizontalAxisHeight;
            HorizontalAxisLabelWidth      = ChartAreaEndX - Const.PaddingLeft - Const.VerticalAxisWidth - Const.VerticalAxisLabelWidth;

            VerticalAxisCanvasLeft      = Const.PaddingLeft + Const.VerticalAxisLabelWidth + Const.VerticalAxisWidth;
            VerticalAxisLabelCanvasLeft = Const.PaddingLeft + Const.VerticalAxisLabelWidth / 2 - (ChartAreaEndY - Const.PaddingTop) / 2;
            VerticalAxisLabelCanvasTop  = Const.PaddingTop + (ChartAreaEndY - Const.PaddingTop) / 2;
            VerticalAxisLabelHeight     = ChartAreaEndY - Const.PaddingTop;

            isSelectionEnabled = Data.Any(bcd => bcd.BarState == BarState.FullySelected || bcd.BarState == BarState.PartiallySelected);

            Double yMin = Data.Select(d => d.EnvelopeValue).Min(),
                   yMax = Data.Select(d => d.EnvelopeValue).Max();

            if (isSelectionEnabled) // 선택된게 하나라도 있으면
            {
                IEnumerable <Double> selected = Data.Where(cd => cd.BarState == BarState.FullySelected || cd.BarState == BarState.PartiallySelected).Select(cd => cd.Value);
                yMin = Math.Min(yMin, selected.Min());
                yMax = Math.Max(yMax, selected.Max());
            }

            if (YStartsFromZero)
            {
                yMin = 0;
            }
            else if (yMin == yMax)
            {
                if (yMin == 0.0)
                {
                    yMin = -1; yMax = 1;
                }
                else if (yMin < 0)
                {
                    yMin *= 1.2; yMax *= 0.8;
                }
                else
                {
                    yMin *= 0.8; yMax *= 1.2;
                }
            }
            else
            {
                if (yMin > 0)
                {
                    yMin *= 0.9;
                }
                else
                {
                    yMin *= 1.1;
                }
            }

            YScale = new Linear()
            {
                DomainStart = yMin,
                DomainEnd   = yMax,
                RangeStart  = ChartAreaEndY,
                RangeEnd    = Const.PaddingTop
            };

            YScale.Nice();

            XScale = new Ordinal()
            {
                RangeStart = VerticalAxisCanvasLeft,
                RangeEnd   = ChartAreaEndX
            };

            foreach (BarChartDatum datum in Data)
            {
                XScale.Domain.Add(datum);
            }

            // getter가 아닌 경우 재대입을 해야함 예를 들어 visibliity나 Scale등

            HandleRectangleElement.Data = D3Data;

            EnvelopeRectangleElement.Data = D3Data;
            RectangleElement.Data         = D3Data;

            HorizontalAxis.Scale = XScale;
            Canvas.SetTop(HorizontalAxis, ChartAreaEndY);
            HorizontalAxis.Visibility = HorizontalAxisVisibility;

            Canvas.SetTop(HorizontalAxisTitleElement, HorizontalAxisLabelCanvasTop);
            Canvas.SetLeft(HorizontalAxisTitleElement, HorizontalAxisLabelCanvasLeft);
            HorizontalAxisTitleElement.Width      = HorizontalAxisLabelWidth;
            HorizontalAxisTitleElement.Visibility = HorizontalAxisVisibility;
            HorizontalAxisTitleElement.Text       = HorizontalAxisTitle;

            VerticalAxis.Scale = YScale;
            Canvas.SetLeft(VerticalAxis, VerticalAxisCanvasLeft);

            Canvas.SetTop(VerticalAxisTitleElement, VerticalAxisLabelCanvasTop);
            Canvas.SetLeft(VerticalAxisTitleElement, VerticalAxisLabelCanvasLeft);
            VerticalAxisTitleElement.Width = VerticalAxisLabelHeight;
            VerticalAxisTitleElement.Text  = VerticalAxisTitle;

            LegendHandleRectangleElement.Data       = D3Data;
            LegendHandleRectangleElement.Visibility = LegendVisibility;

            LegendRectangleElement.Data       = D3Data;
            LegendRectangleElement.Visibility = LegendVisibility;

            LegendTextElement.Data       = D3Data;
            LegendTextElement.Visibility = LegendVisibility;

            IndicatorTextElement.Data = D3Data;

            LegendHandleRectangleElement.Update(TransitionType.None);
            HandleRectangleElement.Update(TransitionType.None);
            EnvelopeRectangleElement.Update(useTransition ? TransitionType.All : TransitionType.None);
            RectangleElement.Update(useTransition ? TransitionType.All : TransitionType.None);
            IndicatorTextElement.Update(useTransition ? TransitionType.All : TransitionType.None);
            HorizontalAxis.Update(useTransition);
            VerticalAxis.Update(useTransition);
        }