Optimize the UX of your applications with the Ignite UI jQuery Radial Menu

Marina Stoyanova / Friday, May 23, 2014

Ignite UI Radial Menu Header imageThe 14.1 release of Ignite UI came with a brand new OneNote MX Inspired jQuery Radial Menu control. This control presents its items in a circular arrangement around a center button and thus allows the end-user to select any item faster because each item is equally positioned in relation to the center. If you have been following my blogs so far you may have read the ones about the  XAML Radial Menu and the WinForms Radial Menu. With the release of this Web UI widget now you can create office inspired apps on every platform.

Essentials

From User experience point of view the Radial Menu strikes 10 out of 10 points when it comes to easy navigation through the different items. With its circular structure every slice is equally distant from the center which means that you can reach/select every one of them for the same duration and considerably faster compared to using a normal menu. The supported item types for this control are various and has unlimited levels of hierarchy. Among those types you can find numerical values, color values as well as buttons  that perform action.

As I said this control is inspired by the OneNote MX menu which means that it is intended to be a tool for text editing but of course it is flexible so you can customize it and use it according to your needs. We are going to take a look at some of the basics to help you get started with this widget effortlessly. Let’s start by saying that by default the Radial Menu has 8 items – meaning that the inner area is separated in 8 equal slides and if you need less items the other space will remain blank. Of course that doesn’t mean that you are obligated to make 8 wedges, you just have to change the value of the minWedgeCount property to the number of items you need. This option comes in handy when you create a numericgauge item because it allows the gauge to spread along the whole inner area of the sub-item.

If you want to create a numeric item you have to add an item of numericitem type which will act as a button to the numeric gauge. Visually the slice will contain a custom image or header if any and an associated numeric value above them. The child item should be of numericgauge type which will allow to select a numeric value.

JS:

  1. $("#radialMenu").igRadialMenu({
  2.     width: "300px",
  3.     height: "300px",
  4.     minWedgeCount: 1,
  5.     items:
  6.     [
  7.         {
  8.             type: "numericitem",
  9.             header: "Font Size",
  10.             iconUri: "/Icons/Size.png",
  11.             value: "8",
  12.             items:
  13.             [
  14.                 {
  15.                     name: "gauge1",
  16.                     type: "numericgauge",
  17.                     ticks: "10,12,18,24,36",
  18.                     value: 12,
  19.                     smallIncrement: 2,
  20.                     valueChanged: function (evt, ui) {
  21.                         if (evt.newValue == 10) setFontSize(2);
  22.                         else if (evt.newValue == 12) setFontSize(3);
  23.                         else if (evt.newValue == 18) setFontSize(5);
  24.                         else if (evt.newValue == 24) setFontSize(6);
  25.                         else if (evt.newValue == 36) setFontSize(7);
  26.                     }
  27.                 }
  28.             ]
  29.         }
  30.     ]
  31. });

MVC:

  1. @(
  2.     Html.Infragistics().RadialMenu()
  3.         .ID("radialMenu")
  4.         .Width("300px")
  5.         .Height("300px")
  6.         .MinWedgeCount(1)
  7.         .Items(i =>
  8.             {
  9.                 i.NumericItem("numItems1")
  10.                     .Header("Size")
  11.                     .IconUri("/Icons/Size.png")
  12.                     .Value(8)
  13.                     .Items(subItem => subItem.NumericGauge("numGauge1")                    
  14.                     .WedgeSpan(5)
  15.                     .Ticks(new double[] {8,9,10,11,12,13,14,16,18,20,22,24,26,28,36,48})
  16.                     .Value(8));
  17.             })
  18.         .Render()
  19.     )

Image:

Ignite UI Radial Menu Numeric Items

Another specific item type is the coloritem. When you add this item to the menu it will display custom image and header if any and an associated color. The child items should be of colorwell type. This item is specialized item that displays associated color in the item area and the outer ring.  To create the whole palette of colors you need to add a hierarchy of  color well children. The snippet below demonstrates how to do that for the yellow color.

JS:

  1. type: "coloritem",
  2.             header: "Foreground",
  3.             iconUri: "/Icons/FColor.png",
  4.             items:
  5.             [
  6.                 {
  7.                     type: "colorwell",
  8.                     color: "#FFFF00",
  9.                     autoRotateChildren: false,
  10.                     items:
  11.                     [
  12.                         {
  13.                             type: "colorwell",
  14.                             color: "#ffffe5"
  15.                         },
  16.                         {
  17.                             type: "colorwell",
  18.                             color: "#ffffcc"
  19.                         },
  20.                         {
  21.                             type: "colorwell",
  22.                             color: "#ffffb9"
  23.                         },
  24.                         {
  25.                             type: "colorwell",
  26.                             color: "#ffff99"
  27.                         },
  28.                         {
  29.                             type: "colorwell",
  30.                             color: "#ffff7f"
  31.                         },
  32.                         {
  33.                             type: "colorwell",
  34.                             color: "#ffff66"
  35.                         },
  36.                         {
  37.                             type: "colorwell",
  38.                             color: "#ffff4c"
  39.                         },
  40.                         {
  41.                             type: "colorwell",
  42.                             color: "#ffff32"
  43.                         },
  44.                         {
  45.                             type: "colorwell",
  46.                             color: "#ffff19"
  47.                         }
  48.                     ]
  49.                 },{...}
  50.          ]

MVC:

  1. i.ColorItem("colorItem1")
  2.                 .Header("Color")
  3.                 .IconUri("/Icons/BColor.png")
  4.                 .Items(si =>
  5.                 {
  6.                     si.ColorWell().Color("#FFFF00").Items(colorItem =>
  7.                     {
  8.                         colorItem.ColorWell().Color("#FFD55F");
  9.                         colorItem.ColorWell().Color("#FFEB9C");
  10.                         colorItem.ColorWell().Color("#FFFF00");
  11.                         colorItem.ColorWell().Color("#AC4D25");
  12.                         colorItem.ColorWell().Color("#D16227");
  13.                         colorItem.ColorWell().Color("#EB7C23");
  14.                         colorItem.ColorWell().Color("#F6901E");
  15.                         colorItem.ColorWell().Color("#FFC000");
  16.                     });
  17.                 });

Image:

Ignite UI Radial Menu Color Items

You can see from the images that in the outer ring above some of the items there are arrows – this is an indicator that these items have sub-items and you can navigate to them through those arrows. All items ( regardless if they have child items or not) act as simple buttons you can assign actions to through the click handler . For the items with hierarchical structure, each time a child item is used, its name is set on the parent's recentItem property. You can use that property to perform the same functionality the child item had from the parent, essentially functioning the same way as a split button would.

JS:

  1. $("#radialMenu").igRadialMenu({
  2.     width: "300px",
  3.     height: "300px",
  4.     minWedgeCount: 1,
  5.     items:
  6.     [
  7.         {
  8.             name: "bold",
  9.             header: "Bold",
  10.             iconUri: "/Icons/Bold.png",
  11.             click: function () { toggleBold(); }
  12.         }
  13.     ]
  14. });

MVC:

  1. @(
  2.     Html.Infragistics().RadialMenu()
  3.         .ID("radialMenu")
  4.         .Width("300px")
  5.         .Height("300px")
  6.         .MinWedgeCount(1)
  7.         .Items(i =>
  8.             {
  9.                 i.Item("button1")
  10.                     .Header("Bold")
  11.                     .IconUri("/Icons/Bold.png")
  12.                     .ClientEvents(new Dictionary<string, string>() { { "click", "function(evt, ui) { alert('Bold clicked'); }" } });
  13.             })
  14.         .Render()
  15.     )

Image:

Radial Menu Bold button

The following snippet is an example how to make  a parent item act like a split button.

  1.     type: "list",
  2.     header: "Font",
  3.     highlightBrush: "#004A7F",
  4.     outerRingButtonFill: "#4C4C4C",
  5.     outerRingButtonHotTrackFill: "#66CCFF",
  6.     autoRotateChildren: false,
  7.     iconUri: "/Icons/Font.png",
  8.     click: function (evt, ui) {
  9.         setFontFamily(evt.item.recentItemName);
  10.     },
  11.     items:
  12.     [
  13.         {
  14.             header: "Arial",
  15.             name: "Arial",
  16.             highlightBrush: "#004A7F",
  17.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  18.         },
  19.         {
  20.             header: "Calibri",
  21.             name: "Calibri",
  22.             highlightBrush: "#004A7F",
  23.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  24.         },
  25.         {
  26.             header: "Comic Sans",
  27.             name: "Comic Sans MS",
  28.             highlightBrush: "#004A7F",
  29.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  30.         },
  31.         {
  32.             header: "Consolas",
  33.             name: "Consolas",
  34.             highlightBrush: "#004A7F",
  35.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  36.         },
  37.         {
  38.             header: "Courier New",
  39.             name: "Courier New",
  40.             highlightBrush: "#004A7F",
  41.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  42.         },
  43.         {
  44.             header: "Segoe",
  45.             name: "Segoe UI",
  46.             highlightBrush: "#004A7F",
  47.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  48.         },
  49.         {
  50.             header: "Tahoma",
  51.             name: "Tahoma",
  52.             highlightBrush: "#004A7F",
  53.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  54.         },
  55.         {
  56.             header: "Times",
  57.             name: "Times New Roman",
  58.             highlightBrush: "#004A7F",
  59.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  60.         },
  61.         {
  62.             header: "Verdana",
  63.             name: "Verdana",
  64.             highlightBrush: "#004A7F",
  65.             click: function (evt, ui) { setFontFamily(evt.item.name); }
  66.         }
  67.     ]
  68. }

Let’s get creative

The radial menu can be separated in three main parts – outer ring, inner area and center button. All of these parts can be easily customized by changing their brush, highlights, border and etc..  Let’s go over the options that are related to these parts and see how to manipulate and change the appearance of the control.

We are going to stat from inside out. The center button! The center button is the first thing you see when you run the control. Thanks to it you can expand or collapse the Radial Menu as well as navigate through the hierarchical levels of the different options (it allows access to menu items on the previous level). It has three main states: closed, open and when you interact with it. Each of there states is connected with two options one for the border stroke and one responsible for the internal fill color.

Ignite UI Radial Menu Customized Center Button

Let’s continue with the inner area. The inner area displays the current level menu items.  Similar to the center button this part of the menu has states, which means that you can change the appearance of the inner area when it is in a undisturbed condition and then you interact with one of the items. The outer edge of this inner area is called a selection arc and in this arc you can see the currently hovered menu item highlights and its checked state.

Ignite UI Radial Menu Customized Inner Area

The outer part of the radial menu is the Outer Ring. If there are arrows above the items in this part of the menu this means that these items have sub-items and you can navigate to them. As you have probably guessed similar to the above mentioned parts of the control you can manipulate the outer ring on few levels. You can change the appearance of the main ring as well as the appearance of the buttons on it. The supported option for customizing this ring are various and detailed. You can even customize the arrow on the the buttons.

Ignite UI Radial Menu Customized Outer Ring

Summary

The main idea behind the radial menu is to be simple and easy to work with. It should present small number of items and distribute them in a circular arrangement which speeds up items selection. It is designed to look and behave like OneNote’s radial menu but it allows you to customize it and adopt it to your needs. This colorful, functional and handy widget can undoubtedly optimize the user experience of your applications.

Check out a live demo on jsFiddle or download the ASP.NET MVC sample.

You can follow us on Twitter @Infragistics and stay in touch on Facebook, Google+ and LinkedIn!