1

I'm using SQL Server and Entity Framework. On my database I have the following data:

ID | Name   | ParentID
 1 | Fire   | null
 2 | Fire2  | 1
 3 | Fire3  | 2
 4 | Blast  | 2
 5 | Water  | null
 6 | Water2 | 5
 7 | WaterX | 5

I won't have massive data, so retrieving everything at once from the database is perfectly acceptable.

I want to retrieve this data and display on screen as a "tree".

    Fire
    Fire2
Fire3   Blast

     Water
Water2   WaterX

How should I do this? Should I create some sort of recursion to render it? Should I somehow convert the list to an IGrouping?

I'm having trouble converting the flat list into something that I can render hierarchically on the screen, how could I do that?

BrunoLM
  • 97,872
  • 84
  • 296
  • 452
  • recursion is the answer – T.S. Jul 12 '15 at 01:53
  • This is like 5 different questions... Do you want to know how to convert this to a structured tree object? Or do you want to know how to take this list from the backend and render it as a tree on the front end? For that I'd say find a library you like and format the data for that library. – thinklarge Jul 12 '15 at 02:07
  • Sorry, I'm just looking for a way to achieve the end result which is displaying data in a tree format. I don't know which would be the best way to do that so I'm thinking 5 different things at the same time and that is giving me headaches haha :) – BrunoLM Jul 12 '15 at 02:11
  • If you want to render to the browser in a tree I'd check out D3.js. That's pretty widely used and something I'm personally looking at learning. http://www.d3noob.org/2014/01/tree-diagrams-in-d3js_11.html. – thinklarge Jul 12 '15 at 02:12
  • I also found this on SO (http://stackoverflow.com/questions/16058073/how-do-i-draw-a-graph-or-tree-structure-in-javascript), but I'd highly recommend D3. We use it internally and it is doing some amazing rendering quickly. But there are so many JS libraries that are great, it's hard to pick. :-) – thinklarge Jul 12 '15 at 02:15
  • That's really cool, I'm going to use it! I just have to output this data in a json format then :) – BrunoLM Jul 12 '15 at 02:17

2 Answers2

1

If you can add another property to your class that has the child items like this:

public class Thing
{
    public Thing()
    {
        Things = new List<Thing>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }
    public List<Thing> Things { get; set; }
}

Then you can easily group the items to their parents like this:

var things = new List<Thing>
{
    new Thing { Id = 1, Name = "Fire", ParentId = null },
    new Thing { Id = 2, Name = "Fire2", ParentId = 1 },
    new Thing { Id = 3, Name = "Fire3", ParentId = 2 },
    new Thing { Id = 4, Name = "Blast", ParentId = 2},
    new Thing { Id = 5, Name = "Water", ParentId = null },
    new Thing { Id = 6, Name = "Water2", ParentId = 5 },
    new Thing { Id = 7, Name = "Waterx", ParentId = 6 }
};

var groupedThings = new List<Thing>();

foreach (var thing in things)
{
    if (thing.ParentId != null)
    {
        things.First(t => t.Id == thing.ParentId).Things.Add(thing);
    }
    else
    {
        groupedThings.Add(thing);
    }
}

groupedThings.Dump();

Saravana
  • 37,852
  • 18
  • 100
  • 108
1

This is the easiest way I know:

var things = new []
{
    new { Id = 1, Name = "Fire", ParentId = (int?)null },
    new { Id = 2, Name = "Fire2", ParentId = (int?)1 },
    new { Id = 3, Name = "Fire3", ParentId = (int?)2 },
    new { Id = 4, Name = "Blast", ParentId = (int?)2 },
    new { Id = 5, Name = "Water", ParentId = (int?)null },
    new { Id = 6, Name = "Water2", ParentId = (int?)5 },
    new { Id = 7, Name = "Waterx", ParentId = (int?)5 }
};

var tree = things.ToLookup(x => x.ParentId, x => new { x.Id, x.Name });

The tree looks like this:

tree

That should be fairly easy to render now.

Enigmativity
  • 113,464
  • 11
  • 89
  • 172