from traitlets import (
    Unicode, Dict, Float, Bool, Union, Any,
)
from ..basewidget import BaseWidget


class Map(BaseWidget):
    """ 
:warning: **Autogenerated class**

**Map.**


Map is mainly used in the visualization of geographic area data, which can be used with [visualMap](#visualMap) component to visualize the data such as population distribution density in different areas.


Series of same [map type](#series-map.map) will show in one map. At this point, the configuration of the first series will be used for the map configuration.



    """

    def __init__(self, **kwargs):

        super().__init__(**kwargs)  
    
    _model_name = Unicode("MapModel").tag(sync=True)
    
    type = Unicode("map", allow_none=True, ).tag(sync=True)
    
    id = Unicode(None, allow_none=True, help="""Component ID, not specified by default. If specified, it can be used to refer the component in option or API.""").tag(sync=True)
    
    name = Unicode(None, allow_none=True, help="""Series name used for displaying in [tooltip](#tooltip) and filtering with [legend](#legend), or updating data and configuration with `setOption`.""").tag(sync=True)
    
    colorBy = Unicode(None, allow_none=True, help="""> Since `v5.2.0`


The policy to take color from [option.color](#color). Valid values:


* `'series'`: assigns the colors in the palette by series, so that all data in the same series are in the same color;
* `'data'`: assigns colors in the palette according to data items, with each data item using a different color.""").tag(sync=True)
    
    map = Unicode(None, allow_none=True, help="""Map name registered in [registerMap](api.html#echarts.registerMap).


**Use geoJSON**



```
$.get('map/china_geo.json', function (geoJson) {
    echarts.registerMap('china', {geoJSON: geoJson});
    var chart = echarts.init(document.getElementById('main'));
    chart.setOption({
        series: [{
            type: 'map',
            map: 'china',
            ...
        }]
    });
});

```

See also [USA Population Estimates](https://echarts.apache.org/examples/en/editor.html?c=map-usa).


The demo above shows that ECharts can uses [geoJSON](http://geojson.org/) format as map outline. You can use third-party [geoJSON](http://geojson.org/) data (like [maps](https://github.com/echarts-maps)) and register them into ECharts.


**Use SVG**



```
$.get('map/topographic_map.svg', function (svg) {
    echarts.registerMap('topo', {svg: svg});
    var chart = echarts.init(document.getElementById('main'));
    chart.setOption({
        series: [{
            type: 'map',
            map: 'topo',
            ...
        }]
    });
});

```

See also [Beef Cuts](https://echarts.apache.org/examples/en/editor.html?c=geo-beef-cuts).


The demo above shows that SVG format can be used in ECharts. See more info in [SVG Base Map](tutorial.html#SVG%20Base%20Map%20in%20Geo%20Coords%20and%20Map%20Series).""").tag(sync=True)
    
    roam = Union([Bool(default_value=None, allow_none=True),Unicode(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Whether to enable mouse zooming and translating. `false` by default. If either zooming or translating is wanted, it can be set to `'scale'` or `'move'`. Otherwise, set it to be `true` to enable both.""").tag(sync=True)
    
    projection = Dict(default_value=None, allow_none=True, help="""> Since `v5.3.0`


For custom map projection, at least two methods `project`, `unproject` should be provided to calculate the coordinates after projection and before projection respectively.


For example, for the Mercator projection.



```
series: {
    type: 'map',
    projection: {
        project: (point) => [point[0] / 180 * Math.PI, -Math.log(Math.tan((Math.PI / 2 + point[1] / 180 * Math.PI) / 2))],
        unproject: (point) => [point[0] * 180 / Math.PI, 2 * 180 / Math.PI * Math.atan(Math.exp(point[1])) - 90]
    }
}

```

In addition to our own implementation of the projection formula, we can also use exists projection implementations provided by third-party libraries such as [d3-geo](https://github.com/d3/d3-geo).



```
const projection = d3.geoConicEqualArea();
// ...
series: {
    type: 'map',
    projection: {
        project: (point) => projection(point),
        unproject: (point) => projection.invert(point)
    }
}


```

Note: Custom projections are only useful when using `GeoJSON` as a data source.""").tag(sync=True)
    
    center = Any(None, allow_none=True, help="""Center of current view-port. It can be an array containing two `number`s in pixels or `string`s in percentage relative to the container width/height.
`string` is supported from version `5.3.3`.


Example:



```
center: [115.97, '30%']

```""").tag(sync=True)
    
    aspectScale = Float(None, allow_none=True, help="""Used to scale aspect of geo. Will be ignored if `projection` is set.


The final aspect is calculated by: `geoBoundingRect.width / geoBoundingRect.height * aspectScale`.""").tag(sync=True)
    
    boundingCoords = Any(None, allow_none=True, help="""Two dimension array. Define coord of left-top, right-bottom in layout box.



```
// A complete world map
map: 'world',
left: 0, top: 0, right: 0, bottom: 0,
boundingCoords: [
    // [lng, lat] of left-top corner
    [-180, 90],
    // [lng, lat] of right-bottom corner
    [180, -90]
],

```""").tag(sync=True)
    
    zoom = Float(None, allow_none=True, help="""Zoom rate of current view-port.""").tag(sync=True)
    
    scaleLimit = Dict(default_value=None, allow_none=True, help="""Limit of scaling, with `min` and `max`. `1` by default.""").tag(sync=True)
    
    nameMap = Dict(default_value=None, allow_none=True, help="""Name mapping for customized areas. For example:



```
{
    'China' : '中国'
}

```""").tag(sync=True)
    
    nameProperty = Unicode(None, allow_none=True, help="""> Since `v4.8.0`


customized property key for GeoJSON feature. By default, 'name' is used as primary key to identify GeoJSON feature.
For example:



```
{
    nameProperty: 'NAME', // key to connect following data point to GeoJSON region {"type":"Feature","id":"01","properties":{"NAME":"Alabama"}, "geometry": { ... }}
    data:[
        {name: 'Alabama', value: 4822023},
        {name: 'Alaska', value: 731449},
    ]
}

```""").tag(sync=True)
    
    selectedMode = Union([Bool(default_value=None, allow_none=True),Unicode(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Selected mode decides whether multiple selecting is supported. By default, `false` is used for disabling selection. Its value can also be `'single'` for selecting single area, or `'multiple'` for selecting multiple areas.""").tag(sync=True)
    
    label = Dict(default_value=None, allow_none=True, help="""Text label of , to explain some data information about graphic item like value, name and so on. `label` is placed under `itemStyle` in ECharts 2.x. In ECharts 3, to make the configuration structure flatter, `label`is taken to be at the same level with `itemStyle`, and has `emphasis` as `itemStyle` does.""").tag(sync=True)
    
    itemStyle = Dict(default_value=None, allow_none=True, help="""Graphic style of Map Area Border, `emphasis` is the style when it is highlighted, like being hovered by mouse, or highlighted via legend connect.""").tag(sync=True)
    
    emphasis = Dict(default_value=None, allow_none=True, help="""Map area style in highlighted state.""").tag(sync=True)
    
    select = Dict(default_value=None, allow_none=True, help="""Map area style in selected state.""").tag(sync=True)
    
    zlevel = Float(None, allow_none=True, help="""`zlevel` value of all graphical elements in .


`zlevel` is used to make layers with Canvas. Graphical elements with different `zlevel` values will be placed in different Canvases, which is a common optimization technique. We can put those frequently changed elements (like those with animations) to a separate `zlevel`. Notice that too many Canvases will increase memory cost, and should be used carefully on mobile phones to avoid crash.


Canvases with bigger `zlevel` will be placed on Canvases with smaller `zlevel`.""").tag(sync=True)
    
    z = Float(None, allow_none=True, help="""`z` value of all graphical elements in , which controls order of drawing graphical components. Components with smaller `z` values may be overwritten by those with larger `z` values.


`z` has a lower priority to `zlevel`, and will not create new Canvas.""").tag(sync=True)
    
    left = Union([Unicode(default_value=None, allow_none=True),Float(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Distance between component and the left side of the container.


`left` can be a pixel value like `20`; it can also be a percentage value relative to container width like `'20%'`; and it can also be `'left'`, `'center'`, or `'right'`.


If the `left` value is set to be `'left'`, `'center'`, or `'right'`, then the component will be aligned automatically based on position.""").tag(sync=True)
    
    top = Union([Unicode(default_value=None, allow_none=True),Float(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Distance between component and the top side of the container.


`top` can be a pixel value like `20`; it can also be a percentage value relative to container width like `'20%'`; and it can also be `'top'`, `'middle'`, or `'bottom'`.


If the `top` value is set to be `'top'`, `'middle'`, or `'bottom'`, then the component will be aligned automatically based on position.""").tag(sync=True)
    
    right = Union([Unicode(default_value=None, allow_none=True),Float(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Distance between component and the right side of the container.


`right` can be a pixel value like `20`; it can also be a percentage value relative to container width like `'20%'`.


Adaptive by default.""").tag(sync=True)
    
    bottom = Union([Unicode(default_value=None, allow_none=True),Float(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Distance between component and the bottom side of the container.


`bottom` can be a pixel value like `20`; it can also be a percentage value relative to container width like `'20%'`.


Adaptive by default.""").tag(sync=True)
    
    layoutCenter = Any(None, allow_none=True, help="""`layoutCenter` and `layoutSize` provides layout strategy other than `left/right/top/bottom/width/height`.


When using `left/right/top/bottom/width/height`, it is hard to put the map inside a box area with a fixed width-height ratio. In this case, `layoutCenter` attribute can be used to define the center position of map, and `layoutSize` can be used to define the size of map. For example:



```
layoutCenter: ['30%', '30%'],
// If width-height ratio is larger than 1, then width is set to be 100.
// Otherwise, height is set to be 100.
// This makes sure that it will not exceed the area of 100x100
layoutSize: 100

```

After setting these two values, `left/right/top/bottom/width/height` becomes invalid.""").tag(sync=True)
    
    layoutSize = Union([Float(default_value=None, allow_none=True),Unicode(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""Size of map, see `layoutCenter` for more information. Percentage relative to screen width, and absolute pixel values are supported.""").tag(sync=True)
    
    geoIndex = Float(None, allow_none=True, help="""In default case, map series create exclusive `geo` component for themselves. But `geoIndex` can be used to specify an outer [geo component](#geo), which can be shared with other series like [pie](#series-pie). Moreover, the region color of the outer [geo component](#geo) can be controlled by the map series (via [visualMap](#visualMap)).


When `geoIndex` specified, [series-map.map](#series-map.map) other style configurations like [series-map.itemStyle](#series-map.itemStyle) will not work, but corresponding configurations in [geo component](#geo) will be used.


For example:""").tag(sync=True)
    
    mapValueCalculation = Unicode(None, allow_none=True, help="""Value of multiple series with the same [map type](#series-map.map) can use this option to get a statistical value.


Supported statistical methods:


* `'sum'`
* `'average'`
* `'max'`
* `'min'`""").tag(sync=True)
    
    showLegendSymbol = Bool(None, allow_none=True, help="""Show the symbol in related area (dot of series symbol). Available when [legend](#legend) component exists.""").tag(sync=True)
    
    seriesLayoutBy = Unicode(None, allow_none=True, help="""When [dataset](#dataset) is used, `seriesLayoutBy` specifies whether the column or the row of `dataset` is mapped to the series, namely, the series is "layout" on columns or rows. Optional values:


* 'column': by default, the columns of `dataset` are mapped the series. In this case, each column represents a dimension.
* 'row'：the rows of `dataset` are mapped to the series. In this case, each row represents a dimension.


Check this [example](https://echarts.apache.org/examples/en/editor.html?c=dataset-series-layout-by).""").tag(sync=True)
    
    datasetIndex = Float(None, allow_none=True, help="""If [series.data](#series.data) is not specified, and [dataset](#dataset) exists, the series will use `dataset`. `datasetIndex` specifies which dataset will be used.""").tag(sync=True)
    
    dataGroupId = Unicode(None, allow_none=True, help="""A group ID assigned to all data items in the series.


This option has a lower priority than `groupId`, which means when `groupId` is specified for a certain data item the `dataGroupId` will be simply ignored for that data item. For more information, please see `series.data.groupId`.""").tag(sync=True)
    
    labelLayout = Union([Any(default_value=None, allow_none=True),Any(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""> Since `v5.0.0`


Unified layout configuration of labels.


It provide a chance to adjust the labels' `(x, y)` position, alignment based on the original layout each series provides.


This option can be a callback with following parameters.



```
// corresponding index of data
dataIndex: number
// corresponding type of data. Only available in graph, in which it can be 'node' or 'edge'
dataType?: string
// corresponding index of series
seriesIndex: number
// Displayed text of label.
text: string
// Bounding rectangle of label.
labelRect: {x: number, y: number, width: number, height: number}
// Horizontal alignment of label.
align: 'left' | 'center' | 'right'
// Vertical alignment of label.
verticalAlign: 'top' | 'middle' | 'bottom'
// Bounding rectangle of the element corresponding to.
rect: {x: number, y: number, width: number, height: number}
// Default points array of labelLine. Currently only provided in pie and funnel series.
// It's null in other series.
labelLinePoints?: number[][]

```

**Example:**


Align the labels on the right. Left 10px margin to the edge.



```
labelLayout(params) {
    return {
        x: params.rect.x + 10,
        y: params.rect.y + params.rect.height / 2,
        verticalAlign: 'middle',
        align: 'left'
    }
}

```

Set the text size based on the size of element bounding rectangle.



```

labelLayout(params) {
    return {
        fontSize: Math.max(params.rect.width / 10, 5)
    };
}

```""").tag(sync=True)
    
    labelLine = Dict(default_value=None, allow_none=True, help="""> Since `v5.0.0`


Configuration of label guide line.""").tag(sync=True)
    
    data = Any(None, allow_none=True, help="""Data array of map series, which can be a single data value, like:



```
[12, 34, 56, 10, 23]

```

Or, if need extra dimensions for components like [visualMap](#visualMap) to map to graphic attributes like color, it can also be in the form of array. For example:



```
[[12, 14], [34, 50], [56, 30], [10, 15], [23, 10]]

```

In this case, we can assign the second value in each array item to [visualMap](#visualMap) component.


More likely, we need to assign name to each data item, in which case each item should be an object:



```
[{
    // name of date item
    name: 'data1',
    // value of date item is 8
    value: 10
}, {
    name: 'data2',
    value: 20
}]

```

Each data item can be further customized:



```
[{
    name: 'data1',
    value: 10
}, {
    // name of data item
    name: 'data2',
    value : 56,
    // user-defined label format that only useful for this data item
    label: {},
    // user-defined special itemStyle that only useful for this data item
    itemStyle:{}
}]

```""").tag(sync=True)
    
    markPoint = Dict(default_value=None, allow_none=True, help="""Mark point in a chart.""").tag(sync=True)
    
    markLine = Dict(default_value=None, allow_none=True, help="""Use a line in the chart to illustrate.""").tag(sync=True)
    
    markArea = Dict(default_value=None, allow_none=True, help="""Used to mark an area in chart. For example, mark a time interval.""").tag(sync=True)
    
    silent = Bool(None, allow_none=True, help="""Whether to ignore mouse events. Default value is false, for triggering and responding to mouse events.""").tag(sync=True)
    
    universalTransition = Any(None, allow_none=True, help="""> Since `v5.2.0`


Configuration related to universal transition animation.


Universal Transition provides the ability to morph between any series. With this feature enabled, each time `setOption`, transitions between series with the same `id` will be automatically associated with each other.


One-to-many or many-to-one animations such as drill-down, aggregation, etc. can also be achieved by specifying data items' `groupId` and `childGroupId`.


This can be enabled directly by configuring `universalTransition: true` in the series. It is also possible to provide an object for more detailed configuration.""").tag(sync=True)
    
    tooltip = Dict(default_value=None, allow_none=True, help="""tooltip settings in this series.""").tag(sync=True)
    
        
