在javascript中使用时间轴创建图形

时间:2017-01-29 06:03:23

标签: javascript graph visualization timeline gojs

我想在javascript中使用时间轴创建动态变化的图形,这看起来像this。 编辑:我想自己决定哪个节点应该在哪个时间片。

我想知道,是否有一个我可以用来做这个的库,或者我需要自己创建它(通过简单地画在画布上)?我试图找到一个,但似乎有很多时间轴和图形的实现,但很难找到这两者的组合。最合适的解决方案是使用gojs。但是我无法创建一个包含两个父节点的节点,因为它是作为树数据结构实现的。

2 个答案:

答案 0 :(得分:2)

你可能不得不玩数学,但我希望这将有用作为一个起点:

DEMO JSFiddle

<强> HTML

<div id='board'>
 <div id='titles'></div>

</div>

<强> CSS

#board { 
  position: relative; 
  width: 500px;
  height: 600px;
  background-color:#f83213;
}
#titles {
  color: #ffffff;
  width: 100%;
  height: 18px;
  font-size: 12px;
}
#titles div {
  display:inline-block;
  margin: 10px;
}
.event{
    border: 0px;
    background-color: #3a2356;
    color: #ffffff;
    width: 18px;
    height: 18px;
    position: absolute;
    padding: 4px;
    font-size: 18px;
    z-index: 2;
}
.line{
    height: 1px;
    width: 60px;
    background-color: #3a2356;
    position: absolute;
    z-index: 1;
}

** JavaScript **

var margin = 20;
var events = {
  "A": {
    day: 0,
    indexInDay: 0,
    lineTos: ["D"]
  },
  "B": {
    day: 0,
    indexInDay: 1,
    lineTos: ["D"]
  },
  "D": {
    day: 1,
    indexInDay: 0,
    lineTos: ["E","F"]
  },
  "E": {
    day: 2,
    indexInDay: 0,
    lineTos: null
  },
  "C": {
    day: 0,
    indexInDay: 2,
    lineTos: ["F"]
  },
  "F": {
    day: 2,
    indexInDay: 2,
    lineTos: null
  },
};

drawAll(events);

function drawAll(events) {
  drawTitles(events);
  drawEvents(events);
  drawLines(events);
}

function drawTitles(events) {
  var titles = document.getElementById('titles');
  var max = 0;
  for (var name in events) {
    if (events[name].day > max)
      max = events[name].day;
  }
  for (var i = 0 ; i <= max ; i++)
    titles.innerHTML += '<div>' + 'Day' + i + '</div>';
}

function drawEvents(events) {
  var board = document.getElementById('board');
  for (var name in events) {
    var ev = events[name];
    var eventDiv = document.createElement('DIV');
    board.appendChild(eventDiv);
    eventDiv.className = 'event';
    setTopLeftEvent(ev, eventDiv);
    eventDiv.innerText = name;

  }
}

function drawLines(events) {
  var board = document.getElementById('board');
  for (var name in events) {
    var from = events[name];
    var tos = from.lineTos;
    if (!tos) continue;
    for (var j = 0 ; j < tos.length ; j++) {
      var to = events[tos[j]];
      var lineDiv = document.createElement('DIV');
      board.appendChild(lineDiv);
      lineDiv.className = 'line';
      setTopLeftLine(from, lineDiv);
      lineDiv.style.width = margin  + 1 * margin * distance(to.indexInDay,from.indexInDay,to.day, from.day) + 'px';
      var tan = (to.indexInDay - from.indexInDay) / (to.day - from.day);
      lineDiv.style.top = lineDiv.offsetTop + (tan * margin) +'px';
      var angle = Math.atan(tan) * 180/Math.PI;
      // Code for Safari
      lineDiv.style.WebkitTransform = "rotate(" + angle + "deg)"; 
      // Code for IE9
      lineDiv.style.msTransform = "rotate(" + angle + "deg)"; 
      // Standard syntax
      lineDiv.style.transform = "rotate(" + angle + "deg)"; 
    }

  }
}

function distance(x1, y1, x2, y2){
 var res = Math.sqrt((y2-y1)*(y2-y1) + (x2-x1)*(x2-x1)); 
 return res;
}

function setTopLeftEvent(event, eventDiv) {
  eventDiv.style.left = (margin + event.day * (margin * 2)) + 'px';
    eventDiv.style.top = (margin * 2 + event.indexInDay * (margin * 2)) + 'px';
}
function setTopLeftLine(event, lineDiv) {
  lineDiv.style.left = (margin + event.day * (margin * 2)) + 'px';
  lineDiv.style.top = (margin * 2.5 + event.indexInDay * (margin * 2)) + 'px';
}

答案 1 :(得分:1)

正如文本中提到GoJS sample一样,很容易用 LayeredDigraphLayout TreeModel 替换 TreeLayout GraphLinksModel 。这就是我刚刚修改样本所做的事情。

SSH_ASKPASS替换为go.TreeLayout,以便自定义布局不再继承自TreeLayout。更改构造函数不要打扰设置TreeLayout特定属性。更改图表的布局以使用LayeredDigraphLayout特定属性:

go.LayeredDigraphLayout

使用包含所需数据的GraphLinksModel替换该样本的模型:

            layout: $(LayeredTreeLayout,  // custom layout is defined above
                      {
                        angle: HORIZONTAL ? 0 : 90,
                        columnSpacing: 5,
                        layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource
                      }),

如果没有更改任何模板或样式,结果是:

enter image description here

为了确保它有效,我还尝试设置// define the node data var nodearray = [ { // this is the information needed for the headers of the bands key: "_BANDS", category: "Bands", itemArray: [ { text: "Day 0" }, { text: "Day 1" }, { text: "Day 2" }, { text: "Day 3" }, { text: "Day 4" }, { text: "Day 5" } ] } ]; var linkarray = [ { from: "A", to: "D" }, { from: "B", to: "D" }, { from: "D", to: "E" }, { from: "D", to: "F" }, { from: "C", to: "F" } ]; myDiagram.model = $(go.GraphLinksModel, { // automatically create node data objects for each "from" or "to" reference // (set this property before setting the linkDataArray) archetypeNodeData: {}, nodeDataArray: nodearray, linkDataArray: linkarray });

enter image description here