
<!--
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">
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script src="lib/esl.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/dat.gui.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
            }
        </style>
        <div id="info"></div>
        <div id="main"></div>
        <script>

            var chart;
            var data;

            require([
                'echarts'
            ], function (echarts) {
                chart = echarts.init(document.getElementById('main'));

                function update(layout) {

                    // Generate data.
                    sourceData = [];
                    for (var seriesIndex = 0; seriesIndex < 3; seriesIndex++) {
                        var seriesData = [];
                        for (var i = 0; i < 18; i++) {
                            var cate = [];
                            for (var j = 0; j < 100; j++) {
                                cate.push(Math.random() * 200);
                            }
                            seriesData.push(cate);
                        }
                        sourceData.push(seriesData);
                    }

                    var categoryAxis = {
                        type: 'category',
                        boundaryGap: true,
                        nameGap: 30,
                        splitArea: {
                            show: true
                        },
                        splitLine: {
                            show: false
                        }
                    };
                    var valueAxis = {
                        type: 'value',
                        name: 'Value',
                        splitArea: {
                            show: false
                        }
                    };

                    chart.setOption({
                        title: [{
                            text: 'Multiple Categories',
                            left: 'center',
                        }],
                        dataset: [{
                            source: sourceData[0]
                        }, {
                            source: sourceData[1]
                        }, {
                            source: sourceData[2]
                        }, {
                            fromDatasetIndex: 0,
                            transform: {
                                type: 'boxplot',
                                config: {
                                    itemNameFormatter: function (params) {
                                        return 'expr ' + params.value;
                                    }
                                }
                            }
                        }, {
                            fromDatasetIndex: 1,
                            transform: {
                                type: 'boxplot',
                                config: {
                                    itemNameFormatter: function (params) {
                                        return 'expr ' + params.value;
                                    }
                                }
                            }
                        }, {
                            fromDatasetIndex: 2,
                            transform: {
                                type: 'boxplot',
                                config: {
                                    itemNameFormatter: function (params) {
                                        return 'expr ' + params.value;
                                    }
                                }
                            }
                        }],
                        legend: {
                            top: '10%'
                        },
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'shadow'
                            }
                        },
                        grid: {
                            left: '10%',
                            top: '20%',
                            right: '10%',
                            bottom: '15%'
                        },
                        xAxis: layout === 'horizontal' ? categoryAxis : valueAxis,
                        yAxis: layout === 'vertical' ? categoryAxis : valueAxis,
                        dataZoom: [
                            {
                                type: 'inside',
                                start: 0,
                                end: 20
                            },
                            {
                                show: true,
                                height: 20,
                                type: 'slider',
                                bottom: 50,
                                xAxisIndex: layout === 'horizontal' ? [0] : [],
                                yAxisIndex: layout === 'horizontal' ? [] : [0],
                                start: 0,
                                end: 20
                            }
                        ],
                        series: [
                            {
                                name: 'category0',
                                type: 'boxplot',
                                itemStyle: {
                                    color: '#a32',
                                    borderColor: '#429',
                                    borderWidth: 3
                                },
                                datasetIndex: 3
                            },
                            {
                                name: 'category1',
                                type: 'boxplot',
                                datasetIndex: 4
                            },
                            {
                                name: 'category2',
                                type: 'boxplot',
                                datasetIndex: 5
                            }
                        ]
                    });
                }

                // var gui = new dat.GUI();
                // var config = {
                //     layout: 'horizontal'
                // };
                // gui
                //     .add(config, 'layout', ['horizontal', 'vertical'])
                //     .onChange(update);

                update('horizontal');
            })

        </script>
    </body>
</html>