このサンプルでは、ワークブックレベルのテーマとテーブル固有のテーマの両方を使用して、ガントシートにテーマを適用する方法を示します。
ワークブックテーマ
currentTheme メソッドを使用して、完全なワークブックテーマを適用できます。SpreadJS は GC.Spread.Sheets.Themes に 22 個の組み込みテーマを提供しています。
テーマの色
新しいテーマを作成し、GC.Spread.Sheets.ThemeColors の配色を適用することで、テーマカラーをカスタマイズできます。
テーマのフォント
同様に、GC.Spread.Sheets.ThemeFonts を使用してテーマフォントをカスタマイズできます。
ガントシートテーマ
ガントシートは テーブルシートを継承し、GC.Spread.Sheets.Tables.TableTheme インスタンスを受け取る applyTableTheme メソッドを提供します。
次の テーブルテーマスタイルが ガントシート に適用されます。
スタイル
適用先
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: "タスク名", width: 200 },
{ value: "duration", caption: "期間", width: 90 },
{ value: "predecessors", caption: "先行タスク", 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);
});
// ワークブックのテーマオプションを設定します
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);
});
// テーマカラーのオプションを設定します
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);
});
// テーマのフォントオプションを設定します
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) {
// 現在のテーブルテーマをクローンします
var baseTheme = GC.Spread.Sheets.Tables.TableThemes[currentGanttThemeName];
var customTableTheme = new GC.Spread.Sheets.Tables.TableTheme();
customTableTheme.fromJSON(baseTheme.toJSON());
// highlightLastColumnStyle を取得して変更します
var lastColStyle = customTableTheme.highlightLastColumnStyle();
if (!lastColStyle) {
lastColStyle = new GC.Spread.Sheets.Tables.TableStyle();
}
// フォントとフォントファミリーを undefined に設定してテーマフォントを使用します
lastColStyle.font = undefined;
lastColStyle.fontFamily = undefined;
customTableTheme.highlightLastColumnStyle(lastColStyle);
// 修正したテーマを適用します
ganttSheet.applyTableTheme(customTableTheme);
} else {
// 元のテーブルテーマを適用します
ganttSheet.applyTableTheme(GC.Spread.Sheets.Tables.TableThemes[currentGanttThemeName]);
}
}
// ガントシートのテーマセレクター
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\/demos\//)[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="ja-jp" />
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/ja/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$/ja/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script>
<script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-resources-ja/dist/gc.spread.sheets.resources.ja.min.js" type="text/javascript"></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">
ワークブックのテーマ
</div>
<div class="option-row selection-box">
<label>テーマ</label>
<select id="workbookTheme"></select>
</div>
</div>
<div class="option-block">
<div class="option-row option-title">
テーマの色
</div>
<div class="option-row selection-box">
<label>色</label>
<select id="themeColors"></select>
</div>
</div>
<div class="option-block">
<div class="option-row option-title">
テーマのフォント
</div>
<div class="option-row selection-box">
<label>フォント</label>
<select id="themeFonts"></select>
</div>
<div class="option-row">
<label class="option-checkbox" id="override-gantt-font">ガントシートのテーマフォントを上書き</label>
<div class="option-info">* highlightLastColumn の fontFamily をテーマフォントで上書きします。</div>
</div>
</div>
<div class="option-block">
<div class="option-row option-title">
ガントシートのテーマ
</div>
<div class="option-row selection-box">
<label>テーマ</label>
<select id="ganttSheetTheme">
<optgroup label="ライトテーマ">
<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="ミディアムテーマ">
<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="ダークテーマ">
<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="プロフェッショナルテーマ">
<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;
}