[CLOSED] Disable/Enable Vertical Marker based on Context Menu

  1. #1

    [CLOSED] Disable/Enable Vertical Marker based on Context Menu

    This is related to the post on Toggling VerticalMarkers that Baidaly was able to help on.

    During the creation of the chart in the behind code I added:

            // QUICK ATTEMPT to enable/disable Vertical Marker based on CheckMenuItem
            if (ShowVerticalMarkers.Checked == true)
                byMonthChart.Listeners.AfterRender.Handler += "Ext.getCmp('CrtsChart').plugins[0].enable();";
            else
                byMonthChart.Listeners.AfterRender.Handler += "Ext.getCmp('CrtsChart').plugins[0].disable();";
    so that the Vertical Marker would be disabled or enabled based on the Context Menu checkMenuItem. If the CheckMenuItem is initially unchecked I received a javascript error.

    <ext:CheckMenuItem ID="ShowVerticalMarkers" runat="server" ClientIDMode="Static" Checked="false" Text="Vertical Marker">
    Below is the entire code sample, but with the CheckMenuItem attribute Checked="true".
    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <%@ Import Namespace="System.Collections.Generic" %>
    <%@ Import Namespace="System.Globalization" %>
    <script runat="server">
    
        public class ChartByMonth
        {
            public string Name { get; set; }
            public double? Y2013 { get; set; }
            public double? Y2012 { get; set; }
            public double? Y2011 { get; set; }
            public double? Y2010 { get; set; }
            public double? Y2009 { get; set; }
    
            public static Dictionary<String, ChartByMonth> GenerateData(int n = 12)
            {
                var data = new Dictionary<String, ChartByMonth>();
                for (int i = 0; i < n; i++)
                {
                    string month = CultureInfo.InvariantCulture.DateTimeFormat.GetAbbreviatedMonthName(i + 1);
                    data.Add(month, new ChartByMonth { Name = month });
                }
                return data;
            }
        }
    
        public class RequestsInfo
        {
            public int RequestMonth { get; set; }
            public int RequestYear { get; set; }
            public int Requests { get; set; }
        }
    
        protected void Page_Init(object sender, EventArgs e)
        {
            BuildChartYearCheckBoxes();
    
            ((Ext.Net.Checkbox)ChartYearsCbGroup.Items[0]).Checked = true;
        }
    
        protected void Page_Load(Object sender, EventArgs e)
        {
            if (X.IsAjaxRequest)
                return;
    
            BuildChart();
    
        }
    
        private void BuildChartYearCheckBoxes()
        {
            // Just hardcode years for this example
            for (int year = 2013; year >= 2009; year--)
            {
                ChartYearsCbGroup.Items.Add(new Ext.Net.Checkbox
                {
                    ID = "Y" + year.ToString(),
                    BoxLabel = year.ToString(),
                    InputValue = year.ToString(),
                    StyleSpec = "StyleSpec='font-size: 11px;'",
                    ClientIDMode = ClientIDMode.Static
                });
            }
    
    
        }
        protected void ChartYearsChange(object sender, DirectEventArgs e)
        {
            BuildChart();
        }
    
        private void BuildChart()
        {
            if (ChartPanelSouth.Hidden) return;
    
            CheckboxGroup cbGroup = X.GetCmp<CheckboxGroup>("ChartYearsCbGroup");
            List<Checkbox> yrsSelected = cbGroup.CheckedItems;
            if (yrsSelected.Count == 0)
            {
                ChartPanel.RemoveAll();
                ChartPanel.Update("<Select a Request Year to display a chart.</p>");
                ChartPanel.BodyStyle = "text-align: center; display: table-cell; vertical-align: middle;";
                ChartPanelSouth.Title = "Charts";
                Ext.Net.X.Mask.Hide();
                return;
            }
            else
            {
                //ChartPanel.ClearContent();
                ChartPanel.BodyStyle = "text-align: left; display:inline; vertical-align: top;";
            }
    
            ChartRequestsByMonth(yrsSelected);
    
        }
    
        private void ChartRequestsByMonth(List<Checkbox> yrsSelected)
        {
    
            int yrsSelectedCount = yrsSelected.Count();
    
            string[] yFields = new string[yrsSelectedCount];
            string[] yTitles = new string[yrsSelectedCount];
            for (int i = 0; i < yrsSelectedCount; i++)
            {
                yFields[i] = "Y" + yrsSelected[i].InputValue;
                yTitles[i] = yrsSelected[i].InputValue;
            }
    
            // Create: Line Chart (Requests by Months)
            Chart byMonthChart = new Chart();
            byMonthChart.ID = "CrtsChart";
            byMonthChart.ClientIDMode = ClientIDMode.Static;
            byMonthChart.StyleSpec = "background:#fff";
            byMonthChart.StandardTheme = StandardChartTheme.Category1;
            byMonthChart.ContextMenuID = "CrtsChart_ContextMenu";
    
            if (!(Ext.Net.RequestManager.IsIE7 || Ext.Net.RequestManager.IsIE8))
            {
                byMonthChart.Animate = true;
                byMonthChart.AnimateConfig = new AnimConfig { Easing = Easing.EaseIn, Duration = 1000 };
                byMonthChart.AnimateConfig.Listeners.AfterAnimate.Fn = "chartAnimateComplete";
            }
            else
                byMonthChart.Listeners.AfterRender.Handler = "Ext.net.Mask.hide();";
    
            // Configure: Chart Legend
            byMonthChart.LegendConfig = new ChartLegend();
            byMonthChart.LegendConfig.Position = LegendPosition.Right;
    
            VerticalMarker vm = new VerticalMarker();
            vm.Snap = true;
            vm.ShowXLabel = true;
            byMonthChart.Plugins.Add(vm);
    
            // QUICK ATTEMPT to enable/disable Vertical Marker based on CheckMenuItem
            if (ShowVerticalMarkers.Checked == true)
                byMonthChart.Listeners.AfterRender.Handler += "Ext.getCmp('CrtsChart').plugins[0].enable();";
            else
                byMonthChart.Listeners.AfterRender.Handler += "Ext.getCmp('CrtsChart').plugins[0].disable();";
           
            // Create: Category Axis
            CategoryAxis cAxis = new CategoryAxis();
            cAxis.Position = Position.Bottom;
            cAxis.Title = "Month";
            cAxis.Fields = new String[] { "Name" };
            byMonthChart.Axes.Add(cAxis);
    
            // Create: Numeric Axis
            NumericAxis nAxis = new NumericAxis();
            nAxis.Position = Position.Left;
            nAxis.Title = "Requests";
            nAxis.Fields = yFields;
            nAxis.MinorTickSteps = 1;
            nAxis.Minimum = 0;
            nAxis.Grid = true;
            nAxis.GridConfig = new AxisGrid { Odd = new SpriteAttributes { Opacity = 1, Fill = "#ddd", Stroke = "#bbb", StrokeWidth = 0.5 } };
            byMonthChart.Axes.Add(nAxis);
    
            // Create: Line series for each year
            for (int i = 0; i < yrsSelectedCount; i++)
            {
                LineSeries lSeries = new LineSeries();
                lSeries.Axis = Position.Left;
                lSeries.XField = new string[] { "Name" };
                lSeries.YField = new string[] { "Y" + yrsSelected[i].InputValue };
                lSeries.Title = yrsSelected[i].InputValue;
                lSeries.HighlightConfig = new SpriteAttributes { Size = 7, Radius = 7 };
                lSeries.MarkerConfig = new SpriteAttributes { Size = 4, Radius = 4, StrokeWidth = 0 };
    
                // Configure: Line Series Tips
                lSeries.Tips = new ChartTip();
                lSeries.Tips.TrackMouse = true;
                lSeries.Tips.BodyStyle = "text-align: center; font-size: 9px; ";
                lSeries.Tips.Renderer.Handler = "this.update('<b>' + storeItem.get('Name') + ' ' + item.series.title + '<br/>Requests</b><hr><font color=blue>' + String(item.value[1]) + '</font>');";
                byMonthChart.Series.Add(lSeries);
            }
    
            // Create: Store
            Store store = new Store();
            store.ID = "ChartStore";
            store.ClientIDMode = ClientIDMode.Static;
    
            // Create: Model based on the years checked and add it to the store.
            store.Model.Add(createModel(yrsSelected));
    
            // Populate: Build the data for the store
            store.DataSource = generateData(yrsSelected).Values.ToList();
            //store.DataBind();
            byMonthChart.Store.Add(store);
    
            ChartPanel.RemoveAll();
            byMonthChart.AddTo(ChartPanel);
    
            ChartPanelSouth.Title = "Requests by Month";
    
        }
    
        // Create a model based on the years checked
        private Model createModel(List<Checkbox> yrsSelected)
        {
            Model model = new Model();
            model.ID = "ModelByMonth";
            model.Fields.Add("Name");
    
            for (int i = 0; i < yrsSelected.Count(); i++)
            {
                ModelField field = new ModelField();
                field.Name = "Y" + yrsSelected[i].InputValue;
                field.Type = ModelFieldType.Float;
    
                // Allow special interpretation of the data only for this line chart.
                field.Convert.Handler = "if (value === null) {value = undefined;} return value;";
                model.Fields.Add(field);
            }
    
            return model;
        }
    
        private Dictionary<String, ChartByMonth> generateData(List<Checkbox> yrsSelected)
        {
            var theData = ChartByMonth.GenerateData();
            Random random = new Random();
            double p = (random.NextDouble() * 11) + 1;
    
            RequestsInfo[] byMonthRequests = new RequestsInfo[yrsSelected.Count() * 12];
            for (int y = 0; y < yrsSelected.Count(); y++)
            {
                for (int m = 0; m < 12; m++)
                {
                    RequestsInfo ri = new RequestsInfo();
                    ri.RequestMonth = m + 1;
                    ri.RequestYear = Convert.ToInt32(yrsSelected[y].InputValue);
                    ri.Requests = Convert.ToInt32(Math.Floor(Math.Max(random.NextDouble() * 100, 0)));
                    byMonthRequests[y * 12 + m] = ri;
                }
            }
    
            foreach (var reqCnts in byMonthRequests)
            {
                string monthName = CultureInfo.InvariantCulture.DateTimeFormat.GetAbbreviatedMonthName(reqCnts.RequestMonth);
    
                switch (reqCnts.RequestYear)
                {
    
                    case 2013:
                        theData[monthName].Y2013 = reqCnts.Requests;
                        break;
    
                    case 2012:
                        theData[monthName].Y2012 = reqCnts.Requests;
                        break;
    
                    case 2011:
                        theData[monthName].Y2011 = reqCnts.Requests;
                        break;
    
                    case 2010:
                        theData[monthName].Y2010 = reqCnts.Requests;
                        break;
    
                    case 2009:
                        theData[monthName].Y2009 = reqCnts.Requests;
                        break;
    
                    default:
                        break;
                }
    
            };
    
            return theData;
        }
        
    </script>
    <!DOCTYPE html >
    <html>
    <head id="Head1" runat="server">
        <title>Window issue IE7</title>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <ext:Viewport ID="Viewport1" runat="server" Layout="BorderLayout">
            <Items>
                <ext:Panel ID="Center" runat="server" Region="Center" Title="Center" />
                <ext:Panel ID="ChartPanelSouth" runat="server" ClientIDMode="Static" Region="South"
                    Title="Charts" TitleAlign="Center" Icon="ChartBar" Height="240" Split="true"
                    Collapsible="true" Layout="BorderLayout" Collapsed="false">
                    <HtmlBin>
                        <script type="text/javascript">
                            function commonChartInit() {
                                Ext.net.Mask.show({ el: Ext.get('ChartPanel'), msg: 'Building Chart ...' });
                            }
    
                            var chartAnimateComplete = Ext.Function.createBuffered(function () { Ext.net.Mask.hide(); }, 1200);
    
                        </script>
                    </HtmlBin>
                    <Bin>
                        <ext:Menu ID="CrtsChart_ContextMenu" runat="server" ClientIDMode="Static" RenderToForm="true"
                            Title="Chart Options" TitleAlign="Center">
                            <Items>
                                <ext:CheckMenuItem ID="ShowVerticalMarkers" runat="server" ClientIDMode="Static"
                                    Checked="true" Text="Vertical Marker">
                                    <Listeners>
                                        <CheckChange Handler="if (checked === true) {Ext.getCmp('CrtsChart').plugins[0].enable();} else {Ext.getCmp('CrtsChart').plugins[0].disable();};" />
                                    </Listeners>
                                </ext:CheckMenuItem>
                            </Items>
                        </ext:Menu>
                    </Bin>
                    <DockedItems>
                        <ext:Toolbar runat="server" Dock="Left" Vertical="true">
                            <Items>
                                <ext:Button ID="ChartYears" runat="server" ToolTip="years" Icon="Calendar" ArrowAlign="Right"
                                    MenuAlign="tl-tr" AutoShow="true">
                                    <Menu>
                                        <ext:Menu ID="ChartYearsMenu" runat="server" Title="Request Years" TitleAlign="Center"
                                            ShowSeparator="false" RenderToForm="true">
                                            <Items>
                                                <ext:CheckboxGroup ID="ChartYearsCbGroup" runat="server" ClientIDMode="Static" ColumnsWidths="80,80"
                                                    Vertical="true">
                                                    <Listeners>
                                                        <Change Fn="commonChartInit" />
                                                    </Listeners>
                                                    <DirectEvents>
                                                        <Change OnEvent="ChartYearsChange" />
                                                    </DirectEvents>
                                                </ext:CheckboxGroup>
                                            </Items>
                                        </ext:Menu>
                                    </Menu>
                                </ext:Button>
                            </Items>
                        </ext:Toolbar>
                    </DockedItems>
                    <Items>
                        <ext:Panel ID="ChartPanel" runat="server" ClientIDMode="Static" Region="Center" Layout="BorderLayout">
                            <Items>
                            </Items>
                        </ext:Panel>
                    </Items>
                </ext:Panel>
            </Items>
        </ext:Viewport>
        </form>
    </body>
    </html>
    Last edited by Daniil; Jun 21, 2013 at 1:44 PM. Reason: [CLOSED]
  2. #2
    Hi Chris,

    Thanks for the test case.

    Here is a fix. Please try it out and tell us if you face any issues with that fix.

    Fix
    Ext.net.VerticalMarker.override({
        init: function (chart) {
            var me = this;                
    
            me.chart = chart;
    
            if (chart.rendered) {
                me.initialize();
            } else {
                me.chart.on("afterrender", me.initialize, me, { single: true, delay: 500 });
            }
        },
    
        initialize: function () {
            var me = this;
    
            if (me.disabled) {
                return;
            }
    
            me.chart.on({
                mousemove: me.onMouseMove,
                mouseleave: me.onMouseLeave,
                scope: me
            });
    
            me.markerSprite = me.chart.surface.add(Ext.apply({
                type: 'path',
                path: ['M', 0, 0],
                zIndex: 1001,
                opacity: 0.6,
                hidden: true,
                stroke: '#00f',
                cursor: 'crosshair'
            }, me.markerConfig || {}));
        },
    
        removeLabels: function () {
            var me = this;
    
            if (me.markerSprite) {
                me.markerSprite.hide(true);
            }
    
            if (me.xFieldLabel) {
                me.xFieldLabel.hide();
            }
    
            delete me.lastItem;
    
            if (me.labels) {
                for (var i = 0, ln = me.labels.length; i < ln; i++) {
                    me.labels[i].rendered && me.labels[i].hide();
                }
            }
        },
    
        disable: function () {
            var me = this;
    
            if (me.disabled === true) {
                return;
            }
    
            if (me.updateTask) {
                me.updateTask.cancel();
            }
    
            me.chart.un({
                mousemove: me.onMouseMove,
                mouseleave: me.onMouseLeave,
                scope: me
            });
    
            me.removeLabels();
            me.disabled = true;
        },
    
        enable: function () {
            var me = this;
    
            if (me.disabled === true) {
                me.disabled = false;
                me.initialize();
            }
        }
    });
  3. #3
    Awesome, for me the changes to VerticalMarker.js work perfectly.

    Please close the thread.
  4. #4
    Nice.

    A small tip. You can replace
    byMonthChart.Listeners.AfterRender.Handler += "Ext.getCmp('CrtsChart').plugins[0].enable();";
    with
    byMonthChart.Listeners.AfterRender.Handler += "this.plugins[0].enable();";
    An component as passed to its event listeners as a scope and the first argument.
  5. #5
    Thank you, much cleaner.

    Since you have the VerticalMarker.js code open here is a graphical issue I found. If you turn on the Vertical Marker and move your mouse to the legend and disable one of the line series the Vertical Marker label for the lines series disabled is not removed. See images below:

    Click image for larger version. 

Name:	VerticalMarker01.PNG 
Views:	18 
Size:	54.6 KB 
ID:	6414Click image for larger version. 

Name:	VerticalMarker02.PNG 
Views:	19 
Size:	38.4 KB 
ID:	6415
  6. #6
    Thanks. I think all the labels should be hidden on each a Chart's redraw call. Clicking on a legend item causes such a call.

    Please try this script.

    Fix
    Ext.net.VerticalMarker.override({
        init: function (chart) {
            var me = this;
    
            me.chart = chart;
    
            if (chart.rendered) {
                me.initialize();
            } else {
                me.chart.on("afterrender", me.initialize, me, { single: true, delay: 500 });
            }
        },
    
        initialize: function () {
            var me = this;
    
            if (me.disabled) {
                return;
            }
    
            me.chart.on({
                mousemove: me.onMouseMove,
                mouseleave: me.onMouseLeave,
                scope: me
            });
    
            me.markerSprite = me.chart.surface.add(Ext.apply({
                type: 'path',
                path: ['M', 0, 0],
                zIndex: 1001,
                opacity: 0.6,
                hidden: true,
                stroke: '#00f',
                cursor: 'crosshair'
            }, me.markerConfig || {}));
    
            me.chart.redraw = Ext.Function.createSequence( me.chart.redraw, function () {
                me.removeLabels();
            }, me);
        },
    
        removeLabels: function () {
            var me = this;
    
            if (me.markerSprite) {
                me.markerSprite.hide(true);
            }
    
            if (me.xFieldLabel) {
                me.xFieldLabel.hide();
            }
    
            delete me.lastItem;
    
            if (me.labels) {
                for (var i = 0, ln = me.labels.length; i < ln; i++) {
                    me.labels[i].rendered && me.labels[i].hide();
                }
            }
        },
    
        disable: function () {
            var me = this;
    
            if (me.disabled === true) {
                return;
            }
    
            if (me.updateTask) {
                me.updateTask.cancel();
            }
    
            me.chart.un({
                mousemove: me.onMouseMove,
                mouseleave: me.onMouseLeave,
                scope: me
            });
    
            me.removeLabels();
            me.disabled = true;
        },
    
        enable: function () {
            var me = this;
    
            if (me.disabled === true) {
                me.disabled = false;
                me.initialize();
            }
        }
    });
  7. #7
    Works perfectly. Sorry about the delayed response, I was at a soccer camp all day with my son yesterday.

    Look forward to seeing this is the trunk soon. Please close the thread.
  8. #8
    Quote Originally Posted by cwolcott View Post
    I was at a soccer camp all day with my son yesterday.
    Nice. Who won?

    Quote Originally Posted by cwolcott View Post
    Look forward to seeing this is the trunk soon.
    I just waited your confirmation. Committed to SVN. Thank you for your findings!

Similar Threads

  1. [CLOSED] Enable/Disable Button
    By FVNoel in forum 2.x Legacy Premium Help
    Replies: 4
    Last Post: Mar 19, 2013, 12:02 PM
  2. Replies: 1
    Last Post: Jan 12, 2013, 4:30 AM
  3. Replies: 6
    Last Post: Aug 17, 2012, 2:02 PM
  4. Replies: 0
    Last Post: Mar 29, 2012, 12:50 PM
  5. how to disable and enable combobox?
    By sadeque in forum 1.x Help
    Replies: 1
    Last Post: Jul 27, 2009, 5:00 AM

Posting Permissions