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


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

Tooltip component.




---


**General Introduction:**


tooltip can be configured on different places:


- Configured on global: [tooltip](#tooltip)
- Configured in a coordinate system: [grid.tooltip](#grid.tooltip), [polar.tooltip](#polar.tooltip), [single.tooltip](#single.tooltip)
- Configured in a series: [series.tooltip](#series.tooltip)
- Configured in each item of `series.data`: [series.data.tooltip](#series.data.tooltip)



    """

    def __init__(self, **kwargs):

        super().__init__(**kwargs)  
    
    _model_name = Unicode("TooltipModel").tag(sync=True)
    
    show = Bool(None, allow_none=True, help="""Whether to show the tooltip component.


including tooltip floating layer and [axisPointer](#tooltip.axisPointer).""").tag(sync=True)
    
    trigger = Unicode(None, allow_none=True, help="""Type of triggering.


Options:


* `'item'`


 Triggered by data item, which is mainly used for charts that don't have a category axis like scatter charts or pie charts.
* `'axis'`


 Triggered by axes, which is mainly used for charts that have category axes, like bar charts or line charts.


 ECharts 2.x only supports axis trigger for category axis. In ECharts 3, it is supported for all types of axes in [grid](#grid) or [polar](#polar). Also, you may assign axis with [axisPointer.axis](#tooltip.axisPointer.axis).
* `'none'`


 Trigger nothing.""").tag(sync=True)
    
    axisPointer = Dict(default_value=None, allow_none=True, help="""Configuration item for axisPointer.


`tooltip.axisPointer` is like syntactic sugar of axisPointer settings on axes (for example, [xAxis.axisPointer](#xAxis.axisPointer) or [angleAxis.axisPointer](#angleAxis.axisPointer)). More detailed features can be configured on `someAxis.axisPointer`. But in common cases, using `tooltip.axisPointer` is more convenient.



> **Notice:** configurations of `tooltip.axisPointer` has lower priority than that of `someAxis.axisPointer`.




---


`axisPointer` is a tool for displaying reference line and axis value under mouse pointer.


For example:



In the demo above, [axisPointer.link](#axisPointer.link) is used to link axisPointer from different coordinate systems.


`axisPointer` can also be used on touch device, where user can drag the button to move the reference line and label.



In the cases that more than one axis exist, axisPointer helps to look inside the data.






---



> **Notice:**
> Generally, axisPointers is configured in each axes who need them (for example [xAxis.axisPointer](#xAxis.axisPointer)), or configured in `tooltip` (for example [tooltip.axisPointer](#tooltip.axisPointer)).



> But these configurations can only be configured in global axisPointer:
> [axisPointer.triggerOn](#axisPointer.triggerOn), [axisPointer.link](#axisPointer.link).




---




---


**How to display axisPointer:**


In [cartesian (grid)](#grid) and [polar](~polar) and (single axis](#single), each axis has its own axisPointer.


Those axisPointer will not be displayed by default, utill configured as follows:


* Set `someAxis.axisPointer.show` (like [xAxis.axisPointer.show](#xAxis.axisPointer.show)) as `true`. Then axisPointer of this axis will be displayed.
* Set [tooltip.trigger](#tooltip.trigger) as `'axis'`, or set [tooltip.axisPointer.type](#tooltip.axisPointer.type) as `'cross'`. Then coordinate system will automatically chose the axes who will display their axisPointers. ([tooltip.axisPointer.axis](#tooltip.axisPointer.axis) can be used to change the choice.) Notice, `axis.axisPointer` will override `tooltip.axisPointer` settings.




---


**How to display the label of axisPointer:**


The label of axisPointer will not be displayed by default(namely, only reference line will be displayed by default), utill configured as follows:


* Set `someAxis.axisPointer.label.show` (for example [xAxis.axisPointer.label.show](#xAxis.axisPointer.show)) as `true`. Then the label of the axisPointer will be displayed.
* Set [tooltip.axisPointer.type](#tooltip.axisPointer.type) as `'cross'`. Then the label of the crossed axisPointers will be displayed.




---


**How to configure axisPointer on touch device:**


Set `someAxis.axisPointer.handle.show` (for example [xAxis.axisPointer.handle.show](#xAxis.axisPointer.handle.show) as `true`. Then the button for dragging will be displayed. (This feature is not supported on polar).


**Notice:**
If tooltip does not work well in this case, try to set[tooltip.triggerOn](#tooltip.triggerOn) as `'none'` (for the effect: show tooltip when finger holding on the button, and hide tooltip after finger left the button), or set [tooltip.alwaysShowContent](#tooltip.alwaysShowContent) as `true` (then tooltip will always be displayed).


See the [example](https://echarts.apache.org/examples/en/editor.html?c=line-tooltip-touch&edit=1&reset=1).




---


**Snap to point**


In value axis and time axis, if [snap](#xAxis.axisPointer.snap) is set as true, axisPointer will snap to point automatically.




---""").tag(sync=True)
    
    showContent = Bool(None, allow_none=True, help="""Whether to show the tooltip floating layer, whose default value is true. It should be configurated to be `false`, if you only need tooltip to trigger the event or show the axisPointer without content.""").tag(sync=True)
    
    alwaysShowContent = Bool(None, allow_none=True, help="""Whether to show tooltip content all the time. By default, it will be hidden [after some time](#tooltip.hideDelay). It can be set to be `true` to preserve displaying.


This attribute is newly added to ECharts 3.0.""").tag(sync=True)
    
    triggerOn = Unicode(None, allow_none=True, help="""Conditions to trigger tooltip. Options:


* `'mousemove'`


 Trigger when mouse moves.
* `'click'`


 Trigger when mouse clicks.
* `'mousemove|click'`


 Trigger when mouse clicks and moves.
* `'none'`


 Do not triggered by `'mousemove'` and `'click'`. Tooltip can be triggered and hidden manually by calling [action.tooltip.showTip](api.html#action.tooltip.showTip) and [action.tooltip.hideTip](api.html#action.tooltip.hideTip). It can also be triggered by [axisPointer.handle](#xAxis.axisPointer.handle) in this case.


This attribute is new to ECharts 3.0.""").tag(sync=True)
    
    showDelay = Float(None, allow_none=True, help="""Delay time for showing tooltip, in ms. No delay by default, and it is not recommended to set. Only valid when [triggerOn](#tooltip.triggerOn) is set to be `'mousemove'`.""").tag(sync=True)
    
    hideDelay = Float(None, allow_none=True, help="""Delay time for hiding tooltip, in ms. It will be invalid when [alwaysShowContent](#tooltip.alwaysShowContent) is `true`.""").tag(sync=True)
    
    enterable = Bool(None, allow_none=True, help="""Whether mouse is allowed to enter the floating layer of tooltip, whose default value is false. If you need to interact in the tooltip like with links or buttons, it can be set as `true`.""").tag(sync=True)
    
    renderMode = Unicode(None, allow_none=True, help="""Render mode for tooltip. By default, it is set to be `'html'` so that extra DOM element is used for tooltip. It can also set to be `'richText'` so that the tooltip will be rendered inside Canvas. This is very useful for environments that don't have DOM, such as Wechat applications.""").tag(sync=True)
    
    confine = Bool(None, allow_none=True, help="""Whether confine tooltip content in the view rect of chart instance.


Useful when tooltip is cut because of `'overflow: hidden'` set on outer dom of chart instance, or because of narrow screen on mobile.""").tag(sync=True)
    
    appendToBody = Bool(None, allow_none=True, help="""> Since `v4.7.0`


(DEPRECATED since `v5.5.0`, use [appendTo](#tooltip.appendTo) instead.)


Whether to append the tooltip DOM element as a child of the `<body>` of the HTML page, when using [renderMode](#tooltip.renderMode) `'html'`.


The default value is `false`, which means that the tooltip DOM element will be one of a descendant of its echarts DOM container. But that means that the tooltip might be cut when overflow the container if some of the ancestors DOM element of the echarts container are styled with `overflow: hidden`. This case could also be resolved by setting [tooltip.confine](#tooltip.confine), but it might not suitable for all scenarios.


Here we provide `appendToBody: true` to auto append the tooltip element to `<body>`, which is a common way to resolve this kind of issue. But `true` is not set as a default value because to void to bring break change for some cases where tooltip is deeply customized and to void some unexpected bad cases.


Note that it also works when CSS transform used.""").tag(sync=True)
    
    appendTo = Union([Unicode(default_value=None, allow_none=True),Any(default_value=None, allow_none=True),Any(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""> Since `v5.5.0`


Which DOM element to append the tooltip to. Only available when using [renderMode](#tooltip.renderMode) `'html'`.


The default value is `null`, which means that the tooltip's DOM node will be added as a descendant node of the chart’s DOM container. However, this approach can cause the tooltip to be truncated if it extends beyond the container, due to ancestors of the chart's DOM container having overflow: hidden set. This issue can be partially addressed using tooltip.confine, but it may not cover all scenarios.


For such scenarios, `appendTo` can be specified. When it is a function, the interface is in the form of



```
(chartContainer: HTMLElement) => HTMLElement | undefined | null

```

which means it returns the node that the tooltip's DOM node should be added to. Returning `undefined` or `null` indicates that the default logic described above should be used. Returning an HTMLElement means that it should be added under that node.


Note that it also works when CSS transform used.""").tag(sync=True)
    
    className = Unicode(None, allow_none=True, help="""> Since `v5.0.0`


Specify the classes for the tooltip root DOM. (Only works in [`html`](#tooltip.renderMode) render mode).


Example:



```
className: 'echarts-tooltip echarts-tooltip-dark'

```""").tag(sync=True)
    
    transitionDuration = Float(None, allow_none=True, help="""The transition duration of tooltip's animation, in seconds. When it is set to be 0, it would move closely with the mouse.""").tag(sync=True)
    
    position = Union([Unicode(default_value=None, allow_none=True),Any(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""The position of the tooltip's floating layer, which would follow the position of mouse by default.


Options:


* `Array`


 Display the position of tooltip's floating layer through array, which supports absolute position and relative percentage.


 Example:



```
  // absolute position, which is 10px to the left side and 10px to the top side of the container
  position: [10, 10]
  // relative position, in the exact center of the container
  position: ['50%', '50%']

```
* `Function`


 Callback function in the following form:



```
  (point: Array, params: Object|Array.<Object>, dom: HTMLDomElement, rect: Object, size: Object) => Array

```

 **Parameters:**  

 point: Mouse position.  

 param: The same as formatter.  

 dom: The DOM object of tooltip.  

 rect: It is valid only when mouse is on graphic elements, which stands for a bounding box with `x`, `y`, `width`, and `height`.  

 size: The size of dom echarts container. For example: `{contentSize: [width, height], viewSize: [width, height]}`.   



 **Return:**  

 Return value is an array standing for tooltip position, which can be absolute pixels, or relative percentage.  

 Or can be an object, like `{left: 10, top: 30}`, or `{right: '20%', bottom: 40}`.  



 For example:



```
  position: function (point, params, dom, rect, size) {
      // fixed at top
      return [point[0], '10%'];
  }

```

 Or:



```
  position: function (pos, params, dom, rect, size) {
      // tooltip will be fixed on the right if mouse hovering on the left,
      // and on the left if hovering on the right.
      var obj = {top: 60};
      obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 5;
      return obj;
  }

```
* `'inside'`


 Center position of the graphic element where the mouse is in, which is only valid when [trigger](#tooltip.trigger) is `'item'`.
* `'top'`


 Top position of the graphic element where the mouse is in, which is only valid when [trigger](#tooltip.trigger) is `'item'`.
* `'left'`


 Left position of the graphic element where the mouse is in, which is only valid when [trigger](#tooltip.trigger) is `'item'`.
* `'right'`


 Right position of the graphic element where the mouse is in, which is only valid when [trigger](#tooltip.trigger) is `'item'`.
* `'bottom'`


 Bottom position of the graphic element where the mouse is in, which is only valid when [trigger](#tooltip.trigger) is `'item'`.""").tag(sync=True)
    
    formatter = Union([Unicode(default_value=None, allow_none=True),Any(default_value=None, allow_none=True),], default_value=None, allow_none=True, help="""The content formatter of tooltip's floating layer which supports string template and callback function.


**1. String template**


The template variables are `{a}`, `{b}`, `{c}`, `{d}` and `{e}`, which stands for series name, data name and data value and ect. When [trigger](#tooltip.trigger) is set to be `'axis'`, there may be data from multiple series. In this time, series index can be referred as `{a0}`, `{a1}`, or `{a2}`.


`{a}`, `{b}`, `{c}`, `{d}` have different meanings for different series types:


* Line (area) charts, bar (column) charts, K charts: `{a}` for series name, `{b}` for category name, `{c}` for data value, `{d}` for none;
* Scatter (bubble) charts: `{a}` for series name, `{b}` for data name, `{c}` for data value, `{d}` for none;
* Map: `{a}` for series name, `{b}` for area name, `{c}` for merging data, `{d}` for none;
* Pie charts, gauge charts, funnel charts: `{a}` for series name, `{b}` for data item name, `{c}` for data value, `{d}` for percentage.


**Example:** 



```
formatter: '{b0}: {c0}<br />{b1}: {c1}'

```

**2. Callback function**


The format of callback function:



```
(params: Object|Array, ticket: string, callback: (ticket: string, html: string)) => string | HTMLElement | HTMLElement[]

```

The first parameter `params` is the data that the formatter needs. Its format is shown as follows:



```
{
    componentType: 'series',
    // Series type
    seriesType: string,
    // Series index in option.series
    seriesIndex: number,
    // Series name
    seriesName: string,
    // Data name, or category name
    name: string,
    // Data index in input data array
    dataIndex: number,
    // Original data as input
    data: Object,
    // Value of data. In most series it is the same as data.
    // But in some series it is some part of the data (e.g., in map, radar)
    value: number|Array|Object,
    // encoding info of coordinate system
    // Key: coord, like ('x' 'y' 'radius' 'angle')
    // value: Must be an array, not null/undefined. Contain dimension indices, like:
    // {
    //     x: [2] // values on dimension index 2 are mapped to x axis.
    //     y: [0] // values on dimension index 0 are mapped to y axis.
    // }
    encode: Object,
    // dimension names list
    dimensionNames: Array<String>,
    // data dimension index, for example 0 or 1 or 2 ...
    // Only work in `radar` series.
    dimensionIndex: number,
    // Color of data
    color: string,
    // The percentage of current data item in the pie/funnel series
    percent: number,
    // The ancestors of current node in the sunburst series (including self)
    treePathInfo: Array,
    // The ancestors of current node in the tree/treemap series (including self)
    treeAncestors: Array
}

```

**How to use `encode` and `dimensionNames`?**


When the dataset is like



```
dataset: {
    source: [
        ['Matcha Latte', 43.3, 85.8, 93.7],
        ['Milk Tea', 83.1, 73.4, 55.1],
        ['Cheese Cocoa', 86.4, 65.2, 82.5],
        ['Walnut Brownie', 72.4, 53.9, 39.1]
    ]
}

```

We can get the value of the y-axis via



```
params.value[params.encode.y[0]]

```

When the dataset is like



```
dataset: {
    dimensions: ['product', '2015', '2016', '2017'],
    source: [
        {product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
        {product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
        {product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
        {product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}
    ]
}

```

We can get the value of the y-axis via



```
params.value[params.dimensionNames[params.encode.y[0]]]

```

When [trigger](#tooltip.trigger) is `'axis'`, or when tooltip is triggered by [axisPointer](#xAxis.axisPointer), `params` is the data array of multiple series. The content of each item of the array is the same as above. Besides,



```
{
    componentType: 'series',
    // Series type
    seriesType: string,
    // Series index in option.series
    seriesIndex: number,
    // Series name
    seriesName: string,
    // Data name, or category name
    name: string,
    // Data index in input data array
    dataIndex: number,
    // Original data as input
    data: Object,
    // Value of data. In most series it is the same as data.
    // But in some series it is some part of the data (e.g., in map, radar)
    value: number|Array|Object,
    // encoding info of coordinate system
    // Key: coord, like ('x' 'y' 'radius' 'angle')
    // value: Must be an array, not null/undefined. Contain dimension indices, like:
    // {
    //     x: [2] // values on dimension index 2 are mapped to x axis.
    //     y: [0] // values on dimension index 0 are mapped to y axis.
    // }
    encode: Object,
    // dimension names list
    dimensionNames: Array<String>,
    // data dimension index, for example 0 or 1 or 2 ...
    // Only work in `radar` series.
    dimensionIndex: number,
    // Color of data
    color: string
}

```

**How to use `encode` and `dimensionNames`?**


When the dataset is like



```
dataset: {
    source: [
        ['Matcha Latte', 43.3, 85.8, 93.7],
        ['Milk Tea', 83.1, 73.4, 55.1],
        ['Cheese Cocoa', 86.4, 65.2, 82.5],
        ['Walnut Brownie', 72.4, 53.9, 39.1]
    ]
}

```

We can get the value of the y-axis via



```
params.value[params.encode.y[0]]

```

When the dataset is like



```
dataset: {
    dimensions: ['product', '2015', '2016', '2017'],
    source: [
        {product: 'Matcha Latte', '2015': 43.3, '2016': 85.8, '2017': 93.7},
        {product: 'Milk Tea', '2015': 83.1, '2016': 73.4, '2017': 55.1},
        {product: 'Cheese Cocoa', '2015': 86.4, '2016': 65.2, '2017': 82.5},
        {product: 'Walnut Brownie', '2015': 72.4, '2016': 53.9, '2017': 39.1}
    ]
}

```

We can get the value of the y-axis via



```
params.value[params.dimensionNames[params.encode.y[0]]]

```

**Note:** Using array to present all the parameters in ECharts 2.x is not supported anymore.


The second parameter `ticket` is the asynchronous callback flag which should be used along with the third parameter `callback` when it is used.


The third parameter `callback` is asynchronous callback. When the content of tooltip is acquired asynchronously, `ticket` and `htm` as introduced above can be used to update tooltip with callback.


Example:



```
formatter: function (params, ticket, callback) {
    $.get('detail?name=' + params.name, function (content) {
        callback(ticket, toHTML(content));
    });
    return 'Loading';
}

```""").tag(sync=True)
    
    valueFormatter = Unicode(None, allow_none=True, help="""> Since `v5.3.0`


Callback function for formatting the value section in tooltip.


Interface:



```
(value: number | string, dataIndex: number) => string

```


> `dataIndex` is provided since `v5.5.0`.


Example:



```
// Add $ prefix
valueFormatter: (value) => '$' + value.toFixed(2)

```""").tag(sync=True)
    
    backgroundColor = Any(None, allow_none=True, help="""The background color of tooltip's floating layer.""").tag(sync=True)
    
    borderColor = Any(None, allow_none=True, help="""The border color of tooltip's floating layer.""").tag(sync=True)
    
    borderWidth = Float(None, allow_none=True, help="""The border width of tooltip's floating layer.""").tag(sync=True)
    
    padding = Float(None, allow_none=True, help="""The floating layer of tooltip space around content. The unit is px. Default values for each position are 5. And they can be set to different values with left, right, top, and bottom.


Examples:



```
// Set padding to be 5
padding: 5
// Set the top and bottom paddings to be 5, and left and right paddings to be 10
padding: [5, 10]
// Set each of the four paddings separately
padding: [
    5,  // up
    10, // right
    5,  // down
    10, // left
]

```""").tag(sync=True)
    
    textStyle = Dict(default_value=None, allow_none=True, help="""The text style of tooltip's floating layer.""").tag(sync=True)
    
    extraCssText = Unicode(None, allow_none=True, help="""Extra CSS style for floating layer. The following is an example for adding shadow.



```
extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);'

```""").tag(sync=True)
    
    order = Unicode(None, allow_none=True, help="""> Since `v5.0.0`


Tooltip order for multiple series. Defaults is `'seriesAsc'`.


Conditions to order tooltip. Options:


* `'seriesAsc'`


 Base on series declaration, ascending order tooltip.
* `'seriesDesc'`


 Base on series declaration, descending order tooltip.
* `'valueAsc'`


 Base on value, ascending order tooltip, only for numeric value.
* `'valueDesc'`


 Base on value, descending order tooltip, only for numeric value.""").tag(sync=True)
    
        
