ComponentOne Information

ComponentOne Studio/Wijmo/Xuniの最新情報を公開中

周期表を.NETのサンバーストチャートで再作成する

データ視覚化の世界では、従来、テーブルや棒グラフ、円グラフのような選択が主流でした。しかし、ユーザーが大量かつ複雑なデータを簡単で効率的に視覚化できるように斬新なアプローチが必要となるかもしれません。本ブログでは、周期表をサンバーストチャートとして作成し、近代のデータ視覚化に新たなパラダイムを確立しています。

下記はFlexChart for WinForms/WPF/UWPで作成できる、周期表のサンバーストチャートです。

Display elements' information in the Sunburst Periodic Table

サンバーストチャートで元素の情報を表示する

 

≫ ComponentOne Studioのダウンロードはこちら

 

従来の周期表

次のテーブルは、我々が学生の時に勉強した周期表です。名前が示すとおり、元素を規則に従って配列した表で、従来の表現になります。

f:id:ComponentOne_JP:20170410172928p:plain

 

この表の重要な部分は、金属と非金属という主要なグループに元素を分類することです。これらのグループは、その化学的性質に基づいて更にハロゲン、希ガス、遷移金属などの異なるサブグループに分類されます。

分類には明確な階層があり、表は階層データにとって理想的な表現ではありません。次のセクションでは、.NETの新しいサンバーストチャートを使用して、この階層的な要素の分類をどのように提示できるかを見ていきます。

 

サンバーストを使用するモダンな周期表

周期表をサンバーストチャートとして表示する実装方法を3段階に分けています。最初にデータの収集と処理を行い、次にデータをチャートにバインドしてチャートの外観を設定します。最後に、追加情報を表示するためにいくつかのチャート要素を指定します。

 

≫ 周期表サンプルのダウンロードはこちら: WinForms | WPF | UWP

 

ステップ1:データの収集と処理

サンバーストチャートで周期表を作成する前に、元素名、原子番号、原子量、カテゴリ(金属、非金属、その他)などのような元素のデータを用意しておく必要があります。

インターネット上に利用できるデータセットは多数ありますが、本ブログでは、Data-Explorerで提供されているXMLデータを使用しています。このXMLファイルには各元素に関する広範囲な情報が含まれています。

 

<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>

 

次のステップではXMLデータを保持するビジネス・オブジェクトを定義します。このサンプルでは、element(元素名)、atomic-number(原子番号)、atomic-weight(原子量)、symbol(元素記号)、type(型)のみを使用します。

 

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; }
}

 

上記のElementクラスではValueプロパティも定義しました。Valueプロパティは、サンバーストチャートにデータをプロットするときに各スライスの掃引角度を決定します。本サンプルでは、スライスごとに掃引角度を同じにするように値を1として設定しています。


次に、.NET のXmlSerializerを使用してXMLを逆シリアル化します。

 

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

 

XMLは元素の詳細を保持する配列に変換されましたので、元素をグループ(金属、非金属、その他)とサブグループ(ハロゲン、希ガスなど)に分割するクラスとチャートのデータソースを提供するクラスを定義します。

 

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();
    }
}

 

GroupElementsメソッドには、XMLの逆シリアル化から取得した元素の配列をグループ化するロジックが含まれています。完全なコードはサンプルをダウンロードして確認できます。

≫ 周期表サンプルのダウンロードはこちら: WinForms | WPF | UWP

 

上記手順でXML データが処理され、.NETオブジェクトに変換されました。次は、この変換されたXMLデータをチャートにプロットします。

 

ステップ2:サンバーストチャートの設定

チャートをデータにバインドして外観を設定する部分は、周期表をサンバーストチャートとして表示するための変換処理の中で最も簡単です。以下は、本サンプルからの抜粋です。

 

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}";

 

これで、周期表がサンバーストチャートに変換されました。

f:id:ComponentOne_JP:20170410175317p:plain

周期表:サンバーストチャートでの変換

 

ステップ3:選択項目の詳細表示

これで、階層的なデータを近代的なサンバーストチャートで表示できました。ただ、周期表ならば、元素の原子番号や化学的性質を表示しなければなりません。

このサンプルでは、3つの階層レベルの情報をチャートの中央に表示するために、レベルごとにパネルを作成しています。

f:id:ComponentOne_JP:20170410175443p:plain

これらのパネルは、IChartModelインターフェースを介して定義されたGroup、SubGroup、Elementsの3つのクラスに関連付けられます。

 

public interface IChartModel
{
    UserControl GetUserControl();
}

 

以下は、1つのパネルの実装方法を示しています。他のパネルに関しては、サンプルを参照してください。

 

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

 

選択した項目は、チャートのHitTest()メソッドを使用して判定されます。

 

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);
}

 

これで最後のステップが完了しました。最終的に周期表の階層的なデータは以下のように表示されます。

Display elements' information in the Sunburst Periodic Table

元素の情報をサンバーストチャートに表示する

 

本ブログでは、周期表を伝統的な表形式から現代のサンバーストに変換して表示しました。使用するデータが階層的であれば、同様にサンバーストチャートを活用できますので、是非お試しください。

 

 ※本ブログの内容は、下記英語版のブログを翻訳したものです。

   ≫ Redesign the Periodic Table as a .NET Sunburst Chart

 

 

ComponentOne