Skip to main content Skip to footer

Redesign the Periodic Table as a .NET Sunburst Chart

In the world of data visualization, standard techniques like Tables, Bars and Pies have always been the conventional choice. However, you may want a more unconventional option so users can visualize large amounts of complex data easily, clearly and efficiently. In this blog, we'll look at how we can turn the Periodic Table into a Sunburst chart, bringing a new paradigm to modern data visualization. Here's our final product, developed for WinForms, WPF, and UWP: Display elements' information in the Sunburst Periodic Table Display elements' information in the Sunburst Periodic Table Let's look at how we did it.

Periodic Table: The Conventional Way

We all studied the Periodic Table of chemical elements back in our school days. As the name suggests, it is a tabular (conventional) representation of chemical elements: The conventional Periodic Table The conventional Periodic Table An important part of this presentation is the classification of elements into major groups of Metals and Non-Metals, which are further classified into different sub-groups such as Halogens, Noble Gases, Transition metals, and more, based on their chemical properties. The classification has a clear hierarchy, and tables are not always an ideal presentation for hierarchical data. In the next sections, we'll see how we can take advantage of our new .NET Sunburst chart to present this hierarchical classification of elements.

Periodic Table: The Sunburst Way

We’ll divide this transformation of Periodic Table presentation into three stages. First we will take care of data collection and processing followed by binding the chart to data and configuring the chart appearance. Finally, we will be adding some elements to the chart view for displaying additional information.

Download the Periodic Table sample: WinForms | WPF | UWP

To begin our transformation of Periodic Table to Sunburst chart, we need our chemical element data: name, Atomic Number, Atomic Weight, Category (metal, non-metal or others). You’ll find there are lot of data sets available online with this information. For this blog, we’ll use the XML data provided by Data-Explorer. This XML file contains extensive information regarding each chemical element, presented in this format:

<PeriodicElement>  
<id>1</id>  
<fields>  
<atomic-number>1</atomic-number>  
<element>Hydrogen</element>  
<symbol>H</symbol>  
<atomic-weight>1.00794</atomic-weight>  
<period>1</period>  
<group>1</group>  
<phase>gas</phase>  
<most-stable-crystal></most-stable-crystal>  
<type>Nonmetal</type>  
<ionic-radius>0.012</ionic-radius>  
<atomic-radius>0.79</atomic-radius>  
<electronegativity>2.2</electronegativity>  
<first-ionization-potential>13.5984</first-ionization-potential>  
<density>8.988E-05</density>  
<melting-point-k>14.175</melting-point-k>  
<boiling-point-k>20.28</boiling-point-k>  
<isotopes>3</isotopes>  
<discoverer>Cavendish</discoverer>  
<year-of-discovery>1766</year-of-discovery>  
<specific-heat-capacity>14.304</specific-heat-capacity>  
<electron-configuration>1s1</electron-configuration>  
<display-PeriodicElement>1</display-PeriodicElement>  
<display-column>1</display-column>  
</fields>  
</PeriodicElement>

The next step involves defining business objects that will hold the XML data. For this sample, we'll be using the element(name), atomic-number, atomic-weight, symbol and type fields only.

public class Element  
{  
[XmlElement("atomic-number")]  
public double AtomicNumber { get; set; }  

[XmlElement("atomic-weight")]  
public double AtomicWeight { get; set; }  

[XmlElement("element")]  
public string ElementName { get; set; }  

[XmlElement("symbol")]  
public string Symbol { get; set; }  

[XmlElement("type")]  
public string Type { get; set; }  

public double Value { get { return 1; } }  
}  

public class ElementRoot  
{  
[XmlElement("id")]  
public int Id { get; set; }  

[XmlElement("fields")]  
public Element Element { get; set; }  
}  

[XmlRoot("Elements")]  
public class ElementsCollection  
{  
[XmlElement("PeriodicElement")]  
public ElementRoot[] Elements { get; set; }  
}  

In the Element class above, we also defined an additional “Value” property. That will help determine the sweep angle for each slice when we plot the sunburst chart. To have equal sweep angles for each slice, let's keep the same value: 1. Next we'll deserialize the XML using .NET’s XmlSerializer:

public static ElementsCollection DeserializeXml(string path)  
{  
using (var reader = new StreamReader(path))  
{  
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ElementsCollection));  
return (ElementsCollection)xmlSerializer.Deserialize(reader);  
}  
} 

At this point, we have our XML transformed to an array that holds the details of chemical elements. Next, we'll define a few more classes that will divide the elements into Groups (Metals, Non-Metals and Others) and their Subgroups (Halogens, Noble Gases, etc.) and provide the source collection for our chart’s DataSource.

public class Group  
{  
public string GroupName { get; set; }  
public List<SubGroup> SubGroups { get; set; }  
}  

public class SubGroup  
{  
public string SubGroupName { get; set; }  
public string Characteristics { get; set; }  
public List<Element> Elements { get; set; }  
}  

public class DataSource  
{  
//This will serve as the chart’s DataSource  
public List<Group> Groups { get; set; }  

public DataSource()  
{  
var metals = new Group("Metals");  
//Add Subgroups to metals  
var nonmetals = new Group("Non Metals");  
//Add Subgroups to non-metals  
var others = new Group("Others");  
//Add Subgroups to Others  

Groups.Add(metals);  
Groups.Add(nonmetals);  
Groups.Add(others);  
GroupElements();  
}  
}  

The GroupElements() method contains the logic for grouping the elements array that we got from the XML deserialization. (You can find the complete code in the sample attached to this blog.) At this point the initial XML data has been processed and transformed into .NET objects, and it's ready to be plotted on the chart. Let’s set up our chart. Stage 2: Set Up the Periodic Table Sunburst Chart You'll notice that, with the help of the sunburst chart, binding the chart to data and configuring its appearance is the easiest part of this whole transformation process. The following code shows how it’s done for this sample:


var data = new Model.DataSource();  
sunburst.Legend.Position = Position.None;  
sunburst.ToolTip.Active = false;  
sunburst.InnerRadius = 0.3;  
sunburst.SelectionMode = ChartSelectionMode.Point;  
sunburst.SelectedItemPosition = Position.Top;  
sunburst.DataSource = data.Groups;  
sunburst.Binding = "Value";  
sunburst.BindingName = "GroupName,SubGroupName,Symbol";  
sunburst.ChildItemsPath = "SubGroups,Elements";  
sunburst.DataLabel.Position = PieLabelPosition.Center;  
sunburst.DataLabel.Content = "{name}";  


This completes our second stage, and you can now see our modern version of the Periodic Table: Periodic Table, take two: the Sunburst chart Periodic Table, take two: the Sunburst chart Stage 3: Display a Selected Item We've achieved one goal: showcase sunburst as a modern visualization option to your hierarchical data. But we're not done yet. Our Periodic Table doesn't show the elements' atomic numbers or chemical properties, so our chart is incomplete. For this sample, we created three panels, one for each hierarchy level, that display this information in the chart’s center: 03-Sunburst-Periodic-Table-Group-Panel The panels will be associated with the Group, __SubGroup and Element classes we defined above via an IChartModel interface

public interface IChartModel  
{  
UserControl GetUserControl();  
}

Implementation for one of the panels is shown below. For rest, you can refer to the sample.

public class Group :IChartModel  
{  
public string GroupName { get; set; }  
public List<SubGroup> SubGroups { get; set; }  
public UserControl GetUserControl()  
{  
return new GroupPanel(this) { Visible = false };  
}  
}

The selected item will be determined by using the chart’s HitTest() method:

UserControl _ctrl;  
private void OnMouseClick(object sender, MouseEventArgs e)  
{  
var ht = sunburst.HitTest(e.Location);  
if (ht == null || ht.Item == null)  
return;  
if (sunburst.Controls.Contains(_ctrl))  
sunburst.Controls.Remove(_ctrl);  
if (ht.Item is Model.IChartModel)  
{  
_ctrl = ((Model.IChartModel)ht.Item).GetUserControl();  
}  
sunburst.Controls.Add(_ctrl);  
SetDimensions(_ctrl);  
SetCoordinates(_ctrl);  
}

This completes the last stage. The image below shows the final version of the sample: Display elements' information in the Sunburst Periodic Table Display elements' information in the Sunburst Periodic Table

Periodic Table – The Modern Version Displaying Selected Item’s Information

We saw above how we transformed the Periodic Table from its traditional tabular representation to the modern Sunburst representation. As long as you can think of your data in a hierarchical perspective, you can use Sunburst to represent it.

Download the Periodic Table sample: WinForms | WPF | UWP

See it in Wijmo 5 JavaScript!

MESCIUS inc.

comments powered by Disqus