
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<html>
    <head>
        <meta charset="utf-8">
        <script src="lib/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/dat.gui.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                'echarts'
            ], function (echarts) {

                var chart = echarts.init(document.getElementById('main'));

                function createNodes(count) {
                    var nodes = [];
                    for (var i = 0; i < count; i++) {
                        nodes.push({
                            id: i
                        });
                    }
                    return nodes;
                }

                function createEdges(count) {
                    var edges = [];
                    if (count === 2) {
                        return [[0, 1]];
                    }
                    for (var i = 0; i < count; i++) {
                        edges.push([i, (i + 1) % count]);
                    }
                    return edges;
                }

                var datas = [];
                for (var i = 0; i < 16; i++) {
                    datas.push({
                        nodes: createNodes(i + 2),
                        edges: createEdges(i + 2)
                    });
                }

                chart.setOption({
                    series: datas.map(function (item, idx) {
                        return {
                            type: 'graph',
                            layout: 'force',
                            animation: false,
                            data: item.nodes,
                            left: (idx % 4) * 25 + '%',
                            top: Math.floor(idx / 4) * 25 + '%',
                            width: '25%',
                            height: '25%',
                            force: {
                                // initLayout: 'circular',
                                // gravity: 0
                                repulsion: 100,
                                edgeLength: 5
                            },
                            edges: item.edges.map(function (e) {
                                return {
                                    source: e[0],
                                    target: e[1]
                                };
                            })
                        };
                    })
                });
            });
        </script>
    </body>
</html>