간트 시트 진행률 선

이 샘플은 진행률 선 API를 사용하여 간트 시트에서 작업 진행률을 프로젝트의 현재 날짜 또는 상태 날짜와 비교하는 방법을 보여 줍니다.

진행률 선 진행률 선은 간트 차트 위에 그려지는 분석용 오버레이입니다. 선택한 기준 날짜를 기준으로 작업 진행 지점을 연결하여 작업의 현재 진행 상황과 프로젝트 계획을 비교할 수 있습니다. 이 샘플은 작업 완료 데이터를 사용하고 사이드 패널에서 진행률 선 API를 제공합니다. 샘플을 열 때 진행률 선이 표시되도록 프로젝트의 현재 날짜와 상태 날짜를 초기화합니다. 프로젝트 날짜를 업데이트하고 진행률 선 표시, 기준 날짜, 경로 형식, 선 스타일, 지점 스타일 및 날짜 레이블 스타일을 구성할 수 있습니다. 프로젝트 날짜 진행률 선은 한 번에 하나의 프로젝트 수준 날짜를 참조합니다. project.currentDate project.statusDate 샘플은 기본적으로 두 날짜를 모두 지정합니다. 사이드 패널에서 날짜를 변경하여 진행률 선이 어떻게 달라지는지 확인할 수 있습니다. 날짜 눈금선 이 샘플의 현재 날짜 눈금선과 상태 날짜 눈금선은 고정 스타일을 사용하며 진행률 선과 독립적으로 구성됩니다. 진행률 선 API ganttSheet.progressLine을 사용하여 진행률 선 구성을 설정하거나 가져올 수 있습니다. 사용 가능한 속성은 다음과 같습니다. display: 진행률 선 표시 여부를 지정합니다. referenceDate: 사용할 프로젝트 날짜를 지정합니다. 값은 "statusDate" 또는 "currentDate"입니다. pathType: 경로가 기준 날짜로 돌아갈지, 진행 지점을 직교선 또는 대각선으로 연결할지를 포함하여 진행률 선 경로가 그려지는 방식을 지정합니다. lineStyle: 진행률 선의 형식과 색을 지정합니다. GC.Spread.Sheets.GanttSheet.GanttGridlineType을 사용합니다. pointStyle: 진행 지점의 모양과 색을 지정합니다. 모양에는 GC.Spread.Sheets.GanttSheet.TaskbarEndShape와 동일한 값을 지원하는 GC.Spread.Sheets.GanttSheet.ProgressPointShape를 사용합니다. dateLabelStyle: 날짜 레이블 표시 여부와 레이블 형식을 지정합니다.
/*REPLACE_MARKER*/ /*DO NOT DELETE THESE COMMENTS*/ var ganttSheet; var GanttGridlineType = GC.Spread.Sheets.GanttSheet.GanttGridlineType; var lineTypeMap = {}; lineTypeMap.thin = GanttGridlineType.thin; lineTypeMap.dashed = GanttGridlineType.dashed; lineTypeMap.dotted = GanttGridlineType.dotted; lineTypeMap.dashDot = GanttGridlineType.dashDot; lineTypeMap.empty = GanttGridlineType.empty; window.onload = function() { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 }); initSpread(spread); initSplitView(spread); }; function initSpread(spread) { spread.suspendPaint(); initGanttSheet(spread); spread.resumePaint(); } function initGanttSheet(spread) { var tableName = "Gantt_Mode"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); var myTable = dataManager.addTable("myTable", { batch: true, remote: { read: { url: apiUrl }, batch: { url: apiUrl + "Collection" } }, schema: { hierarchy: { type: "Parent", column: "parentId" }, columns: { id: { isPrimaryKey: true }, taskNumber: { dataType: "rowOrder" } } } }); ganttSheet = spread.addSheetTab(0, "GanttSheet1", GC.Spread.Sheets.SheetType.ganttSheet); var view = myTable.addView("myView1", [ { value: "taskNumber", caption: "NO", width: 60 }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 120 }, { value: "complete", caption: "% Complete", width: 100 } ]); view.fetch().then(function() { return ganttSheet.bindGanttView(view); }).then(function() { initDefaultProjectDates(); applyFixedGridlines(); applyProgressLine(); }); initSidePanel(); } function initDefaultProjectDates() { var projectStart = ganttSheet.project.startDate; var currentDate = addDays(projectStart, 4); var statusDate = addDays(projectStart, 7); ganttSheet.project.currentDate = currentDate; ganttSheet.project.statusDate = statusDate; document.getElementById("current-date").value = formatInputDate(currentDate); document.getElementById("status-date").value = formatInputDate(statusDate); } function applyFixedGridlines() { ganttSheet.gridlines.currentDate = { lineColor: "#4A8F40", lineType: GanttGridlineType.thin }; ganttSheet.gridlines.statusDate = { lineColor: "#5B9BD5", lineType: GanttGridlineType.dashDot }; } function initSidePanel() { document.getElementById("apply-progress-line").addEventListener("click", function() { applyProjectDates(); applyFixedGridlines(); applyProgressLine(); }); } function applyProjectDates() { var currentDateValue = document.getElementById("current-date").value; ganttSheet.project.currentDate = parseInputDate(currentDateValue); var statusDateValue = document.getElementById("status-date").value; ganttSheet.project.statusDate = parseInputDate(statusDateValue); } function applyProgressLine() { ganttSheet.suspendPaint(); ganttSheet.progressLine = { display: document.getElementById("display").checked, referenceDate: document.getElementById("reference-date").value, pathType: { returnToReferenceDate: document.getElementById("return-to-reference-date").checked, pointConnectionType: document.getElementById("point-connection-type").value }, lineStyle: { lineType: lineTypeMap[document.getElementById("line-type").value], lineColor: document.getElementById("line-color").value }, pointStyle: { shape: document.getElementById("point-shape").value, color: document.getElementById("point-color").value }, dateLabelStyle: { display: document.getElementById("label-display").checked, format: document.getElementById("label-format").value, font: document.getElementById("label-font").value } }; ganttSheet.resumePaint(); } function addDays(date, days) { var result = new Date(date); result.setDate(result.getDate() + days); return result; } function formatInputDate(date) { if (!date) { return ""; } var year = date.getFullYear(); var month = ("0" + (date.getMonth() + 1)).slice(-2); var day = ("0" + date.getDate()).slice(-2); return year + "-" + month + "-" + day; } function parseInputDate(value) { if (!value) { return null; } var parts = value.split("-"); return new Date(Number(parts[0]), Number(parts[1]) - 1, Number(parts[2])); } function getBaseApiUrl() { return window.location.href.match(/http.+spreadjs\/learn-spreadjs\//)[0] + 'server/api'; } function initSplitView(spread) { var host = document.getElementById("split-view"); var content = host.getElementsByClassName("split-content")[0]; var panel = host.getElementsByClassName("split-panel")[0]; new SplitView({ host: host, content: content, panel: panel, refreshContent: function() { spread.refresh(); } }); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="ko-kr"/> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/spread/source/splitView/splitView.css"> <!-- Promise Polyfill for IE, https://www.npmjs.com/package/promise-polyfill --> <script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/splitView/splitView.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div id="split-view" class="sample-tutorial"> <div id="ss" class="sample-spreadsheets split-content"></div> <div class="options-container split-panel"> <div class="option-row option-title"> 진행률 선을 구성합니다. </div> <div class="option-block"> <div class="option-row option-title"> 프로젝트 날짜 </div> <div class="option-row input-box"> <label for="current-date">현재 날짜</label> <input type="date" id="current-date" /> </div> <div class="option-row input-box"> <label for="status-date">상태 날짜</label> <input type="date" id="status-date" /> </div> </div> <div class="option-block"> <div class="option-row option-title"> 눈금선 </div> <div class="option-row"> <span class="line-swatch current-date-line"></span> 현재 날짜: 녹색 실선 </div> <div class="option-row"> <span class="line-swatch status-date-line"></span> 상태 날짜: 파란색 일점쇄선 </div> </div> <div class="option-block"> <div class="option-row option-title"> 진행률 선 </div> <div class="option-row"> <label class="option-checkbox-label"> <input type="checkbox" id="display" checked /> 표시 </label> </div> <div class="option-row selection-box"> <label for="reference-date">기준 날짜</label> <select id="reference-date"> <option value="statusDate" selected>statusDate</option> <option value="currentDate">currentDate</option> </select> </div> </div> <div class="option-block"> <div class="option-row option-title"> 경로 형식 </div> <div class="option-row"> <label class="option-checkbox-label"> <input type="checkbox" id="return-to-reference-date" /> 기준 날짜로 돌아가기 </label> </div> <div class="option-row selection-box"> <label for="point-connection-type">연결</label> <select id="point-connection-type"> <option value="orthogonal" selected>orthogonal</option> <option value="diagonal">diagonal</option> </select> </div> </div> <div class="option-block"> <div class="option-row option-title"> 선 스타일 </div> <div class="option-row selection-box"> <label for="line-type">선 형식</label> <select id="line-type"> <option value="thin" selected>thin</option> <option value="dashed">dashed</option> <option value="dotted">dotted</option> <option value="dashDot">dashDot</option> <option value="empty">empty</option> </select> </div> <div class="option-row input-box"> <label for="line-color">색</label> <input type="text" id="line-color" value="#C0504D" /> <div class="option-info valid">* 유효한 값: 색 문자열</div> </div> </div> <div class="option-block"> <div class="option-row option-title"> 지점 스타일 </div> <div class="option-row selection-box"> <label for="point-shape">모양</label> <select id="point-shape"> <option value="arrowDown">arrowDown</option> <option value="arrowUp">arrowUp</option> <option value="caretDownTop">caretDownTop</option> <option value="caretUpBottom">caretUpBottom</option> <option value="circleDiamond" selected>circleDiamond</option> <option value="circle">circle</option> <option value="circleArrowDown">circleArrowDown</option> <option value="circleArrowUp">circleArrowUp</option> <option value="circleTriangleDown">circleTriangleDown</option> <option value="circleTriangleUp">circleTriangleUp</option> <option value="diamond">diamond</option> <option value="houseDown">houseDown</option> <option value="houseUp">houseUp</option> <option value="leftBracket">leftBracket</option> <option value="leftFade">leftFade</option> <option value="lineShape">lineShape</option> <option value="rightBracket">rightBracket</option> <option value="rightFade">rightFade</option> <option value="square">square</option> <option value="star">star</option> <option value="triangleDown">triangleDown</option> <option value="triangleLeft">triangleLeft</option> <option value="triangleRight">triangleRight</option> <option value="triangleUp">triangleUp</option> </select> </div> <div class="option-row input-box"> <label for="point-color">색</label> <input type="text" id="point-color" value="#C0504D" /> <div class="option-info valid">* 유효한 값: 색 문자열</div> </div> </div> <div class="option-block"> <div class="option-row option-title"> 날짜 레이블 스타일 </div> <div class="option-row"> <label class="option-checkbox-label"> <input type="checkbox" id="label-display" checked /> 표시 </label> </div> <div class="option-row input-box"> <label for="label-format">형식</label> <input type="text" id="label-format" value="yyyy-MM-dd" /> </div> <div class="option-row input-box"> <label for="label-font">글꼴</label> <input type="text" id="label-font" value="10pt Calibri" /> </div> </div> <div class="option-block"> <div class="option-row"> <input type="button" id="apply-progress-line" class="option-button" value="진행률 선 적용"> </div> </div> </div> </div> </body> </html>
.sample-tutorial { width: 100%; height: 100%; } body, html { padding: 0; margin: 0; width: 100%; height: 100%; position: relative; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; } .options-container { float: right; width: 300px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; box-shadow: inset 0px 0 4px 0 rgba(0,0,0,0.4); } .option-block { background: #fff; padding: 8px; margin: 12px 0; border-radius: 4px; border: 1px dashed #82bc00; box-shadow: 0px 0 6px 0 rgba(0,0,0,0.1); } .option-row { font-size: 14px; box-sizing: border-box; padding: 4px 0; color: #656565; } .option-title { font-weight: bold; color: #656565; } .option-info { font-size: 12px; color: #919191; margin-top: 6px; font-weight: normal; } .option-info.valid { color: #82bc00; } .option-button { width: 100%; padding: 0; line-height: 22px; background: #82bc00; color: #fff; transition: 0.3s; cursor: pointer; outline: none; border-radius: 4px; box-sizing: border-box; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); border: none; } .option-button:hover { background: #82bc00; color: #fff; box-shadow: 0 3px 8px 0 rgba(0,0,0,0.4); } .option-checkbox-label { cursor: pointer; } .selection-box { position: relative; } .selection-box > select { text-align: left; width: 100%; height: 20px; padding: 0; line-height: 20px; background: transparent; border: none; border-bottom: 2px solid #656565; color: #656565; transition: 0.3s; cursor: pointer; outline: none; box-sizing: border-box; } .selection-box > select > option { background: white; } .selection-box > select:focus { border-bottom: 2px solid #82bc00; color: #82bc00; box-shadow: 0 2px 6px 0 rgba(0,0,0,0.3); } .selection-box > label { position: absolute; cursor: pointer; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; right: 0; top: 6px; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); } .input-box { position: relative; } .input-box > input[type=text], .input-box > input[type=date] { width: 100%; height: 22px; background: transparent; border: none; color: #656565; border-bottom: 2px solid #656565; outline: none; box-sizing: border-box; transition: 0.3s; } .input-box > input[type=text]:focus, .input-box > input[type=date]:focus { color: #82bc00; border-bottom: 2px solid #82bc00; } .input-box > input:disabled { color: #b0b0b0; border-bottom-color: #c9c9c9; } .input-box > label { cursor: pointer; position: absolute; right: 0; top: 5px; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3); } .line-swatch { display: inline-block; width: 36px; height: 0; margin-right: 6px; vertical-align: middle; } .current-date-line { border-top: 2px solid #4A8F40; } .status-date-line { border-top: 2px dashed #5B9BD5; border-top-style: dashed; }