
<!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.
-->


<meta charset="utf-8">
<style>

text {
    font: 10px sans-serif;
    text-anchor: middle;
}

.node--hover circle {
    stroke: #000;
    stroke-width: 1.2px;
}

#main {
    width: 1000px;
    height: 500px;
}
</style>


<div id="main" style="width:1200px; height:960px;"></div>

<svg width="960" height="960"><g transform="translate(1,1)"></g></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="../dist/echarts.js"></script>
<script src="./lib/testHelper.js"></script>
<script src="./lib/config.js"></script>
<script>

var stratify = d3.stratify()
    .parentId(function(d) {
        return d.id.substring(0, d.id.lastIndexOf("."));
    });

d3.csv("data/flare.csv", function(error, rawData) {
    if (error) throw error;

    var root = stratify(rawData)
        .sum(function(d) {
            return d.value;
        })
        .sort(function(a, b) {
            return b.value - a.value;
        });
    var maxDepth = 0;
    var seriesData = root.descendants().map(function (node) {
        maxDepth = Math.max(maxDepth, node.depth);
        return [
            node.value,
            node.depth,
            node.id
        ];
    });

    var chart = echarts.init(document.getElementById('main'));

    function renderItem(params, api) {
        var context = params.context;
        if (!context.nodes) {
            d3.pack()
                .size([api.getWidth() - 2, api.getHeight() - 2])
                .padding(3)(root);

            context.nodes = {};
            root.descendants().forEach(function (node, index) {
                context.nodes[node.id] = {
                    index: index,
                    node: node
                }
            });
        }

        var nodePath = api.value(2);
        var node = context.nodes[nodePath].node;
        var isLeaf = !node.children || !node.children.length;

        var textFont = api.font({
            fontSize: 12,
            fontFamily: 'Arial'
        });

        var focus = new Uint32Array(node.descendants().map(function (node) {
            return context.nodes[node.id].index;
        }));

        var nodeName = isLeaf ? nodePath.slice(nodePath.lastIndexOf('.') + 1).split(/(?=[A-Z][^A-Z])/g).join('\n') : '';

        var z2 = api.value(1) * 2;

        return {
            type: 'circle',
            focus: focus,
            shape: {
                cx: node.x,
                cy: node.y,
                r: node.r
            },
            z2: z2,
            textContent: {
                type: 'text',
                style: {
                    text: nodeName,
                    width: node.r * 1.3,
                    overflow: 'truncate',
                    fontSize: node.r / 3
                    // fill: 'blue'
                },
                emphasis: {
                    style: {
                        overflow: null,
                        fontSize: Math.max(node.r / 3, 12)
                        // fill: 'red'
                    }
                }
            },
            textConfig: {
                position: 'inside'
            },
            style: {
                fill: api.visual('color'),
                text: nodeName,
                font: textFont,
            },
            emphasis: {
                style: {
                    font: textFont,
                    shadowBlur: 20,
                    shadowOffsetX: 3,
                    shadowOffsetY: 5,
                    shadowColor: 'rgba(0,0,0,0.3)'
                }
            }
        };
    }

    var option = {
        tooltip: {},
        visualMap: {
            show: false,
            min: 0,
            max: maxDepth,
            dimension: 1,
            inRange: {
                color: ['#006edd', '#e0ffff']
            }
        },
        series: {
            type: 'custom',
            renderItem: renderItem,
            coordinateSystem: null,
            encode: {
                tooltip: 0,
                itemName: 2
            },
            data: seriesData
        }
    };

    chart.setOption(option);

});

</script>
