Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to layout a seating chart and what is the best way to convert off a table structure?

I am trying to draw a seating chart onto a webpage dynamically (asp.net-mvc site) from data in a database and the first attempt, I was using a table as a way of laying out the "grid" of rows and columns and it looked something like this:

enter image description here

In my database I have a table called Seat table with the following schema:

Id, Row, Column, Name

To render the above, I would have this in my database:

| Id | Row | Col |   Name   |  
| 1  |  2  |  2  | Seat 1   |  
| 2  |  4  |  3  | Seat 2   |  
| 3  |  6  |  2  | Seat 3   |   
| 4  |  6  |  4  | Seat 123 |  
| 5  |  8  |  2  | Seat ABC |  
| 6  |  9  |  5  | Seat DEF |  

So I am currently storing "location" as "Row" and "Column" in the database and then dynamically drawing the table above by just having a nested loop in my view. The blue items are where seats are being rendered and the rest are spaces in between where there is nothing in the database for that "cell".

Something like:

<table>
    <tr>
        <td class='space'></td>
        <td class='seat'><div class='seatInfo'>Seat ABC</div></td>
        <td class='space'></td>
    </tr>

Where the classes define some basic CSS around backcolor and width of cell.

The issue now is that the table structure forces alignment (which is good thing in some cases but ultimately a constraint as I now need to add seats that are larger than other ones and the table structure doesn't really allow that.

For example, If I want seat in Row 6, Col 4 to be "taller" that automatically makes the seat in Row 6, Column 2 change in height (given that its a table) as well which I don't want.

So here is an example floor plan in Visio and I am realizing that I don't see how I could build this view with this grid structure and maybe have to just go to complete absolute positioning for all seats and no longer have this "row" / "col" idea

enter image description here

I could have the ability to have a seat cover more than one row or column but that still only allows things to be 2x width or 2x height (versus having the flexibility to make something 1.5 times bigger than the "default" seat).

So I am thinking about changing the table to just a matrix of divs / spans and wanted to get some feedback before I started a big refactoring so I don't run into any blockers.

What would be the best way to lay out this set of information that would allow me to not get this too complication but also not hit this constraint so I can have more layout flexibility per seat. I am happy to store more information in my database (like width or height) if required.

like image 438
leora Avatar asked Jan 02 '15 04:01

leora


3 Answers

I am not sure if I have got what exactly is the problem. Assuming, from your question and comments, that you need to fit in different seats with different heights without any space between 2 rows.

This is what I have done. I have created 6 columns and added the seats using a loop such that 1st element will go inside 1st column, 2nd element will go inside the 2nd column and so on. These newly added elements will have ids row-1-col-1, row-1-col-2 ...

I have used mustache for templates for this demo

<div id="wrapper" class="container">
    <div class="row"></div>
    <div class="row">
        <div class="col-md-12">
            <p class="well">Book seats (1,5), (2,2), (2,4), (3,4) <br/>
           <button class="btn btn-primary">Book</button> </p>            
        </div>
    </div>
</div>
<script id="col_template" type="x-tmpl-mustache">
    <div class = 'col-md-2 col-xs-2' > 
      <div class = "row seat" id = "col-{{num}}"> </div>
    </div>
</script>
<script id="row_col_template" type="x-tmpl-mustache">
    <div class = 'col-md-12 row{{rownum}}' id = "row-{{rownum}}-col-{{colnum}}">
    ({{rownum}} ,{{colnum}})                
    </div>
</script>

The final output generated will be

     Col1   |    Col2    |   Col3    |   Col4     // first template generates Col-n
  ========== ============ =========== ==========
  row1-col1 | row1-col2  | row1-col3 | row1-col4  // second template generates boxes inside Col-n
  row2-col1 | row2-col2  | row2-col3 | row2-col4
  row3-col1 | row3-col2  | row3-col3 | row3-col4
  row4-col1 | row4-col2  | row4-col3 | row4-col4

Now in the above example if the height of row2-col3 is increased then row3-col3 will be pushed down, rest elements won't besides won't be affected since others are placed in different containers(Col-n). I have added a border-left to know which row the seat is part of.

enter image description here

The issue with this method is that the final output doesn't look like a proper seat arrangement.

I am not including the JS here as its not required since most logic are done at the backend for you. Hope this is what you wanted.

Demo Fiddle

like image 79
anpsmn Avatar answered Nov 09 '22 12:11

anpsmn


I believe that the most natural for you would be to use the same html structure that your database, ie

div {
  position: absolute;
  width: 50px;
  height: 30px;
  background-color: lightblue;
}
.row2 {top: 40px;}
.row4 {top: 100px;}
.row6 {top: 160px; width: 80px;}
.row8 {top: 220px;}
.row9 {top: 250px;}
.col2 {left: 50px;}
.col3 {left: 150px;}
.col4 {left: 250px;}
.col5 {left: 350px;}
<div class="row2 col2">1</div>
<div class="row4 col3">2</div>
<div class="row6 col2">3</div>
<div class="row6 col4">123</div>
<div class="row8 col2">abc</div>
<div class="row9 col5">def</div>

And then set all the display logic in the style, using absolute position.

There aren't so many CSS styles if you keep the display as a matrix; it would be only one style for every row and another one for every column.

If it is not a matrix, then you can ste specific styles, or may be better add some kind of class in the seats, and make the col position depending from both the column number and the row style.

like image 1
vals Avatar answered Nov 09 '22 11:11

vals


What if you defined a generic size unit for each seat like "seat size". For example, a standard seat size is worth "1". Your DB table would have an additional column for each seat's size. Any seats that are say twice as wide as a standard seat would have the value of "2" in the new DB column.

When rendering the HTML and CSS, each "seat" would be a div instead of a table cell, and would have hard-defined dimensions (even if was a % instead of px). e.g. a seat size of 1 may translate to 50px wide, so if a standard seat is 50px wide by 50px hight, a Seat worth 2 would be 100px wide by 50px high etc.

If you need to control size by height as well as width, then add another additional column to define the height and apply the same principle as above.

E.g.

HTML

<div class="seat-chart">
    <div class="row">
        <div class="seat" style="width: 50px; height: 50px;"> Single Seat </div>
        <div class="seat" style="width: 100px; height: 50px;"> Double Width Seat </div>
        <div class="seat" style="width: 50px; height: 50px;"> Single Seat </div>
    </div>
    <div class="row">
        <div class="seat" style="width: 100px; height: 50px;"> Double Width Seat </div>
        <div class="seat" style="width: 50px; height: 50px;"> Single Seat </div>
        <div class="seat" style="width: 50px; height: 50px;"> Single Seat </div>
    </div>
</div>

Note that you don't necessarily need to have hard defined sizes, you could use something like Bootstrap etc. or even css classes e.g. seat-row-1, seat-row-2, seat-height-2 to make your layout responsive. But I think you may find controlling height and width easier with set dimensions.

like image 1
Samuel MacLachlan Avatar answered Nov 09 '22 12:11

Samuel MacLachlan