diff --git a/Documentation~/en/api.md b/Documentation~/en/api.md index 6a052e11..5183e0ef 100644 --- a/Documentation~/en/api.md +++ b/Documentation~/en/api.md @@ -79,6 +79,9 @@ slug: /api - [EmphasisStyle](#emphasisstyle) - [EndLabelStyle](#endlabelstyle) - [FormatterHelper](#formatterhelper) +- [Graph](#graph) +- [GraphEdge](#graphedge) +- [GraphNode](#graphnode) - [GridCoord](#gridcoord) - [GridCoordContext](#gridcoordcontext) - [GridLayout](#gridlayout) @@ -169,6 +172,7 @@ slug: /api - [SerieDataComponentAttribute](#seriedatacomponentattribute) - [SerieDataContext](#seriedatacontext) - [SerieDataExtraFieldAttribute](#seriedataextrafieldattribute) +- [SerieDataLink](#seriedatalink) - [SerieEventData](#serieeventdata) - [SerieEventDataPool](#serieeventdatapool) - [SerieHandler](#seriehandler) @@ -689,6 +693,7 @@ Background component. |AddData()||public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)
Add a (x,y) data to serie. | |AddData()||public SerieData AddData(string serieName, List<double> multidimensionalData, string dataName = null, string dataId = null)
Add an arbitray dimension data to serie,such as (x,y,z,...). | |AddData()||public SerieData AddData(string serieName, params double[] multidimensionalData)
Add an arbitray dimension data to serie,such as (x,y,z,...). | +|AddLink()||public SerieDataLink AddLink(int serieIndex, string sourceName, string targetName, double value)
Add a link data to serie. | |AddSerie<T>()||public T AddSerie<T>(string serieName = null, bool show = true, bool addToHead = false) where T : Serie| |AddXAxisData()||public void AddXAxisData(string category, int xAxisIndex = 0)
Add a category data to xAxis. | |AddXAxisIcon()||public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0)
Add an icon to xAxis. | @@ -707,9 +712,10 @@ Background component. |CanMultipleComponent()||public bool CanMultipleComponent(Type type)| |ClampInChart()||public void ClampInChart(ref Vector3 pos)| |ClampInGrid()||public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)| -|ClearComponentData()||public virtual void ClearComponentData()
Clear the data of all components. | +|ClearComponentData()|v3.4.0|public virtual void ClearComponentData()
Clear the data of all components. | |ClearData()||public virtual void ClearData()
Clear all components and series data. Note: serie only empties the data and does not remove serie. | -|ClearSerieData()||public virtual void ClearSerieData()
Clear the data of all series. | +|ClearSerieData()|v3.4.0|public virtual void ClearSerieData()
Clear the data of all series. | +|ClearSerieLinks()|v3.10.0|public virtual void ClearSerieLinks()
Clear the link data of all series. | |ClickLegendButton()||public void ClickLegendButton(int legendIndex, string legendName, bool show)
点击图例按钮 | |ConvertSerie()||public bool ConvertSerie(Serie serie, Type type)| |ConvertSerie<T>()||public bool ConvertSerie<T>(Serie serie) where T : Serie| @@ -733,7 +739,7 @@ Background component. |GetItemColor()||public Color32 GetItemColor(Serie serie, SerieData serieData, int colorIndex)| |GetLegendRealShowNameColor()||public Color32 GetLegendRealShowNameColor(string name)| |GetLegendRealShowNameIndex()||public int GetLegendRealShowNameIndex(string name)| -|GetMarkColor()||public Color32 GetMarkColor(Serie serie, SerieData serieData)
获得Serie的标识颜色。 | +|GetMarkColor()|v3.4.0|public Color32 GetMarkColor(Serie serie, SerieData serieData)
获得Serie的标识颜色。 | |GetOrAddChartComponent<T>()||public T GetOrAddChartComponent<T>() where T : MainComponent| |GetPainter()||public Painter GetPainter(int index)| |GetSerie()||public Serie GetSerie(int serieIndex)| @@ -809,6 +815,7 @@ Background component. |RemoveSerie()||public void RemoveSerie(string serieName)| |RemoveSerie<T>()||public void RemoveSerie<T>() where T : Serie| |ReplaceSerie()||public bool ReplaceSerie(Serie oldSerie, Serie newSerie)| +|ResetChartStatus()|v3.10.0|public void ResetChartStatus()
reset chart status. When some parameters are set, due to the animation effect, the chart status may not be correct. | |ResetDataIndex()||public bool ResetDataIndex(int serieIndex)
重置serie的数据项索引。避免数据项索引异常。 | |SetBasePainterMaterial()||public void SetBasePainterMaterial(Material material)
设置Base Painter的材质球 | |SetMaxCache()||public void SetMaxCache(int maxCache)
设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 | @@ -1129,7 +1136,7 @@ Configurations of blur state. ## ChildComponent -> class in XCharts.Runtime / Subclasses: [AnimationStyle](#animationstyle),[AxisAnimation](#axisanimation),[AxisName](#axisname),[AxisSplitArea](#axissplitarea),[AreaStyle](#areastyle),[ArrowStyle](#arrowstyle),[BaseLine](#baseline),[IconStyle](#iconstyle),[ImageStyle](#imagestyle),[ItemStyle](#itemstyle),[Level](#level),[LevelStyle](#levelstyle),[LineArrow](#linearrow),[LineStyle](#linestyle),[Location](#location),[MLValue](#mlvalue),[MarqueeStyle](#marqueestyle),[Padding](#padding),[StageColor](#stagecolor),[SymbolStyle](#symbolstyle),[TextLimit](#textlimit),[TextStyle](#textstyle),[CommentItem](#commentitem),[CommentMarkStyle](#commentmarkstyle),[LabelLine](#labelline),[LabelStyle](#labelstyle),[MarkAreaData](#markareadata),[MarkLineData](#marklinedata),[StateStyle](#statestyle),[VisualMapRange](#visualmaprange),[UIComponentTheme](#uicomponenttheme),[SerieData](#seriedata),[ComponentTheme](#componenttheme),[SerieTheme](#serietheme),[ThemeStyle](#themestyle) +> class in XCharts.Runtime / Subclasses: [AnimationStyle](#animationstyle),[AxisAnimation](#axisanimation),[AxisName](#axisname),[AxisSplitArea](#axissplitarea),[AreaStyle](#areastyle),[ArrowStyle](#arrowstyle),[BaseLine](#baseline),[IconStyle](#iconstyle),[ImageStyle](#imagestyle),[ItemStyle](#itemstyle),[Level](#level),[LevelStyle](#levelstyle),[LineArrow](#linearrow),[LineStyle](#linestyle),[Location](#location),[MLValue](#mlvalue),[MarqueeStyle](#marqueestyle),[Padding](#padding),[StageColor](#stagecolor),[SymbolStyle](#symbolstyle),[TextLimit](#textlimit),[TextStyle](#textstyle),[CommentItem](#commentitem),[CommentMarkStyle](#commentmarkstyle),[LabelLine](#labelline),[LabelStyle](#labelstyle),[MarkAreaData](#markareadata),[MarkLineData](#marklinedata),[StateStyle](#statestyle),[VisualMapRange](#visualmaprange),[UIComponentTheme](#uicomponenttheme),[SerieData](#seriedata),[SerieDataLink](#seriedatalink),[ComponentTheme](#componenttheme),[SerieTheme](#serietheme),[ThemeStyle](#themestyle) |public method|since|description| @@ -1369,6 +1376,53 @@ Configurations of emphasis state. |TrimAndReplaceLine()||public static string TrimAndReplaceLine(string content)| |TrimAndReplaceLine()||public static string TrimAndReplaceLine(StringBuilder sb)| +## Graph + +> class in XCharts.Runtime + +the data struct of graph. + +|public method|since|description| +|--|--|--| +|AddEdge()||public GraphEdge AddEdge(string nodeId1, string nodeId2, double value)| +|AddNode()||public GraphNode AddNode(string nodeId, string nodeName, int dataIndex)| +|BreadthFirstTraverse()||public void BreadthFirstTraverse(GraphNode startNode, System.Action<GraphNode> onTraverse)| +|Clear()||public void Clear()| +|DeepFirstTraverse()||public void DeepFirstTraverse(GraphNode startNode, System.Action<GraphNode> onTraverse)| +|EachNode()||public void EachNode(System.Action<GraphNode> onEach)| +|GetDepthNodes()||public List<List<GraphNode>> GetDepthNodes()| +|GetEdge()||public GraphEdge GetEdge(string nodeId1, string nodeId2)| +|GetMaxDepth()||public int GetMaxDepth()| +|GetNode()||public GraphNode GetNode(string nodeId)| +|GetNodeDepth()||// public int GetNodeDepth(GraphNode node)| +|GetNodeDepth()||// public void GetNodeDepth(GraphNode node, ref int depth, int recursiveCount = 0)| +|GetNodeDepth()||public int GetNodeDepth(GraphNode node, int recursiveCount = 0)| +|GetNodesTotalValue()||public static double GetNodesTotalValue(List<GraphNode> nodes)| +|GetRootNodes()||public List<GraphNode> GetRootNodes()| +|Graph()||public Graph(bool directed)| +|Refresh()||public void Refresh()| + +## GraphEdge + +> class in XCharts.Runtime + +The edge of graph. + +|public method|since|description| +|--|--|--| +|GraphEdge()||public GraphEdge(GraphNode node1, GraphNode node2, double value)| + +## GraphNode + +> class in XCharts.Runtime + +The node of graph. + +|public method|since|description| +|--|--|--| +|GraphNode()||public GraphNode(string id, string name, int dataIndex)| +|ToString()||public override string ToString()| + ## GridCoord > class in XCharts.Runtime / Inherits from: [CoordSystem](#coordsystem),[IUpdateRuntimeData](#iupdateruntimedata),[ISerieContainer](#iseriecontainer) @@ -1735,6 +1789,8 @@ Legend component.The legend component shows different sets of tags, colors, and > class in XCharts.Runtime / Inherits from: [ChildComponent](#childcomponent) +> Since `v3.10.0` + ## Line @@ -2242,6 +2298,7 @@ Configurations of select state. |AddData()||public SerieData AddData(List<double> valueList, string dataName = null, string dataId = null)
将一组数据添加到系列中。 如果数据只有一个,默认添加到维度Y中。 | |AddData()||public SerieData AddData(params double[] values)
添加任意维数据到系列中。 | |AddExtraComponent<T>()||public T AddExtraComponent<T>() where T : ChildComponent, ISerieComponent| +|AddLink()||public SerieDataLink AddLink(string sourceName, string targetName, double value)
Add a link data. | |AddSerieData()||public void AddSerieData(SerieData serieData)| |AddXYData()||public SerieData AddXYData(double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到维度X和维度Y | |AddYData()||public SerieData AddYData(double value, string dataName = null, string dataId = null)
添加一个数据到维度Y(此时维度X对应的数据是索引) | @@ -2258,6 +2315,7 @@ Configurations of select state. |ClearData()||public override void ClearData()
清空所有数据 | |ClearDirty()||public override void ClearDirty()| |ClearHighlight()||public void ClearHighlight()
清除所有数据的高亮标志 | +|ClearLinks()||public void ClearLinks()
清空所有Link数据 | |ClearSerieNameDirty()||public void ClearSerieNameDirty()| |ClearVerticesDirty()||public override void ClearVerticesDirty()| |Clone()||public Serie Clone()| @@ -2435,6 +2493,14 @@ The attribute for serie data component. |SerieDataExtraFieldAttribute()||public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5, string field6)| |SerieDataExtraFieldAttribute()||public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5, string field6, string field7)| +## SerieDataLink + +> class in XCharts.Runtime / Inherits from: [ChildComponent](#childcomponent) + +> Since `v3.10.0` + +the link of serie data. Used for sankey chart. Sankey chart only supports directed acyclic graph. make sure the data link is directed acyclic graph. + ## SerieEventData > class in XCharts.Runtime @@ -2472,6 +2538,7 @@ the data of serie event. |ForceUpdateSerieContext()||public virtual void ForceUpdateSerieContext() { }| |InitComponent()||public virtual void InitComponent() { }| |OnBeginDrag()||public virtual void OnBeginDrag(PointerEventData eventData) { }| +|OnDataUpdate()||public virtual void OnDataUpdate() { }| |OnDrag()||public virtual void OnDrag(PointerEventData eventData) { }| |OnEndDrag()||public virtual void OnEndDrag(PointerEventData eventData) { }| |OnLegendButtonClick()||public virtual void OnLegendButtonClick(int index, string legendName, bool show) { }| diff --git a/Documentation~/en/configuration.md b/Documentation~/en/configuration.md index 6a1674d9..d8e107d3 100644 --- a/Documentation~/en/configuration.md +++ b/Documentation~/en/configuration.md @@ -121,6 +121,7 @@ import APITable from '@site/src/components/APITable'; - [RadiusAxisTheme](#radiusaxistheme) - [SelectStyle](#selectstyle) - [SerieData](#seriedata) +- [SerieDataLink](#seriedatalink) - [SerieSymbol](#seriesymbol) - [SerieTheme](#serietheme) - [StageColor](#stagecolor) @@ -744,7 +745,7 @@ Configurations of blur state. ## ChildComponent -> class in XCharts.Runtime / Subclasses: [AnimationStyle](#animationstyle), [AxisAnimation](#axisanimation), [AxisName](#axisname), [AxisSplitArea](#axissplitarea), [AreaStyle](#areastyle), [ArrowStyle](#arrowstyle), [BaseLine](#baseline), [IconStyle](#iconstyle), [ImageStyle](#imagestyle), [ItemStyle](#itemstyle), [Level](#level), [LevelStyle](#levelstyle), [LineArrow](#linearrow), [LineStyle](#linestyle), [Location](#location), [MLValue](#mlvalue), [MarqueeStyle](#marqueestyle), [Padding](#padding), [StageColor](#stagecolor), [SymbolStyle](#symbolstyle), [TextLimit](#textlimit), [TextStyle](#textstyle), [CommentItem](#commentitem), [CommentMarkStyle](#commentmarkstyle), [LabelLine](#labelline), [LabelStyle](#labelstyle), [MarkAreaData](#markareadata), [MarkLineData](#marklinedata), [StateStyle](#statestyle), [VisualMapRange](#visualmaprange), [UIComponentTheme](#uicomponenttheme), [SerieData](#seriedata), [ComponentTheme](#componenttheme), [SerieTheme](#serietheme), [ThemeStyle](#themestyle) +> class in XCharts.Runtime / Subclasses: [AnimationStyle](#animationstyle), [AxisAnimation](#axisanimation), [AxisName](#axisname), [AxisSplitArea](#axissplitarea), [AreaStyle](#areastyle), [ArrowStyle](#arrowstyle), [BaseLine](#baseline), [IconStyle](#iconstyle), [ImageStyle](#imagestyle), [ItemStyle](#itemstyle), [Level](#level), [LevelStyle](#levelstyle), [LineArrow](#linearrow), [LineStyle](#linestyle), [Location](#location), [MLValue](#mlvalue), [MarqueeStyle](#marqueestyle), [Padding](#padding), [StageColor](#stagecolor), [SymbolStyle](#symbolstyle), [TextLimit](#textlimit), [TextStyle](#textstyle), [CommentItem](#commentitem), [CommentMarkStyle](#commentmarkstyle), [LabelLine](#labelline), [LabelStyle](#labelstyle), [MarkAreaData](#markareadata), [MarkLineData](#marklinedata), [StateStyle](#statestyle), [VisualMapRange](#visualmaprange), [UIComponentTheme](#uicomponenttheme), [SerieData](#seriedata), [SerieDataLink](#seriedatalink), [ComponentTheme](#componenttheme), [SerieTheme](#serietheme), [ThemeStyle](#themestyle) ## Comment @@ -1341,9 +1342,11 @@ Legend component.The legend component shows different sets of tags, colors, and |field|default|since|comment| |--|--|--|--| -|label|||文本标签样式。 [LabelStyle](#labelstyle)| -|upperLabel|||上方的文本标签样式。 [LabelStyle](#labelstyle)| -|itemStyle|||数据项样式。 [ItemStyle](#itemstyle)| +|depth|0|v3.10.0|the depth of level. +|label|||the label style of level. [LabelStyle](#labelstyle)| +|upperLabel|||the upper label style of level. [LabelStyle](#labelstyle)| +|lineStyle||v3.10.0|the line style of level. [LineStyle](#linestyle)| +|itemStyle|||the item style of level. [ItemStyle](#itemstyle)| ```mdx-code-block @@ -1353,6 +1356,8 @@ Legend component.The legend component shows different sets of tags, colors, and > class in XCharts.Runtime / Inherits from: [ChildComponent](#childcomponent) +> Since `v3.10.0` + ```mdx-code-block ``` @@ -1836,6 +1841,7 @@ Configurations of select state. |animation|||The start animation. [AnimationStyle](#animationstyle)| |itemStyle|||The style of data item. [ItemStyle](#itemstyle)| |data|||系列中的数据内容数组。SerieData可以设置1到n维数据。 +|links|||数据节点的边。 ```mdx-code-block @@ -1868,6 +1874,29 @@ A data item of serie. ``` +## SerieDataLink + +> class in XCharts.Runtime / Inherits from: [ChildComponent](#childcomponent) + +> Since `v3.10.0` + +the link of serie data. Used for sankey chart. Sankey chart only supports directed acyclic graph. make sure the data link is directed acyclic graph. + +```mdx-code-block + +``` + + +|field|default|since|comment| +|--|--|--|--| +|source|||the source node name. +|target|||the target node name. +|value|||the value of link. decide the width of link. + +```mdx-code-block + +``` + ## SerieSymbol > class in XCharts.Runtime / Inherits from: [SymbolStyle](#symbolstyle), [ISerieDataComponent](#iseriedatacomponent) diff --git a/Documentation~/zh/api.md b/Documentation~/zh/api.md index 1e41b181..f77cf17c 100644 --- a/Documentation~/zh/api.md +++ b/Documentation~/zh/api.md @@ -79,6 +79,9 @@ slug: /api - [EmphasisStyle](#emphasisstyle) - [EndLabelStyle](#endlabelstyle) - [FormatterHelper](#formatterhelper) +- [Graph](#graph) +- [GraphEdge](#graphedge) +- [GraphNode](#graphnode) - [GridCoord](#gridcoord) - [GridCoordContext](#gridcoordcontext) - [GridLayout](#gridlayout) @@ -169,6 +172,7 @@ slug: /api - [SerieDataComponentAttribute](#seriedatacomponentattribute) - [SerieDataContext](#seriedatacontext) - [SerieDataExtraFieldAttribute](#seriedataextrafieldattribute) +- [SerieDataLink](#seriedatalink) - [SerieEventData](#serieeventdata) - [SerieEventDataPool](#serieeventdatapool) - [SerieHandler](#seriehandler) @@ -689,6 +693,7 @@ slug: /api |AddData()||public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到指定系列中。 | |AddData()||public SerieData AddData(string serieName, List<double> multidimensionalData, string dataName = null, string dataId = null)
添加多维数据(x,y,z...)到指定的系列中。 | |AddData()||public SerieData AddData(string serieName, params double[] multidimensionalData)
添加多维数据(x,y,z...)到指定的系列中。 | +|AddLink()||public SerieDataLink AddLink(int serieIndex, string sourceName, string targetName, double value)
添加一个关系图的关系数据。 | |AddSerie<T>()||public T AddSerie<T>(string serieName = null, bool show = true, bool addToHead = false) where T : Serie| |AddXAxisData()||public void AddXAxisData(string category, int xAxisIndex = 0)
添加一个类目数据到指定的x轴。 | |AddXAxisIcon()||public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0)
添加一个图标到指定的x轴。 | @@ -707,9 +712,10 @@ slug: /api |CanMultipleComponent()||public bool CanMultipleComponent(Type type)| |ClampInChart()||public void ClampInChart(ref Vector3 pos)| |ClampInGrid()||public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)| -|ClearComponentData()||public virtual void ClearComponentData()
清空所有组件的数据。 | +|ClearComponentData()|v3.4.0|public virtual void ClearComponentData()
清空所有组件的数据。 | |ClearData()||public virtual void ClearData()
清空所有组件和Serie的数据。注意:Serie只是清空数据,不会移除Serie。 | -|ClearSerieData()||public virtual void ClearSerieData()
清空所有serie的数据。 | +|ClearSerieData()|v3.4.0|public virtual void ClearSerieData()
清空所有serie的数据。 | +|ClearSerieLinks()|v3.10.0|public virtual void ClearSerieLinks()
清空所有serie的link数据。 | |ClickLegendButton()||public void ClickLegendButton(int legendIndex, string legendName, bool show)
点击图例按钮 | |ConvertSerie()||public bool ConvertSerie(Serie serie, Type type)| |ConvertSerie<T>()||public bool ConvertSerie<T>(Serie serie) where T : Serie| @@ -733,7 +739,7 @@ slug: /api |GetItemColor()||public Color32 GetItemColor(Serie serie, SerieData serieData, int colorIndex)| |GetLegendRealShowNameColor()||public Color32 GetLegendRealShowNameColor(string name)| |GetLegendRealShowNameIndex()||public int GetLegendRealShowNameIndex(string name)| -|GetMarkColor()||public Color32 GetMarkColor(Serie serie, SerieData serieData)
获得Serie的标识颜色。 | +|GetMarkColor()|v3.4.0|public Color32 GetMarkColor(Serie serie, SerieData serieData)
获得Serie的标识颜色。 | |GetOrAddChartComponent<T>()||public T GetOrAddChartComponent<T>() where T : MainComponent| |GetPainter()||public Painter GetPainter(int index)| |GetSerie()||public Serie GetSerie(int serieIndex)| @@ -809,6 +815,7 @@ slug: /api |RemoveSerie()||public void RemoveSerie(string serieName)| |RemoveSerie<T>()||public void RemoveSerie<T>() where T : Serie| |ReplaceSerie()||public bool ReplaceSerie(Serie oldSerie, Serie newSerie)| +|ResetChartStatus()|v3.10.0|public void ResetChartStatus()
重置图表状态。当设置某些参数后,由于动画影响,可能导致图表状态不正确,此时可以调用该接口重置图表状态。 | |ResetDataIndex()||public bool ResetDataIndex(int serieIndex)
重置serie的数据项索引。避免数据项索引异常。 | |SetBasePainterMaterial()||public void SetBasePainterMaterial(Material material)
设置Base Painter的材质球 | |SetMaxCache()||public void SetMaxCache(int maxCache)
设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 | @@ -1129,7 +1136,7 @@ slug: /api ## ChildComponent -> class in XCharts.Runtime / 子类: [AnimationStyle](#animationstyle),[AxisAnimation](#axisanimation),[AxisName](#axisname),[AxisSplitArea](#axissplitarea),[AreaStyle](#areastyle),[ArrowStyle](#arrowstyle),[BaseLine](#baseline),[IconStyle](#iconstyle),[ImageStyle](#imagestyle),[ItemStyle](#itemstyle),[Level](#level),[LevelStyle](#levelstyle),[LineArrow](#linearrow),[LineStyle](#linestyle),[Location](#location),[MLValue](#mlvalue),[MarqueeStyle](#marqueestyle),[Padding](#padding),[StageColor](#stagecolor),[SymbolStyle](#symbolstyle),[TextLimit](#textlimit),[TextStyle](#textstyle),[CommentItem](#commentitem),[CommentMarkStyle](#commentmarkstyle),[LabelLine](#labelline),[LabelStyle](#labelstyle),[MarkAreaData](#markareadata),[MarkLineData](#marklinedata),[StateStyle](#statestyle),[VisualMapRange](#visualmaprange),[UIComponentTheme](#uicomponenttheme),[SerieData](#seriedata),[ComponentTheme](#componenttheme),[SerieTheme](#serietheme),[ThemeStyle](#themestyle) +> class in XCharts.Runtime / 子类: [AnimationStyle](#animationstyle),[AxisAnimation](#axisanimation),[AxisName](#axisname),[AxisSplitArea](#axissplitarea),[AreaStyle](#areastyle),[ArrowStyle](#arrowstyle),[BaseLine](#baseline),[IconStyle](#iconstyle),[ImageStyle](#imagestyle),[ItemStyle](#itemstyle),[Level](#level),[LevelStyle](#levelstyle),[LineArrow](#linearrow),[LineStyle](#linestyle),[Location](#location),[MLValue](#mlvalue),[MarqueeStyle](#marqueestyle),[Padding](#padding),[StageColor](#stagecolor),[SymbolStyle](#symbolstyle),[TextLimit](#textlimit),[TextStyle](#textstyle),[CommentItem](#commentitem),[CommentMarkStyle](#commentmarkstyle),[LabelLine](#labelline),[LabelStyle](#labelstyle),[MarkAreaData](#markareadata),[MarkLineData](#marklinedata),[StateStyle](#statestyle),[VisualMapRange](#visualmaprange),[UIComponentTheme](#uicomponenttheme),[SerieData](#seriedata),[SerieDataLink](#seriedatalink),[ComponentTheme](#componenttheme),[SerieTheme](#serietheme),[ThemeStyle](#themestyle) |API|版本|描述| @@ -1369,6 +1376,53 @@ DataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息 |TrimAndReplaceLine()||public static string TrimAndReplaceLine(string content)| |TrimAndReplaceLine()||public static string TrimAndReplaceLine(StringBuilder sb)| +## Graph + +> class in XCharts.Runtime + +数据结构-图。 + +|API|版本|描述| +|--|--|--| +|AddEdge()||public GraphEdge AddEdge(string nodeId1, string nodeId2, double value)| +|AddNode()||public GraphNode AddNode(string nodeId, string nodeName, int dataIndex)| +|BreadthFirstTraverse()||public void BreadthFirstTraverse(GraphNode startNode, System.Action<GraphNode> onTraverse)| +|Clear()||public void Clear()| +|DeepFirstTraverse()||public void DeepFirstTraverse(GraphNode startNode, System.Action<GraphNode> onTraverse)| +|EachNode()||public void EachNode(System.Action<GraphNode> onEach)| +|GetDepthNodes()||public List<List<GraphNode>> GetDepthNodes()| +|GetEdge()||public GraphEdge GetEdge(string nodeId1, string nodeId2)| +|GetMaxDepth()||public int GetMaxDepth()| +|GetNode()||public GraphNode GetNode(string nodeId)| +|GetNodeDepth()||// public int GetNodeDepth(GraphNode node)| +|GetNodeDepth()||// public void GetNodeDepth(GraphNode node, ref int depth, int recursiveCount = 0)| +|GetNodeDepth()||public int GetNodeDepth(GraphNode node, int recursiveCount = 0)| +|GetNodesTotalValue()||public static double GetNodesTotalValue(List<GraphNode> nodes)| +|GetRootNodes()||public List<GraphNode> GetRootNodes()| +|Graph()||public Graph(bool directed)| +|Refresh()||public void Refresh()| + +## GraphEdge + +> class in XCharts.Runtime + +图的边。 + +|API|版本|描述| +|--|--|--| +|GraphEdge()||public GraphEdge(GraphNode node1, GraphNode node2, double value)| + +## GraphNode + +> class in XCharts.Runtime + +图的节点。 + +|API|版本|描述| +|--|--|--| +|GraphNode()||public GraphNode(string id, string name, int dataIndex)| +|ToString()||public override string ToString()| + ## GridCoord > class in XCharts.Runtime / 继承自: [CoordSystem](#coordsystem),[IUpdateRuntimeData](#iupdateruntimedata),[ISerieContainer](#iseriecontainer) @@ -1735,6 +1789,8 @@ Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart > class in XCharts.Runtime / 继承自: [ChildComponent](#childcomponent) +> 从 `v3.10.0` 开始支持 + ## Line @@ -2242,6 +2298,7 @@ Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适 |AddData()||public SerieData AddData(List<double> valueList, string dataName = null, string dataId = null)
将一组数据添加到系列中。 如果数据只有一个,默认添加到维度Y中。 | |AddData()||public SerieData AddData(params double[] values)
添加任意维数据到系列中。 | |AddExtraComponent<T>()||public T AddExtraComponent<T>() where T : ChildComponent, ISerieComponent| +|AddLink()||public SerieDataLink AddLink(string sourceName, string targetName, double value)
添加一个关系图的关系数据。 | |AddSerieData()||public void AddSerieData(SerieData serieData)| |AddXYData()||public SerieData AddXYData(double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到维度X和维度Y | |AddYData()||public SerieData AddYData(double value, string dataName = null, string dataId = null)
添加一个数据到维度Y(此时维度X对应的数据是索引) | @@ -2258,6 +2315,7 @@ Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适 |ClearData()||public override void ClearData()
清空所有数据 | |ClearDirty()||public override void ClearDirty()| |ClearHighlight()||public void ClearHighlight()
清除所有数据的高亮标志 | +|ClearLinks()||public void ClearLinks()
清空所有Link数据 | |ClearSerieNameDirty()||public void ClearSerieNameDirty()| |ClearVerticesDirty()||public override void ClearVerticesDirty()| |Clone()||public Serie Clone()| @@ -2435,6 +2493,14 @@ Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适 |SerieDataExtraFieldAttribute()||public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5, string field6)| |SerieDataExtraFieldAttribute()||public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5, string field6, string field7)| +## SerieDataLink + +> class in XCharts.Runtime / 继承自: [ChildComponent](#childcomponent) + +> 从 `v3.10.0` 开始支持 + +数据节点之间的连线。可用于桑基图等,桑基图只支持有向无环图,请保证数据的连线是有向无环图。 + ## SerieEventData > class in XCharts.Runtime @@ -2472,6 +2538,7 @@ serie事件的数据。 |ForceUpdateSerieContext()||public virtual void ForceUpdateSerieContext() { }| |InitComponent()||public virtual void InitComponent() { }| |OnBeginDrag()||public virtual void OnBeginDrag(PointerEventData eventData) { }| +|OnDataUpdate()||public virtual void OnDataUpdate() { }| |OnDrag()||public virtual void OnDrag(PointerEventData eventData) { }| |OnEndDrag()||public virtual void OnEndDrag(PointerEventData eventData) { }| |OnLegendButtonClick()||public virtual void OnLegendButtonClick(int index, string legendName, bool show) { }| diff --git a/Documentation~/zh/changelog.md b/Documentation~/zh/changelog.md index 9de840a6..545b770b 100644 --- a/Documentation~/zh/changelog.md +++ b/Documentation~/zh/changelog.md @@ -70,6 +70,8 @@ slug: /changelog ## master +* (2023.12.09) 增加`LevelStyle`的`LineStyle`和`depth`支持 +* (2023.12.09) 增加`Serie`的`Link`可用于桑基图添加节点边关系 * (2023.12.05) 增加`ResetChartStatus()`可主动重置图表状态 ## v3.9.0 diff --git a/Documentation~/zh/configuration.md b/Documentation~/zh/configuration.md index a8e29b40..b9ed2f37 100644 --- a/Documentation~/zh/configuration.md +++ b/Documentation~/zh/configuration.md @@ -121,6 +121,7 @@ import APITable from '@site/src/components/APITable'; - [RadiusAxisTheme](#radiusaxistheme) - [SelectStyle](#selectstyle) - [SerieData](#seriedata) +- [SerieDataLink](#seriedatalink) - [SerieSymbol](#seriesymbol) - [SerieTheme](#serietheme) - [StageColor](#stagecolor) @@ -725,7 +726,7 @@ import APITable from '@site/src/components/APITable'; ## ChildComponent -> class in XCharts.Runtime / 子类: [AnimationStyle](#animationstyle), [AxisAnimation](#axisanimation), [AxisName](#axisname), [AxisSplitArea](#axissplitarea), [AreaStyle](#areastyle), [ArrowStyle](#arrowstyle), [BaseLine](#baseline), [IconStyle](#iconstyle), [ImageStyle](#imagestyle), [ItemStyle](#itemstyle), [Level](#level), [LevelStyle](#levelstyle), [LineArrow](#linearrow), [LineStyle](#linestyle), [Location](#location), [MLValue](#mlvalue), [MarqueeStyle](#marqueestyle), [Padding](#padding), [StageColor](#stagecolor), [SymbolStyle](#symbolstyle), [TextLimit](#textlimit), [TextStyle](#textstyle), [CommentItem](#commentitem), [CommentMarkStyle](#commentmarkstyle), [LabelLine](#labelline), [LabelStyle](#labelstyle), [MarkAreaData](#markareadata), [MarkLineData](#marklinedata), [StateStyle](#statestyle), [VisualMapRange](#visualmaprange), [UIComponentTheme](#uicomponenttheme), [SerieData](#seriedata), [ComponentTheme](#componenttheme), [SerieTheme](#serietheme), [ThemeStyle](#themestyle) +> class in XCharts.Runtime / 子类: [AnimationStyle](#animationstyle), [AxisAnimation](#axisanimation), [AxisName](#axisname), [AxisSplitArea](#axissplitarea), [AreaStyle](#areastyle), [ArrowStyle](#arrowstyle), [BaseLine](#baseline), [IconStyle](#iconstyle), [ImageStyle](#imagestyle), [ItemStyle](#itemstyle), [Level](#level), [LevelStyle](#levelstyle), [LineArrow](#linearrow), [LineStyle](#linestyle), [Location](#location), [MLValue](#mlvalue), [MarqueeStyle](#marqueestyle), [Padding](#padding), [StageColor](#stagecolor), [SymbolStyle](#symbolstyle), [TextLimit](#textlimit), [TextStyle](#textstyle), [CommentItem](#commentitem), [CommentMarkStyle](#commentmarkstyle), [LabelLine](#labelline), [LabelStyle](#labelstyle), [MarkAreaData](#markareadata), [MarkLineData](#marklinedata), [StateStyle](#statestyle), [VisualMapRange](#visualmaprange), [UIComponentTheme](#uicomponenttheme), [SerieData](#seriedata), [SerieDataLink](#seriedatalink), [ComponentTheme](#componenttheme), [SerieTheme](#serietheme), [ThemeStyle](#themestyle) ## Comment @@ -1302,8 +1303,10 @@ Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart |参数|默认|版本|描述| |--|--|--|--| +|depth|0|v3.10.0|层级深度。 |label|||文本标签样式。 [LabelStyle](#labelstyle)| |upperLabel|||上方的文本标签样式。 [LabelStyle](#labelstyle)| +|lineStyle||v3.10.0|线条样式。 [LineStyle](#linestyle)| |itemStyle|||数据项样式。 [ItemStyle](#itemstyle)| ```mdx-code-block @@ -1314,6 +1317,8 @@ Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart > class in XCharts.Runtime / 继承自: [ChildComponent](#childcomponent) +> 从 `v3.10.0` 开始支持 + ```mdx-code-block ``` @@ -1781,6 +1786,7 @@ Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适 |animation|||起始动画。 [AnimationStyle](#animationstyle)| |itemStyle|||图形样式。 [ItemStyle](#itemstyle)| |data|||系列中的数据内容数组。SerieData可以设置1到n维数据。 +|links|||数据节点的边。 ```mdx-code-block @@ -1812,6 +1818,28 @@ Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适 ``` +## SerieDataLink + +> class in XCharts.Runtime / 继承自: [ChildComponent](#childcomponent) + +> 从 `v3.10.0` 开始支持 + +数据节点之间的连线。可用于桑基图等,桑基图只支持有向无环图,请保证数据的连线是有向无环图。 + +```mdx-code-block + +``` + +|参数|默认|版本|描述| +|--|--|--|--| +|source|||边的源节点名称。 +|target|||边的目标节点名称。 +|value|||边的值。决定边的宽度。 + +```mdx-code-block + +``` + ## SerieSymbol > class in XCharts.Runtime / 继承自: [SymbolStyle](#symbolstyle), [ISerieDataComponent](#iseriedatacomponent) diff --git a/Editor/ChildComponents/LevelStyleDrawer.cs b/Editor/ChildComponents/LevelStyleDrawer.cs index 8879a5e7..07833d95 100644 --- a/Editor/ChildComponents/LevelStyleDrawer.cs +++ b/Editor/ChildComponents/LevelStyleDrawer.cs @@ -27,11 +27,16 @@ namespace XCharts.Editor public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) { base.OnGUI(pos, prop, label); - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Label"); - PropertyField(prop, "m_UpperLabel"); - PropertyField(prop, "m_ItemStyle"); - --EditorGUI.indentLevel; + if (MakeComponentFoldout(prop, "m_Depth", true)) + { + ++EditorGUI.indentLevel; + PropertyField(prop, "m_Depth"); + PropertyField(prop, "m_Label"); + PropertyField(prop, "m_UpperLabel"); + PropertyField(prop, "m_LineStyle"); + PropertyField(prop, "m_ItemStyle"); + --EditorGUI.indentLevel; + } } } } \ No newline at end of file diff --git a/Editor/MainComponents/AxisEditor.cs b/Editor/MainComponents/AxisEditor.cs index eb6978e5..2a1d6e8e 100644 --- a/Editor/MainComponents/AxisEditor.cs +++ b/Editor/MainComponents/AxisEditor.cs @@ -92,7 +92,7 @@ namespace XCharts.Editor { PropertyListField("m_Data", true, new HeaderMenuInfo("Import ECharts Axis Data", () => { - PraseExternalDataEditor.UpdateData(chart, null, component as Axis); + PraseExternalDataEditor.UpdateData(chart, null, component as Axis, false); PraseExternalDataEditor.ShowWindow(); })); } diff --git a/Editor/Series/SerieDataLinkDrawer.cs b/Editor/Series/SerieDataLinkDrawer.cs new file mode 100644 index 00000000..5b629558 --- /dev/null +++ b/Editor/Series/SerieDataLinkDrawer.cs @@ -0,0 +1,24 @@ +using UnityEditor; +using UnityEngine; +using XCharts.Runtime; + +namespace XCharts.Editor +{ + [CustomPropertyDrawer(typeof(SerieDataLink), true)] + public class SerieDataLinkDrawer : BasePropertyDrawer + { + public override string ClassName { get { return "Link"; } } + public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) + { + base.OnGUI(pos, prop, label); + if (MakeComponentFoldout(prop, "", true)) + { + ++EditorGUI.indentLevel; + PropertyField(prop, "m_Source"); + PropertyField(prop, "m_Target"); + PropertyField(prop, "m_Value"); + --EditorGUI.indentLevel; + } + } + } +} \ No newline at end of file diff --git a/Editor/Series/SerieDataLinkDrawer.cs.meta b/Editor/Series/SerieDataLinkDrawer.cs.meta new file mode 100644 index 00000000..3c8a0ce3 --- /dev/null +++ b/Editor/Series/SerieDataLinkDrawer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 877ff0f4c473d47f29e7e7e3a3eaf53b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/Series/SerieEditor.cs b/Editor/Series/SerieEditor.cs index e251d810..6f3d330d 100644 --- a/Editor/Series/SerieEditor.cs +++ b/Editor/Series/SerieEditor.cs @@ -12,6 +12,8 @@ namespace XCharts.Editor private bool m_DataFoldout = false; private bool m_DataComponentFoldout = true; private Dictionary m_DataElementFoldout = new Dictionary(); + private bool m_LinksFoldout = false; + private Dictionary m_LinksElementFoldout = new Dictionary(); public override void OnInspectorGUI() { @@ -31,12 +33,16 @@ namespace XCharts.Editor OnCustomInspectorGUI(); OnExtraInspectorGUI(); PropertyFieldData(); + OnEndCustomInspectorGUI(); --EditorGUI.indentLevel; } public virtual void OnCustomInspectorGUI() { } + public virtual void OnEndCustomInspectorGUI() + { } + private void OnExtraInspectorGUI() { foreach (var kv in Serie.extraComponentMap) @@ -52,7 +58,7 @@ namespace XCharts.Editor m_DataFoldout = ChartEditorHelper.DrawHeader("Data", m_DataFoldout, false, null, null, new HeaderMenuInfo("Import ECharts Data", () => { - PraseExternalDataEditor.UpdateData(chart, serie, null); + PraseExternalDataEditor.UpdateData(chart, serie, null, false); PraseExternalDataEditor.ShowWindow(); })); if (!m_DataFoldout) return; @@ -97,6 +103,48 @@ namespace XCharts.Editor EditorGUI.indentLevel--; } + protected void PropertyFieldLinks() + { + m_LinksFoldout = ChartEditorHelper.DrawHeader("Links", m_LinksFoldout, false, null, null, + new HeaderMenuInfo("Import ECharts Link", () => + { + //PraseExternalDataEditor.UpdateData(chart, serie, null, true); + //PraseExternalDataEditor.ShowWindow(); + })); + if (!m_LinksFoldout) return; + EditorGUI.indentLevel++; + var m_Links = FindProperty("m_Links"); + var listSize = m_Links.arraySize; + listSize = EditorGUILayout.IntField("Size", listSize); + if (listSize < 0) listSize = 0; + if (listSize != m_Links.arraySize) + { + while (listSize > m_Links.arraySize) m_Links.arraySize++; + while (listSize < m_Links.arraySize) m_Links.arraySize--; + } + if (listSize > 30) // && !XCSettings.editorShowAllListData) + { + int num = listSize > 10 ? 10 : listSize; + for (int i = 0; i < num; i++) + { + DrawSerieDataLink(m_Links, i); + } + if (num >= 10) + { + ChartEditorHelper.DrawHeader("... ", false, false, null, null); + DrawSerieDataLink(m_Links, listSize - 1); + } + } + else + { + for (int i = 0; i < m_Links.arraySize; i++) + { + DrawSerieDataLink(m_Links, i); + } + } + EditorGUI.indentLevel--; + } + protected void PropertyFiledMore(System.Action action) { m_MoreFoldout = ChartEditorHelper.DrawHeader(MORE, m_MoreFoldout, false, null, null); @@ -118,7 +166,7 @@ namespace XCharts.Editor var serieData = m_Datas.GetArrayElementAtIndex(index); var dataIndex = serieData.FindPropertyRelative("m_Index").intValue; m_DataElementFoldout[index] = ChartEditorHelper.DrawHeader("SerieData " + dataIndex, flag, false, null, - delegate(Rect drawRect) + delegate (Rect drawRect) { //drawRect.width -= 2f; var maxX = drawRect.xMax; @@ -242,5 +290,38 @@ namespace XCharts.Editor } EditorGUI.indentLevel--; } + + private void DrawSerieDataLink(SerializedProperty m_Datas, int index) + { + bool flag; + if (!m_LinksElementFoldout.TryGetValue(index, out flag)) + { + flag = false; + m_LinksElementFoldout[index] = false; + } + var dataLink = m_Datas.GetArrayElementAtIndex(index); + m_LinksElementFoldout[index] = ChartEditorHelper.DrawHeader("Link " + index, flag, false, null, + delegate (Rect drawRect) + { + var sourceIndex = dataLink.FindPropertyRelative("m_Source"); + var targetIndex = dataLink.FindPropertyRelative("m_Target"); + var value = dataLink.FindPropertyRelative("m_Value"); + ChartEditorHelper.MakeThreeField(ref drawRect, drawRect.width, sourceIndex, targetIndex, value, ""); + }); + if (m_LinksElementFoldout[index]) + { + DrawSerieDataLinkDetail(m_Datas, index); + } + } + + private void DrawSerieDataLinkDetail(SerializedProperty m_Links, int index) + { + EditorGUI.indentLevel++; + var dataLink = m_Links.GetArrayElementAtIndex(index); + PropertyField(dataLink.FindPropertyRelative("m_Source")); + PropertyField(dataLink.FindPropertyRelative("m_Target")); + PropertyField(dataLink.FindPropertyRelative("m_Value")); + EditorGUI.indentLevel--; + } } } \ No newline at end of file diff --git a/Editor/Utilities/ChartEditorHelper.cs b/Editor/Utilities/ChartEditorHelper.cs index 3d59a66b..b1fcc618 100644 --- a/Editor/Utilities/ChartEditorHelper.cs +++ b/Editor/Utilities/ChartEditorHelper.cs @@ -106,6 +106,23 @@ namespace XCharts.Editor drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; } + public static void MakeThreeField(ref Rect drawRect, float rectWidth, SerializedProperty prop1, + SerializedProperty prop2, SerializedProperty prop3, string name) + { + EditorGUI.LabelField(drawRect, name); + var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; + var diff = 13 + EditorGUI.indentLevel * 14; + var offset = diff - INDENT_WIDTH; + var tempWidth = (rectWidth - startX + diff) / 3; + var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height - 1); + var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth - 1, drawRect.height - 1); + var centerZRect = new Rect(centerYRect.x + tempWidth - offset, drawRect.y, tempWidth - 1, drawRect.height - 1); + EditorGUI.PropertyField(centerXRect, prop1, GUIContent.none); + EditorGUI.PropertyField(centerYRect, prop2, GUIContent.none); + EditorGUI.PropertyField(centerZRect, prop3, GUIContent.none); + drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; + } + public static void MakeVector2(ref Rect drawRect, float rectWidth, SerializedProperty prop, string name) { EditorGUI.LabelField(drawRect, name); diff --git a/Editor/Windows/PraseExternalDataEditor.cs b/Editor/Windows/PraseExternalDataEditor.cs index 2e7667a8..52b85f6f 100644 --- a/Editor/Windows/PraseExternalDataEditor.cs +++ b/Editor/Windows/PraseExternalDataEditor.cs @@ -11,6 +11,7 @@ namespace XCharts.Editor private static BaseChart s_Chart; private static Serie s_Serie; private static Axis s_Axis; + private static bool s_LinksData; private static PraseExternalDataEditor window; private static string inputJsonText = ""; @@ -23,11 +24,12 @@ namespace XCharts.Editor window.Show(); } - public static void UpdateData(BaseChart chart, Serie serie, Axis axis) + public static void UpdateData(BaseChart chart, Serie serie, Axis axis, bool linksData) { s_Chart = chart; s_Serie = serie; s_Axis = axis; + s_LinksData = linksData; inputJsonText = UnityEngine.GUIUtility.systemCopyBuffer; } @@ -97,7 +99,8 @@ namespace XCharts.Editor { arrayData = arrayData.Trim(); if (!arrayData.StartsWith("data: Array")) return false; - serie.ClearData(); + if (s_LinksData) serie.ClearLinks(); + else serie.ClearData(); var list = arrayData.Split('\n'); for (int i = 1; i < list.Length; i++) { @@ -140,7 +143,8 @@ namespace XCharts.Editor private static bool ParseJsonData(Serie serie, string jsonData) { if (!CheckJsonData(ref jsonData)) return false; - serie.ClearData(); + if (s_LinksData) serie.ClearLinks(); + else serie.ClearData(); if (jsonData.IndexOf("],") > -1 || jsonData.IndexOf("] ,") > -1) { string[] datas = jsonData.Split(new string[] { "],", "] ," }, StringSplitOptions.RemoveEmptyEntries); diff --git a/Runtime/Component/Child/LevelStyle.cs b/Runtime/Component/Child/LevelStyle.cs index cdca2419..3bb64cd0 100644 --- a/Runtime/Component/Child/LevelStyle.cs +++ b/Runtime/Component/Child/LevelStyle.cs @@ -6,19 +6,35 @@ namespace XCharts.Runtime [System.Serializable] public class Level : ChildComponent { + [SerializeField][Since("v3.10.0")] private int m_Depth = 0; [SerializeField] private LabelStyle m_Label = new LabelStyle(); [SerializeField] private LabelStyle m_UpperLabel = new LabelStyle(); + [SerializeField][Since("v3.10.0")] private LineStyle m_LineStyle = new LineStyle(); [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); + /// - /// 文本标签样式。 + /// the depth of level. + /// ||层级深度。 + /// + public int depth { get { return m_Depth; } set { m_Depth = value; } } + /// + /// the label style of level. + /// ||文本标签样式。 /// public LabelStyle label { get { return m_Label; } } /// - /// 上方的文本标签样式。 + /// the upper label style of level. + /// ||上方的文本标签样式。 /// public LabelStyle upperLabel { get { return m_UpperLabel; } } /// - /// 数据项样式。 + /// the line style of level. + /// ||线条样式。 + /// + public LineStyle lineStyle { get { return m_LineStyle; } } + /// + /// the item style of level. + /// ||数据项样式。 /// public ItemStyle itemStyle { get { return m_ItemStyle; } } } diff --git a/Runtime/Internal/BaseChart.API.cs b/Runtime/Internal/BaseChart.API.cs index 233a7bfb..e799dbd4 100644 --- a/Runtime/Internal/BaseChart.API.cs +++ b/Runtime/Internal/BaseChart.API.cs @@ -222,14 +222,15 @@ namespace XCharts.Runtime public virtual void ClearData() { ClearSerieData(); + ClearSerieLinks(); ClearComponentData(); } - [Since("v3.4.0")] /// /// Clear the data of all series. /// ||清空所有serie的数据。 /// + [Since("v3.4.0")] public virtual void ClearSerieData() { foreach (var serie in m_Series) @@ -238,11 +239,24 @@ namespace XCharts.Runtime RefreshChart(); } - [Since("v3.4.0")] + /// + /// Clear the link data of all series. + /// ||清空所有serie的link数据。 + /// + [Since("v3.10.0")] + public virtual void ClearSerieLinks() + { + foreach (var serie in m_Series) + serie.ClearLinks(); + m_CheckAnimation = false; + RefreshChart(); + } + /// /// Clear the data of all components. /// ||清空所有组件的数据。 /// + [Since("v3.4.0")] public virtual void ClearComponentData() { foreach (var component in m_Components) @@ -625,13 +639,13 @@ namespace XCharts.Runtime return theme.GetBackgroundColor(background); } - [Since("v3.4.0")] /// /// 获得Serie的标识颜色。 /// /// /// /// + [Since("v3.4.0")] public Color32 GetMarkColor(Serie serie, SerieData serieData) { var itemStyle = SerieHelper.GetItemStyle(serie, serieData); diff --git a/Runtime/Internal/BaseChart.Serie.cs b/Runtime/Internal/BaseChart.Serie.cs index 26aaa113..e402ee4d 100644 --- a/Runtime/Internal/BaseChart.Serie.cs +++ b/Runtime/Internal/BaseChart.Serie.cs @@ -442,6 +442,27 @@ namespace XCharts.Runtime return null; } + /// + /// Add a link data to serie. + /// ||添加一个关系图的关系数据。 + /// + /// the index of serie + /// the source name of link + /// the target name of link + /// the value of link + /// + public SerieDataLink AddLink(int serieIndex, string sourceName, string targetName, double value) + { + var serie = GetSerie(serieIndex); + if (serie != null) + { + var link = serie.AddLink(sourceName, targetName, value); + RefreshPainter(serie.painter); + return link; + } + return null; + } + /// /// Update serie data by serie name. /// ||更新指定系列中的指定索引数据。 diff --git a/Runtime/Internal/Data.meta b/Runtime/Internal/Data.meta new file mode 100644 index 00000000..27158379 --- /dev/null +++ b/Runtime/Internal/Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fcb8d4f1ad56b432f8a8eae9fa5941b3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Internal/Data/Graph.cs b/Runtime/Internal/Data/Graph.cs new file mode 100644 index 00000000..a0ff595d --- /dev/null +++ b/Runtime/Internal/Data/Graph.cs @@ -0,0 +1,412 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace XCharts.Runtime +{ + /// + /// the data struct of graph. + /// ||数据结构-图。 + /// + public class Graph + { + public bool directed; + public List nodes = new List(); + public List edges = new List(); + + public Dictionary nodeMap = new Dictionary(); + public Dictionary edgeMap = new Dictionary(); + + public Graph(bool directed) + { + this.directed = directed; + } + + public void Clear() + { + nodes.Clear(); + edges.Clear(); + nodeMap.Clear(); + edgeMap.Clear(); + } + + public void Refresh() + { + foreach (var node in nodes) + { + node.depth = GetNodeDepth(node); + } + } + + public static double GetNodesTotalValue(List nodes) + { + double totalValue = 0; + foreach (var node in nodes) + { + totalValue += node.totalValues; + } + return totalValue; + } + + public List> GetDepthNodes() + { + List> depthNodes = new List>(); + var maxDepth = GetMaxDepth(); + for (int i = 0; i <= maxDepth; i++) + { + depthNodes.Add(new List()); + } + foreach (var node in nodes) + { + if (node.inDegree == 0) + { + depthNodes[0].Add(node); + } + else + { + int deep = GetNodeDepth(node); + depthNodes[maxDepth - deep].Add(node); + } + } + return depthNodes; + } + + public List GetRootNodes() + { + List rootNodes = new List(); + foreach (var node in nodes) + { + if (node.inDegree == 0) + { + rootNodes.Add(node); + } + } + return rootNodes; + } + + public int GetMaxDepth() + { + int maxDepth = 0; + foreach (var node in nodes) + { + int deep = GetNodeDepth(node); + if (deep > maxDepth) + { + maxDepth = deep; + } + } + return maxDepth; + } + + // public int GetNodeDepth(GraphNode node) + // { + // int depth = 0; + // GetNodeDepth(node, ref depth); + // return depth; + // } + + // public void GetNodeDepth(GraphNode node, ref int depth, int recursiveCount = 0) + // { + // if (recursiveCount > 50) + // { + // XLog.Error("Graph.GetNodeDeep(): recursiveCount > 50, maybe graph is ring"); + // return; + // } + // if (node.inDegree == 0) + // { + // return; + // } + // else + // { + // depth += 1; + // foreach (var edge in node.inEdges) + // { + // GetNodeDepth(edge.node1, ref depth, recursiveCount + 1); + // } + // } + // } + + public int GetNodeDepth(GraphNode node, int recursiveCount = 0) + { + if (recursiveCount > 50) + { + XLog.Error("Graph.GetNodeDeep(): recursiveCount > 50, maybe graph is ring"); + return 0; + } + int depth = 0; + if (node.outDegree == 0) + { + return depth; + } + else + { + foreach (var edge in node.outEdges) + { + int otherDeep = GetNodeDepth(edge.node2, recursiveCount + 1); + if (otherDeep > depth) + { + depth = otherDeep; + } + } + return depth + 1; + } + } + + + + public GraphNode GetNode(string nodeId) + { + if (nodeMap.ContainsKey(nodeId)) + { + return nodeMap[nodeId]; + } + else + { + return null; + } + } + + public GraphEdge GetEdge(string nodeId1, string nodeId2) + { + if (directed) + { + return edgeMap[nodeId1 + "_" + nodeId2]; + } + else + { + var key = nodeId1 + "_" + nodeId2; + if (edgeMap.ContainsKey(key)) + { + return edgeMap[key]; + } + else + { + key = nodeId2 + "_" + nodeId1; + if (edgeMap.ContainsKey(key)) + { + return edgeMap[key]; + } + else + { + return null; + } + } + } + } + + public GraphNode AddNode(string nodeId, string nodeName, int dataIndex) + { + if (nodeMap.ContainsKey(nodeId)) + { + return nodeMap[nodeId]; + } + else + { + GraphNode node = new GraphNode(nodeId, nodeName, dataIndex); + node.hostGraph = this; + nodeMap.Add(nodeId, node); + nodes.Add(node); + return node; + } + } + + public GraphEdge AddEdge(string nodeId1, string nodeId2, double value) + { + GraphNode node1, node2; + if (!nodeMap.TryGetValue(nodeId1, out node1)) + { + XLog.Warning("Graph.AddEdge(): " + nodeId1 + " not exist"); + return null; + } + if (!nodeMap.TryGetValue(nodeId2, out node2)) + { + XLog.Warning("Graph.AddEdge(): " + nodeId2 + " not exist"); + return null; + } + if (node1 == null) + { + XLog.Warning("Graph.AddEdge(): node1 is null"); + return null; + } + if (node2 == null) + { + XLog.Warning("Graph.AddEdge(): node2 is null"); + return null; + } + if (node1 == node2) + { + XLog.Warning("Graph.AddEdge(): node1 == node2"); + return null; + } + string edgeKey = nodeId1 + "_" + nodeId2; + if (edgeMap.ContainsKey(edgeKey)) + { + return edgeMap[edgeKey]; + } + else + { + GraphEdge edge = new GraphEdge(node1, node2, value); + edge.key = edgeKey; + edge.hostGraph = this; + + if (directed) + { + node1.outEdges.Add(edge); + node2.inEdges.Add(edge); + } + node1.edges.Add(edge); + if (node1 != node2) + { + node2.edges.Add(edge); + } + + edgeMap.Add(edgeKey, edge); + edges.Add(edge); + return edge; + } + } + + public void EachNode(System.Action onEach) + { + if (onEach == null) return; + foreach (var node in nodes) + { + onEach(node); + } + } + + public void BreadthFirstTraverse(GraphNode startNode, System.Action onTraverse) + { + if (startNode == null) return; + foreach (var node in nodes) + { + node.visited = false; + } + + onTraverse(startNode); + startNode.visited = true; + + Queue queue = new Queue(); + queue.Enqueue(startNode); + while (queue.Count > 0) + { + var currentNode = queue.Dequeue(); + foreach (var edge in currentNode.edges) + { + var otherNode = edge.node1 == currentNode ? edge.node2 : edge.node1; + if (!otherNode.visited) + { + onTraverse(otherNode); + otherNode.visited = true; + queue.Enqueue(otherNode); + } + } + } + } + + public void DeepFirstTraverse(GraphNode startNode, System.Action onTraverse) + { + if (startNode == null) return; + foreach (var node in nodes) + { + node.visited = false; + } + + Stack stack = new Stack(); + stack.Push(startNode); + while (stack.Count > 0) + { + var currentNode = stack.Pop(); + if (!currentNode.visited) + { + onTraverse(currentNode); + currentNode.visited = true; + } + foreach (var edge in currentNode.edges) + { + var otherNode = edge.node1 == currentNode ? edge.node2 : edge.node1; + if (!otherNode.visited) + { + stack.Push(otherNode); + } + } + } + } + } + + /// + /// The node of graph. + /// ||图的节点。 + /// + public class GraphNode + { + public string id; + public string name; + public List edges = new List(); + public List inEdges = new List(); + public List outEdges = new List(); + public Graph hostGraph; + public int dataIndex; + public bool visited; + public int depth = -1; + + public GraphNode(string id, string name, int dataIndex) + { + this.id = id; + this.name = name; + this.dataIndex = dataIndex; + } + + public int degree { get { return edges.Count; } } + + public int inDegree { get { return inEdges.Count; } } + + public int outDegree { get { return outEdges.Count; } } + + public double totalValues + { + get + { + double totalValue = 0; + if (inEdges.Count == 0) + { + foreach (var edge in outEdges) + { + totalValue += edge.value; + } + } + else + { + foreach (var edge in inEdges) + { + totalValue += edge.value; + } + } + return totalValue; + } + } + public override string ToString() + { + return name; + } + } + + /// + /// The edge of graph. + /// ||图的边。 + /// + public class GraphEdge + { + public string key; + public GraphNode node1; + public GraphNode node2; + public double value; + public Graph hostGraph; + + public GraphEdge(GraphNode node1, GraphNode node2, double value) + { + this.node1 = node1; + this.node2 = node2; + this.value = value; + } + } +} \ No newline at end of file diff --git a/Runtime/Internal/Data/Graph.cs.meta b/Runtime/Internal/Data/Graph.cs.meta new file mode 100644 index 00000000..67978019 --- /dev/null +++ b/Runtime/Internal/Data/Graph.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1d778205a63524227a09c7e5b0e8736f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Serie/Serie.cs b/Runtime/Serie/Serie.cs index c724c80a..a807c1c4 100644 --- a/Runtime/Serie/Serie.cs +++ b/Runtime/Serie/Serie.cs @@ -309,6 +309,7 @@ namespace XCharts.Runtime [SerializeField] private AnimationStyle m_Animation = new AnimationStyle(); [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); [SerializeField] private List m_Data = new List(); + [SerializeField] private List m_Links = new List(); [NonSerialized] internal int m_FilterStart; [NonSerialized] internal int m_FilterEnd; @@ -966,6 +967,10 @@ namespace XCharts.Runtime /// public List data { get { return m_Data; } } /// + /// 数据节点的边。 + /// + public List links { get { return m_Links; } } + /// /// 取色策略是否为按数据项分配。 /// public bool colorByData { get { return colorBy == SerieColorBy.Data; } } @@ -1271,6 +1276,15 @@ namespace XCharts.Runtime SetVerticesDirty(); } + /// + /// 清空所有Link数据 + /// + public void ClearLinks() + { + m_Links.Clear(); + SetVerticesDirty(); + } + /// /// 移除指定索引的数据 /// @@ -1504,6 +1518,26 @@ namespace XCharts.Runtime } } + /// + /// Add a link data. + /// ||添加一个关系图的关系数据。 + /// + /// + /// + /// + /// + public SerieDataLink AddLink(string sourceName, string targetName, double value) + { + var link = new SerieDataLink(); + link.source = sourceName; + link.target = targetName; + link.value = value; + m_Links.Add(link); + SetVerticesDirty(); + labelDirty = true; + return link; + } + private void CheckMaxCache() { if (m_MaxCache <= 0) return; diff --git a/Runtime/Serie/SerieDataContext.cs b/Runtime/Serie/SerieDataContext.cs index 2666950d..d8a7e114 100644 --- a/Runtime/Serie/SerieDataContext.cs +++ b/Runtime/Serie/SerieDataContext.cs @@ -69,6 +69,8 @@ namespace XCharts.Runtime } private bool m_Highligth; public bool selected; + public double inTotalValue; + public double outTotalValue; public void Reset() { diff --git a/Runtime/Serie/SerieDataLink.cs b/Runtime/Serie/SerieDataLink.cs new file mode 100644 index 00000000..9d8e650e --- /dev/null +++ b/Runtime/Serie/SerieDataLink.cs @@ -0,0 +1,47 @@ +using UnityEngine; + +namespace XCharts.Runtime +{ + /// + /// the link of serie data. Used for sankey chart. Sankey chart only supports directed acyclic graph. make sure the data link is directed acyclic graph. + /// ||数据节点之间的连线。可用于桑基图等,桑基图只支持有向无环图,请保证数据的连线是有向无环图。 + /// + [System.Serializable] + [Since("v3.10.0")] + public class SerieDataLink : ChildComponent + { + [SerializeField] private string m_Source; + [SerializeField] private string m_Target; + [SerializeField] private double m_Value; + + /// + /// the source node name. + /// ||边的源节点名称。 + /// + public string source + { + get { return m_Source; } + set { m_Source = value; } + } + + /// + /// the target node name. + /// ||边的目标节点名称。 + /// + public string target + { + get { return m_Target; } + set { m_Target = value; } + } + + /// + /// the value of link. decide the width of link. + /// ||边的值。决定边的宽度。 + /// + public double value + { + get { return m_Value; } + set { m_Value = value; } + } + } +} \ No newline at end of file diff --git a/Runtime/Serie/SerieDataLink.cs.meta b/Runtime/Serie/SerieDataLink.cs.meta new file mode 100644 index 00000000..0940800c --- /dev/null +++ b/Runtime/Serie/SerieDataLink.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7402f12ebc4aa4421939efecae53624d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Serie/SerieHandler.cs b/Runtime/Serie/SerieHandler.cs index fb1e94f7..8f91d196 100644 --- a/Runtime/Serie/SerieHandler.cs +++ b/Runtime/Serie/SerieHandler.cs @@ -31,6 +31,7 @@ namespace XCharts.Runtime public virtual void OnBeginDrag(PointerEventData eventData) { } public virtual void OnEndDrag(PointerEventData eventData) { } public virtual void OnScroll(PointerEventData eventData) { } + public virtual void OnDataUpdate() { } public virtual void RefreshLabelNextFrame() { } public virtual void RefreshLabelInternal() { } public virtual void ForceUpdateSerieContext() { } @@ -38,7 +39,8 @@ namespace XCharts.Runtime public virtual void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, string marker, string itemFormatter, string numericFormatter, string ignoreDataDefaultContent, - ref List paramList, ref string title) { } + ref List paramList, ref string title) + { } public virtual void OnLegendButtonClick(int index, string legendName, bool show) { } public virtual void OnLegendButtonEnter(int index, string legendName) { } public virtual void OnLegendButtonExit(int index, string legendName) { } @@ -76,7 +78,7 @@ namespace XCharts.Runtime internal override void SetSerie(Serie serie) { - this.serie = (T) serie; + this.serie = (T)serie; this.serie.context.param.serieType = typeof(T); m_NeedInitComponent = true; AnimationStyleHelper.UpdateSerieAnimation(serie); @@ -107,6 +109,7 @@ namespace XCharts.Runtime } if (serie.dataDirty) { + OnDataUpdate(); SeriesHelper.UpdateSerieNameList(chart, ref chart.m_LegendRealShowName); chart.OnSerieDataUpdate(serie.index); serie.OnDataUpdate(); @@ -387,7 +390,7 @@ namespace XCharts.Runtime return; } InitRoot(); - var dataAutoColor = (Color) chart.GetLegendRealShowNameColor(serie.legendName); + var dataAutoColor = (Color)chart.GetLegendRealShowNameColor(serie.legendName); m_EndLabel = ChartHelper.AddChartLabel(s_SerieEndLabelObjectName, m_SerieRoot.transform, serie.endLabel, chart.theme.common, "", dataAutoColor, TextAnchor.MiddleLeft); m_EndLabel.SetActive(serie.endLabel.show); @@ -599,7 +602,7 @@ namespace XCharts.Runtime var colorIndex = serie.colorByData ? serieData.index : serie.index; Color32 color, toColor; SerieHelper.GetItemColor(out color, out toColor, serie, serieData, chart.theme, colorIndex, SerieState.Normal, false); - return (Color) color; + return (Color)color; } protected void UpdateCoordSerieParams(ref List paramList, ref string title,