Index: arms/html/analysisTime/content-container.html
===================================================================
diff -u -r6422fbb2efe07767440438476316d261d65f0e31 -r6a9ec845786738e07ba7ccc64a6cea1e21900c6f
--- arms/html/analysisTime/content-container.html (.../content-container.html) (revision 6422fbb2efe07767440438476316d261d65f0e31)
+++ arms/html/analysisTime/content-container.html (.../content-container.html) (revision 6a9ec845786738e07ba7ccc64a6cea1e21900c6f)
@@ -818,7 +818,6 @@
Index: arms/js/analysisTime.js
===================================================================
diff -u -r6422fbb2efe07767440438476316d261d65f0e31 -r6a9ec845786738e07ba7ccc64a6cea1e21900c6f
--- arms/js/analysisTime.js (.../analysisTime.js) (revision 6422fbb2efe07767440438476316d261d65f0e31)
+++ arms/js/analysisTime.js (.../analysisTime.js) (revision 6a9ec845786738e07ba7ccc64a6cea1e21900c6f)
@@ -50,8 +50,8 @@
//"https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.7/raphael.min.js",
"../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/css/newtimeline.css",
"../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/js/raphael.min.js",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/js/timeline.js",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/js/newdemo.js",
+ "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/js/newtimeline.js",
+ //"../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/js/newdemo.js",
// 3번째 박스 데이터 테이블 내 차트
"../reference/light-blue/lib/sparkline/jquery.sparkline.js",
"../reference/jquery-plugins/echarts-5.4.3/dist/echarts.min.js",
@@ -253,6 +253,7 @@
// 버전 선택 시 데이터 파싱
networkChart(data);
calendarHeatMap(data);
+ statusTimeline(data);
sevenTimeline(data);
globalJiraIssue = data;
@@ -2231,6 +2232,151 @@
}
*/
+////////////////////
+// 여섯번째 박스
+////////////////////
+
+function statusTimeline(data) {
+
+ // 필요한 데이터만 추출
+ var extractedData = extractDataForStatusTimeline(data);
+
+ // 버전 별로 그룹화
+ var groupedDataByVersion = groupingByVersionForStatusTimeline(extractedData);
+
+ // 데이터 포맷팅
+ var relatedIssues = dataFormattingForStatusTimeline(groupedDataByVersion);
+
+ // 요소 호버
+ $(".reqNode").hover(
+ function() {
+
+ $(this).find('title').text('');
+ var classValue = $(this).attr('class');
+ //console.log(classValue);
+ var key = classValue.split(" ").pop(); // 요구사항 이슈 키
+
+ $("." + key).css("opacity", "0.7");
+
+ var tooltip = $('');
+ tooltip.html(`
+
+
+ 하위 이슈 |
+ 상태 |
+
+ ${relatedIssues[key] ? relatedIssues[key] : '데이터가 없습니다 |
'}
+
+ `);
+
+ tooltip.css({
+ "visibility": "visible",
+ "opacity": "1",
+ "position": "absolute",
+ "left": event.pageX + 10,
+ "top": event.pageY + 10,
+ });
+
+ $("body").append(tooltip);
+
+ }, function() {
+ $(".reqNode").css("opacity", "1");
+ $("#stlTooltip").remove();
+
+ }
+ );
+}
+
+function extractDataForStatusTimeline(data){
+
+ var extractedData = [];
+
+ data.forEach(item => {
+ var extractedItem = {
+ version: item.pdServiceVersion,
+ issueKey: item.key,
+ isReq: item.isReq,
+ parentReqKey: item.parentReqKey,
+ createdDate: new Date(Date.parse(item.created)),
+ summary: item.summary,
+ status: item.status.status_name
+ };
+ extractedData.push(extractedItem);
+ });
+
+ return extractedData;
+}
+
+function groupingByVersionForStatusTimeline(data) {
+
+ var groupedData = data.reduce((result, item) => {
+ var pdServiceVersion = item.version;
+ if (!result[pdServiceVersion]) {
+ result[pdServiceVersion] = [];
+ }
+ result[pdServiceVersion].push(item);
+ return result;
+ }, {});
+
+ return groupedData;
+}
+
+function dataFormattingForStatusTimeline(data) {
+
+ var statusTimelineData = {};
+ var formattedData = [];
+ var relatedIssues = {};
+
+ for (const version in data) {
+
+ var reqIssue = data[version].filter(item => item.isReq === true); // 요구사항 이슈만 필터링
+ var versionData = convertVersionIdToTile(version); // text (버전)
+
+ var reqIssues = []; // children 전체
+
+ reqIssue.forEach(reqIssue => {
+
+ // children 요소 중 하나
+ var req = {
+ text: reqIssue.summary + " | " + reqIssue.status,
+ id: reqIssue.issueKey
+ };
+
+ reqIssues.push(req);
+
+ // 호버 시 하위 이슈 볼 수 있도록 데이터 포맷팅
+ var relatedIssue = data[version].filter(item => item.parentReqKey === reqIssue.issueKey);
+ console.log("연관 이슈: ", relatedIssue);
+
+ relatedIssue.forEach(relatedIssue => {
+
+ if (!relatedIssues[relatedIssue.parentReqKey]) {
+ relatedIssues[relatedIssue.parentReqKey] = '';
+ }
+
+ relatedIssues[relatedIssue.parentReqKey] += "" +
+ relatedIssue.summary +
+ " | " +
+ relatedIssue.status +
+ " |
";
+ });
+ });
+
+ var totalData = {
+ text: versionData,
+ children: reqIssues
+ };
+
+ formattedData.push(totalData);
+ }
+ statusTimelineData.data = formattedData;
+
+ $("#demo").timeline(statusTimelineData);
+ console.log("연관 이슈 전체: ", relatedIssues);
+
+ return relatedIssues;
+}
+
function sevenTimeline(data) {
var sevenTimeLineDiv = document.getElementById("sevenTimeLine");
sevenTimeLineDiv.innerHTML = "";
Index: reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/js/newdemo.js
===================================================================
diff -u -r59c474d8308039ba223fee679f4c08a53147f87e -r6a9ec845786738e07ba7ccc64a6cea1e21900c6f
--- reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/js/newdemo.js (.../newdemo.js) (revision 59c474d8308039ba223fee679f4c08a53147f87e)
+++ reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/js/newdemo.js (.../newdemo.js) (revision 6a9ec845786738e07ba7ccc64a6cea1e21900c6f)
@@ -1,6 +1,6 @@
$(function () {
var opt1 = {
- legend: [{
+ /*legend: [{
text: "Text 1-Test-images/compact_disc.png",
name: "1",
icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/compact_disc.png"
@@ -12,288 +12,104 @@
text: "Text 3",
name: "3",
icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/computer-keyboard.png"
- }, {
- text: "Text 4-Test-abcdefg",
- name: "4",
- icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/contacts.png"
- }, {
- text: "Text 5",
- name: "5",
- icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/contacts-alt.png"
- }, {
- text: "legend6",
- name: "6",
- icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png"
- }],
+ }],*/
data: [{
- text: "item0405/item0405/A.001",
- imageUrl: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png",
+ text: "1.0",
children: [{
- text: "Test",
- legendName: "1",
- imageUrl: ""
- }]
- },
- {
- text: "Node 1",
- imageUrl: ["../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png"],
- children: [{
- text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
+ text: "이슈1 | Complete",
+ id: "node1"
}, {
- text: "1-2",
- legendName: "2",
- imageUrl: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/contacts-alt.png"
+ text: "이슈2 | Backlog",
+ id: "node2"
}, {
- text: "1-3",
- legendName: "3",
- imageUrl: ["../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/contacts-alt.png",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/computer-keyboard.png"]
+ text: "이슈3 | Open",
+ id: "node3"
}, {
- text: "1-4:test",
- legendName: "4",
- imageUrl: ""
+ text: "이슈4 | Open",
+ id: "node4"
}, {
- text: "1-5",
- legendName: "5",
- imageUrl: ["../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png"]
+ text: "이슈5 | Backlog",
+ id: "node5"
}, {
- text: "1-6",
- legendName: "6",
- imageUrl: ""
+ text: "이슈6 | Complete",
+ id: "node6"
}]
},
{
- text: "Node 2",
- imageUrl: ["../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png",
- "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/counter.png"]
- },
- {
- text: "Node 3",
+ text: "3.0",
children: [{
text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
}, {
text: "1-2",
- legendName: "2",
- imageUrl: ""
}, {
text: "1-3",
- legendName: "3",
- imageUrl: ""
}, {
text: "1-4:test",
- legendName: "4",
- imageUrl: ""
}, {
text: "1-5",
- legendName: "5",
- imageUrl: ""
}, {
text: "1-6",
- legendName: "6",
- imageUrl: ""
}]
- },
- {
- text: "Node 4",
- children: [{
- text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
- }]
- },
- {
- text: "Node 5",
- children: [{
- text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
- },
- {
- text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
- }
- ]
- },
- {
- text: "Node 6"
}
]
};
- var opt2 = {
- legend: [{
- text: "Text 1-Test-images/compact_disc.png",
- name: "1",
- icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/compact_disc.png"
- }, {
- text: "Text 2",
- name: "2",
- icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/compose.png"
- }, {
- text: "Text 3",
- name: "3",
- icon: "../reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/images/computer-keyboard.png"
- }],
- data: [{
- text: "Node 1",
- children: [{
- text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
- }, {
- text: "1-2",
- legendName: "2",
- imageUrl: ""
- }, {
- text: "1-3",
- legendName: "3",
- imageUrl: ""
- }, {
- text: "1-4:test",
- legendName: "4",
- imageUrl: ""
- }, {
- text: "1-5",
- legendName: "5",
- imageUrl: ""
- }, {
- text: "1-6",
- legendName: "6",
- imageUrl: ""
- }]
- },
- {
- text: "Node 2"
- },
- {
- text: "Node 3",
- children: [{
- text: "1-1:Text 1-Test-images/compact_disc.png",
- legendName: "1",
- imageUrl: ""
- }, {
- text: "1-2",
- legendName: "2",
- imageUrl: ""
- }, {
- text: "1-3",
- legendName: "3",
- imageUrl: ""
- }, {
- text: "1-4:test",
- legendName: "4",
- imageUrl: ""
- }, {
- text: "1-5",
- legendName: "5",
- imageUrl: ""
- }, {
- text: "1-6",
- legendName: "6",
- imageUrl: ""
- }]
- },
- {
- text: "Node 4"
- }
-
- ]
- };
- opt2.theme = {
- lengend: {
- fill: "#000000",
- },
- startNode: {
- radius: 10,
- fill: "#7E899D"
- },
- endNode: {
- radius: 10,
- fill: "#7E899D"
- },
+ opt1.theme = {
centralAxisNode: {
- height: 21,
- radius: 4,
- fill: "#1A84CE",
- color: "#ffffff",
- inner: {
- fill: "#1A84CE",
- "stroke-width": 0,
- stroke: "#1A84CE"
- },
- outer: {
- fill: "#1A84CE",
- "stroke-width": 3,
- stroke: "#1A84CE"
- }
- },
- centralAxisLine: {
- fill: "#7E899D"
- },
- centralAxisBranchNode: {
- fill: "#F9BF3B",
- radius: 10
- },
- centralAxisBranchLine: {
- stroke: '#F9BF3B',
- fill: "#F9BF3B"
- },
- centralAxisBranchContent: {
- fill: "#F9BF3B",
- color: "#ffffff",
- stroke: '#ffffff',
- height: 24
+ color: "#1a84ce"
}
- }
+ };
- opt1.legend = null;
+ // opt1.theme = {
+ // startNode: {
+ // radius: 10,
+ // fill: "#7E899D"
+ // },
+ // endNode: {
+ // radius: 10,
+ // fill: "#7E899D"
+ // },
+ // centralAxisNode: {
+ // height: 21,
+ // radius: 4,
+ // fill: "#F9BF3B",
+ // color: "#1a84ce",
+ // inner: {
+ // fill: "#F9BF3B",
+ // "stroke-width": 0,
+ // stroke: "#F9BF3B"
+ // },
+ // outer: {
+ // fill: "#F9BF3B",
+ // "stroke-width": 3,
+ // stroke: "#F9BF3B"
+ // }
+ // },
+ // centralAxisLine: {
+ // fill: "#7E899D"
+ // },
+ // centralAxisBranchNode: {
+ // fill: "#1A84CE",
+ // radius: 10
+ // },
+ // centralAxisBranchLine: {
+ // stroke: '#1A84CE',
+ // fill: "#1A84CE"
+ // },
+ // centralAxisBranchContent: {
+ // fill: "#1A84CE",
+ // color: "#ffffff",
+ // stroke: '#ffffff',
+ // height: 24
+ // }
+ // };
- var theme = 'default';
+ //opt1.legend = null;
- var opt3 = {
- legend: [],
- data: [{
- text: "Node 1",
- children: []
- },
- {
- text: "Node 2"
- },
- {
- text: "Node 3",
- children: []
- },
- {
- text: "Node 4"
- }
- ]
- };
//opt2.data = [];
- $("#demo").timeline(opt2);
+ //$("#demo").timeline(opt1);
- $("#reload").click(function () {
- if (theme === 'default') {
- theme = 'custom';
- } else {
- theme = 'default';
- }
-
- theme === 'default' ? $("#demo").timeline(opt2) : $("#demo").timeline(opt1);
- });
-
-
-
-
});
\ No newline at end of file
Index: reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/css/newtimeline.css
===================================================================
diff -u -r59c474d8308039ba223fee679f4c08a53147f87e -r6a9ec845786738e07ba7ccc64a6cea1e21900c6f
--- reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/css/newtimeline.css (.../newtimeline.css) (revision 59c474d8308039ba223fee679f4c08a53147f87e)
+++ reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/css/newtimeline.css (.../newtimeline.css) (revision 6a9ec845786738e07ba7ccc64a6cea1e21900c6f)
@@ -2,8 +2,45 @@
fill: black;
}
-#reload {
- padding:.5em 1em;
- margin-top:2em;
+.statusTimeline tspan {
+ cursor: default;
+}
+
+/* 툴팁 테이블 */
+.stltable {
+ width: 100%;
+ border-collapse: separate;
+ border-spacing: 0;
+}
+
+.stltable th:first-child {
+ border-top-left-radius: 3px;
+}
+
+.stltable th:last-child {
+ border-top-right-radius: 3px;
+}
+
+.stltable tr:last-child td:first-child {
+ border-bottom-left-radius: 3px;
+}
+
+.stltable tr:last-child td:last-child {
+ border-bottom-right-radius: 3px;
+}
+
+.stltable th, .stltable td {
+ border: 1px solid #ddd;
+ padding: 3px;
+ text-align: left;
color: black;
+}
+
+.stltable th {
+ text-align: center;
+ background-color: rgba(69, 80, 91, 0.29);
+}
+
+.stltable tr {
+ background-color: rgba(242, 242, 242, 0.8);
}
\ No newline at end of file
Index: reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/js/newtimeline.js
===================================================================
diff -u
--- reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/js/newtimeline.js (revision 0)
+++ reference/jquery-plugins/Timeline-Graphs-jQuery-Raphael/timeline/js/newtimeline.js (revision 6a9ec845786738e07ba7ccc64a6cea1e21900c6f)
@@ -0,0 +1,632 @@
+/*!
+ * timeline v1.1.0 - jQuery plug
+ *
+ * Includes jquery.js
+ * Includes raphael.js
+ *
+ * Copyright © 2016-2017 huangqing
+ * Released under the MIT license
+ *
+ * Date: 2016-11-15
+ */
+
+(function ($) {
+
+ 'use strict';
+ $.fn.extend({
+ timeline: function (opt) {
+
+ var container = this,
+ paper = container.data('timeline'),
+ pagerHeight = 0,
+ pagerWidth = 0,
+ ViewBoxX = 0,
+ ViewBoxY = 0,
+ startX = 0,
+ startY = 0,
+ nextX = startX,
+ nextY = startY,
+ endX = 0,
+ endY = 0,
+ currentBranchCount = 0,
+ legend = {},
+ legendHeight = 60,
+ data = [],
+ theme = $.extend(true, {}, $.timeline.theme.gray);
+
+ $.extend(true, theme, opt.theme);
+
+ if (!paper) {
+ paper = Raphael(container[0]);
+ container.data('timeline', paper);
+ } else {
+ paper.clear();
+ }
+
+ //计算下一节点的X轴起始位置
+ function getNextX(offsetWidth) {
+ nextX += offsetWidth;
+ }
+
+ ///计算下一节点的Y轴起始位置:用于分支节点的高度计算
+ function getNextY() {
+ var r = 10,
+ lineHeight = 0,
+ operator = +1,
+ baseLineHeight = 6 * r,
+ offsetHeight = 4 * r;
+ //Y轴坐标为初始坐标,根据子节点的数量计算高度
+ //第一个子节点首先定位在Y轴反向位置,第二个子节点定位在Y轴正向与第一个节点对称的位置
+ if (nextY === startY) {
+ operator = -1;
+ lineHeight = baseLineHeight + Math.ceil(currentBranchCount / 2) * offsetHeight;
+ lineHeight = operator * (Math.abs(lineHeight) - offsetHeight);
+ nextY = startY + lineHeight;
+ setEndY(lineHeight);
+
+ }
+ //定位Y轴正向节点
+ else if (nextY < startY) {
+ operator = +1;
+ nextY = Math.abs(nextY);
+ }
+ //递减定位下一个节点
+ else {
+ operator = -1;
+ lineHeight = operator * (Math.abs(nextY) - offsetHeight);
+ nextY = startY + lineHeight;
+ }
+ }
+
+ //设置x轴结束位置
+ function setEndX(x) {
+ if (endX < x) {
+ endX = x;
+ }
+ }
+
+ //获取皮肤
+ function getTheme() {
+ return theme;
+ }
+
+ //计算图形最高高度
+ function setEndY(offsetHeight) {
+ if (Math.abs(endY) < Math.abs(offsetHeight)) {
+ endY = Math.abs(offsetHeight);
+ }
+ }
+
+ //获取图片url
+ //imageUrl:url字符串,或url数组
+ function getImageUrl(imageUrl, legendType) {
+
+ var url = [],
+ image,
+ host;
+
+ if (legend[legendType] && legend[legendType].icon) {
+ url.push(legend[legendType].icon);
+ }
+
+ if (imageUrl && typeof imageUrl === 'string') {
+ url.push(imageUrl);
+ } else if (imageUrl instanceof Array && imageUrl.length > 0) {
+ url = url.concat(imageUrl);
+ }
+
+ for (var i = 0, len = url.length; i < len; i++) {
+ image = url[i];
+ if (image.indexOf("~") === 0) {
+ host = location.protocol + "//" + location.hostname + (location.port ? ":" + location.port : "");
+ url[i] = image.replace(/~/, host);
+ }
+ }
+
+ return url;
+ }
+
+ //创建开始节点
+ function createStartNode(x, y) { // 시작 노드
+ var theme = getTheme().startNode,
+ r = theme.radius,
+ bgColor = theme.fill,
+ lineWidth = 60;
+
+ x += r;
+
+ paper.circle(x, y, r).attr({
+ fill: bgColor,
+ "stroke-width": 0,
+ stroke: bgColor
+ });
+
+ paper.path("M" + x + " " + y + "L" + (x + lineWidth - 10) + " " + y).attr({
+ "stroke-width": 2,
+ stroke: bgColor,
+ "stroke-dasharray": ["-"]
+ });
+
+ getNextX(lineWidth);
+ }
+
+ //创建结束节点
+ function createEndNode(x, y) { // 끝 노드 (화살표)
+ var theme = getTheme().endNode,
+ r = theme.radius,
+ bgColor = theme.fill,
+ lineWidth = 60,
+ _endX = x + lineWidth,
+ pathStr = "";
+
+ if (_endX < endX) {
+ lineWidth = endX - x;
+ }
+ pathStr = "M" + x + " " + y + "L" + (x + lineWidth) + " " + y;
+ paper.path(pathStr).attr({
+ "stroke-width": 2,
+ stroke: bgColor,
+ "stroke-dasharray": ["-"]
+ });
+
+ pathStr = ["M", x + lineWidth, " ", y,
+ "L", x + lineWidth, " ", y + r,
+ "L", x + lineWidth + r, " ", y,
+ "L", x + lineWidth, " ", y - r,
+ "L", x + lineWidth, " ", y,
+ "z"
+ ].join("");
+ paper.path(pathStr).attr({
+ fill: bgColor,
+ "stroke-width": 0,
+ stroke: bgColor
+ });
+
+ getNextX(lineWidth + r);
+ }
+
+ //创建中轴线上的主节点
+ function createCentralAxisNode(x, y, text, imageUrl) { // 버전 노드
+
+ var theme = getTheme().centralAxisNode,
+ //r = 10,
+ width = 100,
+ height = theme.height,
+ innerRectElement,
+ outRectElement,
+ imageX,
+ imageY,
+ imageWidth = 0,
+ imageElements = [],
+ imageSize = 14,
+ textElement,
+ paddingSize = 4,
+ radius = theme.radius,
+ fill = theme.fill,
+ stroke = theme.stroke,
+ textFillColor = theme.color,
+ position,
+ lineWidth,
+ contentX = x,
+ contentY = y;
+
+ if (imageUrl && imageUrl.length > 0) {
+
+ imageX = x + 2 * paddingSize;
+ imageY = y - imageSize / 2 + 1;
+ for (var i = 0, len = imageUrl.length; i < len; i++) {
+ imageElements.push(paper.image(imageUrl[i], imageX, imageY, imageSize, imageSize));
+ if (i !== len - 1) {
+ imageX += paddingSize + imageSize;
+ } else {
+ imageX += paddingSize;
+ }
+ }
+ imageWidth = imageX - x;
+ }
+
+ x = x + imageWidth + 3 * paddingSize;
+ textElement = paper.text(x, y, text).attr({
+ "font-size": 12,
+ "font-weight": "bolder",
+ fill: textFillColor,
+ "text-anchor": "start"
+ });
+
+ position = textElement.getBBox();
+ width = position.width;
+
+ innerRectElement = paper.rect(contentX + paddingSize, y - height / 2, width + 4 * paddingSize + imageWidth, height, radius).attr({
+ fill: theme.inner.fill,
+ "stroke-width": theme.inner["stroke-width"],
+ stroke: theme.inner.stroke
+ });
+
+ outRectElement = paper.rect(contentX, y - height / 2 - paddingSize, width + imageWidth + 6 * paddingSize, height + 2 * paddingSize, radius).attr({
+ stroke: theme.outer.stroke,
+ "stroke-width": theme.outer["stroke-width"]
+ });
+
+ textElement.toFront();
+ for (i = 0, len = imageElements.length; i < len; i++) {
+ imageElements[i].toFront();
+ }
+
+ position = outRectElement.getBBox();
+ lineWidth = position.width;
+
+ getNextX(lineWidth);
+ endY === 0 ? endY = Math.ceil(position.height / 2) + 6 : null;
+ }
+
+ //创建中轴线上的线
+ function createCentralAxisLine(x, y, radius) { // 가로선
+
+ var r = 10,
+ theme = getTheme().centralAxisLine,
+ bgColor = theme.fill,
+ lineWidth = 4 * r,
+ pathStr = "";
+
+ pathStr = "M" + x + " " + y + "L" + (x + lineWidth) + " " + y;
+ paper.path(pathStr).attr({
+ "stroke-width": 2,
+ stroke: bgColor,
+ "stroke-dasharray": ["-"]
+ });
+
+ getNextX(lineWidth);
+ }
+
+ //创建中轴线上的分支节点
+ function createCentralAxisBranchNode(x, y) { // 가로선 위 동그라미
+ var theme = getTheme().centralAxisBranchNode,
+ r = theme.radius,
+ bgColor = theme.fill;
+
+ paper.circle(x, y, r - 2).attr({
+ "stroke-width": 2,
+ stroke: bgColor
+ });
+
+ paper.circle(x, y, r - 5).attr({
+ fill: bgColor,
+ "stroke-width": 0,
+ stroke: bgColor
+ });
+
+ }
+
+ //创建中轴线上分支节点的内容
+ function createCentralAxisBranchContent(x, y, text, imageUrl, id) { // 요구사항 이슈 노드
+
+ var r = 10,
+ r_bottom = 2,
+ content_theme = getTheme().centralAxisBranchContent,
+ line_theme = getTheme().centralAxisBranchLine,
+ bgColor = content_theme.fill,
+ textFillColor = content_theme.color,
+ stroke = content_theme.stroke,
+ pathStr = "",
+ height = content_theme.height,
+ width = 0,
+ index = index || 1,
+ offsetLineHeight = 2 * r,
+ operator = +1,
+ _endX = 0,
+ _endY = 0,
+ contentX,
+ contentY,
+ imageX,
+ imageY,
+ imageWidth = 0,
+ rectElement,
+ textX,
+ textY,
+ textElement,
+ imageElements = [],
+ imageSize = 14,
+ position;
+
+ getNextY();
+ nextY > 0 ? operator = +1 : operator = -1;
+ _endX = x;
+ _endY = nextY;
+
+
+ pathStr = "M" + x + " " + y + "L" + x + " " + _endY;
+ paper.path(pathStr).attr({
+ "stroke-width": 1,
+ stroke: line_theme.stroke
+ });
+
+ paper.circle(x, _endY - operator * r_bottom, r_bottom).attr({
+ fill: line_theme.stroke,
+ "stroke-width": 0,
+ stroke: line_theme.stroke
+ });
+
+ _endX = x - 2 * r;
+ _endY = operator > 0 ? _endY - operator * (height + 6) :
+ _endY - operator * 6 + r_bottom;
+
+ contentX = _endX;
+ contentY = _endY;
+ imageX = contentX + content_theme["padding"];
+
+ if (imageUrl && imageUrl.length > 0) {
+
+ imageX = imageX + r / 2;
+ imageY = contentY + 4;
+ for (var i = 0, len = imageUrl.length; i < len; i++) {
+ imageElements.push(paper.image(imageUrl[i], imageX, imageY, imageSize, imageSize));
+ if (i !== len - 1) {
+ imageX += r / 2 + imageSize;
+ } else {
+ imageX += r;
+ }
+ }
+ imageWidth = imageX - contentX;
+ }
+
+ textX = imageX + r;
+ textY = contentY + r;
+ textElement = paper.text(textX, textY, text).attr({
+ "font-size": 12,
+ fill: textFillColor,
+ "text-anchor": "start",
+ title: text
+ });
+ // 클래스 및 아이디 설정
+ textElement.node.classList.add("reqNode", id);
+
+ position = textElement.getBBox();
+ width = position.width;
+ height = position.height + 5;
+
+ rectElement = paper.rect(contentX, contentY, imageWidth + position.width + content_theme["padding"] + 2 * r, height, content_theme.radius).attr({
+ fill: bgColor,
+ stroke: stroke,
+ "stroke-width": 1
+ });
+ // 클래스 및 아이디 설정
+ rectElement.node.classList.add("reqNode", id);
+
+ //判断分支内容的实际结束位置,用于作为生成结束节点的x轴参数
+ _endX = contentX + imageWidth + position.width + 2 * r;
+ setEndX(_endX);
+
+ for (i = 0, len = imageElements.length; i < len; i++) {
+ imageElements[i].toFront();
+ }
+ textElement.toFront();
+ }
+
+ //创建中轴线上的分支节点
+ function createBranchNode(x, y, text, imageUrl, radius, id) {
+ var r = radius;
+ createCentralAxisLine(x, y, r);
+ //中间位置
+ x += r * 2;
+ createCentralAxisBranchNode(x, y);
+ createCentralAxisBranchContent(x, y, text, imageUrl, id);
+ }
+
+ //创建图例
+ function createLegend() {
+ var item,
+ text,
+ name,
+ imageUrl,
+ r = 5,
+ imageSize = 14,
+ position,
+ _startX = startX + 2 * r,
+ _startY = 0,
+ textElement;
+
+ _startY = -(endY + legendHeight) + 4 * r;
+
+ for (var i in legend) {
+ item = legend[i];
+ text = item.text;
+ imageUrl = getImageUrl(item.icon);
+
+ paper.image(imageUrl, _startX - 6, _startY - 6, imageSize, imageSize);
+
+ _startX += imageSize;
+ textElement = paper.text(_startX, _startY, text).attr({
+ "font-size": 12,
+ "fill": theme.lengend.fill,
+ "text-anchor": "start"
+ });
+
+ position = textElement.getBBox();
+ _startX += position.width + 4 * r;
+
+ }
+
+ }
+
+ function init(opt) { // 초기 호출
+
+ var _legend,
+ children = [],
+ item,
+ text,
+ type,
+ imageUrl,
+ r,
+ id;
+
+ _legend = opt.legend || [];
+ data = opt.data || [];
+
+ if (_legend.length === 0) {
+ legendHeight = 0;
+ }
+ //将图例数据格式转换为以name类型为键值的对象
+ for (var i = 0, len = _legend.length; i < len; i++) {
+ item = _legend[i];
+ legend[item.name] = item;
+ }
+
+ if (!data || data.length === 0) {
+ return;
+ }
+
+ //创建开始节点
+ createStartNode(startX, startY);
+ //创建内容节点
+ for (i = 0, len = data.length; i < len; i++) {
+ item = data[i];
+ text = item.text;
+ imageUrl = getImageUrl(item.imageUrl, null);
+ children = item.children || [];
+ r = 10;
+ //创建主节点
+ createCentralAxisNode(nextX, startY, text, imageUrl);
+ //创建分支节点
+ if (children.length === 0 && i !== len - 1) {
+ //不存在分支节点,只创建中轴线
+ createCentralAxisLine(nextX, startY, r);
+ } else if (children.length > 0) {
+ //重置nextY,新的主节点下的分支节点Y轴位置回复为初始位置
+ nextY = startY;
+ currentBranchCount = children.length;
+ //存在分支节点,创建分支内容节点
+ for (var j = 0, lenj = children.length; j < lenj; j++) {
+ item = children[j];
+ text = item.text;
+ imageUrl = getImageUrl(item.imageUrl, item.legendName);
+ id = item.id;
+ createBranchNode(nextX, startY, text, imageUrl, r, id);
+ }
+ }
+ }
+
+ console.log(endX)
+ //创建结束节点
+ createEndNode(nextX, startY);
+
+ //创建图例
+ createLegend();
+ //设置画布大小
+ pagerWidth = nextX + ViewBoxX;
+ pagerHeight = Math.abs(endY * 2) + legendHeight;
+ paper.setSize(pagerWidth, pagerHeight);
+ //设置ViewBox偏移量
+ ViewBoxY = Math.abs(endY * 2) / 2 + legendHeight;
+ paper.setViewBox(-ViewBoxX, -ViewBoxY, pagerWidth, pagerHeight, false);
+ }
+
+ container.addClass("statusTimeline");
+ init(opt);
+ return container;
+ },
+ });
+
+ $.extend({
+ timeline: {
+ theme: {
+ yellow: {
+ lengend: {
+ fill: "#000000",
+ },
+ startNode: {
+ radius: 10,
+ fill: "#7E899D"
+ },
+ endNode: {
+ radius: 10,
+ fill: "#7E899D"
+ },
+ centralAxisNode: {
+ height: 21,
+ radius: 4,
+ fill: "#1A84CE",
+ color: "#ffffff",
+ inner: {
+ fill: "#1A84CE",
+ "stroke-width": 0,
+ stroke: "#1A84CE"
+ },
+ outer: {
+ fill: "#1A84CE",
+ "stroke-width": 3,
+ stroke: "#1A84CE"
+ }
+ },
+ centralAxisLine: {
+ fill: "#7E899D"
+ },
+ centralAxisBranchNode: {
+ fill: "#F9BF3B",
+ radius: 10
+ },
+ centralAxisBranchLine: {
+ stroke: '#F9BF3B',
+ fill: "#F9BF3B"
+ },
+ centralAxisBranchContent: {
+ fill: "#F9BF3B",
+ color: "#ffffff",
+ stroke: '#ffffff',
+ height: 24,
+ radius: 6,
+ "padding": 0
+ }
+ },
+ gray: {
+ lengend: {
+ fill: "#5A5A5A",
+ },
+ startNode: {
+ radius: 6,
+ fill: "#7E899D"
+ },
+ endNode: {
+ radius: 6,
+ fill: "#7E899D"
+ },
+ centralAxisNode: {
+ height: 18,
+ radius: 2,
+ //fill: "#1A84CE",
+ color: "#1A84CE",
+ inner: {
+ fill: "#ffffff",
+ "stroke-width": 0,
+ stroke: "#1A84CE"
+ },
+ outer: {
+ fill: "#1A84CE",
+ "stroke-width": 2,
+ stroke: "#1A84CE"
+ }
+ },
+ centralAxisLine: {
+ fill: "#7E899D"
+ },
+ centralAxisBranchNode: {
+ fill: "#7E899D",
+ radius: 8
+ },
+ centralAxisBranchLine: {
+ stroke: '#526079',
+ fill: "'#526079"
+ },
+ centralAxisBranchContent: {
+ fill: "#FFFFFF",
+ color: "#111111",
+ stroke: '#526079',
+ height: 24,
+ radius: 12,
+ "padding": 6
+ }
+ }
+ }
+ }
+ });
+
+})(jQuery);
\ No newline at end of file