布置座位表的最佳方式是什么?转换 table 结构的最佳方式是什么?

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

我正在尝试根据数据库中的数据在网页(asp.net-mvc 站点)上动态绘制座位表,第一次尝试时,我使用的是 table作为布置 "grid" 行和列的一种方式,它看起来像这样:

在我的数据库中,我有一个名为 Seat table 的 table,具有以下 schema

编号、行、列、名称

要呈现以上内容,我的数据库中会有这个:

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

所以我目前将 "location" 作为 "Row""Column" 存储在数据库中,然后通过在我的视图中使用嵌套循环动态绘制上面的 table .蓝色项目是正在渲染座位的地方,其余是数据库中没有任何内容的空间 "cell"

类似于:

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

其中 类 围绕 backcolorwidth 单元格定义一些基本 CSS

现在的问题是 table 结构强制对齐(这在某些情况下是好事,但最终是一个限制,因为我现在需要添加比其他座位更大的座位和 table 结构不允许这样。

例如,如果我希望第 6 行第 4 列的座位为 "taller",这会自动使第 6 行第 2 列的座位高度发生变化(假设它是 table) 以及我不想要的。

所以这是 Visio 中的示例平面图,我意识到我不知道如何使用此网格结构构建此视图,并且可能只需要完成所有的绝对定位席位,不再有这个 "row" / "col" 想法

我可以拥有超过一排或一列的座套,但这仍然只允许 2x width2x height(相对于可以灵活地制作 1.5 倍的东西)比 "default" 座位大)。

所以我正在考虑将 table 更改为 divs / spans 的矩阵,并希望在开始大型重构之前获得一些反馈,因此我不会 运行任何障碍物。

布置这组信息的最佳方式是什么,既不会让我变得太复杂,又不会遇到这个限制,这样我就可以在每个座位上有更多的布局灵活性。如果需要,我很乐意在我的数据库中存储更多信息(例如宽度或高度)。

如果您像 "seat size" 一样为每个座位定义一个通用尺寸单位会怎么样?例如,标准座位尺寸值“1”。您的 DB table 将为每个座位的大小增加一列。任何比标准座位宽两倍的座位在新数据库列中的值为“2”。

渲染 HTML 和 CSS 时,每个 "seat" 将是一个 div 而不是 table 单元格,并且将具有硬定义尺寸(即使是 % 而不是 px)。例如一个座位大小为 1 可能会转化为 50 像素宽,所以如果一个标准座位是 50 像素宽乘以 50 像素高,那么一个 2 号座位将是 100 像素宽乘以 50 像素高等。

如果您需要通过高度和宽度来控制尺寸,则添加另一列来定义高度并应用与上述相同的原理。

例如

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>

请注意,您不一定需要硬定义尺寸,您可以使用 Bootstrap 等,甚至 css 类,例如seat-row-1seat-row-2seat-height-2 使您的布局具有响应性。但我认为您可能会发现通过设置尺寸更容易控制高度和宽度。

我不确定我是否明白到底是什么问题。假设根据您的问题和评论,您需要坐在不同高度的不同座位上,两排之间没有任何 space。

这就是我所做的。我创建了 6 列并使用循环添加了座位,这样第一个元素将进入第一列,第二个元素将进入第二列,依此类推。这些新添加的元素将具有 ID row-1-col-1row-1-col-2 ...

我在这个演示的模板中使用了小胡子

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

生成的最终输出将是

     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

现在在上面的例子中,如果 row2-col3 的高度增加,那么 row3-col3 将被向下推,其余元素不会此外不会受到影响,因为其他元素被放置在不同的容器中(Col-n)。我添加了一个 border-left 来知道座位属于哪一行。

此方法的问题是最终输出看起来不像正确的座位安排。

我没有在此处包含 JS,因为它不是必需的,因为大多数逻辑都是在后端为您完成的。希望这就是你想要的。

Demo Fiddle

我相信最自然的做法是使用与数据库相同的 html 结构,即

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>

然后在样式中设置所有显示逻辑,使用绝对位置。

如果您将显示保持为矩阵,那么 CSS 样式不会太多;每行只有一种样式,每列只有一种样式。

如果不是矩阵,那么你可以设置特定的样式,或者最好在座位中添加某种class,并使col位置取决于列号和行风格。

我相信实现您想要的最有效方法是使用显示器:flex css 属性。 Here 您可以了解更多有关 flex 的信息。

我为您创建了一个简单的示例:

<div class="container">
    <div class="row">
        <div class="cell" style="width: 120px;background: #0F0">1</div>
        <div class="cell">2</div>
        <div class="cell">3</div>
    </div>
    <div class="row">
        <div class="cell">1</div>
        <div class="cell" style="height: 90px;background: #0FF">2</div>
        <div class="cell">3</div>
    </div>
    <div class="row">
        <div class="cell">1</div>
        <div class="cell">2</div>
        <div class="cell">3</div>
    </div>
</div>

.row {
    display: flex;
}
.cell {
    background: #000;
    color: #fff;
    width: 90px;
    height: 60px;
    flex: 0 0 auto;
    text-align: center;
    padding: 12px;
    border-right: 3px solid #fff;
    border-bottom: 3px solid #fff;
}

希望对您有所帮助。

Fiddle: simple example

上面的回答都不错,不过你可以考虑走JS路线。有许多打包算法,您可以在其中控制最终布局,但不必将自己限制在与 table 布局紧密耦合的单个 DOM 结构中。

例如,如果您使用 Packery 或类似的东西,您可以只拥有一个座位列表,其大小使用 styles 和 packery 本身设置 - 这样它只是一个列表 dom 元素。当然,您必须检查您是否可以依赖放置,在 Packery 的情况下,有很多您不想要的选项,例如拖放。

如果不绝对定位您的元素,您所要求的灵活性是不可能的。您不能动态地放置和调整它们的大小,同时保持最大的灵活性。这就是为什么没有人能给你一个很好的答案。

折衷方案是使用基于百分比的网格布局库,并在该库中设置每行的最大单元格数。然后,您希望将 类 分配给每个单元格,以根据数据库中每条记录的相应大小列定义宽度和高度(或样式)。我会考虑用 Bootstrap 来做这个方法:http://getbootstrap.com/

或者 - 您可以硬着头皮将座位组映射到座位模板,每个座位都具有预定义的绝对位置。不好玩,但像素完美。

晚会迟到者:为什么不用实物图,html5canvas来制作座位表呢?绘制 jpg,将座位分配直接覆盖在 Canvas 中的座位上。 (old skool,粗短的铅笔风格)。保留一个座位位置数组(SeatLocationName、xAxis、yAxis、personInSeat)。保持简单,真的很简单。关键是要获得准确的平面图图像文件。当您计划缩放时,请记住 html5 canvas 在 96 pixels/inch 下工作。 xAxis 和 yAxis 值必须相应地缩放。 (明智地选择你的单位.. dots/pixels,或英寸或毫米。)

还要记住,有一些非常简单的工具可以从大规模 canvas --> PDF 输出。为什么选择PDF?请记住,免费的 Adob​​e Reader 工具现在具有海报选项,可以非常轻松地在纸上打印大型内容...