Ejemplo n.º 1
0
        public void SetGlyphDrawer(GlyphDrawer glyphDrawer, double fontSize)
        {
            if (this.glyphDrawer == glyphDrawer && this.fontSize == fontSize)
            {
                return;
            }

            this.glyphDrawer = glyphDrawer;
            this.fontSize    = fontSize;

            if (timeSpanUnitConfigs == null)
            {
                timeSpanUnitConfigs = new TimeSpanUnitConfig[(int)TimeSpanUnitEnum.max + 1];
            }

            maxFollowLabelWidth = double.MinValue;
            for (TimeSpanUnitEnum timeSpanUnitIndex = TimeSpanUnitEnum.none + 1; timeSpanUnitIndex <= TimeSpanUnitEnum.max; timeSpanUnitIndex++)
            {
                TimeSpanUnitMask mask             = timeSpanUnitIndex.GetMask();
                double           firstLabelWidth  = glyphDrawer.GetLength(mask.FirstLabelMask !, fontSize);
                double           followLabelWidth = glyphDrawer.GetLength(mask.FollowLabelMask !, fontSize);
                maxFollowLabelWidth = Math.Max(followLabelWidth, maxFollowLabelWidth);
                timeSpanUnitConfigs[(int)timeSpanUnitIndex] = new TimeSpanUnitConfig(timeSpanUnitIndex, firstLabelWidth, followLabelWidth);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Renders the notes to the drawingContext. The notes gets  scaled to the available height and width displaying only
        /// values between minDisplayValueX and maxDisplayValueX, if the x-values are sorted.
        /// </summary>
        protected override void OnCreateVisual(DrawingContext drawingContext, double width, double height, DrawingVisual drawingVisual)
        {
            if (glyphDrawers == null || fontFamilytracked != chart.FontFamily || fontSizeTracked != chart.FontSize)
            {
                fontFamilytracked = chart.FontFamily;
                fontSizeTracked   = chart.FontSize;
                if (glyphDrawers == null)
                {
                    glyphDrawers = new GlyphDrawer[fontDefinitions.Length];
                }
                for (int fontDefinitionIndex = 0; fontDefinitionIndex < fontDefinitions.Length; fontDefinitionIndex++)
                {
                    FontDefinition fontDefinition = fontDefinitions[fontDefinitionIndex];
                    glyphDrawers[fontDefinitionIndex] = new GlyphDrawer(
                        fontDefinition.FontFamily ?? chart.FontFamily,
                        fontDefinition.FontStyle ?? chart.FontStyle,
                        fontDefinition.FontWeight ?? chart.FontWeight,
                        fontDefinition.FontStretch ?? chart.FontStretch,
                        VisualTreeHelper.GetDpi(drawingVisual).PixelsPerDip);
                }
            }

            double minDisplayValueX = MinDisplayValues[DimensionX];
            double maxDisplayValueX = MaxDisplayValues[DimensionX];
            double minDisplayValueY = MinDisplayValues[DimensionY];
            double maxDisplayValueY = MaxDisplayValues[DimensionY];
            int    chartNotesLength = chartNotes.Length;

            for (int chartNotesIndex = 0; chartNotesIndex < chartNotesLength; chartNotesIndex++)
            {
                ChartNote chartNote   = chartNotes[chartNotesIndex];
                double    chartNotesX = chartNote.Values[0];
                if (chartNotesX < minDisplayValueX)
                {
                    continue;
                }
                double         chartNotesY    = chartNote.Values[1];
                FontDefinition fontDefinition = fontDefinitions[chartNote.FontDefinitionId];
                if ((minDisplayValueY <= chartNotesY && chartNotesY <= maxDisplayValueY) || double.IsInfinity(chartNotesY))
                {
                    Point chartNotePoint = TranslateValueXYToPoint(chartNotesX, chartNotesY, width, height);
                    if (double.IsPositiveInfinity(chartNotesY))
                    {
                        //draw at top
                        const double fontOffset = 1.3; //need to move the letters a bit down
                        chartNotePoint.Y = fontOffset * (fontDefinition.FontSize ?? chart.FontSize);
                    }
                    else if (double.IsPositiveInfinity(chartNotesY))
                    {
                        //draw at bottom
                        chartNotePoint.Y = height;
                    }
                    glyphDrawers[chartNote.FontDefinitionId].Write(drawingContext, chartNotePoint, chartNote.Note,
                                                                   fontDefinition.FontSize ?? chart.FontSize, fontDefinition.FontBrush ?? chart.Foreground);
                }

                if (chartNotesX > maxDisplayValueX)
                {
                    break;
                }
            }
        }
Ejemplo n.º 3
0
        sealed protected override Size MeasureContentOverride(Size availableSize)
        {
            if (double.IsNaN(DisplayValue) || double.IsNaN(DisplayValueRange))
            {
                //Replace default data with some data which can be displayed.
                OnProvideDefaultValues(out var displayValue, out var displayValueRange);
                DisplayValue      = displayValue;
                DisplayValueRange = displayValueRange;
            }

            //ensure that DisplayValue, DisplayValueRange, MinValue and MaxValue all have legal values
            if (double.IsInfinity(DisplayValue))
            {
                throw new Exception("DisplayValue " + DisplayValue + " cannot be infinite.");
            }

            if (double.IsInfinity(DisplayValueRange))
            {
                throw new Exception("DisplayValueRange " + DisplayValueRange + " cannot be infinite.");
            }

            if (DisplayValueRange < double.Epsilon * 1e+9)
            {
                throw new ApplicationException("DisplayValueRange " + DisplayValueRange + " must be positive.");
            }

            if (double.IsNaN(MinValue) != double.IsNaN(MaxValue))
            {
                throw new ApplicationException("MinValue " + MinValue + " and MaxValue " + MaxValue + " must be both NaN or not.");
            }

            if (!double.IsNaN(MinValue))
            {
                //min and max values are defined. Ensure that Max>Min and they are bigger or equal DisplayValue and DisplayValueRange
                if (MaxValue < MinValue)
                {
                    throw new ApplicationException("MaxValue " + MaxValue + " must be greater than MinValue " + MinValue + " .");
                }
                if (MinValue > DisplayValue)
                {
                    MinValue = DisplayValue;
                }
                if (MaxValue < DisplayValue + DisplayValueRange)
                {
                    MaxValue = DisplayValue + DisplayValueRange;
                }
            }

            Size requiredSize = availableSize;

            if (double.IsInfinity(requiredSize.Width))
            {
                //evaluate a minimum value if host gives unlimited space. The size requested as indicated in the return value of
                //MeasureContentOverride() can be changed in OnLegendMeasurement(() by an inheritor
                //
                //Normally, the legend should be in a container telling the legend the available space. If it is unlimited (Scroll Region or host
                //wants Legend to take all available space), arrange will later provide the space available, even requiredSize was 0. Another
                //reason for unlimited space is that Grid sometimes makes 2 measurement calls, in which the first one has infinite space to get
                //the requested size, followed by second measurement call with the available size, after processing the measurement information
                //from other GridCells

                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                {
                    //in Visual Studio require some width to display something
                    requiredSize.Width = 200;
                }
                else
                {
                    //normally, the legend should be in a container telling the legend the available width. If it is unlimited (Scroll Container),
                    //arrange will return all width available, even requiredSize.Width is 0.
                    requiredSize.Width = 0;
                }
            }
            //do the same for required Height
            if (double.IsInfinity(requiredSize.Height))
            {
                requiredSize.Height = System.ComponentModel.DesignerProperties.GetIsInDesignMode(this) ? 200 : 0;
            }

            if (double.IsNaN(FontSize))
            {
                throw new Exception("FontSize cannot be NaN.");
            }
            if (FontFamily == null)
            {
                throw new Exception("FontFamily cannot be null.");
            }

            if (fontFamilyTracked != FontFamily || fontSizeTracked != FontSize)
            {
                bool hasOnlyFontSizeChanged = fontFamilyTracked == FontFamily && fontSizeTracked != FontSize;
                fontFamilyTracked = FontFamily;
                fontSizeTracked   = FontSize;

                if (FontSize < 1 || FontSize > 200)
                {
                    throw new Exception("FontSize: " + FontSize + " should be between 1 and 200.");
                }

                //font might have different dimension than before. Recalculate space needed
                isNewGlyphDrawer  = true;
                LegendGlyphDrawer = new GlyphDrawer(FontFamily, FontStyle, FontWeight, FontStretch, VisualTreeHelper.GetDpi(this).PixelsPerDip);
                OnFontChanged(hasOnlyFontSizeChanged);
            }

            return(OnLegendMeasurement(requiredSize));
        }