Spread.Sheets
カスタムスライサーの作成
Spread.Sheets > 開発者の手引き > ユーザーインタフェースの管理 > スライサーの使用 > カスタムスライサーの作成

カスタムスライサーを作成するには、GeneralSlicerDataクラスまたは TableSlicerDataクラスを使用します。

GeneralSlicerDataクラスは、2次元配列のデータを処理するために使用します。このクラスは、データをフィルタリングし、フィルタ結果を取得するための各種のプロパティおよびメソッドを備えています。1つのカスタムスライサーには、複数のスライサーを連結できます。個々のスライサーは、1つの列のデータをフィルタリングします。1つのスライサーのフィルタリングが完了すると、他のスライサーはGeneralSlicerDataクラスによって通知されます。この後、各スライサーはGeneralSlicerDataからフィルタ結果を取得し、それぞれのUIを更新します。

スライサーは以下の手順に基づき、 GeneralSlicerDataクラスと連携して動作します。

  1. データを指定し、新規のGeneralSlicerDataを作成します。
  2. カスタムスライサーを新規作成し、GeneralSlicerDataに接続します。.
  3. GeneralSlicerDataから列データを取得し、スライサーのUIを作成します。
  4. UIイベントに応答し、GeneralSlicerDataの doFilterメソッドを呼び出します。
  5. GeneralSlicerDataからフィルタ結果を取得し、スライサーのUIを更新します。

特定の列の全データを取得するには、 getDataメソッドを使用します。排他データ(重複しないデータ)を取得するには、 getExclusiveDataメソッドを使用します。列をフィルタリングするにはdoFilterメソッドを使用し、フィルタリング情報を消去するにはdoUnfilterメソッドを使用します。全メソッドの一覧については、GeneralSlicerDataクラスを参照してください。

リスナーをGeneralSlicerDataに接続するにはattachListener関数を使用し、リスナーを接続解除するにはdetachListener関数を使用します。

次の図は、カスタムスライサーを示します。

コードの使用

次のサンプルコードは、カスタムスライサーを作成します。

JavaScript
コードのコピー

<!DOCTYPE html>
<html>
<head>
    <title>Spread.Sheets Sample</title>
    <link href="./css/gc.spread.sheets.excel2013white.xx.x.x.css" rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-2.0.2.js" type="text/javascript"></script>
    <script src="./scripts/gc.spread.sheets.all.xx.x.x.min.js"></script>

    <script type="text/javascript">
        // データソースを定義します。
        columnNames = ["Name", "City", "Birthday"];
        data = [
            ["Bob", "NewYork", "1968/6/8"],
            ["Betty", "Washington", "1972/7/3"],
            ["Alice", "NewYork", "1964/3/2"]];

        // カスタムスライサーを定義します。
        function MySlicer(container) {
            this.container = container;
            this.slicerData = null;
            this.columnName = null;
        }
        MySlicer.prototype.setData = function (slicerData, columnName) {
            this.slicerData = slicerData;
            this.columnName = columnName;
            this.slicerData.attachListener(this);
            this.onDataLoaded();
        }
        MySlicer.prototype.onDataLoaded = function () {
            // スライサーのDOMツリーを作成します。
            var columnName = this.columnName,
            exclusiveData = this.slicerData.getExclusiveData(columnName);
            $(this.container).append($('<span>' + this.columnName + ':</span>' + '<br />'));
            var domString = "";
            for (var i = 0; i < exclusiveData.length; i++) {
                domString += '<input type="checkbox" name="' + columnName + '" value="' + exclusiveData[i] + '">';
                domString += '<span>' + exclusiveData[i] + '</span>';
                domString += '<br />';
            }
            $(this.container).append($(domString));
            // イベントをDOMに接続します。
            var self = this;
            $("[name='" + self.columnName + "']").change(function () {
                var slicer = self,
                exclusiveData = slicer.slicerData.getExclusiveData(slicer.columnName),
                parent = $(this).parent(),
                items = parent.children(),
                indexes = [];
                for (var i = 0, length = items.length; i < length; i++) {
                    if (items[i].checked) {
                        var value = items[i].value;
                        if (!isNaN(parseInt(value))) {
                            value = parseInt(value);
                        }
                        indexes.push(exclusiveData.indexOf(value))
                    }
                }
                if (indexes.length === 0) {
                    slicer.slicerData.doUnfilter(slicer.columnName);
                } else {
                    slicer.slicerData.doFilter(slicer.columnName, { exclusiveRowIndexes: indexes });
                }
            });
        };
        MySlicer.prototype.onFiltered = function () {
            // 以下は、フィルタ結果を表示する例です。
            var slicerdata = this.slicerData;
            var filteredRowIndexs = slicerdata.getFilteredRowIndexes();
            var trs = $listTable.find("tr");
            for (var i = 0; i < slicerdata.data.length; i++) {
                if (filteredRowIndexs.indexOf(i) !== -1) {
                    $(trs[i + 1]).show();
                } else {
                    $(trs[i + 1]).hide();
                }
            }
        }

        // フィルタ結果の表示メソッドを定義します。
        function initFilteredResultList() {
            var tableStr = "<table border='1' cellpadding='0' cellspacing='0'><tr>";
            for (var i = 0; i < columnNames.length; i++) {
                tableStr += "<th>" + columnNames[i] + "</th>";
            }
            tableStr += "</tr>";
            for (var i = 0; i < data.length; i++) {
                tableStr += "<tr>";
                for (var j = 0; j < data[i].length; j++) {
                    tableStr += "<td>" + data[i][j] + "</td>";
                }
                tableStr += "</tr>";
            }
            tableStr += "</table>";
            $listTable = $(tableStr);
            $("#list").append($listTable);
        }

        $(document).ready(function () {
            // フィルタ結果リストを初期化します。
            initFilteredResultList();
            // カスタムスライサーを作成し、このスライサーを"slicerContainer" divに追加します。
            var slicer = new MySlicer($("#slicerContainer")[0]);
            var slicerData = new GC.Spread.Slicers.GeneralSlicerData(data, columnNames);
            slicer.setData(slicerData, "Name");
        });
    </script>

</head>
<body>
    <div id="slicerContainer" style="border:1px solid gray;width:190px"></div>
    <hr/>
    <div id="list" style="width:300px;float:left"></div>
</body>
</html>

次のサンプルコードは、カスタムスライサーを作成し、TableSlicerDataクラスを使用してデータを設定します。

JavaScript
コードのコピー

<!DOCTYPE html>
<html>
<head>
    <title>Spread.Sheets Development Sample</title>
<link href="./css/gc.spread.sheets.excel2013white.xx.x.x.css" rel="stylesheet" type="text/css" />
     <script src="http://code.jquery.com/jquery-2.0.2.js" type="text/javascript"></script>
      <script src="./scripts/gc.spread.sheets.all.xx.x.x.min.js"></script>
      <script type="text/javascript">
        // データソースを定義します。
        data = [
            { "Name": "Bob", "City": "NewYork", "Birthday": "1968/6/8" },
            { "Name": "Bob", "City": "NewYork", "Birthday": "1968/6/8" },
            { "Name": "Bob", "City": "NewYork", "Birthday": "1968/6/8" },
            { "Name": "Bob", "City": "NewYork", "Birthday": "1968/6/8" },
            { "Name": "Betty", "City": "Washington", "Birthday": "1972/7/3" },
            { "Name": "Betty", "City": "Washington", "Birthday": "1972/7/3" },
            { "Name": "Betty", "City": "Washington", "Birthday": "1972/7/3" },
            { "Name": "Alice", "City": "NewYork", "Birthday": "1964/3/2" },
            { "Name": "Alice", "City": "NewYork", "Birthday": "1964/3/2" },
            { "Name": "Alice", "City": "NewYork", "Birthday": "1964/3/2" }];

        // カスタムスライサーを定義します。
        function MySlicer(container) {
            this.container = container;
            this.slicerData = null;
            this.columnName = null;
        }
        MySlicer.prototype.setData = function (slicerData, columnName) {
            this.slicerData = slicerData;
            this.columnName = columnName;
            this.slicerData.attachListener(this);
            this.onDataLoaded();
        }
        MySlicer.prototype.onDataLoaded = function () {
            // スライサーのDOMツリーを作成します。
            var columnName = this.columnName,
            exclusiveData = this.slicerData.getExclusiveData(columnName);
            $(this.container).append($('<span>' + this.columnName + ':</span>' + '<br />'));
            var domString = "";
            for (var i = 0; i < exclusiveData.length; i++) {
                domString += '<input type="checkbox" name="' + columnName + '" value="' + exclusiveData[i] + '">';
                domString += '<span>' + exclusiveData[i] + '</span>';
                domString += '<br />';
            }
            $(this.container).append($(domString));
            // イベントをDOMに接続します。
            var self = this;
            $("[name='" + self.columnName + "']").change(function () {
                var slicer = self,
                exclusiveData = slicer.slicerData.getExclusiveData(slicer.columnName),
                parent = $(this).parent(),
                items = parent.children(),
                indexes = [];
                for (var i = 0, length = items.length; i < length; i++) {
                    if (items[i].checked) {
                        var value = items[i].value;
                        if (!isNaN(parseInt(value))) {
                            value = parseInt(value);
                        }
                        indexes.push(exclusiveData.indexOf(value))
                    }
                }
                if (indexes.length === 0) {
                    slicer.slicerData.doUnfilter(slicer.columnName);
                } else {
                    slicer.slicerData.doFilter(slicer.columnName, { exclusiveRowIndexes: indexes });
                }
            });
        };
        MySlicer.prototype.onFiltered = function () {
            // Spread.Sheetsテーブルによってデータがフィルタリングされた場合には、状態を同期します。
            var slicerdata = this.slicerData;
            var exclusiveIndexes = slicerdata.getFilteredIndexes(this.columnName);
            $.each($("#slicerContainer").children("input"), function (i,input) {

            });
        }

        $(document).ready(function () {
           var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"),{sheetCount:1});
            var sheet = spread.getActiveSheet();

            // カスタムスライサーを作成し、このスライサーを"slicerContainer" divに追加します。
            var slicer = new MySlicer($("#slicerContainer")[0]);
            var table = sheet.tables.addFromDataSource("table1", 1, 1, data);
            var slicerData = table.getSlicerData();
            slicer.setData(slicerData, "Name");

        });
    </script>

</head>
<body>
    <div id="slicerContainer" style="border:1px solid gray;width:190px"></div>
    <hr />
    <div id="ss" style="width:500px;height:500px;border:1px solid gray"></div>
</body>
</html>