
<!--
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/esl.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
    </head>
    <body>
        <style>
            html, body, #main {
                width: 100%;
                height: 100%;
                margin: 0;
            }
        </style>
        <div id="main"></div>
        <script>

            require([
                'echarts'
                // 'echarts/chart/scatter',
                // 'echarts/component/title',
                // 'echarts/component/grid',
                // 'echarts/component/tooltip'
            ], function (echarts) {

                var chart = echarts.init(document.getElementById('main'));
                $.get('data/masterPainterColorChoice.json', function (json) {

                    var data = json[0].x.map(function (x, idx) {
                        return [+x, +json[0].y[idx]];
                    });

                    chart.setOption({
                        title: {
                            text: 'Master Painter Color Choices Throughout History',
                            subtext: 'Data From Plot.ly',
                            x: 'right'
                        },
                        tooltip: {
                            trigger: 'axis',
                            axisPointer: {
                                type: 'cross'
                            }
                        },
                        xAxis: {
                            type: 'value',
                            splitLine: {
                                show: false
                            },
                            scale: true,
                            splitNumber: 5,
                            axisLabel: {
                                formatter: function (val) {
                                    return val + 's';
                                }
                            }
                        },
                        yAxis: {
                            type: 'value',
                            min: 0,
                            max: 360,
                            splitNumber: 6,
                            name: 'Hue',
                            splitLine: {
                                show: false
                            }
                        },
                        series: [{
                            name: 'scatter',
                            type: 'scatter',
                            symbolSize: function (val, param) {
                                return json[0].marker.size[param.dataIndex] / json[0].marker.sizeref;
                            },
                            itemStyle: {
                                normal: {
                                    color: function (param) {
                                        return json[0].marker.color[param.dataIndex];
                                    }
                                }
                            },
                            data: data
                        }]
                    });
                });
            });

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