Графическое представление (Tree-View) объекта JavaScript? - PullRequest
1 голос
/ 16 апреля 2019

У меня есть проблема, которую я не могу решить самостоятельно.У меня есть объект JavaScript с так называемыми ГРУППАМИ.Каждая группа может иметь одну или несколько подгрупп или так называемые системы.

Моя задача теперь состоит в том, чтобы отобразить эту структуру графически - своего рода древовидное представление (цветные элементы DIV).Но я понятия не имею, как читать этот объект, чтобы построить его графически.

Мой объект:

const test = {
      grp: [
        {
          groupID: 'group-1',
          grp : [
            {
              groupID: 'group-2',
              grp: [
                {
                  groupID: 'group-3',
                  sys: ['sys1','sys2','sys3']
                },
                {
                  groupID: 'group-4',
                  grp: [
                    {
                      groupID: 'group-5',
                      sys: ['sys4','sys5','sys6']
                    },
                    {
                      groupID: 'group-6',
                      grp: [
                        {
                          groupID: 'group-7',
                          sys: ['sys7','sys8','sys9']
                        }
                      ]
                    }
                  ]
                }
              ],
              sys: ['sys0']
            }
          ]
        }
      ]
    };

Вот графический пример: https://pic -hoster.net / view / 69453 / grp-sys.jpg.htm

Я очень надеюсь, что кто-то здесь может мне помочь.Как бы вы подошли к этой задаче?

Графическое представление (Tree-View) объекта JavaScript

Ответы [ 2 ]

0 голосов
/ 16 апреля 2019

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

Чистое решение javascript

const test = {"grp":[{"groupID":"group-1","grp":[{"groupID":"group-2","grp":[{"groupID":"group-3","sys":["sys1","sys2","sys3"]},{"groupID":"group-4","grp":[{"groupID":"group-5","sys":["sys4","sys5","sys6"]},{"groupID":"group-6","grp":[{"groupID":"group-7","sys":["sys7","sys8","sys9"]}]}]}],"sys":["sys0"]}]}]}

function tree(data, parent) {
  if(data.grp) {
    data.grp.forEach(obj => {
      const child = document.createElement('div')
      child.className = 'child'

      const children = document.createElement('div')
      children.className = 'children'

      if(obj.groupID) {
        const name = document.createElement('div');
        name.className = 'name'
        name.textContent = obj.groupID
        child.appendChild(name)
      }

      if(obj.sys) {
        const system = document.createElement('div')
        system.className = 'system';

        obj.sys.forEach(s => {
          const sys = document.createElement('div')
          sys.className = 'item'
          sys.textContent = s
          system.appendChild(sys)
        })

        children.appendChild(system)
      }

      child.appendChild(children)
      parent.appendChild(child)
      tree(obj, children)
    })
  }
}

const root = document.body.querySelector('#root')
tree(test, root)
#root * {
  color: white;
}

.system {
  background: #E00022;
  display: flex;
  flex-direction: column-reverse;
  padding: 10px;
}

.name {
  background: #595959;
  padding: 10px;
}

.child {
  display: flex;
  flex-direction: column-reverse;
}

.children {
  display: flex;
  align-items: flex-end;
}

.children > div {
  flex: 1;
  border-bottom: 1px solid white;
}
<div id="root"></div>

Реакционный раствор

const {Component} = React;
const data = {"grp":[{"groupID":"group-1","grp":[{"groupID":"group-2","grp":[{"groupID":"group-3","sys":["sys1","sys2","sys3"]},{"groupID":"group-4","grp":[{"groupID":"group-5","sys":["sys4","sys5","sys6"]},{"groupID":"group-6","grp":[{"groupID":"group-7","sys":["sys7","sys8","sys9"]}]}]}],"sys":["sys0"]}]}]}

class Systems extends Component {
  render() {
    const { data } = this.props;
    return <div className="systems">
      {data.map((sys, i) => (
        <div key={i} className="system">{sys}</div>
      ))}
    </div>
  }
}

class Group extends Component {
  render() {
    const { data } = this.props;
    return data.map((group, i) => (
      <div key={i} className="group">
        {group.groupID && <div className="group-name">{group.groupID}</div>}
        <div className="children">
          {group.sys && <Systems data={group.sys} />}
          {group.grp && <Group data={group.grp} />}
        </div>
      </div>
    ))
  }
}

class App extends Component {
  state = {
    data: {}
  }

  componentWillMount = () => {
    this.setState({ data: this.props.data })
  }

  render() {
    console.log(this.state)
    return <div className="root">
      <Group data={this.state.data.grp} />
    </div>
  }
}

ReactDOM.render(
  <App data={data} />,
  document.getElementById('container')
);
#root * {
  color: white;
}

.group {
  display: flex;
  flex-direction: column-reverse;
}

.group-name {
  background: rgb(89, 89, 89);
  padding: 10px;
  color: white;
  border-top: 1px solid white;
}

.group-name {
  opacity: 0.85;
  transition: all 0.25s;
}

.children {
  display: flex;
}

.children > * {
  flex: 1;
}

.systems {
  display: flex;
  flex-direction: column-reverse;
}

.system {
  background: red;
  color: white;
  padding: 10px;
  opacity: 0.6;
  transition: all 0.25s;
  border-top: 1px solid white;
}

.system:hover,
.group-name:hover{
  opacity: 1;
}

.as-console-wrapper {
  display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>
0 голосов
/ 16 апреля 2019

Здесь важно определить структуру данных, чтобы вы могли рекурсивно атаковать проблему.

В вашем случае ваши группы можно определить так:

{ groupID: string, sys?: string[], grp?: IGroup[] }

(где IGroup определил вышеуказанную структуру)

Все группы имеют groupID, некоторые имеют sys, а некоторые имеют grp детей.

Отсюда мы можем определить функцию, в которой логика выглядит следующим образом:

  1. Создать двухстрочную структуру для текущей группы.
  2. Для каждого sys дочернего элементаэлемент (если они существуют), добавьте ячейку в верхнюю строку со значением sys.
  3. Для каждого дочернего элемента grp (если он существует), вызовите эту функцию и добавьте возвращающую структуру кячейка в верхнем ряду.
  4. Вставьте ячейку в нижний ряд на ширине colspan дочернего элемента.Установите для содержимого ячейки текущее значение grp groupID
  5. Возврат двухстрочного элемента структуры, либо ввод в процесс рекурсивной сборки, либо в качестве окончательного результата.

Здесьгрубая реализация вышеперечисленных пунктов:

function groupToHTML(grp) {
    //Table to append to and return
    var container = document.createElement("table");
    container.border = "1";
    container.style.borderCollapse = "collapse";
    //Insert row to children of this node
    var childRow = container.appendChild(document.createElement("tr"));
    //Append all "sys" elements as cells
    if (grp.sys !== void 0) {
        for (var sysIndex = 0; sysIndex < grp.sys.length; sysIndex++) {
            var sys = grp.sys[sysIndex];
            var sysCell = childRow.appendChild(document.createElement("td"));
            sysCell.innerHTML = sys;
            sysCell.style.backgroundColor = "red";
            sysCell.style.verticalAlign = "bottom";
        }
    }
    //Append all "grp" children by calling "groupToHTML" on them and appending the returning table
    if (grp.grp !== void 0) {
        for (var grpIndex = 0; grpIndex < grp.grp.length; grpIndex++) {
            var child = grp.grp[grpIndex];
            var grpCell = childRow.appendChild(document.createElement("td"));
            grpCell.appendChild(groupToHTML(child));
            grpCell.style.verticalAlign = "bottom";
        }
    }
    //Add a row and cell for "this" grp
    var thisRow = container.appendChild(document.createElement("tr"));
    var thisCell = thisRow.appendChild(document.createElement("th"));
    thisCell.innerHTML = grp.groupID;
    thisCell.style.textAlign = "center";
    //Set cell colspan to number of child elements
    thisCell.colSpan = Math.max(1, (grp.grp !== void 0 ? grp.grp.length : 0) + (grp.sys !== void 0 ? grp.sys.length : 0));
    //Return table
    return container;
}
//TEST
//testdata
var data = {
    groupID: 'group-1',
    grp: [
        {
            groupID: 'group-2',
            grp: [
                {
                    groupID: 'group-3',
                    sys: ['sys1', 'sys2', 'sys3']
                }, {
                    groupID: 'group-4',
                    grp: [
                        {
                            groupID: 'group-5',
                            sys: ['sys4', 'sys5', 'sys6']
                        }, {
                            groupID: 'group-6',
                            grp: [
                                {
                                    groupID: 'group-7',
                                    sys: ['sys7', 'sys8', 'sys9']
                                }
                            ]
                        }
                    ]
                }
            ],
            sys: ['sys0']
        }
    ]
};
//Initiate
var node = groupToHTML(data);
//Append
document.body.appendChild(node);
...