<!DOCTYPE html>
<!--
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/simpleRequire.js"></script>
        <script src="lib/config.js"></script>
        <script src="lib/jquery.min.js"></script>
        <script src="lib/facePrint.js"></script>
        <script src="lib/testHelper.js"></script>
        <!-- <script src="ut/lib/canteen.js"></script> -->
        <link rel="stylesheet" href="lib/reset.css" />
    </head>
    <body>
        <style>
        </style>



        <div id="main_regression"></div>




        <script>

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

            echarts.registerTransform(ecStat.transform.regression);

            var rawData = [
                [1, 4862.4],
                [2, 5294.7],
                [3, 5934.5],
                [4, 7171.0],
                [5, 8964.4],
                [6, 10202.2],
                [7, 11962.5],
                [8, 14928.3],
                [9, 16909.2],
                [10, 18547.9],
                [11, 21617.8],
                [12, 26638.1],
                [13, 34634.4],
                [14, 46759.4],
                [15, 58478.1],
                [16, 67884.6],
                [17, 74462.6],
                [18, 79395.7]
            ];

            var option = {
                dataset: [{
                    source: rawData
                }, {
                    transform: {
                        type: 'ecStat:regression',
                        config: {
                            method: 'exponential'
                        }
                    }
                }, {
                    fromDatasetIndex: 1,
                    fromTransformResult: 1
                }],
                legend: {
                    bottom: 20
                },
                tooltip: {
                },
                xAxis: {
                    type: 'category',
                },
                yAxis: {
                },
                series: [{
                    name: 'scatter',
                    type: 'scatter',
                    datasetIndex: 0
                }, {
                    name: 'regression',
                    type: 'line',
                    symbolSize: 0.1,
                    symbol: 'circle',
                    datasetIndex: 1,
                    label: { show: true, fontSize: 16 },
                    labelLayout: { dx: -20 },
                    encode: { label: 2, tooltip: 1 }
                }]
            };

            var chart = testHelper.create(echarts, 'main_regression', {
                title: [
                    'Regression: the **expression string** should be displayed',
                ],
                option: option
            });


        });

        </script>


    </body>
</html>

