Profile Picture

Interactive Tooltip overlapped, multichart

Posted By Mike Dando 9 Years Ago
Author
Message
Mike Dando
Problem Posted 9 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)Forum Newbie (0 reputation)

Group: Forum Members
Last Active: 9 Years Ago
Posts: 3, Visits: 36
Hello guys.
I'm testing ability to port lates NevronChart for ASP to our solution, witch is realized on Dundas-lib.
And have some problems in (see attached pics from existing app - as have to be realized with Nevron chart):
a) showing tooltips - the chart overlap them....
b) disapearing labels on Y-axe - the upper label only partly is drawn
c) the custom legend isn't shown... only in Automatic mode but thus it covered by itself the X-Axe...
d) how to make multichart with one chartcontrol where all charts are vertical aligned and synchronized on datetime X-Axe during Zoom operation.
----
I put some code used for these tasks, witch i little bit optimised for you attention

///For each kind of data the Class is executed, and ChartControl object is putting as parameter.  So for charts there will be two classes.
public class CNevronChart
{
        private   NThinChartControl NevronCurrentChartControl;
        protected NDockPanel        contentPanel;
        protected NChart            theNChart;        //  will store it for missunderstandings. it's the same object as theChart
        protected NCartesianChart   theChart;        //  Cartesian charts have five built-in axes that are always present in the axis collection
        protected NLegend           NevronCurrentLegend;
        protected NLabel            NevronCurrentTitle;

        public override void Render()
        {
            Init_NevronChart( <the Chart Control>, <the chartarea index>Wink; // create NChart object  and add it to panel, init zooming ability
            //using Init_Seria() in cycle to add series to the chart
            Init_ChartPosition();
            Init_Title();     // create legend object and add to panel
            Init_Legend();// create custom legend and add to panel
            Init_Axes();   // create axe-scales
            RenderData();// add individual legend item about seria  to legend object
            NevronCurrentChartControl.document.Calculate();// do we need it?
        }

        int Init_NevronChart( NevronChartControl NevronCurrentChartControl, int iCurrentChartIndex)
        {
     
            theChart = new NCartesianChart();
            theChart.Name = this.Get_UniqControllerName();
            theChart.AllowContentZoom = true;
            theNChart = theChart;

            //theNChart.Margins = new NMarginsL(2, 0, 2, 2);
            theNChart.Projection.SetPredefinedProjection(PredefinedProjection.Orthogonal);
            theNChart.LightModel.SetPredefinedLightModel(PredefinedLightModel.NorthernLights);
            theNChart.LightModel.EnableLighting = true;
            theNChart.Axis(StandardAxis.Depth).Visible = true;
            theNChart.Wall(ChartWallType.Floor).Visible = false;
            theNChart.Wall(ChartWallType.Left).Visible = false;
            theNChart.BoundsMode = BoundsMode.Stretch;
            theNChart.DockMode = PanelDockMode.Fill;
            theNChart.Location = new NPointL(new NLength(0, NRelativeUnit.ParentPercentage), new NLength(5, NRelativeUnit.ParentPercentage));
            theNChart.Size = new NSizeL(new NLength(90, NRelativeUnit.ParentPercentage), new NLength(95, NRelativeUnit.ParentPercentage));

            // some examples with dockpanels https://www.nevron.com/Forum/8973/How-to-change-Label-Size 
            contentPanel = new NDockPanel();
            //contentPanel.Margins = new NMarginsL(5, 5, 5, 5);
            contentPanel.PositionChildPanelsInContentBounds = true; //
            contentPanel.Name = theChart.Name;
            contentPanel.BoundsMode = BoundsMode.Stretch;
            contentPanel.DockMode = PanelDockMode.None;

            //iNevronChartIndex = contentPanel.ChildPanels.Add(theChart);
            iNevronChartIndex = NevronCurrentChartControl.Panels.Add(theChart);
            iPanelindex = NevronCurrentChartControl.Panels.Add(contentPanel);

            if (iCurrentChartIndex > 0)
            {   // in multichart execution - the 2,3,4,5... charts
                sPreviousGroupName = NevronCurrentChartControl.Charts[iCurrentChartIndex - 1].Name;
                theNChart.SetPredefinedChartStyle(PredefinedChartStyle.Vertical);
                theNChart.DockMode = PanelDockMode.Top;
                theNChart.BoundsMode = BoundsMode.Stretch;
            }
            else
            {  // if the only one chart  OR  for the first chart in multichart execution
                NevronCurrentChartControl.Legends.Clear();
                NevronCurrentChartControl.BackgroundStyle.FillStyle = new NColorFillStyle(Color.Cyan);

                // apply style sheet
                NStyleSheet styleSheet = NStyleSheet.CreatePredefinedStyleSheet(PredefinedStyleSheet.NevronMultiColor);
                styleSheet.Apply(NevronCurrentChartControl.Document);

                NevronCurrentChartControl.Settings.EnableJittering = true;
                NevronCurrentChartControl.Settings.JitterMode = JitterMode.Enabled;
                NevronCurrentChartControl.BackgroundStyle.FrameStyle.Visible = false;
                sPreviousGroupName = "";

                NevronCurrentChartControl.Controller.SetActivePanel(theNChart);
                #region Zoom
                NevronCurrentChartControl.ServerSettings.JQuery.SourceType = JQuerySourceType.Url;//JQuerySourceType.Url;
                NTooltipTool toolTip = new NTooltipTool();
                toolTip.Enabled = true;
                toolTip.Exclusive = true;
                NevronCurrentChartControl.Controller.Tools.Add(toolTip);
                NDataZoomTool datazoom = new NDataZoomTool();
                datazoom.Enabled = true;
                datazoom.Exclusive = true;
                datazoom.AllowXAxisZoom = true;
                datazoom.AllowYAxisZoom = true;
                datazoom.ZoomOutResetsAxes = true;
                NevronCurrentChartControl.Controller.Tools.Add(new NDataZoomTool());
                // add a cursor change tool
                NevronCurrentChartControl.Controller.Tools.Add(new NCursorTool());
                //NevronCurrentChartControl.Controller.Tools.Add(new NClientMouseEventTool());

                Nevron.Chart.ThinWeb.NDataZoomTool dzt = (Nevron.Chart.ThinWeb.NDataZoomTool)NevronCurrentChartControl.Controller.Tools.FindToolOfType(typeof(Nevron.Chart.ThinWeb.NDataZoomTool));
                dzt.ZoomOutResetsAxes = true;
                #endregion
            }

            theNChart.Axis(StandardAxis.PrimaryX).ScrollBar.Visible = true;
            theNChart.Axis(StandardAxis.PrimaryX).ScrollBar.ShowSliders = true;
            theNChart.Axis(StandardAxis.PrimaryY).ScrollBar.Visible = true;
            theNChart.Axis(StandardAxis.PrimaryY).ScrollBar.ShowSliders = true;
        }

        protected override void Init_Title()
        {
            string sChartTitleName = this.Get_Title();
            string sGroupServiceChartName = this.Get_UniqControllerName();

            NevronCurrentTitle = new NLabel();
            NevronCurrentTitle.TextStyle.FontStyle = new NFontStyle("Times New Roman", 9, FontStyle.Italic);
            NevronCurrentTitle.TextStyle.ShadowStyle.Type = ShadowType.LinearBlur;
           
            NevronCurrentTitle.BoundsMode = BoundsMode.Fit;
            NevronCurrentTitle.ContentAlignment = ContentAlignment.TopCenter;
            NevronCurrentTitle.Text = sChartTitleName;
            NevronCurrentTitle.Name = sGroupServiceChartName;
            NevronCurrentTitle.DockMode = PanelDockMode.Top;
            NevronCurrentTitle.Margins = new NMarginsL(0, 10, 0, 10);
            NevronCurrentTitle.Padding = new NMarginsL(4, 6, 4, 6);
            theNChart.ChildPanels.Add(NevronCurrentTitle);
        }
        protected override void Init_Legend()
        {
            string sGroupServiceChartName = this.Get_UniqControllerName();
            NevronCurrentLegend = new NLegend(); //NevronCurrentChartControl.Legends.Add(); commented it, because we make 2 charts
            NevronCurrentLegend.Name = sGroupServiceChartName;
            NevronCurrentLegend.DockMode = PanelDockMode.Bottom;
            NevronCurrentLegend.BoundsMode = BoundsMode.Fit;
            NevronCurrentLegend.UseAutomaticSize = true;
            NevronCurrentLegend.ScaleLegendGridLines = true;
           
            NevronCurrentLegend.ContentAlignment = ContentAlignment.BottomCenter;
            NevronCurrentLegend.SetPredefinedLegendStyle(PredefinedLegendStyle.Bottom);
            NevronCurrentLegend.FillStyle.SetTransparencyPercent(40);
            NevronCurrentLegend.Mode = LegendMode.Manual;
            NevronCurrentLegend.Data.ExpandMode = LegendExpandMode.HorzWrap;
           

            contentPanel.ChildPanels.Add(NevronCurrentLegend);
            //theNChart.DisplayOnLegend = NevronCurrentLegend; Because we use LegendMode.Manual
        }
        protected virtual void Init_ChartPosition()
        {
            if (iCurrentChartIndex > 0)
                theNChart.DockMode = PanelDockMode.Top;
            else
                theNChart.DockMode = PanelDockMode.Fill;
            theNChart.SetPredefinedChartStyle(PredefinedChartStyle.Vertical);//the charts organized like in chartares in vertical bound, and are synchronized by time on X axis, also during moving coursor
        }

        protected virtual void Init_Axes()
        {
            //----------------------------------------------------------------------------------------------------------
            // disable the depth axis, Y axis
            NAxis axis = theNChart.Axis(StandardAxis.PrimaryY);
            NLinearScaleConfigurator linearScale = (NLinearScaleConfigurator)theNChart.Axis(StandardAxis.PrimaryY).ScaleConfigurator;
            // configure ticks and grid lines
            linearScale.MajorGridStyle.SetShowAtWall(ChartWallType.Back, true);
            linearScale.InnerMajorTickStyle.Length = new NLength(0, NGraphicsUnit.Pixel);
            linearScale.RoundToTickMin = true;  //
            linearScale.RoundToTickMax = true;  // this helps to disapear the label on Y-axe?
            linearScale.LabelStyle.TextStyle.FontStyle = new NFontStyle("Times New Roman", 10, FontStyle.Regular);
            linearScale.LabelGenerationMode = LabelGenerationMode.SingleLevel;
            linearScale.LabelFitModes = new LabelFitMode[] { LabelFitMode.AutoScale };
            //NTextStyle textStyleResultY = new NTextStyle(new NFontStyle(YAxisFontDropDownList.SelectedValue));
            //linearScale.Title.TextStyle = textStyleResultY;
            linearScale.Title.Text = "some title";
            linearScale.Title.ContentAlignment = ContentAlignment.MiddleCenter;
            linearScale.Title.RulerAlignment = HorzAlign.Center;

            linearScale.LabelValueFormatter = new NNumericValueFormatter(NumericValueFormat.LimitedPrecision3);// we don't use labels cause they fullfill the chartarea and series will not be seen. just for to be we left the code.

            theNChart.Axis(StandardAxis.PrimaryY).ScaleConfigurator = linearScale;
            //----------------------------------------------------------------------------------------------------------
            // switch the X axis to datetime.
All series (have to) in all chartareas have the same amount of points
            NDateTimeScaleConfigurator dateTimeScale = new NDateTimeScaleConfigurator();
            dateTimeScale.AutoLabels = true;
            dateTimeScale.InnerMajorTickStyle.Visible = true;
            dateTimeScale.MajorTickMode = MajorTickMode.AutoMaxCount;
            dateTimeScale.MajorGridStyle.LineStyle.Pattern = LinePattern.Dot;
            dateTimeScale.MajorGridStyle.SetShowAtWall(ChartWallType.Back, true);

            dateTimeScale.LabelGenerationMode = LabelGenerationMode.SingleLevel;// all X-axes's label on one level
            dateTimeScale.LabelStyle.TextStyle.FontStyle = new NFontStyle("Times New Roman", 8, FontStyle.Regular);
            dateTimeScale.LabelStyle.Angle = new NScaleLabelAngle(ScaleLabelAngleMode.View, 0);
            dateTimeScale.LabelStyle.ContentAlignment = ContentAlignment.MiddleLeft;      
            dateTimeScale.LabelFitModes = new LabelFitMode[] { LabelFitMode.AutoScale };
            //dateTimeScale.AutoDateTimeUnits = new NDateTimeUnit[] { NDateTimeUnit.Day, NDateTimeUnit.Month, NDateTimeUnit.Hour, NDateTimeUnit.Minute};
            //dateTimeScale.LabelValueFormatter = new NDateTimeValueFormatter("dd.MM HH:mm"); // we will add the array
            dateTimeScale.LabelValueFormatter = new NDateTimeValueFormatter(DateTimeValueFormat.ShortDateShortTime24Hour);
            dateTimeScale.EnableUnitSensitiveFormatting = true;

            //dateTimeScale.RoundToTickMin = true;
            //dateTimeScale.RoundToTickMax = true;

            ArrayList dateTimeUnits = new ArrayList();  // установим масштаб для оси X (времени)
            dateTimeUnits.Add(NDateTimeUnit.Minute);
            dateTimeUnits.Add(NDateTimeUnit.Hour);
            dateTimeUnits.Add(NDateTimeUnit.HalfDay);
            dateTimeUnits.Add(NDateTimeUnit.Day);
            dateTimeUnits.Add(NDateTimeUnit.Week);
            dateTimeUnits.Add(NDateTimeUnit.Month);
            dateTimeUnits.Add(NDateTimeUnit.Quarter);
            dateTimeUnits.Add(NDateTimeUnit.Year);

            NDateTimeUnit[] autoUnits = new NDateTimeUnit[dateTimeUnits.Count];
            for (int i = 0; i < autoUnits.Length; i++)
            {
                autoUnits[i] = (NDateTimeUnit)dateTimeUnits[i];
            }
            dateTimeScale.AutoDateTimeUnits = autoUnits;

            theNChart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = dateTimeScale;

            //----------------------------------------------------------------------------------------------------------
            // add interlace stripe
            NScaleStripStyle stripStyle = new NScaleStripStyle(new NColorFillStyle(Color.Beige), null, true, 0, 0, 1, 1);
            stripStyle.Interlaced = true;
            stripStyle.SetShowAtWall(ChartWallType.Back, true);//  stripStyle.ShowAtWalls = new ChartWallType[] { ChartWallType.Back };
            stripStyle.SetShowAtWall(ChartWallType.Left, true);
            linearScale.StripStyles.Add(stripStyle);
        }
        protected override void RenderData()
        {
            int iNevronSeriasCount = 10;
            int iIndex = 0;
            NSeries theSeria = null;
            NLegendItemCellData theLegendItem = null;
            INevronLineSeria theINevronLineSeria = null;
            NRectangularCallout annotation = null;
           
            for (iIndex = 0; iIndex < iNevronSeriasCount; iIndex++)
            {
                annotation = Get_Annotation();// as in: https://www.nevron.com/Forum/8220/How-to-configure-annotations-to-appear-in-plot-area-only
                theSeria = theINevronLineSeria.Get_Seria();
                theLegendItem = theINevronLineSeria.Get_Legend();

                theChart.ChildPanels.Add(annotation);
                //NevronCurrentChartControl.Panels.Add(annotation);
                //Each series derived from NSeriesBase has an associated NSeriesLegend object controlling the information displayed for the series in the legend.
                // It is accessible with the help of the Legend property of the NSeriesBase class.
                //theSeria.Legend = NevronCurrentLegend;
                //theChart.Series.Add(theSeria);
                NevronCurrentLegend.Data.Items.Add(theLegendItem);
            }
        }

        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //    Working with seria
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public virtual void Init_Seria()
        {
            NSeries theSeria;
            Color SeriesColor = GetColor();
            int iPrec = 3;
            Color cMarkerColor = SeriesColor;
            Color cMarkerBorderColor = SeriesColor;
            int iMarkerBorderWidth = 2;
            int iMarkerSize = 4;
            NMarkerStyle mMarkerStyle = new NMarkerStyle(); // marker styles
            string sToolTip = "Some tooltip";       
            Array markShapes = Enum.GetValues(typeof(LegendMarkShape));
           
                     theSeria = new NLineSeries();
                    ((NLineSeries)theSeria).LineSegmentShape = LineSegmentShape.Line;
                    ((NLineSeries)theSeria).UseXValues = true;
   
            NXYZScatterSeries theSeriaAssign = theSeria as NXYZScatterSeries;
            if (theSeriaAssign != null)
            {
                theSeriaAssign.UseXValues = true;
                theSeriaAssign.UseZValues = false;
            }

            theSeria.Values.ValueFormatter = new NNumericValueFormatter("N" + iPrec.ToString());
            theSeria.FillStyle = new NColorFillStyle(SeriesColor);//Color.LightSteelBlue);
            theSeria.BorderStyle.Color = SeriesColor;// Color.MidnightBlue;
            theSeria.BorderStyle.Width = new NLength(2, NGraphicsUnit.Pixel);

            // add a step line series
            theSeria.Name = "some seria's name from array of series";
            theSeria.DataLabelStyle.VertAlign = VertAlign.Center;
            theSeria.DataLabelStyle.Visible = false;
            theSeria.InflateMargins = true;

            #region Legends
            // --------------------     Custom Legends for each seria-object
            theSeria.Legend.Mode = SeriesLegendMode.Series;
            theSeria.Legend.TextStyle = new NTextStyle(new NFontStyle("Arial", 11));
            //theSeria.Legend.TextStyle.FontStyle.EmSize = new NLength(7);//theSeria.Legend.TextStyle.FontStyle.EmSize = new NLength(7, NGraphicsUnit.Point);

            legendItem = new NLegendItemCellData(); // the object returns by public NLegendItemCellData Get_Legend() { return legendItem; }
            legendItem.Name = sLineName;
            legendItem.TextStyle.FillStyle = new NColorFillStyle(Color.DarkBlue);
            legendItem.TextStyle.FontStyle = new NFontStyle("Arial", 8);//(.EmSize = new NLength(8);barSeries.Legend.TextStyle.FontStyle.EmSize = new NLength(8, NGraphicsUnit.Point);
            legendItem.Text = sLineName_user;
            legendItem.InteractivityStyle = new NInteractivityStyle(string.IsNullOrEmpty(sToolTip) ? "No legend text" : sToolTip);
            legendItem.MarkShape = LegendMarkShape.Ellipse;
            legendItem.MarkFillStyle = new NColorFillStyle(cMarkerColor);
            legendItem.MarkBorderStyle.Color = cMarkerColor;
            legendItem.MarkBorderStyle.Width = new NLength(iMarkerBorderWidth, NGraphicsUnit.Pixel);
            legendItem.ContentAlignment = ContentAlignment.BottomCenter;
            legendItem.TextFitMode = LegendTextFitMode.None;
            legendItem.MaxTextWidth = new NLength(25);

            #endregion
 
            //-----------------------------------------------------------------------------------------------------------------------------
            // Markers

                mMarkerStyle.PointShape = PointShape.Cylinder;
                mMarkerStyle.Width = new NLength(1.0f, NRelativeUnit.ParentPercentage);
                mMarkerStyle.Height = new NLength(1.0f, NRelativeUnit.ParentPercentage);
                mMarkerStyle.BorderStyle.Color = cMarkerBorderColor;
                mMarkerStyle.FillStyle = new NColorFillStyle(cMarkerBorderColor);//lightColor);
                mMarkerStyle.BorderStyle.Width = new NLength(iMarkerBorderWidth);
                mMarkerStyle.AutoDepth = true;
                mMarkerStyle.Visible = true;
            theSeria.MarkerStyle = mMarkerStyle;

            //theSeria.DataLabelStyle.Format = "<value>";
            //            The NSeries class implements support for the following formatting commands:
            //<value> - the current data point value (extracted from the Values data series)
            //<label> - the current data point label (extracted from the Labels data series)
            //<total> - represents the total sum of the values contained in the Values series
            //<percent> - represents the percentage of the current data point value to the total value
            //<cumulative> - represents the cumulative sum accumulated up to this data point
            //<index> - represents the index of the current data point
            // any other type od data do existing??

            // EmptyDataPoints
            theSeria.Values.EmptyDataPoints.ValueMode = EmptyDataPointsValueMode.Skip;
            theSeria.Values.EmptyDataPoints.CustomValue = 0;
            theSeria.EmptyDataPointsAppearance.AppearanceMode = EmptyDataPointsAppearanceMode.None;
        }

        public void AddPointXY(NSeries theSeria, DateTime dDate, double? dValue, string sTooltip)
        {
            int iPointNumber = 0;
            NXYZScatterSeries theSeriaAssign = theSeria as NXYZScatterSeries;
            NInteractivityStyle intstyle = null;

            if (theSeriaAssign != null)
            {
                if (dValue != null)
                    iPointNumber = theSeriaAssign.Values.Add(dValue);
                else
                    iPointNumber = theSeriaAssign.Values.Add(DBNull.Value);
                theSeriaAssign.XValues.Add(dDate);
                intstyle = new NInteractivityStyle();
                intstyle.Tooltip = new NTooltipAttribute(sTooltip);
                intstyle.Cursor = new NCursorAttribute(CursorType.Hand);
                theSeriaAssign.InteractivityStyles.Add(iPointNumber, intstyle);
            }
        }

        public NLegendItemCellData Get_Legend() { return legendItem; }

        public NRectangularCallout Get_Annotation()
        {   //https://www.nevron.com/Forum/8220/How-to-configure-annotations-to-appear-in-plot-area-only
            NMyAnchor anchor = new NMyAnchor(theSeria, 50, ContentAlignment.MiddleCenter, StringAlignment.Center);

            NRectangularCallout annotation = new NRectangularCallout();
            annotation.Text = "Annotated Data Point";
            annotation.Anchor = anchor;
            annotation.UseAutomaticSize = true;

            annotation.AlwaysInsideParent = false;
            annotation.ArrowBasePercent = 0F;
            annotation.ArrowLength = new NLength(10F, NRelativeUnit.ParentPercentage);
            annotation.FillStyle = new NColorFillStyle(Color.FromArgb(255, 255, 200));
            annotation.PositionMode = CalloutPositionMode.AlignToText;
            annotation.Orientation = 270F;
            annotation.VisibilityMode = VisibilityMode.Visible;
            return annotation;
        }
};



Attachments
Dundas__ToolTip_NO_Problem.jpg (769 views, 55.00 KB)
Nevron__ToolTip_Problem.jpg (749 views, 43.00 KB)



Similar Topics


Reading This Topic