【问题标题】:Using JS to append REST data to a Matrix Grid使用 JS 将 REST 数据附加到矩阵网格
【发布时间】:2021-07-24 01:20:21
【问题描述】:

我创建了一个网格/矩阵,我想附加我通过 Fetch 从 SharePoint 列表收集的 JSON 数据。

我为每个方格应用了一个 ID,以便可以附加项目。我到了这个地步,脑子里放了个屁,不知道如何实际输入/附加数据。我不想只在方块上显示文字,当我将鼠标悬停在事件所在的方块上时,我正在考虑使用 (::before and ::after) 伪元素,将弹出一个包含有关事件信息的模式或对话框。

我通过 fetch 提取的数据在 data.d.results 中被格式化为 JSON。

这是数据样本

JSON 响应

{
  "d": {
    "results": [
      {
        "Title": "Pandemic & Natural Disasters",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(2)",
        "Likelihood": "5",
        "Consequence": "3"
      },
      {
        "Title": "New Example",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(3)",
        "Likelihood": "4",
        "Consequence": "4"
      },
      {
        "Title": "Example #2",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(3) Performance (Scope)",
        "Likelihood": "4",
        "Consequence": "3"
      },
      {
        "Title": "Delays",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(2) Schedule",
        "Likelihood": "5",
        "Consequence": "2"
      }
    ]
  }
}

所以网格是 5x5,对话框/模态的位置取决于数据值似然(Y 轴)和结果(X 轴)。所以在样本数据中 x=3, y=4 所以它会在黄色方块中。然后在对话框/模态中,文本应显示如下:

-------------------------------------
|               Title               |
|              Category             |
|              Priority             |
|               Status              |
|              Severity       
|
------------------------------------

我怎样才能做到这一点?

这是我的矩阵:

.box {
  position: relative;
  background-color: lightgrey;
  color: #fff;
  border-radius: 0px;
  padding: 20px;
  font-size: 150%;
  border: 1px solid black;
}

.wrapper {
  margin: 60px 0 90px 90px;
  display: grid;
  grid-gap: 0;
  grid-template-columns: repeat(5, 100px);
  grid-template-rows: repeat(5, 100px);
  grid-auto-flow: column;
}

#red {
  background-color: red;
}
#yellow {
  background-color: yellow;
}
#green {
  background-color: green;
}
section {
  position: relative;
  width: 600px;
}
p.likelihood {
   transform: rotate(-90deg) translateY(-50%);
   transform-origin: top;
   position: absolute;
   top: 50%;
   left: -20px;
   font-size: 30px;
   margin: 0;
}

p.consequence {
   font-size: 30px;
   position: absolute;
   transform: translateX(-50%);
   left: calc(50% + 45px);
   bottom: -60px;
   margin: 0;
}

.numbers-container {
  position: absolute;
  display: flex;
}

.numbers-container-x {
  padding-top: 10px;
  left: 90px;
  bottom: -25px; 
}

.numbers-container-x .number {
  width: 100px;
  text-align: center;
}

.numbers-container-y {
  flex-direction: column-reverse;
  left: 70px;
  top: 0;
}

.numbers-container-y .number {
  height: 100px;
  line-height: 100px;
}
<section>
  <div class="wrapper">
    <div class="box box1" id="5" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="4" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="3" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="2" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="1" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="6" style="background-color: #ffff32;">

    </div> 
    <div class="box box1" id="7" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="8" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="9" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="10" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="15"  style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="14" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="13" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="12" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="11" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="16" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="17" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="18" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="19" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="20" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="25" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="24" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="23" style="background-color: #ff3232;">


    </div>
    <div class="box box1" id="22" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="21" style="background-color: #ffff32;">

    </div>
  </div>
  
  <div class="numbers-container numbers-container-y">
    <div class="number">1</div>
    <div class="number">2</div>
    <div class="number">3</div>
    <div class="number">4</div>
    <div class="number">5</div>
  </div>
  
  <div class="numbers-container numbers-container-x">
    <div class="number">1</div>
    <div class="number">2</div>
    <div class="number">3</div>
    <div class="number">4</div>
    <div class="number">5</div>
  </div>
  
  <p class="likelihood">
    Likelihood
  </p>
  <p class="consequence">
    Consequence
  </p>
</section>

【问题讨论】:

  • 我没有正确理解这个问题。我认为为了更好地理解,您可以提供一些失败的测试用例并解释结果应该是什么。有问题的行为是什么以及预期的行为是什么的屏幕截图也会有很大帮助。
  • 可以选择修改DOM结构吗?

标签: javascript html css pseudo-element


【解决方案1】:

如果可能的话,您可以按照此模板修改 DOM 结构并让 5 行包含 5 个框,从而使您更轻松:

  <div class="wrapper">
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      ...
    </div>
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      ...
    </div>
  </div>

你可以很容易地在 JavaScript 中使用这个函数来获取对应的盒子节点:

const getBoxNode = (x, y) => {
  const rowId = Math.abs(y - 5)
  const row = document.querySelector(`.row:nth-child(${rowId + 1})`)

  return row.querySelector(`.box:nth-child(${x})`)
}

然后您可以将数据添加到此节点:

const appendData = (data) => {
  const {Title, category, Priority, Status, Severity} = data
  const x = data.consequence
  const y = data.likelihood

  const box = getBoxNode(x, y);
  
  // add texts
  [Title, category, Priority, Status, Severity].forEach((text) => {
    const pNode = document.createElement('p')
    pNode.textContent = text
    
    box.appendChild(pNode)
  })
}

完整代码如下:

const risks = {
  "d": {
    "results": [{
        "Title": "Pandemic & Natural Disasters",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(2)",
        "Likelihood": "5",
        "Consequence": "3"
      },
      {
        "Title": "New Example",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(3)",
        "Likelihood": "4",
        "Consequence": "4"
      },
      {
        "Title": "Example #2",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(3) Performance (Scope)",
        "Likelihood": "4",
        "Consequence": "3"
      },
      {
        "Title": "Delays",
        "Status": "Active",
        "Priority": "(1) High",
        "Category": "(2) Schedule",
        "Likelihood": "5",
        "Consequence": "2"
      }
    ]
  }
}




const getBoxNode = (x, y) => {
  const rowId = Math.abs(y - 5)
  const row = document.querySelector(`.row:nth-child(${rowId + 1})`)

  return row.querySelector(`.box:nth-child(${x})`)
}

const appendData = (item) => {
  const {
    Title,
    Category,
    Priority,
    Status,
    Severity
  } = item
  const x = Number(item.Consequence)
  const y = Number(item.Likelihood)

  const box = getBoxNode(x, y);

  // add texts
  [Title, Category, Priority, Status, Severity].forEach((text) => {
    const pNode = document.createElement('p')
    pNode.textContent = text

    box.appendChild(pNode)
  })
}

Promise.resolve(risks)
  .then((data) => {
    data.d.results.forEach((item) => {
      appendData(item)
    });
  });
.row {
  display: flex;
}

.box {
  position: relative;
  background-color: lightgrey;
  color: #fff;
  border-radius: 0px;
  width: 98px;
  height: 98px;
  font-size: 150%;
  border: 1px solid black;
  overflow: scroll;
}

.box p {
  font-size: 12px;
  color: black;
  margin: 5px;
}

.wrapper {
  margin: 60px 0 90px 90px;
}

#red {
  background-color: red;
}

#yellow {
  background-color: yellow;
}

#green {
  background-color: green;
}

section {
  position: relative;
  width: 600px;
}

p.likelihood {
  transform: rotate(-90deg) translateY(-50%);
  transform-origin: top;
  position: absolute;
  top: 50%;
  left: -20px;
  font-size: 30px;
  margin: 0;
}

p.consequence {
  font-size: 30px;
  position: absolute;
  transform: translateX(-50%);
  left: calc(50% + 45px);
  bottom: -60px;
  margin: 0;
}

.numbers-container {
  position: absolute;
  display: flex;
}

.numbers-container-x {
  padding-top: 10px;
  left: 90px;
  bottom: -25px;
}

.numbers-container-x .number {
  width: 100px;
  text-align: center;
}

.numbers-container-y {
  flex-direction: column-reverse;
  left: 70px;
  top: 0;
}

.numbers-container-y .number {
  height: 100px;
  line-height: 100px;
}
<section>
  <div class="wrapper">
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>
    <div class="row">
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
      <div class="box"></div>
    </div>

    <div class="numbers-container numbers-container-y">
      <div class="number">1</div>
      <div class="number">2</div>
      <div class="number">3</div>
      <div class="number">4</div>
      <div class="number">5</div>
    </div>

    <div class="numbers-container numbers-container-x">
      <div class="number">1</div>
      <div class="number">2</div>
      <div class="number">3</div>
      <div class="number">4</div>
      <div class="number">5</div>
    </div>

    <p class="likelihood">
      Likelihood
    </p>
    <p class="consequence">
      Consequence
    </p>
</section>

查看JsFiddle

【讨论】:

  • 感谢您的回答,请参阅此评论所附的我的小提琴。您的回答与我正在尝试做的最接近。在我初始化一个名为风险的新获取请求后,我在 fetch(risks) 中 let items = data.d.results,然后是 items.forEach((item) =&gt; { console.log(item.Title, item.Category, item.Status, item.Priority, item.Likelihood, item.Consequence, item.Severity); });
  • jsfiddle.net/BeerusDev/kq58un32/1 在我实现之后在控制台中,它告诉我@ line 19 Cannot destructure property 'Title' of 'items' as it is undefined. at appendData
  • @BeerusDev 这很正常,因为我还更新了 HTML 的结构,通过添加一些 .row 包装器来赋予它更多逻辑。因此,请考虑对 HTML 和 CSS 所做的更改。
  • 我仍然遇到同样的错误,我很困惑。我需要将 Title 的类型设置为 ?string 吗?
  • @BeerusDev 我用完整的 JSON 响应更新了我的代码,希望它现在也能在你身边工作:) 如果确实如此,请不要忘记将赏金归因于它不会自动完成。
【解决方案2】:

如果您已经获取数据 - 这意味着您正在使用 javascript。在这种情况下,您可以使用title 属性将信息显示为工具提示。为了简化您查找特定单元格的方式,您可能需要更改ids,以便更容易找到正确的单元格。

这是您提供的数据的示例。将鼠标悬停在 [4,3] 元素上方,您将看到带有数据的工具提示。

const dataFromFetch = {
  "likelihood" : 4, 
  "consequence": 3, 
  "severity" : 12, 
  "category": "Category Name", 
  "Status": "Active", 
  "Title": "This is the Title of the Occurrence", 
  "Priority": "High"
}

document.getElementById( dataFromFetch.likelihood + '-' + dataFromFetch.consequence ).title =  
  dataFromFetch.category + '\n' + 
  dataFromFetch.Status + '\n' + 
  dataFromFetch.Title + '\n' +
  dataFromFetch.Priority
.box {
  position: relative;
  background-color: lightgrey;
  color: #fff;
  border-radius: 0px;
  padding: 20px;
  font-size: 150%;
  border: 1px solid black;
}

.wrapper {
  margin: 60px 0 90px 90px;
  display: grid;
  grid-gap: 0;
  grid-template-columns: repeat(5, 100px);
  grid-template-rows: repeat(5, 100px);
  grid-auto-flow: column;
}

#red {
  background-color: red;
}
#yellow {
  background-color: yellow;
}
#green {
  background-color: green;
}
section {
  position: relative;
  width: 600px;
}
p.likelihood {
   transform: rotate(-90deg) translateY(-50%);
   transform-origin: top;
   position: absolute;
   top: 50%;
   left: -20px;
   font-size: 30px;
   margin: 0;
}

p.consequence {
   font-size: 30px;
   position: absolute;
   transform: translateX(-50%);
   left: calc(50% + 45px);
   bottom: -60px;
   margin: 0;
}

.numbers-container {
  position: absolute;
  display: flex;
}

.numbers-container-x {
  padding-top: 10px;
  left: 90px;
  bottom: -25px; 
}

.numbers-container-x .number {
  width: 100px;
  text-align: center;
}

.numbers-container-y {
  flex-direction: column-reverse;
  left: 70px;
  top: 0;
}

.numbers-container-y .number {
  height: 100px;
  line-height: 100px;
}
<section>
  <div class="wrapper">
    <div class="box box1" id="5-1" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="4-1" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="3-1" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="2-1" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="1-1" style="background-color: 
  #329932;">
    </div>
    <div class="box box1" id="5-2" style="background-color: #ffff32;">

    </div> 
    <div class="box box1" id="4-2" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="3-2" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="2-2" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="1-2" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="5-3"  style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="4-3" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="3-3" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="2-3" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="1-3" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="5-4" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="4-4" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="3-4" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="2-4" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="1-4" style="background-color: 
  #329932;">

    </div>
    <div class="box box1" id="5-5" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="4-5" style="background-color: #ff3232;">

    </div>
    <div class="box box1" id="3-5" style="background-color: #ff3232;">


    </div>
    <div class="box box1" id="2-5" style="background-color: #ffff32;">

    </div>
    <div class="box box1" id="1-5" style="background-color: #ffff32;">

    </div>
  </div>
  
  <div class="numbers-container numbers-container-y">
    <div class="number">1</div>
    <div class="number">2</div>
    <div class="number">3</div>
    <div class="number">4</div>
    <div class="number">5</div>
  </div>
  
  <div class="numbers-container numbers-container-x">
    <div class="number">1</div>
    <div class="number">2</div>
    <div class="number">3</div>
    <div class="number">4</div>
    <div class="number">5</div>
  </div>
  
  <p class="likelihood">
    Likelihood
  </p>
  <p class="consequence">
    Consequence
  </p>
</section>

【讨论】:

  • 我真的很喜欢工具提示!你每天学习新的东西!我怎么能在盒子里弹出一些东西来表明有东西呢?
  • jsfiddle.net/BeerusDev/z6v5a29q/1 看我的小提琴。这个方法我试过了,在控制台报错:Uncaught (in promise) ReferenceError: item is not defined
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多