
<!--
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',
                'extension/dataTool',
                './data/les-miserables.gexf',
                'theme/vintage'
            ], function (echarts, dataTool, xml) {
                var gexf = dataTool.gexf;
                var chart = echarts.init(document.getElementById('main'), 'vintage');

                var graph = gexf.parse(xml);
                var categories = [];
                for (var i = 0; i < 9; i++) {
                    categories[i] = {
                        name: '类目' + i
                    };
                }
                graph.nodes.forEach(function (node) {
                    delete node.itemStyle;
                    node.value = node.symbolSize;
                    node.label = {
                        normal: {
                            show: node.symbolSize > 30
                        },
                        emphasis: {
                            show: true
                        }
                    };
                    node.category = node.attributes['modularity_class'];
                });
                graph.links.forEach(function (link) {
                    delete link.lineStyle;
                });
                var option = {
                    aria: {
                        show: true,
                        description: 'Les Miserables 的关系主要分为六个区域，这张图描述了他们之间的相互关联。'
                    },
                    tooltip: {},
                    legend: [{
                        // selectedMode: 'single',
                        data: categories.map(function (a) {
                            return a.name;
                        })
                    }],
                    animationDurationUpdate: 1500,
                    animationEasingUpdate: 'quinticInOut',
                    series : [
                        {
                            name: 'Les Miserables',
                            type: 'graph',
                            layout: 'none',
                            data: graph.nodes,
                            links: graph.links,
                            categories: categories,
                            cursor: 'crosshair',
                            roam: true,
                            draggable: true,
                            itemStyle: {
                                normal: {
                                    borderColor: '#fff',
                                    borderWidth: 2,
                                    shadowBlur: 10,
                                    shadowColor: 'rgba(0, 0, 0, 0.3)'
                                }
                            },
                            emphasis: {
                                focus: 'adjacency'
                            },
                            // edgeSymbol: ['none', 'arrow'],
                            // scaleLimit: {
                            //     min: 1.5,
                            //     max: 2
                            // },
                            label: {
                                normal: {
                                    position: 'right',
                                    formatter: '{b}'
                                }
                            },
                            lineStyle: {
                                normal: {
                                    color: 'source',
                                    curveness: 0.3
                                },
                                emphasis: {
                                    width: 10
                                }
                            }
                        }
                    ]
                };

                chart.setOption(option);

                var config = {
                    layout: 'none',
                    focusNodeAdjacency: true,
                    manualFocusNodeAdjacency: function () {
                        chart.dispatchAction({
                            type: 'highlight',
                            seriesName: 'Les Miserables',
                            dataIndex: 2
                        });
                    },
                    manualUnfocusNodeAdjacency: function () {
                        chart.dispatchAction({
                            type: 'downplay',
                            seriesName: 'Les Miserables'
                        });
                    },
                    'circular.rotateLabel': false
                };

                chart.on('click', function (params) {
                    console.log(params, params.data);
                });

                var gui = new dat.GUI();
                gui.add(config, 'layout', ['none', 'circular'])
                    .onChange(function (value) {
                        chart.setOption({
                            series: [{
                                name: 'Les Miserables',
                                layout: value
                            }]
                        });
                    });
                gui.add(config, 'focusNodeAdjacency')
                    .onChange(function (value) {
                        chart.setOption({
                            series: [{
                                name: 'Les Miserables',
                                emphasis: {
                                    focus: config.focusNodeAdjacency ? 'adjacency' : null
                                }
                            }]
                        });
                    });
                gui.add(config, 'manualFocusNodeAdjacency');
                gui.add(config, 'manualUnfocusNodeAdjacency');
                gui.add(config, 'circular.rotateLabel')
                    .onChange(function (value) {
                        chart.setOption({
                            series: [{
                                name: 'Les Miserables',
                                circular: {rotateLabel: !!value}
                            }]
                        });
                    });
            });
        </script>
    </body>
</html>