Search code examples
angulardynamicdata-visualizationmarkupangular2-template

Dynamic data visualization in angular2 using HTML/angular2 template engine


When working with data in the frontend there are often challenges to visualize data understandable for the user. The (dynamic) data to visualize is well structured and simple (with a focus on data size and the prevention of overloading).

But the data structure below (DATA) is off course not the best visual representation for the user.

Let me explain the problem I can't solve well yet using the following example:

And let me point out here that I come from a perspective of template engines like EJS etc. which might be the main reason why I don't find a simple way to solve — don't know...

Example: Matrix Table (e.g. time slots in a year by a weekly resolution)

Data (DATA):

[
    {
        name:'Slot 1',
        slot:{
                start:3,
                end:5
             }
    },
    {
        name:'Slot 2',
        slot:{
                start:32,
                end:50
             }
    },
    {
        name:'Slot 3',
        slot:{
                start:10,
                end:26
             }
    }
]

Visualization:

The data should be rendered into a matrix table with three rows (as many rows as items in the data) and with a resolution of 52 weeks (cells) per row. And the range (start - end) should be highlighted in that table.

enter image description here

As mentioned above I came with a perspective of other templating engines and so I try to figure out how to write loops or so in angular to get this visualization. In other templating engines I would 'interpret' the data within the template and create the HTML in two loops because this "overloading" is only relevant for visual purposes.

Dynamically generated markup (EJS) - way

<table>

<%  var i, weeks=52;
    for(i=0;i<DATA.length;i+=1){
%>

<tr>
    <td><%-DATA[i].name%></td>

    <%  var j;
        for(j=1;j<=weeks;j+=1){
    %>

    <td class="<%((j>=DATA[i].slot.start && j<= DATA[i].slot.end)?'in-range':'')%>">
        <%- j %>
    <td>


    <%}%>

</tr>

<%}>

</table>

Qustion:

Actually I'm not able to solve this in an efficient way in Angular 2.x and the only solution I can achieve yet (which is not good of course) is to write the entire HTML for such a table matrix.

This obiously ends in a huge overhead whenever there is a change in the HTML required (e.g. adding a class or so). I know search & replace in the markup ;) but it's still a lot of markup to maintain which could be generated and I think there must be a way to do that in Angular2 either.

Thanks for any help pointing me into a better direction.


Solution

  • You can get desired layout with this code:

      <table>
        <tr *ngFor="let row of DATA">
          <td>{{ row.name }}</td>
          <td *ngFor="let week of weeks"
              [class.in-range]="row.slot.start <= week && week <= row.slot.end">
            {{ week }} 
          </td>
        </tr>
      </table>
    

    where weeks = [1, 2, 3, ..., 52] or, with this helper function:

    export function range(count: number, from = 0) {
      return Array.from(Array(count)).map((_, i) => i + from);
    }
    
    <td *ngFor="let week of range(52)">