【问题标题】:flight trip status bar implementation in angular角度的飞行旅行状态栏实现
【发布时间】:2022-01-12 05:53:31
【问题描述】:

大家好,我需要在 Angular 中实现飞行行程状态栏。

  1. 如果是连续旅行(例如班加罗尔到钦奈,钦奈到乌蒂),那么直线应该在 1 层

2 如果不是继续旅行(例如班加罗尔到钦奈,乌蒂到班加罗尔),那么直线应该有一个箭头并且位于 1 层。

  1. 如果连续行程具有相同的上车和下车地点,则应位于 2 级 enter image description here

【问题讨论】:

    标签: javascript css angular


    【解决方案1】:

    当我们想要“连接”不同的元素时,我们可以使用 SVG。

    首先我们可以定义您的数据。我想玩具有一个像

    这样的数组
    trips = [
        { text: 'BLR-MAA', level: 1 },
        { text: 'MAA-HYD', level: 1 },
        { text: 'BLR-HYD', level: 1 },
        { text: 'HYB-DEL', level: 0 },
        { text: 'HYB-DEL', level: 0 },
        { text: 'DEL-BLR', level: 1 },
      ];
    

    我从上到下(0 最上)对级别进行编号

    你可以有,那么

     <div #wrapper class="wrapper">
        <ng-container *ngFor="let trip of trips; let i = index">
          <div
            #airport
            class="airport"
            [style.padding-top.px]="trip.level * 50"
          >
            {{ trip.text }}
          </div>
        </ng-container>
      </div>
    

    在哪里

    .wrapper{
      display:flex;
      justify-content:space-between;
      flex-wrap: nowrap;
      min-height: 68px;
    }
    .wrapper::after{
      content:' '
    }
    .airport
    {
      width:80px;
      text-align: center;
    }
    

    要绘制 svg,我们需要创建一系列“路径”。这个路径需要知道元素的 with 和 wrapper 的宽度,这就是我们需要的原因

    @ViewChild('wrapper') wrapper:ElementRef
    @ViewChild('airport') airport:ElementRef
    

    “有趣”是创建返回路径数组的函数

    getPaths()
      {
        const rect=this.wrapper.nativeElement.getBoundingClientRect();
        let width=this.airport.nativeElement.getBoundingClientRect().width
        const space=(rect.width-width*this.trips.length)/(this.trips.length)
        width=width+space
        const paths = [];
    
        this.trips.forEach((trip, i) => {
          if (i) {
            const fromY = this.trips[i - 1].level * 50+1; //add 1 to to allow showed the line
            const fromX = i * width - space;
            const toY = trip.level * 50+1; //add 1 to allow showed the line
            const toX = i *width;
    
            if (trip.level == this.trips[i - 1].level) {
              paths.push(
                'M' + fromX + ',' + fromY + ' L' + (toX) + ',' + toY
              );
            } else {
              const middle=(fromX+toX)/2)
              paths.push(
                'M' + fromX + ',' + fromY + ' C' + middle + ',' + fromY+
                ' '+middle+','+toY+' '+toX+','+toY
              );
            }
          }
        });
        return paths;
      }
    }
    

    看到两个相邻的元素在同一层我们创建一条线(我们用M移动到原点,用L画线

    如果两个相邻元素在不同的关卡中,我们创建一条曲线(我们使用 M 移动到原点,使用 C 来创建曲线)

    最后创建一个包含在绝对位置的 div 中的 svg,并在一个具有相对位置的 div 中创建 svg

    <div style="position:relative">
      <div #wrapper class="wrapper">
        ...
      </div>
      <div style="position:absolute;top:.5rem">
        <svg stroke="red" fill="transparent" [attr.width]="wrapper.offsetWidth" 
                 [attr.heigth]="wrapper.offsetHeight" >
          <path *ngFor="let path of paths" [attr.d]="path" />
        </svg>
      </div>
    </div>
    

    看看我们如何使用模板引用变量“wrapper”和 offsetHeigth/offsetWidth 为 svg 赋予相同的宽度和高度

    stackblitz

    【讨论】:

      猜你喜欢
      • 2013-12-19
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      相关资源
      最近更新 更多