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


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

Surface. Support to drawn the [Parameter surface] (<https://en.wikipedia.org/wiki/Parametric_surface>) by [parametric](#series-surface.parametric).


The figure below is a parametric surface similar to a metal part configured as a metal material.


![](documents/asset/gl/img/parametric-surface.png)



    """

    def __init__(self, **kwargs):

        super().__init__(**kwargs)  
    
    _model_name = Unicode("SurfaceModel").tag(sync=True)
    
    type = Unicode("surface", allow_none=True, ).tag(sync=True)
    
    name = Unicode(None, allow_none=True, help="""Series name used for displaying in [tooltip](https://echarts.apache.org/zh/option.html#tooltip) and filtering with [legend](https://echarts.apache.org/zh/option.html#legend), or updating data and configuration with `setOption`.""").tag(sync=True)
    
    coordinateSystem = Unicode(None, allow_none=True, help="""The coordinate used in the series, whose options are:


* `'cartesian3D'`


 Use a 3D rectangular coordinate (also known as Cartesian coordinate), with [xAxisIndex](#series-.xAxisIndex) and [yAxisIndex](#series-.yAxisIndex) to assign the corresponding axis component.""").tag(sync=True)
    
    grid3DIndex = Float(None, allow_none=True, help="""Use the index of the [grid3D](#grid3D) component. The first [grid3D](#grid3D) component is used by default.""").tag(sync=True)
    
    parametric = Bool(None, allow_none=True, help="""Whether it is a parametric surface.""").tag(sync=True)
    
    wireframe = Dict(default_value=None, allow_none=True, help="""The wireframe of the surface.""").tag(sync=True)
    
    equation = Dict(default_value=None, allow_none=True, help="""The function expression of the surface. If you need to display a function surface, you can set the function expression by [equation](#series-surface.equation) without setting [data](#series-surface.data). For example, the ripple effect can be simulated by the following function.



```
equation: {
    x: {
        step: 0.1,
        min: -3,
        max: 3,
    },
    y: {
        step: 0.1,
        min: -3,
        max: 3,
    },
    z: function (x, y) {
        return Math.sin(x * x + y * y) * x / 3.14
    }
}

```""").tag(sync=True)
    
    parametricEquation = Dict(default_value=None, allow_none=True, help="""The [parameter equation] of the surface (<https://zh.wikipedia.org/wiki/%E5%8F%83%E6%95%B8%E6%96%B9%E7%A8%8B)>. When [data](#series-surface.data) is not set, the parameter parameter equation can be declared by [parametricEquation](#series-surface.equation). Valid when [parametric](#series-surface) is `true`.


The parametric equations is [x](#series-surface.parametricEquation.x), [y](#series-surface.parametricEquation.y), [z](#series-surface.parametricEquation.z) about the equations of the parameters [u](#series-surface.parametricEquation.u), [v](#series-surface.parametricEquation.v).


The following parametric equation is to plot the parametric surface of a similar metal part in the previous figure:



```
var aa = 0.4;
var r = 1 - aa * aa;
var w = sqrt(r);
...
parametricEquation: {
    u: {
        min: -13.2,
        max: 13.2,
        step: 0.5
    },
    v: {
        min: -37.4,
        max: 37.4,
        step: 0.5
    },
    x: function (u, v) {
        var denom = aa * (pow(w * cosh(aa * u), 2) + aa * pow(sin(w * v), 2))
        return -u + (2 * r * cosh(aa * u) * sinh(aa * u) / denom);
    },
    y: function (u, v) {
        var denom = aa * (pow(w * cosh(aa * u), 2) + aa * pow(sin(w * v), 2))
        return 2 * w * cosh(aa * u) * (-(w * cos(v) * cos(w * v)) - (sin(v) * sin(w * v))) / denom;
    },
    z: function (u, v) {
        var denom = aa * (pow(w * cosh(aa * u), 2) + aa * pow(sin(w * v), 2))
        return  2 * w * cosh(aa * u) * (-(w * sin(v) * cos(w * v)) + (cos(v) * sin(w * v))) / denom
    }
}

```""").tag(sync=True)
    
    itemStyle = Dict(default_value=None, allow_none=True, help="""The color, opacity, and other styles of the surface.""").tag(sync=True)
    
    data = Any(None, allow_none=True, help="""The data array of the surface.


The data is an array of linear stores containing multiply `X vertices` by `Y vertices` data. A 5 x 5 surface has a total of 25 vertices, and the index of the data in the array is as follows


![](documents/asset/gl/img/surface-index.png)


The data used in the above figure:



```
data: [
    [-1,-1,0],[-0.5,-1,0],[0,-1,0],[0.5,-1,0],[1,-1,0],
    [-1,-0.5,0],[-0.5,-0.5,1],[0,-0.5,0],[0.5,-0.5,-1],[1,-0.5,0],
    [-1,0,0],[-0.5,0,0],[0,0,0],[0.5,0,0],[1,0,0],
    [-1,0.5,0],[-0.5,0.5,-1],[0,0.5,0],[0.5,0.5,1],[1,0.5,0],
    [-1,1,0],[-0.5,1,0],[0,1,0],[0.5,1,0],[1,1,0]
]

```

Each item is `x`, `y`, `z`.


For the parametric equation, each item needs to store five data, namely `x`, `y`, `z` and the parameters `u`, `v`. The index of the data is in the order of `u`, `v`. For example the following data:



```
data: [
    // v is 0, u is from -3.14 to 3.13
    [0,0,1,-3.14,0],[0,0,1,-1.57,0],[0,0,1,0,0],[0,0,1,1.57,0],[0,0,1,3.14,0],
    // v is 1.57, u is from -3.14 to 3.13
    [0,-1,0,-3.14,1.57],[-1,0,0,-1.57,1.57],[0,1,0,0,1.57],[1,0,0,1.57,1.57],[0,-1,0,3.14,1.57],
    // v is 3.14, u is from -3.14 to 3.13
    [0,0,-1,-3.14,3.14],[0,0,-1,-1.57,3.14],[0,0,-1,0,3.14],[0,0,-1,1.57,3.14],[0,0,-1,3.14,3.14]]
]

```

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: [12, 14, 10]
}, {
    name: 'data2',
    value: 20
}]

```

Each data item can be further customized:



```
[{
    name: 'data1',
    value: [12, 14, 10]
}, {
    // name of data item
    name: 'data2',
    value : [34, 50, 15],
    // user-defined special itemStyle that only useful for this data item
    itemStyle:{}
}]

```""").tag(sync=True)
    
    shading = Unicode(None, allow_none=True, help="""The coloring effect of 3D graphics in surface. The following three coloring methods are supported in echarts-gl:


* `'color'`
Only display colors, not affected by other factors such as lighting.
* `'lambert'`
Through the classic [lambert] coloring, can express the light and dark that the light shows.
* `'realistic'`
Realistic rendering, combined with [light.ambientCubemap](#globe.light.ambientCubemap) and [postEffect](#globe.postEffect), can improve the quality and texture of the display. [Physical Based Rendering (PBR)] (<https://www.marmoset.co/posts/physically-based-rendering-and-you-can-too/>) is used in ECharts GL to represent realistic materials.""").tag(sync=True)
    
    realisticMaterial = Dict(default_value=None, allow_none=True, help="""The configuration item of the realistic material is valid when [shading](#series-surface.shading) is `'realistic'`.""").tag(sync=True)
    
    lambertMaterial = Dict(default_value=None, allow_none=True, help="""The configuration item of the lambert material is valid when [shading](#series-surface.shading) is `'lambert'`.""").tag(sync=True)
    
    colorMaterial = Dict(default_value=None, allow_none=True, help="""The color material related configuration item is valid when [shading](#series-surface.shading) is `'color'`.""").tag(sync=True)
    
    zlevel = Float(None, allow_none=True, help="""The layer in which the component is located.


`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 the crash.


Canvases with bigger `zlevel` will be placed on Canvases with smaller `zlevel`.


**Note:** The layers of the components in echarts-gl need to be separated from the layers of the components in echarts. The same `zlevel` cannot be used for both WebGL and Canvas drawing at the same time.""").tag(sync=True)
    
    silent = Bool(None, allow_none=True, help="""Whether the graph doesn`t respond and triggers a mouse event. The default is false, which is to respond to and trigger mouse events.""").tag(sync=True)
    
    animation = Bool(None, allow_none=True, help="""Whether to enable animation.""").tag(sync=True)
    
    animationDurationUpdate = Float(None, allow_none=True, help="""The duration time for update the transition animation.""").tag(sync=True)
    
    animationEasingUpdate = Unicode(None, allow_none=True, help="""The easing effect for update transition animation.""").tag(sync=True)
    
        
