Profile Picture

Interactive Tooltip overlapped, multichart

Posted By Mike Dando 7 Years Ago
Author
Message
Mike Dando
Problem Posted 7 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: 7 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 (683 views, 55.00 KB)
Nevron__ToolTip_Problem.jpg (653 views, 43.00 KB)
Nevron Support
Posted 7 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,031, Visits: 3,692
Hi Mike,

a) showing tooltips - the chart overlap them....
This is caused because you use annotations instead of data point labels (where the chart has an option to resolve overlapping data labels and to push them inside the plot bounds). The following code snippet shows how to enable data labels:

   NChart chart = nChartControl1.Charts[0];

   chart.LabelLayout.EnableInitialPositioning = true;
   chart.LabelLayout.EnableLabelAdjustment = true;

   NLineSeries line = new NLineSeries();
   chart.Series.Add(line);

   line.DataLabelStyle.Visible = true;
   line.DataLabelStyle.Format = "<value> <label>";

   line.Values.Add(10);
   line.Labels.Add("Some Label 1");

   line.Values.Add(20);
   line.Labels.Add("Some Label 2");


b) disapearing labels on Y-axe - the upper label only partly is drawn
You need to provide some margin to the chart:
chart.Margins = new Nevron.GraphicsCore.NMarginsL(10);
It is probably docked to fill the whole area so that's why the upper part of the last y label get cut off.

c) the custom legend isn't shown... only in Automatic mode but thus it covered by itself the X-Axe...
The legend is not populated with data - we could not see where you add the custom legend item to the legend. If you want to use an automatic legend then you need to connect it to the chart - after both the chart and the legend panels are added to the document you need to write:
chart.DisplayOnLegend = legend;

where legend is a reference to the legend panel you created.

d) how to make multichart with one chartcontrol where all charts are vertical aligned and synchronized on datetime X-Axe during Zoom operation.
The following code snippet shows how to create two charts that have a synchronized x axis. The user can zoom and scroll the second chart and the first chart will be updated automatically:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!NThinChartControl1.Initialized)
            {
                NThinChartControl1.BackgroundStyle.FrameStyle.Visible = false;
                NThinChartControl1.Panels.Clear();

                // create the top chart
                NCartesianChart chart1 = new NCartesianChart();
                NThinChartControl1.Panels.Add(chart1);

                chart1.Location = new NPointL(0, 0);
                chart1.Margins = new NMarginsL(10);
                chart1.BoundsMode = BoundsMode.Stretch;
                chart1.Size = new NSizeL(new NLength(100, NRelativeUnit.ParentPercentage), new NLength(50, NRelativeUnit.ParentPercentage));

                NPointSeries point1 = new NPointSeries();
                point1.DataLabelStyle.Visible = false;
                GenerateXYData(point1);
                chart1.Series.Add(point1);

                // create the bottom chart
                NCartesianChart chart2 = new NCartesianChart();
                chart2.Margins = new NMarginsL(10);
                NThinChartControl1.Panels.Add(chart2);
                chart2.Location = new NPointL(new NLength(0), new NLength(50, NRelativeUnit.ParentPercentage));
                chart2.BoundsMode = BoundsMode.Stretch;
                chart2.Size = new NSizeL(new NLength(100, NRelativeUnit.ParentPercentage), new NLength(50, NRelativeUnit.ParentPercentage));

                NPointSeries point2 = new NPointSeries();
                point2.DataLabelStyle.Visible = false;
                GenerateXYData(point2);
                chart2.Series.Add(point2);

                // make sure they are aligned to the left
                NSideGuideline guideline = new NSideGuideline();

                guideline.Side = PanelSide.Left;
                guideline.Targets.Add(chart1);
                guideline.Targets.Add(chart2);

                NThinChartControl1.document.RootPanel.Guidelines.Add(guideline);

                // configure the x axis of the top chart to be slave of the x axis of the bottom chart
                chart2.Axis(StandardAxis.PrimaryX).Slaves.Add(chart1.Axis(StandardAxis.PrimaryX));
                chart2.Axis(StandardAxis.PrimaryX).ScrollBar.Visible = true;

                // enable data zooming and scrolling
                NThinChartControl1.Controller.SetActivePanel(chart2);
                NDataZoomTool dzt = new NDataZoomTool();
                dzt.AllowYAxisZoom = false;

                NThinChartControl1.Controller.Tools.Add(dzt);
                NThinChartControl1.Controller.Tools.Add(new NTooltipTool());
            }
        }
   
        private void GenerateXYData(NPointSeries series)
        {
            for (int i = 0; i < 200; i++)
            {
                double u1 = Random.NextDouble();
                double u2 = Random.NextDouble();

                if (u1 == 0)
                    u1 += 0.0001;

                if (u2 == 0)
                    u2 += 0.0001;

                double z0 = 100 * Math.Sqrt(-2 * Math.Log(u1)) * Math.Cos(2 * Math.PI * u2);
                double z1 = 100 * Math.Sqrt(-2 * Math.Log(u1)) * Math.Sin(2 * Math.PI * u2);

                series.XValues.Add(z0);
                series.Values.Add(z1);
                series.InteractivityStyles.Add(i, new NInteractivityStyle("X: " + z0.ToString("0.00") + ", Y:" + z1.ToString("0.00")));
            }
        }

Hope this helps - let us know if you meet any problems or have any questions.



Best Regards,
Nevron Support Team



Mike Dando
Posted 7 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: 7 Years Ago
Posts: 3, Visits: 36
Hello Team.
Thank you for your quick response and i tried asap to implement you propositions. Here's the result:
a) showing tooltips
According to your proposition i commented already existing line №239 in code witch you could see above(first my message).
The result: nothing changes/negative. (see att.pic).
b) disapearing labels on Y-axe  - solved
c) Legend
According to your proposition i recommented already existing line №141 from above code: the result is on pic, it's negative, i can't see the line. the needed tooltip is still overlapped.
My be it's needed to make smth. with line №243?
The creation of custom legend item is at line №293. And adding it at lines №237 and №245.
d) Multichart.
Is it the only mode when one chart is master and other are slaves?
i mean, the problem about Y-Axes in multichart understandable, that it can have different kind of data&scaling. But in the proposed example X-axe is the same type,using same amount of data points.
That's i mean that in existing solution we have zoom-func in both chartareas - we can zoom in any chart in multichart and that's automatically reflects on others chart on their X-Axe (but not Y). Do any Nevron limitations exists in zoom-func? Plus some problems with align, with what the scroll bar is displayed but cann't use it in slave charts (see pic& new code behind).

    protected void Page_Load(object sender, EventArgs e)
    {
        CreateNChart(theChartControl, 0); // create a first chart
        CreateNChart(theChartControl, 1); // create a second chart
    }

    public CreateNChart(NThinChartControl NevronCurrentChartControl,// Nevron ThinWebControl in witch we create multichart
                                    , int iCurrentChartIndex = 0    // the index of a chart we create in the NThinChartControl
    {
        NSideGuideline guideline = null;
        // You can create an unlimited number of charts and legends and display them in the control canvas.
        // To accomplish this you must add new instances of NChart derived objects and NLegend objects to the Panels collection of the control.
        theChart = new NCartesianChart();
        theChart.Name = "just our name for the chart";
        theChart.AllowContentZoom = true;
        NChart theNChart = theChart;// NevronCurrentChartControl.Charts[iNevronChartIndex];

        theNChart.Projection.SetPredefinedProjection(PredefinedProjection.Orthogonal);
        theNChart.LightModel.SetPredefinedLightModel(PredefinedLightModel.NorthernLights);
        theNChart.LightModel.EnableLighting = true;

        NevronCurrentChartControl.Panels.Add(theChart);


        if (iCurrentChartIndex > 0)
        {    // this code executed for the second chart, witch will have an index = 1
            theNChart.SetPredefinedChartStyle(PredefinedChartStyle.Vertical);

            theNChart.Margins = new NMarginsL(10);    // thus we will not cover the upper label on Y-Axe
            theNChart.Location = new NPointL(new NLength(0), new NLength(50, NRelativeUnit.ParentPercentage)); // the second chart will cover 50% of all chart area at the bottom
            theNChart.BoundsMode = BoundsMode.Stretch;
            theNChart.Size = new NSizeL(new NLength(100, NRelativeUnit.ParentPercentage), new NLength(50,NRelativeUnit.ParentPercentage));// 50% of all chartarea occupied by the chartcontrol

            //----------------    make sure they are aligned to the left - the result of using it
            // it doesn't give a difference to you to get the object from [0] or create a new one
            guideline = (NSideGuideline)NevronCurrentChartControl.document.RootPanel.Guidelines[0];// willing that all charts will be aligned to the first chart
            if (guideline!=null)
                guideline.Targets.Add(theNChart);

            //guideline = new NSideGuideline();
            //guideline.Side = PanelSide.Left;
            //guideline.Targets.Add(theNChart);
            //NevronCurrentChartControl.document.RootPanel.Guidelines.Add(guideline);
            //---------------------------------------------------------------------------------------
            // configure the x axis of the top chart to be slave of the x axis of the bottom chart
            NChart theFirstChart = NevronCurrentChartControl.Charts[0];
            if (theFirstChart != null)
            {
                theFirstChart.Axis(StandardAxis.PrimaryX).Slaves.Add(theNChart.Axis(StandardAxis.PrimaryX));// 2,3,4th chart will serve for first upper chart
            }
            
            NDataZoomTool dzt = new NDataZoomTool();
            dzt.Enabled = true;
            dzt.Exclusive = true;
            dzt.AllowXAxisZoom = true;
            dzt.AllowYAxisZoom = true;
            dzt.ZoomOutResetsAxes = true;
            NevronCurrentChartControl.Controller.Tools.Add(dzt);
        }
        else
        {    // this code executed for the second chart, witch will have an index = 0
            theNChart.Margins = new NMarginsL(10);        // thus we will not cover the upper label on Y-Axe
            theNChart.BoundsMode = BoundsMode.Stretch;
            theNChart.Location = new NPointL(0, 0);
            theNChart.Size = new NSizeL(new NLength(100, NRelativeUnit.ParentPercentage), new NLength(50, NRelativeUnit.ParentPercentage));

            guideline = new NSideGuideline();

            guideline.Side = PanelSide.Left;
            guideline.Targets.Add(theNChart);
            NevronCurrentChartControl.document.RootPanel.Guidelines.Add(guideline);

            NevronCurrentChartControl.Legends.Clear();

            // 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; // hide the frame around Nevron controll

            NevronCurrentChartControl.Controller.SetActivePanel(theNChart);
            #region Zoom
            // 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());
            // enable data zooming and scrolling
            NevronCurrentChartControl.Controller.SetActivePanel(theNChart);

            Nevron.Chart.ThinWeb.NDataZoomTool dzt = (Nevron.Chart.ThinWeb.NDataZoomTool)NevronCurrentChartControl.Controller.Tools.FindToolOfType(typeof(Nevron.Chart.ThinWeb.NDataZoomTool));
            dzt.ZoomOutResetsAxes = true;
            #endregion
        }
            // All charts in chartcontrol will have scroll bars
        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;
    }



Attachments
Nevron__ToolTip_Problem_Labels.jpg (778 views, 73.00 KB)
Nevron - zoom multichart problem.JPG (649 views, 55.00 KB)
Nevron Support
Posted 7 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)Supreme Being (4,278 reputation)

Group: Forum Members
Last Active: Last Week
Posts: 3,031, Visits: 3,692
Hi Mike,

Can you send the test project to support@nevron.com so that we can review / modify it - we feel that will be easier instead of communicating through the forum...


Best Regards,
Nevron Support Team





Similar Topics


Reading This Topic