【问题标题】:What is the best way to layout a seating chart and what is the best way to convert off a table structure?布局座位表的最佳方式是什么?转换表格结构的最佳方式是什么?
【发布时间】:2015-02-28 12:00:27
【问题描述】:

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

在我的数据库中,我有一个名为 Seat 的表,其中包含以下 schema:

ID、行、列、名称

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

| 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" 在数据库中,然后通过在我的视图中使用嵌套循环来动态绘制上面的表格。蓝色项目是正在呈现座位的位置,其余是在数据库中没有任何内容的空间之间的空间 "cell"。

类似:

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

类在单元格的backcolor 和width 周围定义了一些基本的CSS。

现在的问题是桌子结构强制对齐(这在某些情况下是件好事,但最终是一个约束,因为我现在需要添加比其他座位更大的座位,而桌子结构实际上不允许这样做。

例如,如果我希望第 6 行第 4 列的座位“更高”,这会自动使第 6 行第 2 列的座位的高度发生变化(因为它是一张桌子),而我不这样做'不想。

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

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

因此,我正在考虑将表格更改为仅包含 divs / spans 的矩阵,并希望在开始大规模重构之前获得一些反馈,这样我就不会遇到任何阻碍。

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

【问题讨论】:

  • 如果您想要具有统一高度的行,其中包含看起来具有不同高度的单元格,请在每个单元格内添加一个具有您想要的高度的元素并将阴影应用于该元素(不是 td )。如果您想实现任意行高的最佳拟合,我会考虑Masonry。
  • 所以我的 TD 中确实有 div(我试图让问题尽可能简单,但我在问题中添加了一个 div 以使其更明确)但我仍然有问题如果有一排我有一个相邻的座位列表,并且在下一排我想在座位之间留出空间。似乎表格结构总是会导致我遇到一行或一列会影响另一行或列的间距的问题
  • 这是我今天的小贴士!看看下面的答案,当你失去了桌子结构时,阅读座位表似乎变得非常复杂和困难。当一排排座位不再排成一列时,看起来很奇怪,很难看出到底是怎么回事。我会建议完全不同的东西。使用其他视觉提示来显示座位更大,例如颜色编码,或者只是在单元格中添加文本说 “1.5x 宽” 或类似的东西。看起来会干净很多,普通人也能看清楚座位表。
  • ^ 随时转移我的赏金;) ........
  • 既然已经提到了很多好主意,但它们似乎对你没有用,你介意展示一个基本方案,说明你想要的结果是什么样的吗?

标签: jquery html css asp.net-mvc html-table


【解决方案1】:

迟到者:为什么不直接使用实际图像和 html5 画布来创建座位表?直接在 Canvas 中的座位上绘制 jpg 覆盖的座位分配。 (老派,粗短的铅笔风格)。保留座位位置数组(SeatLocationName、xAxis、yAxis、personInSeat)。保持简单,真的很简单。关键是要获得准确的平面图图像文件。当您计划缩放时,请记住 html5 画布以 96 像素/英寸的速度工作。 xAxis 和 yAxis 值必须相应地缩放。 (明智地选择你的单位......点/像素,或英寸或毫米。)

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 顺便说一句,我的回答确实涉及绝对定位。 (当然,我并不是说它很棒:-)。它还允许逐个像素定位每个座位,这仅取决于您想要样式表的大小
    【解决方案3】:

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

    例如,如果您使用Packery 或类似的东西,您可以只使用样式和包装本身来设置座位大小的列表——这样它只是一个 dom 元素的列表。当然,您必须检查您是否可以依赖该展示位置,并且对于 Packery,有很多您不想要的选项,例如拖放。

    【讨论】:

    • 我不认为包装或砌体是解决我问题的正确方法,因为它们似乎擅长布局并将事物放入边界,但在我的情况下,我试图复制非常固定和静态的东西布局
    【解决方案4】:

    我相信完成你想要的最有效的方法是使用 display: 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;
    }
    

    希望这会有所帮助。

    小提琴:simple example

    【讨论】:

      【解决方案5】:

      我相信对您来说最自然的是使用与您的数据库相同的 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 样式;每行只有一种样式,每列只有一种样式。

      如果不是矩阵,则可以指定特定的样式,或者最好在席位中添加某种类,并根据列号和行样式来确定col位置。

      【讨论】:

        【解决方案6】:

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

        在呈现 HTML 和 CSS 时,每个“座位”将是 div 而不是表格单元格,并且具有硬定义的尺寸(即使是 % 而不是 px)。例如座位尺寸为 1 可能会转换为 50 像素宽,因此如果标准座位是 50 像素宽 x 50 像素高,那么价值 2 的座位将是 100 像素宽 x 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-1、seat-row-2、seat-height-2 使您的布局响应。但我认为您可能会发现使用设置尺寸更容易控制高度和宽度。

        【讨论】:

          【解决方案7】:

          我不确定我是否知道到底是什么问题。假设,根据您的问题和 cmets,您需要适合不同高度的不同座椅,两排之间没有任何空间。

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

          我在这个演示中使用了 mustache 作为模板

          <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

          【讨论】:

          • 这并不是我真正想要的,因为它只能部分解决问题。我的要求不是“两排之间没有任何空间”,而是反映座位布局不是完美“网格”的准确画面,在某些情况下,某些座位比其他座位占用更多空间,因此比例符合真的是地板上的布局。在您的示例中,如果其中一个座位的宽度更大而不是高度怎么办?
          • @leora 哦,好的。然后,正如 adeneo 在他的评论中提到的那样,最好让它具有相同的宽度和高度,并且您可以让座椅在悬停在座椅上时展开,或者您可以拥有一个信息图标,单击该图标会打开一个弹出窗口。 Something like this when on hover
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-19
          • 2013-09-15
          • 1970-01-01
          • 1970-01-01
          • 2012-06-30
          • 1970-01-01
          • 2012-01-26
          相关资源
          最近更新 更多