이 샘플은 통합 문서 수준 테마와 테이블별 테마를 사용하여 간트 시트에 테마를 적용하는 방법을 보여 줍니다.
통합 문서 테마
currentTheme 메서드를 사용하여 전체 통합 문서 테마를 적용할 수 있습니다. SpreadJS는 GC.Spread.Sheets.Themes에서 22개의 기본 제공 테마를 제공합니다.
테마 색
새 테마를 만들고 GC.Spread.Sheets.ThemeColors의 색 구성표를 적용하여 테마 색을 사용자 지정할 수 있습니다.
테마 글꼴
마찬가지로 GC.Spread.Sheets.ThemeFonts를 사용하여 테마 글꼴을 사용자 지정할 수 있습니다.
간트 시트 테마
간트 시트는 테이블 시트를 상속하며, applyTableTheme 메서드를 제공합니다. 이 메서드는 GC.Spread.Sheets.Tables.TableTheme 인스턴스를 받습니다.
다음 TableTheme 스타일이 간트 시트에 적용됩니다.
스타일
적용 대상
headerRowStyle
열 머리글 영역의 기본 스타일에 적용
wholeTableStyle
뷰포트 영역 및 열 머리글 영역의 기본 스타일에 적용
firstRowStripStyle
뷰포트 영역의 alternatingRowOptions 스타일에 적용
secondRowStripStyle
뷰포트 영역의 alternatingRowOptions 스타일에 적용
firstRowStripSize
뷰포트 영역의 alternatingRowOptions 단계에 적용
secondRowStripSize
뷰포트 영역의 alternatingRowOptions 단계에 적용
기존 기본 제공 테이블 테마인 21개의 밝은 테마, 28개의 중간 테마, 11개의 어두운 테마 외에도 간트 시트는 "professional" 접두사가 붙은 24개의 새 테마를 지원합니다.
/*REPLACE_MARKER*/
/*DO NOT DELETE THESE COMMENTS*/
var myTable;
var ganttSheet;
window.onload = function() {
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 0 });
initSpread(spread);
initSplitView(spread);
};
function initSpread(spread) {
spread.suspendPaint();
spread.options.autoFitType = GC.Spread.Sheets.AutoFitType.cellWithHeader;
initDataSource(spread);
initGanttSheet(spread);
spread.resumePaint();
}
function initDataSource(spread) {
var tableName = "Gantt_Id";
var baseApiUrl = getBaseApiUrl();
var apiUrl = baseApiUrl + "/" + tableName;
var dataManager = spread.dataManager();
myTable = dataManager.addTable("myTable", {
batch: true,
remote: {
read: {
url: apiUrl
}
},
schema: {
hierarchy: {
type: "Parent",
column: "parentId"
},
columns: {
id: { isPrimaryKey: true },
taskNumber: { dataType: "rowOrder" }
}
}
});
}
function initGanttSheet(spread) {
ganttSheet = spread.addSheetTab(0, "GanttSheet", GC.Spread.Sheets.SheetType.ganttSheet);
ganttSheet.options.allowAddNew = false;
ganttSheet.setDefaultRowHeight(40, GC.Spread.Sheets.SheetArea.colHeader);
ganttSheet.applyTableTheme(GC.Spread.Sheets.Tables.TableThemes.light2);
ganttSheet.project.timescale.nonWorkingTime.color = 'Accent 4 60';
ganttSheet.project.timescale.nonWorkingTime.pattern = 'darkFil';
var view = myTable.addView("ganttView", [
{ 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 }
]);
view.fetch().then(function() {
ganttSheet.bindGanttView(view);
}).then(function(){
var taskStyle = ganttSheet.project.taskStyleRules.getRule('task');
taskStyle.style.taskbarStyle.middleColor = 'Accent 1';
taskStyle.style.taskbarStyle.topText = 'name';
var taskStyleIndex = ganttSheet.project.taskStyleRules.getIndexByItem(taskStyle);
ganttSheet.project.taskStyleRules.setItemAt(taskStyleIndex, taskStyle);
});
// Populate Workbook Theme options
var workbookThemeSelect = document.getElementById("workbookTheme");
Object.keys(GC.Spread.Sheets.Themes).forEach(function(themeName) {
var option = document.createElement("option");
option.value = themeName;
option.text = themeName;
if (themeName === "Office") {
option.selected = true;
}
workbookThemeSelect.appendChild(option);
});
workbookThemeSelect.addEventListener("change", function () {
let selectedTheme = workbookThemeSelect.value;
let theme = GC.Spread.Sheets.Themes[selectedTheme];
ganttSheet.currentTheme(theme);
});
// Populate Theme Colors options
var themeColorsSelect = document.getElementById("themeColors");
Object.keys(GC.Spread.Sheets.ThemeColors).forEach(function(colorName) {
var option = document.createElement("option");
option.value = colorName;
option.text = colorName;
if (colorName === "Office") {
option.selected = true;
}
themeColorsSelect.appendChild(option);
});
themeColorsSelect.addEventListener("change", function () {
let selectedColorScheme = themeColorsSelect.value;
let currentTheme = ganttSheet.currentTheme();
let newTheme = new GC.Spread.Sheets.Theme();
newTheme.fromJSON(currentTheme.toJSON());
newTheme.colors(GC.Spread.Sheets.ThemeColors[selectedColorScheme]);
newTheme.name('custom-theme');
ganttSheet.currentTheme(newTheme);
});
// Populate Theme Fonts options
var themeFontsSelect = document.getElementById("themeFonts");
var overrideGanttFontCheckbox = document.getElementById("override-gantt-font");
var shouldOverrideGanttFont = false;
var currentGanttThemeName = "light2"; // Track current gantt theme
Object.keys(GC.Spread.Sheets.ThemeFonts).forEach(function(fontName) {
var option = document.createElement("option");
option.value = fontName;
option.text = fontName;
if (fontName === "Office") {
option.selected = true;
}
themeFontsSelect.appendChild(option);
});
overrideGanttFontCheckbox.addEventListener("click", function() {
if (overrideGanttFontCheckbox.classList.contains("active")) {
overrideGanttFontCheckbox.classList.remove("active");
shouldOverrideGanttFont = false;
} else {
overrideGanttFontCheckbox.classList.add("active");
shouldOverrideGanttFont = true;
}
applyGanttTableTheme();
});
themeFontsSelect.addEventListener("change", function () {
applyThemeFont();
});
function applyThemeFont() {
let selectedFont = themeFontsSelect.value;
let currentTheme = ganttSheet.currentTheme();
let newTheme = new GC.Spread.Sheets.Theme();
newTheme.fromJSON(currentTheme.toJSON());
newTheme.font(GC.Spread.Sheets.ThemeFonts[selectedFont]);
newTheme.name('custom-theme');
ganttSheet.currentTheme(newTheme);
if (shouldOverrideGanttFont) {
applyGanttTableTheme();
}
}
function applyGanttTableTheme() {
if (shouldOverrideGanttFont) {
// Clone the current table theme
var baseTheme = GC.Spread.Sheets.Tables.TableThemes[currentGanttThemeName];
var customTableTheme = new GC.Spread.Sheets.Tables.TableTheme();
customTableTheme.fromJSON(baseTheme.toJSON());
// Get and modify the highlightLastColumnStyle
var lastColStyle = customTableTheme.highlightLastColumnStyle();
if (!lastColStyle) {
lastColStyle = new GC.Spread.Sheets.Tables.TableStyle();
}
// Set font and fontFamily to undefined to use theme font
lastColStyle.font = undefined;
lastColStyle.fontFamily = undefined;
customTableTheme.highlightLastColumnStyle(lastColStyle);
// Apply the modified theme
ganttSheet.applyTableTheme(customTableTheme);
} else {
// Apply the original table theme
ganttSheet.applyTableTheme(GC.Spread.Sheets.Tables.TableThemes[currentGanttThemeName]);
}
}
// GanttSheet Theme selector
var ganttThemeSelect = document.getElementById("ganttSheetTheme");
ganttThemeSelect.addEventListener("change", function () {
let selectedTheme = ganttThemeSelect.value;
currentGanttThemeName = selectedTheme;
applyGanttTableTheme();
});
}
function getBaseApiUrl() {
var url = window.location.href;
return url.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$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.min.js"></script>
<script src="$DEMOROOT$/spread/source/splitView/splitView.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-block">
<div class="option-row option-title">
Workbook Theme
</div>
<div class="option-row selection-box">
<label>Theme</label>
<select id="workbookTheme"></select>
</div>
</div>
<div class="option-block">
<div class="option-row option-title">
Theme Colors
</div>
<div class="option-row selection-box">
<label>Colors</label>
<select id="themeColors"></select>
</div>
</div>
<div class="option-block">
<div class="option-row option-title">
Theme Fonts
</div>
<div class="option-row selection-box">
<label>Fonts</label>
<select id="themeFonts"></select>
</div>
<div class="option-row">
<label class="option-checkbox" id="override-gantt-font">Override GanttSheet Theme Font</label>
<div class="option-info">* Override highlightLastColumn fontFamily with theme font.</div>
</div>
</div>
<div class="option-block">
<div class="option-row option-title">
GanttSheet Theme
</div>
<div class="option-row selection-box">
<label>Theme</label>
<select id="ganttSheetTheme">
<optgroup label="Light Themes">
<option value="light1">light1</option>
<option value="light2" selected>light2</option>
<option value="light3">light3</option>
<option value="light4">light4</option>
<option value="light5">light5</option>
<option value="light6">light6</option>
<option value="light7">light7</option>
<option value="light8">light8</option>
<option value="light9">light9</option>
<option value="light10">light10</option>
<option value="light11">light11</option>
<option value="light12">light12</option>
<option value="light13">light13</option>
<option value="light14">light14</option>
<option value="light15">light15</option>
<option value="light16">light16</option>
<option value="light17">light17</option>
<option value="light18">light18</option>
<option value="light19">light19</option>
<option value="light20">light20</option>
<option value="light21">light21</option>
</optgroup>
<optgroup label="Medium Themes">
<option value="medium1">medium1</option>
<option value="medium2">medium2</option>
<option value="medium3">medium3</option>
<option value="medium4">medium4</option>
<option value="medium5">medium5</option>
<option value="medium6">medium6</option>
<option value="medium7">medium7</option>
<option value="medium8">medium8</option>
<option value="medium9">medium9</option>
<option value="medium10">medium10</option>
<option value="medium11">medium11</option>
<option value="medium12">medium12</option>
<option value="medium13">medium13</option>
<option value="medium14">medium14</option>
<option value="medium15">medium15</option>
<option value="medium16">medium16</option>
<option value="medium17">medium17</option>
<option value="medium18">medium18</option>
<option value="medium19">medium19</option>
<option value="medium20">medium20</option>
<option value="medium21">medium21</option>
<option value="medium22">medium22</option>
<option value="medium23">medium23</option>
<option value="medium24">medium24</option>
<option value="medium25">medium25</option>
<option value="medium26">medium26</option>
<option value="medium27">medium27</option>
<option value="medium28">medium28</option>
</optgroup>
<optgroup label="Dark Themes">
<option value="dark1">dark1</option>
<option value="dark2">dark2</option>
<option value="dark3">dark3</option>
<option value="dark4">dark4</option>
<option value="dark5">dark5</option>
<option value="dark6">dark6</option>
<option value="dark7">dark7</option>
<option value="dark8">dark8</option>
<option value="dark9">dark9</option>
<option value="dark10">dark10</option>
<option value="dark11">dark11</option>
</optgroup>
<optgroup label="Professional Themes">
<option value="professional1">professional1</option>
<option value="professional2">professional2</option>
<option value="professional3">professional3</option>
<option value="professional4">professional4</option>
<option value="professional5">professional5</option>
<option value="professional6">professional6</option>
<option value="professional7">professional7</option>
<option value="professional8">professional8</option>
<option value="professional9">professional9</option>
<option value="professional10">professional10</option>
<option value="professional11">professional11</option>
<option value="professional12">professional12</option>
<option value="professional13">professional13</option>
<option value="professional14">professional14</option>
<option value="professional15">professional15</option>
<option value="professional16">professional16</option>
<option value="professional17">professional17</option>
<option value="professional18">professional18</option>
<option value="professional19">professional19</option>
<option value="professional20">professional20</option>
<option value="professional21">professional21</option>
<option value="professional22">professional22</option>
<option value="professional23">professional23</option>
<option value="professional24">professional24</option>
</optgroup>
</select>
</div>
</div>
</div>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.options-container {
float: right;
width: 280px;
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;
}
.option-title {
font-weight: bold;
color: #656565;
}
.option-info {
font-size: 12px;
color: #919191;
margin-top: 6px;
font-weight: normal;
}
.option-checkbox {
background: #fff;
border: 1px dashed #f7a711;
color: #f7a711;
padding: 2px 4px;
transition: 0.3s;
box-sizing: border-box;
cursor: pointer;
display: inline-block;
}
.option-checkbox.active {
color: #fff;
background: #f7a711;
box-shadow: 0 1px 4px 0 rgba(0,0,0,0.3);
border-radius: 4px;
}
.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);
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}