Как нарисовать план одного этажа здания, используя javascript - PullRequest
0 голосов
/ 05 мая 2020

Я хочу нарисовать двухмерный план этажа на странице html.

У меня набор данных выглядит, как показано ниже.

Набор данных

{
  floor:{
    "id" : 2,
     rooms:[
       {
        "id" : 21,
        "x"  : 0.0,
        "y"  : 0.0,
        "height" : 15,
        "weight" : 20 
       }
       .
       .
       .
     ]
  }
}

Я хочу получить план, аналогичный изображенному ниже

floor plan 2D

И я хочу добавить всплывающую подсказку при наведении курсора на комнату.

enter image description here

Есть ли библиотека, которую вы можете порекомендовать?

Ответы [ 4 ]

6 голосов
/ 13 мая 2020

Библиотека не требуется, рисуйте фигуры SVG самостоятельно, это того стоит.

Ваши основные элементы SVG:

Дверные проемы представляют собой белые прямоугольники, уложенные сверху.

Альтернативой является использование PATH

Мой совет: сначала нарисуйте 5 прямоугольников, а затем изучите обозначение PATH (рисование той же формы RECT)

Наложения - это слушатели событий с наведением указателя мыши, которые показывают / скрывают (группируют) SVG, точно так же, как вы показываете / скрываете HTML Элементы с JavaScript

Начните с ввод SVG в JSFiddle или CodePen.
Если вы используете VS-Code, добавьте расширение SVG Preview: https://github.com/SimonSiefke/vscode-svg-preview

У вас будет первый черновик в течение часа.

Примечание. В вашем текущем наборе данных нет / не отображаются координаты, поэтому рисование зависит от вас.

2 голосов
/ 18 мая 2020

Вам потребуется дополнительная информация в вашем наборе данных. Вот код, который создает желаемое изображение ... или что-то в этом роде.

      const dataSet = {
        floor:{
          "id" : 2,
           rooms:[
             {
              "id" : 21,
              "x"  : 0.0,
              "y"  : 0.0,
              "height" : 15,
              "width" : 15,
              "weight": 0.4,
              "gap": 0.8,
              "roomSize": 5,
              "corridor": 2

             }
           ]
        }
      }
    
      const roomData = dataSet.floor.rooms[0]
      const { id
           , x
           , y
          , height
          , width
          , weight
          , gap
          , roomSize
          , corridor
          } = roomData

      const areaWidth = width - roomSize - 2 * weight
      const areaHeight = roomSize - weight
      const area = areaWidth * areaHeight
      const areas = {
        room1: area
      , room2: area
      , room3: area - weight * areaWidth
      , room4: (roomSize - 2* weight) * (roomSize - 2* weight)
      }
  
      let html = `<svg
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 ${width} ${height}"
        style={style}
      >
         <path
          d="M ${x},${y}
             h ${width - roomSize}
             v ${height - roomSize}
             h ${roomSize}
             v ${roomSize}

             h -${roomSize + 2 * weight}
             v -${weight}
             h ${weight}
             v -${weight}
             h ${weight}
             v ${weight}

             h ${roomSize - weight}
             v -${roomSize - 2 * weight}
             h -${roomSize - weight}
             v ${roomSize - 3 * weight - gap}
             h -${weight}

             v -${height - 3 * weight - gap}
             h -${width - roomSize - 2 * weight}
             
             v ${roomSize - weight}
             h ${width - roomSize - 2 * weight - corridor}
             v ${ weight}
             h -${width - roomSize - 2 * weight - corridor}

             v ${roomSize - weight}         
             h ${width - roomSize - 2 * weight - corridor}
             v ${ weight}
             h -${width - roomSize - 2 * weight - corridor}

             v ${roomSize - 2 * weight}
             h ${width - roomSize - 2 * weight - corridor}
             v ${weight}
             H 0
             z
            "
        />
        <rect
          id="room1"
          x="${weight}"
          y="${weight}"
          width="${width - roomSize - 2 * weight}"
          height="${roomSize - weight}"
          fill="#fee"
        />
        <rect
          id="room2"
          x="${weight}"
          y="${roomSize + weight}"
          width="${width - roomSize - 2 * weight}"
          height="${roomSize - weight}"
          fill="#efe"
        />
        <rect
          id="room3"
          x="${weight}"
          y="${roomSize * 2 + weight}"
          width="${width - roomSize - 2 * weight}"
          height="${roomSize - 2 * weight}"
          fill="#eef"
        />
        <rect
          id="room4"
          x="${width - roomSize}"
          y="${roomSize * 2 + weight}"
          width="${roomSize - weight}"
          height="${roomSize - 2 * weight}"
          fill="#fef"
        />
      </svg>
      `
     
      const svg = document.createElement("svg")
      svg.innerHTML = html

      document.body.appendChild(svg)

      const showArea = (event) => {
        const id = event.target.id
        const area = Math.round(areas[id])
        console.log("Area " + area + " square feet")
      }

      const rooms = [...document.querySelectorAll("rect")]
      rooms.forEach(room => {
        room.addEventListener("mouseenter", showArea, false)
      })

Область комнаты отображается в консоли, а не в виде наложения, поэтому вам придется изменить код, чтобы отобразить ее как всплывающую подсказку.

2 голосов
/ 16 мая 2020

Я думаю, вам понадобится решение на основе SVG, потому что SVG эффективны, когда есть взаимодействия с пользователем, такие как щелчки и наведение мыши. ха есть парочка библиотек. Я бы порекомендовал Raphael. js

Он существует уже некоторое время, его просто настроить и легко использовать. Есть также пара хороших книг для начинающих, которые помогут вам изучить всю библиотеку за день. Рафаэль JS, Рафаэль JS Стартер

1 голос
/ 17 мая 2020

Я думаю, вы можете использовать D3. js, хотя я не знаю, будет ли это излишним для вашего варианта использования. D3. js - отличная библиотека для создания документов, управляемых данными, то есть когда у вас есть некоторые пользовательские данные, и вы хотите использовать эти данные для управления элементами HTML DOM. Он также поддерживает динамическое c поведение и анимацию во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...