飛行機の座席表

このデモは、カスタムシェイプを使用して平面座席図を作成する方法を示しています。

シェイプでは、ビルトインシェイプのほかにカスタムシェイプを作成することができます。カスタムシェイプでは、セル内のデータに基づいて形状を動的に生成できます。
var cmdMap = { moveTo: 'M', lineTo: 'L', bezierCurveTo: 'B', quadraticCurveTo: 'Q', arc: 'A', arcTo: 'AT', closePath: 'Z' }; var spread; var sheet; var sheetData; var selectedSeatsArray = []; // convert svg points to shape path function pointsToPath(points) { var ps = points.split(' '); var mx = 10000; // shift the shape to (0, 0) var my = 10000; ps = ps.map(function (p) { var t = p.split(','); if (parseFloat(t[0]) < mx) { mx = parseFloat(t[0]); } if (parseFloat(t[1]) < my) { my = parseFloat(t[1]); } return { x: parseFloat(t[0]), y: parseFloat(t[1]) }; }); var cmds = []; cmds.push(['M', ps[0].x - mx, ps[0].y - my]); for (var i = 1; i < ps.length; i++) { cmds.push(['L', ps[i].x - mx, ps[i].y - my]); } cmds.push(['Z']); return [cmds]; } // convert svg path to shape path function convertPath(d) { var cmds = parser.parse(d); var mx = 10000; // shift the shape to (0, 0) var my = 10000; var pathCommands = cmds.map(function (cmd) { for (var i = 0; i < cmd.args.length; i = i + 2) { if (cmd.args[i] < mx) { mx = cmd.args[i]; } if (cmd.args[i + 1] < my) { my = cmd.args[i + 1]; } } return [cmdMap[cmd.type]].concat(cmd.args); }); var ret = []; var t = []; for (var i = 0; i < pathCommands.length; i++) { var cmd = pathCommands[i]; for (var j = 1; j < cmd.length; j = j + 2) { cmd[j] = cmd[j] - mx; cmd[j + 1] = cmd[j + 1] - my; } t.push(cmd); if (cmd[0] == 'Z') { ret.push(t); t = []; } } return ret; } function convertStatus(seatStatus) { var ret = -1 //O: Open: green //1: Reserved: red //2: Upgrade: orange switch (seatStatus) { case 0: ret = "green"; break; case 1: ret = "red"; break; case 2: ret = "orange"; break; } return ret } function convertNumbertoLetter(ssCol) { var ret = "" switch (ssCol) { case 0: ret = "A"; break; case 1: ret = "B"; break; case 2: ret = "C"; break; case 3: ret = "D"; break; case 4: ret = "E"; break; case 5: ret = "F"; break; } return ret } var shapeFormula = "=CHOOSE(VLOOKUP(name,Sheet2!A1:B186,2,False)+1, \"green\", \"red\", \"orange\")"; function createShape(serverpathCommands, sleft, stop, swidth, sheight, shapename) { var servermodel = { name: shapename, left: sleft, top: stop, width: swidth, height: sheight, angle: 0, options: { fill: { type: GC.Spread.Sheets.Shapes.ShapeFillType.solid, color: shapeFormula, width: 1 }, stroke: { type: GC.Spread.Sheets.Shapes.ShapeFillType.solid, color: shapeFormula }, textFormatOptions: { allowTextToOverflowShape: false, wrapTextInShape: false, font: '="11px Arial"', fill: { type: GC.Spread.Sheets.Shapes.ShapeFillType.solid, color: 'black' } } }, path: serverpathCommands }; return servermodel; } function addData(sheet) { //O: Open: green //1: Reserved: red //2: Upgrade: orange sheet.setValue(2, 5, "Available Seats:") sheet.getCell(2, 7).backColor("green"); sheet.setValue(4, 5, "Reserved Seats:") sheet.getCell(4, 7).backColor("red"); sheet.setValue(6, 5, "Premium Seats") sheet.getCell(6, 7).backColor("orange"); sheet.setValue(11, 5, "You have Selected:"); sheet.addSpan(11, 5, 1, 3); sheet.options.protectionOptions.allowEditObjects = false; sheet.setColumnWidth(7, 20); sheet.options.colHeaderVisible = false; sheet.options.rowHeaderVisible = false; sheet.options.selectionBorderColor = "Transparent"; } window.onload = initFunction; function initFunction() { var constleft = 137.5; var consttop = 230; var aislespacer = 25; var rowspacer = 32.8; var shapewidth = 25; var shapeheight = 25; var shapeleft = constleft; var shapetop = consttop; var i; var j; var sheetDataRow = 0; //counter for Seats on Data sheet var sheetDataSeatRow = 2; //seat number counter for display - 2A, 2B, 3A, etc var seatNum = "" //seat number as shown on ticket- 2A, 2B, 3A, etc var selectedSeat = ""; spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount: 1 }); spread.setSheetCount(2); spread.suspendPaint(); spread.suspendCalcService(); sheet = spread.getSheet(0); sheet.setRowCount(100); sheetData = spread.getSheet(1); sheetData.setRowCount(200); sheet.setColumnWidth(0, 200); sheet.addSpan(0, 0, 80, 5); sheet.getCell(0, 0).backgroundImage("$DEMOROOT$/spread/source/images/airplane.png"); sheet.options.isProtected = true; sheet.options.gridline = { showVerticalGridline: false, showHorizontalGridline: false }; sheet.setColumnResizable(-1, true, GC.Spread.Sheets.SheetArea.colHeader); sheet.setRowResizable(-1, true, GC.Spread.Sheets.SheetArea.rowHeader); addData(sheet); var airseat1 = "M 151.917 691.735 h -14.676 c -0.039 0 -3.689 -0.066 -3.689 -4.245 l 0.004 -17.254 c 0.096 -0.683 0.735 -1.976 2.47 -1.976 c 1.552 0 2.339 0.682 2.339 2.029 v 14.269 c 0.153 0.357 1.246 2.427 5.952 2.427 c 5.117 0 6.417 -2.265 6.522 -2.473 V 670.29 c 0.031 -0.713 0.52 -2.029 2.149 -2.029 c 1.149 0 1.909 0.606 2.257 1.802 c 0.009 0.029 0.015 0.051 0.021 0.067 l -0.015 0.005 c 0.103 0.431 0.113 2.671 0.052 17.723 c 0.005 0.042 0.126 1.774 -0.934 2.918 C 153.781 691.412 152.956 691.735 151.917 691.735 Z M 134.324 670.321 v 17.169 c 0 3.4 2.802 3.473 2.921 3.474 h 14.672 c 0.814 0 1.45 -0.24 1.888 -0.713 c 0.832 -0.9 0.73 -2.352 0.729 -2.366 c 0.026 -6.665 0.05 -16.629 0.007 -17.496 c -0.012 -0.034 -0.022 -0.071 -0.034 -0.112 c -0.17 -0.581 -0.496 -1.247 -1.518 -1.247 c -1.308 0 -1.377 1.224 -1.379 1.275 l 0 14.253 c 0 0.65 -1.903 3.197 -7.293 3.197 c -5.646 0 -6.663 -2.882 -6.704 -3.005 l -0.02 -0.058 V 670.29 c 0 -0.44 0 -1.258 -1.568 -1.258 C 134.629 669.031 134.363 670.107 134.324 670.321 Z M 135.261 669.105 c -0.002 -0.047 -0.046 -1.17 0.788 -2.047 c 0.627 -0.657 1.56 -0.99 2.773 -0.99 l 12.006 0.005 c 0.969 0.16 2.8 0.996 2.8 3.014 h -0.771 c 0 -1.779 -1.86 -2.197 -2.126 -2.248 h -11.91 c -0.995 0 -1.74 0.252 -2.215 0.751 c -0.6 0.629 -0.577 1.469 -0.577 1.477 L 135.261 669.105 Z"; //Get the seat shape var s1commands = convertPath(airseat1); //Rows loop //USE 30 for (var r = 0; r <= 185; r++) { sheetData.setValue(r, 1, Math.floor(Math.random() * Math.floor(3))); } for (i = 0; i < 31; i++) { for (j = 0; j < 6; j++) { seatNum = sheetDataSeatRow + "" + convertNumbertoLetter(j) //airline Seat var s1shape = createShape(s1commands, shapeleft, shapetop, shapewidth, shapeheight, seatNum); //Add Name var ret2 = sheet.shapes.add(seatNum, s1shape); ret2.allowMove(false); ret2.allowResize(false); ret2.dynamicMove(false); ret2.dynamicSize(false); ret2.isLocked(true); //Add the SeatNumber to first column sheetData.setValue(sheetDataRow, 0, seatNum); sheetDataRow = sheetDataRow + 1; if (j == 5) { sheetDataSeatRow = sheetDataSeatRow + 1; } //increment shapeleft = shapeleft + shapewidth; if (j == 2) { // D,E,F seats. Add aisle spacer shapeleft = shapeleft + aislespacer; } } //reset left and top to start new rows shapeleft = constleft; shapetop = shapetop + rowspacer; if (i == 12) { shapetop = shapetop + 10; } if (i == 13) { shapetop = shapetop + 10; } if (i == 22) { shapetop = shapetop - 3; } } spread.resumeCalcService(); spread.resumePaint(); //handle spread div click event for shapes document.getElementById("ss").addEventListener("click", function (e) { var sp = document.getElementById("ss"); var x = e.pageX - sp.offsetLeft; var y = e.pageY - sp.offsetTop; var target = spread.getActiveSheet().hitTest(x, y); if (target.shapeHitInfo == null && x > 700) { y = y - 300; target = spread.getActiveSheet().hitTest(x, y); } var preselectionseatval = ""; if (target.shapeHitInfo) { var shape = target.shapeHitInfo.shape; // var preselectionseatval = if (shape) { spread.suspendPaint(); if (selectedSeat == "") { var searchCondition = new GC.Spread.Sheets.Search.SearchCondition(); searchCondition.searchString = shape.name(); searchCondition.startSheetIndex = 1; searchCondition.endSheetIndex = 1; searchCondition.searchOrder = GC.Spread.Sheets.Search.SearchOrder.nOrder; searchCondition.searchTarget = GC.Spread.Sheets.Search.SearchFoundFlags.cellText; searchCondition.searchFlags = GC.Spread.Sheets.Search.SearchFlags.ignoreCase | GC.Spread.Sheets.Search.SearchFlags.useWildCards; var searchresult = spread.search(searchCondition); var val = sheetData.getValue(searchresult.foundRowIndex, searchresult.foundColumnIndex + 1); if (val == 0) { sheetData.setValue(searchresult.foundRowIndex, searchresult.foundColumnIndex + 1, 1, GC.Spread.Sheets.SheetArea.viewport, false); selectedSeat = shape.name(); sheet.setValue(11, 8, selectedSeat); preselectionseatval = val; } else if (val == 2) { if (confirm("これはプレミアムシートです。アップグレードしてもよろしいですか?")) { sheetData.setValue(searchresult.foundRowIndex, searchresult.foundColumnIndex + 1, 1, GC.Spread.Sheets.SheetArea.viewport, false); selectedSeat = shape.name(); sheet.setValue(11, 8, selectedSeat); preselectionseatval = val; } } else { alert("この席はすでに予約されています"); } } else { sheetData.suspendPaint(); var searchCondition = new GC.Spread.Sheets.Search.SearchCondition(); searchCondition.searchString = selectedSeat; searchCondition.startSheetIndex = 1; searchCondition.endSheetIndex = 1; searchCondition.searchOrder = GC.Spread.Sheets.Search.SearchOrder.nOrder; searchCondition.searchTarget = GC.Spread.Sheets.Search.SearchFoundFlags.cellText; searchCondition.searchFlags = GC.Spread.Sheets.Search.SearchFlags.ignoreCase | GC.Spread.Sheets.Search.SearchFlags.useWildCards; var searchresult = spread.search(searchCondition); var selectedseatval = sheetData.getValue(searchresult.foundRowIndex, searchresult.foundColumnIndex + 1); var searchCondition1 = new GC.Spread.Sheets.Search.SearchCondition(); searchCondition1.searchString = shape.name(); searchCondition1.startSheetIndex = 1; searchCondition1.endSheetIndex = 1; searchCondition1.searchOrder = GC.Spread.Sheets.Search.SearchOrder.nOrder; searchCondition1.searchTarget = GC.Spread.Sheets.Search.SearchFoundFlags.cellText; searchCondition1.searchFlags = GC.Spread.Sheets.Search.SearchFlags.ignoreCase | GC.Spread.Sheets.Search.SearchFlags.useWildCards; var searchresult1 = spread.search(searchCondition1); var val = sheetData.getValue(searchresult1.foundRowIndex, searchresult1.foundColumnIndex + 1); if (val == 1) { alert("この席はすでに予約されています"); } else if (val == 0) { sheetData.setValue(searchresult1.foundRowIndex, searchresult1.foundColumnIndex + 1, 1, GC.Spread.Sheets.SheetArea.viewport, false); sheetData.setValue(searchresult.foundRowIndex, searchresult.foundColumnIndex + 1, 0, GC.Spread.Sheets.SheetArea.viewport, false); selectedSeat = shape.name(); sheet.setValue(11, 8, selectedSeat); } else if (val == 2) { if (confirm("これはプレミアムシートです。アップグレードしてもよろしいですか?")) { sheetData.setValue(searchresult1.foundRowIndex, searchresult1.foundColumnIndex + 1, 1, GC.Spread.Sheets.SheetArea.viewport, false); sheetData.setValue(searchresult.foundRowIndex, searchresult.foundColumnIndex + 1, 0, GC.Spread.Sheets.SheetArea.viewport, false); selectedSeat = shape.name(); sheet.setValue(11, 8, selectedSeat); } } sheetData.resumePaint(); } spread.resumePaint(); } } }, false); }
<!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"> <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-shapes/dist/gc.spread.sheets.shapes.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/js/license.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/data/svgpath.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 class="sample-tutorial"> <div id="ss" style="width:100%;height:100%"></div> </div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }