
<!--
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 {
                width: 100%;
                height: 100%;
                margin: 0;
            }
            .chart {
                width: 50%;
                float: left;
                height: 100%;
            }
        </style>
        <div id="main0" class="chart"></div>
        <div id="main1" class="chart"></div>
        <script>

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

                [0.1, 0.9].forEach(function (friction, index) {
                    var chart = echarts.init(document.getElementById('main' + index));

                    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;
                    }

                    chart.setOption({
                        series: {
                            type: 'graph',
                            layout: 'force',
                            animation: false,
                            data: createNodes(22),
                            width: '50%',
                            height: '50%',
                            force: {
                                layoutAnimation: false,
                                repulsion: 100,
                                edgeLength: 5,
                                friction
                            },
                            edges: createEdges(22).map(function (e) {
                                return {
                                    source: e[0],
                                    target: e[1]
                                };
                            })
                        }
                    });
                });
            });
        </script>
    </body>
</html>