From b53612d3c69ac1c3e47f55989a71c5efbfc783c0 Mon Sep 17 00:00:00 2001 From: Koha9 Date: Thu, 3 Nov 2022 07:07:51 +0900 Subject: [PATCH] In-game real time reward chart, free camera, result viewer and etc... In-game real time reward chart, result viewer, free camera, kill bonus reward(not so good. set 0 to unuse it) Fix ray-sensor throw error when initialization issue. Fix ray-sensor info panel face to wrong position. --- Assets/EnviromentUIControl.cs | 46 + .../Documentation.meta => FreeFlyCamera.meta} | 2 +- .../res.meta => FreeFlyCamera/Demo.meta} | 5 +- .../Demo/Materials.meta} | 5 +- .../Demo/Materials/Material1.mat | 74 + .../Demo/Materials/Material1.mat.meta | 8 + .../Demo/Materials/Material2.mat | 74 + .../Demo/Materials/Material2.mat.meta | 8 + .../Demo/Materials/Material3.mat | 74 + .../Demo/Materials/Material3.mat.meta | 8 + .../Demo/Scenes.meta} | 5 +- Assets/FreeFlyCamera/Demo/Scenes/Demo.unity | 919 + .../FreeFlyCamera/Demo/Scenes/Demo.unity.meta | 8 + .../Demo/Scenes/DemoSettings.lighting | 63 + .../Demo/Scenes/DemoSettings.lighting.meta | 8 + Assets/FreeFlyCamera/Demo/Scripts.meta | 9 + .../Demo/Scripts/ToggleGameObjectEnable.cs | 18 + .../Scripts/ToggleGameObjectEnable.cs.meta} | 5 +- Assets/FreeFlyCamera/Documentation.meta | 9 + .../Documentation/FreeFlyCamera_en.pdf | Bin 0 -> 258436 bytes .../Documentation/FreeFlyCamera_en.pdf.meta | 8 + .../Documentation/FreeFlyCamera_ru.pdf | Bin 0 -> 263092 bytes .../Documentation/FreeFlyCamera_ru.pdf.meta | 8 + Assets/FreeFlyCamera/Scripts.meta | 9 + Assets/FreeFlyCamera/Scripts/FreeFlyCamera.cs | 218 + .../Scripts/FreeFlyCamera.cs.meta} | 3 +- Assets/FreeFlyCamera/readme.txt | 24 + .../readme.txt.meta} | 5 +- Assets/ML-Agents/Timers/InGame_timers.json | 2 +- Assets/Prefeb/MessageContents.prefab | 81 - Assets/Prefeb/MessageContents.prefab.meta | 7 - Assets/Scenes/InGame.unity | 99913 ++++++++++++++-- Assets/Script/InGame/AgentWithGun.cs | 36 +- Assets/Script/InGame/RaySensors.cs | 3 +- Assets/Script/InGame/rayInfoUI.cs | 22 +- Assets/XCharts/CHANGELOG.md | 705 - Assets/XCharts/CHANGELOG.md.meta | 7 - Assets/XCharts/Documentation/CHANGELOG-EN.md | 570 - .../Documentation/CHANGELOG-EN.md.meta | 7 - Assets/XCharts/Documentation/README-EN.md | 141 - Assets/XCharts/Documentation/SUPPORT.md | 76 - Assets/XCharts/Documentation/SUPPORT.md.meta | 7 - Assets/XCharts/Documentation/XChartsAPI-EN.md | 1075 - .../Documentation/XChartsAPI-EN.md.meta | 7 - Assets/XCharts/Documentation/XChartsAPI-ZH.md | 1075 - .../Documentation/XChartsAPI-ZH.md.meta | 7 - .../Documentation/XChartsConfiguration-EN.md | 1528 - .../XChartsConfiguration-EN.md.meta | 7 - .../Documentation/XChartsConfiguration-ZH.md | 1528 - .../XChartsConfiguration-ZH.md.meta | 7 - Assets/XCharts/Documentation/XChartsFAQ-EN.md | 150 - .../Documentation/XChartsFAQ-EN.md.meta | 7 - Assets/XCharts/Documentation/XChartsFAQ-ZH.md | 154 - .../Documentation/XChartsFAQ-ZH.md.meta | 7 - .../Documentation/XChartsTutorial01-EN.md | 262 - .../XChartsTutorial01-EN.md.meta | 7 - .../Documentation/XChartsTutorial01-ZH.md | 262 - .../XChartsTutorial01-ZH.md.meta | 7 - Assets/XCharts/Documentation/res/alipay.png | Bin 31382 -> 0 bytes .../XCharts/Documentation/res/alipay.png.meta | 76 - .../Documentation/res/linechart-simple.png | Bin 7058 -> 0 bytes .../res/linechart-simple.png.meta | 76 - .../XCharts/Documentation/res/linechart.png | Bin 5843 -> 0 bytes .../Documentation/res/linechart.png.meta | 76 - .../XCharts/Documentation/res/linechart1.png | Bin 6903 -> 0 bytes .../Documentation/res/linechart1.png.meta | 76 - .../XCharts/Documentation/res/linechart2.png | Bin 10668 -> 0 bytes .../Documentation/res/linechart2.png.meta | 76 - .../XCharts/Documentation/res/linechart3.png | Bin 11889 -> 0 bytes .../Documentation/res/linechart3.png.meta | 76 - .../XCharts/Documentation/res/linechart4.png | Bin 11978 -> 0 bytes .../Documentation/res/linechart4.png.meta | 76 - .../Documentation/res/op_addcomponent.png | Bin 61620 -> 0 bytes .../res/op_addcomponent.png.meta | 76 - .../XCharts/Documentation/res/op_addserie.png | Bin 51413 -> 0 bytes .../Documentation/res/op_addserie.png.meta | 76 - .../res/op_addseriecomponent.png | Bin 64321 -> 0 bytes .../res/op_addseriecomponent.png.meta | 76 - .../res/op_addseriedatacomponent.png | Bin 56038 -> 0 bytes .../res/op_addseriedatacomponent.png.meta | 76 - .../Documentation/res/op_textmeshpro.png | Bin 65659 -> 0 bytes .../Documentation/res/op_textmeshpro.png.meta | 76 - .../Documentation/res/op_textmeshpro3.png | Bin 30997 -> 0 bytes .../res/op_textmeshpro3.png.meta | 76 - Assets/XCharts/Documentation/res/wechat.png | Bin 11704 -> 0 bytes .../XCharts/Documentation/res/wechat.png.meta | 76 - .../Attributes/ComponentEditorAttribute.cs | 15 - .../Editor/Attributes/SerieEditorAttribute.cs | 15 - Assets/XCharts/Editor/Charts.meta | 8 - .../XCharts/Editor/Charts/BaseChartEditor.cs | 320 - .../Editor/Charts/BaseChartEditor.cs.meta | 11 - Assets/XCharts/Editor/ChildComponents.meta | 8 - .../Editor/ChildComponents/AnimationDrawer.cs | 29 - .../ChildComponents/AnimationDrawer.cs.meta | 11 - .../Editor/ChildComponents/AreaStyleDrawer.cs | 27 - .../ChildComponents/AreaStyleDrawer.cs.meta | 11 - .../ChildComponents/BasePropertyDrawer.cs | 211 - .../BasePropertyDrawer.cs.meta | 11 - .../ChildComponents/CommentItemDrawer.cs | 26 - .../ChildComponents/CommentItemDrawer.cs.meta | 11 - .../ChildComponents/CommentMarkStyleDrawer.cs | 22 - .../CommentMarkStyleDrawer.cs.meta | 11 - .../ChildComponents/ComponentThemeDrawer.cs | 163 - .../ComponentThemeDrawer.cs.meta | 11 - .../Editor/ChildComponents/DebugInfoDrawer.cs | 25 - .../ChildComponents/DebugInfoDrawer.cs.meta | 11 - .../ChildComponents/EmphasisStyleDrawer.cs | 43 - .../EmphasisStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/IconStyleDrawer.cs | 30 - .../ChildComponents/IconStyleDrawer.cs.meta | 11 - .../ChildComponents/ImageStyleDrawer.cs | 27 - .../ChildComponents/ImageStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/ItemStyleDrawer.cs | 39 - .../ChildComponents/ItemStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/LabelLineDrawer.cs | 30 - .../ChildComponents/LabelLineDrawer.cs.meta | 11 - .../ChildComponents/LabelStyleDrawer.cs | 40 - .../ChildComponents/LabelStyleDrawer.cs.meta | 11 - .../ChildComponents/LevelStyleDrawer.cs | 37 - .../ChildComponents/LevelStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/LineArrowDrawer.cs | 43 - .../ChildComponents/LineArrowDrawer.cs.meta | 11 - .../Editor/ChildComponents/LineDrawer.cs | 66 - .../Editor/ChildComponents/LineDrawer.cs.meta | 11 - .../Editor/ChildComponents/LineStyleDrawer.cs | 28 - .../ChildComponents/LineStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/LocationDrawer.cs | 25 - .../ChildComponents/LocationDrawer.cs.meta | 11 - .../ChildComponents/SerieSymbolDrawer.cs | 52 - .../ChildComponents/SerieSymbolDrawer.cs.meta | 11 - .../Editor/ChildComponents/SettingsDrawer.cs | 36 - .../ChildComponents/SettingsDrawer.cs.meta | 11 - .../ChildComponents/SymbolStyleDrawer.cs | 35 - .../ChildComponents/SymbolStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/TextLimitDrawer.cs | 24 - .../ChildComponents/TextLimitDrawer.cs.meta | 11 - .../ChildComponents/TextPaddingDrawer.cs | 25 - .../ChildComponents/TextPaddingDrawer.cs.meta | 11 - .../Editor/ChildComponents/TextStyleDrawer.cs | 43 - .../ChildComponents/TextStyleDrawer.cs.meta | 11 - .../Editor/ChildComponents/ThemeDrawer.cs | 136 - .../ChildComponents/ThemeDrawer.cs.meta | 11 - .../ChildComponents/TitleStyleDrawer.cs | 12 - .../ChildComponents/TitleStyleDrawer.cs.meta | 11 - Assets/XCharts/Editor/MainComponents.meta | 8 - .../Editor/MainComponents/AxisEditor.cs | 205 - .../Editor/MainComponents/AxisEditor.cs.meta | 11 - .../Editor/MainComponents/BackgroundEditor.cs | 20 - .../MainComponents/BackgroundEditor.cs.meta | 11 - .../Editor/MainComponents/CommentEditor.cs | 18 - .../MainComponents/CommentEditor.cs.meta | 11 - .../Editor/MainComponents/DataZoomEditor.cs | 60 - .../MainComponents/DataZoomEditor.cs.meta | 11 - .../Editor/MainComponents/GridCoordEditor.cs | 23 - .../MainComponents/GridCoordEditor.cs.meta | 11 - .../Editor/MainComponents/LegendEditor.cs | 29 - .../MainComponents/LegendEditor.cs.meta | 11 - .../MainComponents/MainComponentBaseEditor.cs | 116 - .../MainComponentBaseEditor.cs.meta | 11 - .../MainComponents/MainComponentEditor.cs | 8 - .../MainComponentEditor.cs.meta | 11 - .../MainComponents/MainComponentListEditor.cs | 161 - .../MainComponentListEditor.cs.meta | 11 - .../Editor/MainComponents/MarkAreaEditor.cs | 55 - .../MainComponents/MarkAreaEditor.cs.meta | 11 - .../Editor/MainComponents/MarkLineEditor.cs | 59 - .../MainComponents/MarkLineEditor.cs.meta | 11 - .../MainComponents/ParallelCoordEditor.cs | 21 - .../ParallelCoordEditor.cs.meta | 11 - .../Editor/MainComponents/PolarCoordEditor.cs | 18 - .../MainComponents/PolarCoordEditor.cs.meta | 11 - .../Editor/MainComponents/RadarCoordEditor.cs | 50 - .../MainComponents/RadarCoordEditor.cs.meta | 11 - .../Editor/MainComponents/ThemeEditor.cs | 39 - .../Editor/MainComponents/ThemeEditor.cs.meta | 11 - .../Editor/MainComponents/TitleEditor.cs | 21 - .../Editor/MainComponents/TitleEditor.cs.meta | 11 - .../Editor/MainComponents/TooltipEditor.cs | 49 - .../MainComponents/TooltipEditor.cs.meta | 11 - .../Editor/MainComponents/VisualMapEditor.cs | 64 - .../MainComponents/VisualMapEditor.cs.meta | 11 - Assets/XCharts/Editor/Series.meta | 8 - Assets/XCharts/Editor/Series/BarEditor.cs | 47 - .../XCharts/Editor/Series/BarEditor.cs.meta | 11 - .../Editor/Series/CandlestickEditor.cs | 25 - .../Editor/Series/CandlestickEditor.cs.meta | 11 - .../Editor/Series/EffectScatterEditor.cs | 26 - .../Editor/Series/EffectScatterEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/HeatmapEditor.cs | 17 - .../Editor/Series/HeatmapEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/LineEditor.cs | 43 - .../XCharts/Editor/Series/LineEditor.cs.meta | 11 - .../XCharts/Editor/Series/ParallelEditor.cs | 16 - .../Editor/Series/ParallelEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/PieEditor.cs | 26 - .../XCharts/Editor/Series/PieEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/RadarEditor.cs | 19 - .../XCharts/Editor/Series/RadarEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/RingEditor.cs | 21 - .../XCharts/Editor/Series/RingEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/ScatterEditor.cs | 26 - .../Editor/Series/ScatterEditor.cs.meta | 11 - .../XCharts/Editor/Series/SerieBaseEditor.cs | 160 - .../Editor/Series/SerieBaseEditor.cs.meta | 11 - Assets/XCharts/Editor/Series/SerieEditor.cs | 244 - .../XCharts/Editor/Series/SerieEditor.cs.meta | 11 - .../XCharts/Editor/Series/SerieListEditor.cs | 268 - .../Editor/Series/SerieListEditor.cs.meta | 11 - .../Editor/Series/SimplifiedBarEditor.cs | 19 - .../Editor/Series/SimplifiedBarEditor.cs.meta | 11 - .../Series/SimplifiedCandlestickEditor.cs | 17 - .../SimplifiedCandlestickEditor.cs.meta | 11 - .../Editor/Series/SimplifiedLineEditor.cs | 19 - .../Series/SimplifiedLineEditor.cs.meta | 11 - Assets/XCharts/Editor/Utilities.meta | 8 - .../Editor/Utilities/ChartEditorHelper.cs | 734 - .../Utilities/ChartEditorHelper.cs.meta | 11 - .../XCharts/Editor/Utilities/EditorStyles.cs | 32 - .../Editor/Utilities/EditorStyles.cs.meta | 11 - Assets/XCharts/Editor/Utilities/ThemeCheck.cs | 71 - .../Editor/Utilities/ThemeCheck.cs.meta | 11 - Assets/XCharts/Editor/Widgets.meta | 8 - .../Editor/Widgets/ProgressBarEditor.cs | 51 - .../Editor/Widgets/ProgressBarEditor.cs.meta | 11 - Assets/XCharts/Editor/Windows.meta | 8 - .../Editor/Windows/PraseExternalDataEditor.cs | 238 - .../Windows/PraseExternalDataEditor.cs.meta | 11 - .../Editor/Windows/XCSettingsEditor.cs | 59 - .../Editor/Windows/XCSettingsEditor.cs.meta | 11 - .../XCharts/Editor/Windows/XChartsEditor.cs | 197 - .../Editor/Windows/XChartsEditor.cs.meta | 11 - Assets/XCharts/Editor/XCharts.Editor.asmdef | 17 - .../XCharts/Editor/XCharts.Editor.asmdef.meta | 7 - Assets/XCharts/Examples.meta | 8 - .../XCharts/Examples/Example00_CheatSheet.cs | 322 - .../Examples/Example00_CheatSheet.cs.meta | 11 - .../XCharts/Examples/Example01_UpdateData.cs | 46 - .../Examples/Example01_UpdateData.cs.meta | 11 - .../XCharts/Examples/Example02_ChartEvent.cs | 58 - .../Examples/Example02_ChartEvent.cs.meta | 11 - .../Examples/Example03_ChartAnimation.cs | 37 - .../Examples/Example03_ChartAnimation.cs.meta | 11 - .../XCharts/Examples/Example10_LineChart.cs | 266 - .../Examples/Example10_LineChart.cs.meta | 11 - .../XCharts/Examples/Example11_AddSinCurve.cs | 62 - .../Examples/Example11_AddSinCurve.cs.meta | 11 - .../Examples/Example12_CustomDrawing.cs | 41 - .../Examples/Example12_CustomDrawing.cs.meta | 11 - .../XCharts/Examples/Example13_LineSimple.cs | 59 - .../Examples/Example13_LineSimple.cs.meta | 11 - Assets/XCharts/Examples/Example20_BarChart.cs | 158 - .../Examples/Example20_BarChart.cs.meta | 11 - Assets/XCharts/Examples/Example21_BarRace.cs | 46 - .../Examples/Example21_BarRace.cs.meta | 11 - Assets/XCharts/Examples/Example30_PieChart.cs | 205 - .../Examples/Example30_PieChart.cs.meta | 11 - .../Examples/Example31_PieUpdateName.cs | 74 - .../Examples/Example31_PieUpdateName.cs.meta | 11 - Assets/XCharts/Examples/Example40_Radar.cs | 135 - .../XCharts/Examples/Example40_Radar.cs.meta | 11 - .../XCharts/Examples/Example41_RadarUpdate.cs | 73 - .../Examples/Example41_RadarUpdate.cs.meta | 11 - Assets/XCharts/Examples/Example50_Scatter.cs | 35 - .../Examples/Example50_Scatter.cs.meta | 11 - Assets/XCharts/Examples/Example60_Heatmap.cs | 111 - .../Examples/Example60_Heatmap.cs.meta | 11 - Assets/XCharts/Examples/Example80_Polar.cs | 52 - .../XCharts/Examples/Example80_Polar.cs.meta | 11 - .../XCharts/Examples/Example90_Candlestick.cs | 68 - .../Examples/Example90_Candlestick.cs.meta | 11 - Assets/XCharts/Examples/Example_AddChart.cs | 66 - .../XCharts/Examples/Example_AddChart.cs.meta | 11 - Assets/XCharts/Examples/Example_Component.cs | 35 - .../Examples/Example_Component.cs.meta | 11 - Assets/XCharts/Examples/Example_Dynamic.cs | 70 - .../XCharts/Examples/Example_Dynamic.cs.meta | 11 - Assets/XCharts/Examples/Example_LargeData.cs | 52 - .../Examples/Example_LargeData.cs.meta | 11 - Assets/XCharts/Examples/Example_PieChart.cs | 40 - .../XCharts/Examples/Example_PieChart.cs.meta | 11 - Assets/XCharts/Examples/Example_Test.cs | 66 - Assets/XCharts/Examples/Example_Test.cs.meta | 11 - Assets/XCharts/Examples/Example_TestTime.cs | 50 - .../XCharts/Examples/Example_TestTime.cs.meta | 11 - .../XCharts/Examples/XCharts.Examples.asmdef | 14 - .../Examples/XCharts.Examples.asmdef.meta | 7 - Assets/XCharts/LICENSE.md | 21 - Assets/XCharts/LICENSE.md.meta | 7 - Assets/XCharts/README.md | 153 - Assets/XCharts/README.md.meta | 7 - Assets/XCharts/Resources.meta | 2 +- Assets/XCharts/Resources/XCLang-EN.asset.meta | 2 +- Assets/XCharts/Resources/XCLang-ZH.asset.meta | 2 +- .../XCharts/Resources/XCSettings.asset.meta | 2 +- .../XCharts/Resources/XCTheme-Dark.asset.meta | 2 +- .../Resources/XCTheme-Default.asset.meta | 2 +- Assets/XCharts/Runtime.meta | 8 - Assets/XCharts/Runtime/Chart.meta | 8 - Assets/XCharts/Runtime/Chart/BarChart.cs | 29 - Assets/XCharts/Runtime/Chart/BarChart.cs.meta | 11 - .../XCharts/Runtime/Chart/CandlestickChart.cs | 29 - .../Runtime/Chart/CandlestickChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/HeatmapChart.cs | 84 - .../Runtime/Chart/HeatmapChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/LineChart.cs | 29 - .../XCharts/Runtime/Chart/LineChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/ParallelChart.cs | 30 - .../Runtime/Chart/ParallelChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/PieChart.cs | 20 - Assets/XCharts/Runtime/Chart/PieChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/PolarChart.cs | 33 - .../XCharts/Runtime/Chart/PolarChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/RadarChart.cs | 19 - .../XCharts/Runtime/Chart/RadarChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/RingChart.cs | 18 - .../XCharts/Runtime/Chart/RingChart.cs.meta | 11 - Assets/XCharts/Runtime/Chart/ScatterChart.cs | 31 - .../Runtime/Chart/ScatterChart.cs.meta | 11 - .../Runtime/Chart/SimplifiedBarChart.cs | 29 - .../Runtime/Chart/SimplifiedBarChart.cs.meta | 11 - .../Chart/SimplifiedCandlestickChart.cs | 29 - .../Chart/SimplifiedCandlestickChart.cs.meta | 11 - .../Runtime/Chart/SimplifiedLineChart.cs | 29 - .../Runtime/Chart/SimplifiedLineChart.cs.meta | 11 - Assets/XCharts/Runtime/Component.meta | 8 - .../XCharts/Runtime/Component/Animation.meta | 8 - .../Component/Animation/AnimationStyle.cs | 630 - .../Animation/AnimationStyle.cs.meta | 11 - .../Animation/AnimationStyleContext.cs | 13 - .../Animation/AnimationStyleContext.cs.meta | 11 - .../Animation/AnimationStyleHelper.cs | 65 - .../Animation/AnimationStyleHelper.cs.meta | 11 - Assets/XCharts/Runtime/Component/Axis.meta | 8 - .../Runtime/Component/Axis/AngleAxis.meta | 8 - .../Component/Axis/AngleAxis/AngleAxis.cs | 48 - .../Axis/AngleAxis/AngleAxis.cs.meta | 11 - .../Axis/AngleAxis/AngleAxisHandler.cs | 164 - .../Axis/AngleAxis/AngleAxisHandler.cs.meta | 11 - Assets/XCharts/Runtime/Component/Axis/Axis.cs | 791 - .../Runtime/Component/Axis/Axis.cs.meta | 11 - .../Runtime/Component/Axis/AxisContext.cs | 125 - .../Component/Axis/AxisContext.cs.meta | 11 - .../Runtime/Component/Axis/AxisHandler.cs | 782 - .../Component/Axis/AxisHandler.cs.meta | 11 - .../Runtime/Component/Axis/AxisHelper.cs | 561 - .../Runtime/Component/Axis/AxisHelper.cs.meta | 11 - .../Runtime/Component/Axis/AxisLabel.cs | 230 - .../Runtime/Component/Axis/AxisLabel.cs.meta | 11 - .../Runtime/Component/Axis/AxisLine.cs | 77 - .../Runtime/Component/Axis/AxisLine.cs.meta | 11 - .../Runtime/Component/Axis/AxisName.cs | 76 - .../Runtime/Component/Axis/AxisName.cs.meta | 11 - .../Runtime/Component/Axis/AxisSplitArea.cs | 80 - .../Component/Axis/AxisSplitArea.cs.meta | 11 - .../Runtime/Component/Axis/AxisSplitLine.cs | 74 - .../Component/Axis/AxisSplitLine.cs.meta | 11 - .../Runtime/Component/Axis/AxisTick.cs | 110 - .../Runtime/Component/Axis/AxisTick.cs.meta | 11 - .../Runtime/Component/Axis/ParallelAxis.meta | 8 - .../Axis/ParallelAxis/ParallelAxis.cs | 29 - .../Axis/ParallelAxis/ParallelAxis.cs.meta | 11 - .../Axis/ParallelAxis/ParallelAxisHander.cs | 167 - .../ParallelAxis/ParallelAxisHander.cs.meta | 11 - .../Runtime/Component/Axis/RadiusAxis.meta | 8 - .../Component/Axis/RadiusAxis/RadiusAxis.cs | 28 - .../Axis/RadiusAxis/RadiusAxis.cs.meta | 11 - .../Axis/RadiusAxis/RadiusAxisHandler.cs | 188 - .../Axis/RadiusAxis/RadiusAxisHandler.cs.meta | 11 - .../Runtime/Component/Axis/SingleAxis.meta | 8 - .../Component/Axis/SingleAxis/SingleAxis.cs | 152 - .../Axis/SingleAxis/SingleAxis.cs.meta | 11 - .../Axis/SingleAxis/SingleAxisHandler.cs | 125 - .../Axis/SingleAxis/SingleAxisHandler.cs.meta | 11 - .../XCharts/Runtime/Component/Axis/XAxis.meta | 8 - .../Runtime/Component/Axis/XAxis/XAxis.cs | 32 - .../Component/Axis/XAxis/XAxis.cs.meta | 11 - .../Component/Axis/XAxis/XAxisHander.cs | 152 - .../Component/Axis/XAxis/XAxisHander.cs.meta | 11 - .../XCharts/Runtime/Component/Axis/YAxis.meta | 8 - .../Runtime/Component/Axis/YAxis/YAxis.cs | 30 - .../Component/Axis/YAxis/YAxis.cs.meta | 11 - .../Component/Axis/YAxis/YAxisHander.cs | 149 - .../Component/Axis/YAxis/YAxisHander.cs.meta | 11 - .../XCharts/Runtime/Component/Background.meta | 8 - .../Component/Background/Background.cs | 80 - .../Component/Background/Background.cs.meta | 11 - .../Component/Background/BackgroundHandler.cs | 57 - .../Background/BackgroundHandler.cs.meta | 11 - Assets/XCharts/Runtime/Component/Child.meta | 8 - .../Runtime/Component/Child/AreaStyle.cs | 131 - .../Runtime/Component/Child/AreaStyle.cs.meta | 11 - .../Runtime/Component/Child/ArrowStyle.cs | 92 - .../Component/Child/ArrowStyle.cs.meta | 11 - .../Runtime/Component/Child/BaseLine.cs | 82 - .../Runtime/Component/Child/BaseLine.cs.meta | 11 - .../Runtime/Component/Child/IconStyle.cs | 118 - .../Runtime/Component/Child/IconStyle.cs.meta | 11 - .../Runtime/Component/Child/ImageStyle.cs | 81 - .../Component/Child/ImageStyle.cs.meta | 11 - .../Runtime/Component/Child/ItemStyle.cs | 350 - .../Runtime/Component/Child/ItemStyle.cs.meta | 11 - .../Runtime/Component/Child/LevelStyle.cs | 41 - .../Component/Child/LevelStyle.cs.meta | 11 - .../Runtime/Component/Child/LineArrow.cs | 63 - .../Runtime/Component/Child/LineArrow.cs.meta | 11 - .../Runtime/Component/Child/LineStyle.cs | 238 - .../Runtime/Component/Child/LineStyle.cs.meta | 11 - .../Runtime/Component/Child/Location.cs | 321 - .../Runtime/Component/Child/Location.cs.meta | 11 - .../Runtime/Component/Child/SerieSymbl.cs | 243 - .../Component/Child/SerieSymbl.cs.meta | 11 - .../Runtime/Component/Child/StageColor.cs | 26 - .../Component/Child/StageColor.cs.meta | 11 - .../Runtime/Component/Child/SymbolStyle.cs | 191 - .../Component/Child/SymbolStyle.cs.meta | 11 - .../Runtime/Component/Child/TextLimit.cs | 150 - .../Runtime/Component/Child/TextLimit.cs.meta | 11 - .../Runtime/Component/Child/TextPadding.cs | 79 - .../Component/Child/TextPadding.cs.meta | 11 - .../Runtime/Component/Child/TextStyle.cs | 234 - .../Runtime/Component/Child/TextStyle.cs.meta | 11 - Assets/XCharts/Runtime/Component/Comment.meta | 8 - .../Runtime/Component/Comment/Comment.cs | 65 - .../Runtime/Component/Comment/Comment.cs.meta | 11 - .../Component/Comment/CommentHander.cs | 71 - .../Component/Comment/CommentHander.cs.meta | 11 - .../Runtime/Component/Comment/CommentItem.cs | 55 - .../Component/Comment/CommentItem.cs.meta | 11 - .../Component/Comment/CommentMarkStyle.cs | 27 - .../Comment/CommentMarkStyle.cs.meta | 11 - .../XCharts/Runtime/Component/DataZoom.meta | 8 - .../Runtime/Component/DataZoom/DataZoom.cs | 687 - .../Component/DataZoom/DataZoom.cs.meta | 11 - .../Component/DataZoom/DataZoomContext.cs | 26 - .../DataZoom/DataZoomContext.cs.meta | 11 - .../Component/DataZoom/DataZoomHandler.cs | 614 - .../DataZoom/DataZoomHandler.cs.meta | 11 - .../Component/DataZoom/DataZoomHelper.cs | 62 - .../Component/DataZoom/DataZoomHelper.cs.meta | 11 - Assets/XCharts/Runtime/Component/Debug.meta | 8 - .../Runtime/Component/Debug/DebugInfo.cs | 158 - .../Runtime/Component/Debug/DebugInfo.cs.meta | 11 - .../XCharts/Runtime/Component/Emphasis.meta | 8 - .../Runtime/Component/Emphasis/Emphasis.cs | 74 - .../Component/Emphasis/Emphasis.cs.meta | 11 - .../Component/Emphasis/EmphasisItemStyle.cs | 11 - .../Emphasis/EmphasisItemStyle.cs.meta | 11 - .../Component/Emphasis/EmphasisLabelLine.cs | 11 - .../Emphasis/EmphasisLabelLine.cs.meta | 11 - .../Component/Emphasis/EmphasisLabelStyle.cs | 11 - .../Emphasis/EmphasisLabelStyle.cs.meta | 11 - .../Runtime/Component/Interaction.meta | 8 - .../Component/Interaction/InteractData.cs | 207 - .../Interaction/InteractData.cs.meta | 11 - Assets/XCharts/Runtime/Component/Label.meta | 8 - .../Runtime/Component/Label/EndLabelStyle.cs | 17 - .../Component/Label/EndLabelStyle.cs.meta | 11 - .../Runtime/Component/Label/LabelLine.cs | 145 - .../Runtime/Component/Label/LabelLine.cs.meta | 11 - .../Runtime/Component/Label/LabelStyle.cs | 319 - .../Component/Label/LabelStyle.cs.meta | 11 - Assets/XCharts/Runtime/Component/Legend.meta | 8 - .../Runtime/Component/Legend/Legend.cs | 425 - .../Runtime/Component/Legend/Legend.cs.meta | 11 - .../Runtime/Component/Legend/LegendContext.cs | 31 - .../Component/Legend/LegendContext.cs.meta | 11 - .../Runtime/Component/Legend/LegendHandler.cs | 253 - .../Component/Legend/LegendHandler.cs.meta | 11 - .../Runtime/Component/Legend/LegendHelper.cs | 276 - .../Component/Legend/LegendHelper.cs.meta | 11 - Assets/XCharts/Runtime/Component/Mark.meta | 8 - .../Runtime/Component/Mark/MarkArea.cs | 192 - .../Runtime/Component/Mark/MarkArea.cs.meta | 11 - .../Runtime/Component/Mark/MarkAreaHandler.cs | 195 - .../Component/Mark/MarkAreaHandler.cs.meta | 11 - .../Runtime/Component/Mark/MarkLine.cs | 256 - .../Runtime/Component/Mark/MarkLine.cs.meta | 11 - .../Runtime/Component/Mark/MarkLineHandler.cs | 310 - .../Component/Mark/MarkLineHandler.cs.meta | 11 - .../Runtime/Component/Mark/MarkLineHelper.cs | 48 - .../Component/Mark/MarkLineHelper.cs.meta | 11 - Assets/XCharts/Runtime/Component/Radar.meta | 8 - .../Runtime/Component/Radar/RadarCoord.cs | 447 - .../Component/Radar/RadarCoord.cs.meta | 11 - .../Component/Radar/RadarCoordContext.cs | 22 - .../Component/Radar/RadarCoordContext.cs.meta | 11 - .../Component/Radar/RadarCoordHandler.cs | 170 - .../Component/Radar/RadarCoordHandler.cs.meta | 11 - .../XCharts/Runtime/Component/Settings.meta | 8 - .../Runtime/Component/Settings/Settings.cs | 169 - .../Component/Settings/Settings.cs.meta | 11 - Assets/XCharts/Runtime/Component/Title.meta | 8 - .../XCharts/Runtime/Component/Title/Title.cs | 105 - .../Runtime/Component/Title/Title.cs.meta | 11 - .../Runtime/Component/Title/TitleHandler.cs | 88 - .../Component/Title/TitleHandler.cs.meta | 11 - .../Runtime/Component/Title/TitleStyle.cs | 15 - .../Component/Title/TitleStyle.cs.meta | 11 - Assets/XCharts/Runtime/Component/Tooltip.meta | 8 - .../Runtime/Component/Tooltip/Tooltip.cs | 549 - .../Runtime/Component/Tooltip/Tooltip.cs.meta | 11 - .../Component/Tooltip/TooltipContext.cs | 24 - .../Component/Tooltip/TooltipContext.cs.meta | 11 - .../Component/Tooltip/TooltipHandler.cs | 641 - .../Component/Tooltip/TooltipHandler.cs.meta | 11 - .../Component/Tooltip/TooltipHelper.cs | 99 - .../Component/Tooltip/TooltipHelper.cs.meta | 11 - .../Runtime/Component/Tooltip/TooltipView.cs | 270 - .../Component/Tooltip/TooltipView.cs.meta | 11 - .../XCharts/Runtime/Component/VisualMap.meta | 8 - .../Runtime/Component/VisualMap/VisualMap.cs | 641 - .../Component/VisualMap/VisualMap.cs.meta | 11 - .../Component/VisualMap/VisualMapContext.cs | 19 - .../VisualMap/VisualMapContext.cs.meta | 11 - .../Component/VisualMap/VisualMapHandler.cs | 371 - .../VisualMap/VisualMapHandler.cs.meta | 11 - .../Component/VisualMap/VisualMapHelper.cs | 191 - .../VisualMap/VisualMapHelper.cs.meta | 11 - Assets/XCharts/Runtime/Coord.meta | 8 - Assets/XCharts/Runtime/Coord/Calendar.meta | 8 - .../Runtime/Coord/Calendar/CalendarCoord.cs | 18 - .../Coord/Calendar/CalendarCoord.cs.meta | 11 - .../Coord/Calendar/CalendarCoordHandler.cs | 9 - .../Calendar/CalendarCoordHandler.cs.meta | 11 - Assets/XCharts/Runtime/Coord/Grid.meta | 8 - .../XCharts/Runtime/Coord/Grid/GridCoord.cs | 173 - .../Runtime/Coord/Grid/GridCoord.cs.meta | 11 - .../Runtime/Coord/Grid/GridCoordContext.cs | 21 - .../Coord/Grid/GridCoordContext.cs.meta | 11 - .../Runtime/Coord/Grid/GridCoordHandler.cs | 90 - .../Coord/Grid/GridCoordHandler.cs.meta | 11 - Assets/XCharts/Runtime/Coord/Parallel.meta | 8 - .../Runtime/Coord/Parallel/ParallelCoord.cs | 123 - .../Coord/Parallel/ParallelCoord.cs.meta | 11 - .../Coord/Parallel/ParallelCoordContext.cs | 20 - .../Parallel/ParallelCoordContext.cs.meta | 11 - .../Coord/Parallel/ParallelCoordHandler.cs | 176 - .../Parallel/ParallelCoordHandler.cs.meta | 11 - Assets/XCharts/Runtime/Coord/Polar.meta | 8 - .../XCharts/Runtime/Coord/Polar/PolarCoord.cs | 71 - .../Runtime/Coord/Polar/PolarCoord.cs.meta | 11 - .../Runtime/Coord/Polar/PolarCoordContext.cs | 20 - .../Coord/Polar/PolarCoordContext.cs.meta | 11 - .../Runtime/Coord/Polar/PolarCoordHandler.cs | 35 - .../Coord/Polar/PolarCoordHandler.cs.meta | 11 - .../Runtime/Coord/Polar/PolarHelper.cs | 27 - .../Runtime/Coord/Polar/PolarHelper.cs.meta | 11 - Assets/XCharts/Runtime/Coord/SingleAxis.meta | 8 - .../Coord/SingleAxis/SingleAxisCoord.cs | 9 - .../Coord/SingleAxis/SingleAxisCoord.cs.meta | 11 - Assets/XCharts/Runtime/Helper.meta | 8 - Assets/XCharts/Runtime/Helper/CheckHelper.cs | 138 - .../Runtime/Helper/CheckHelper.cs.meta | 11 - .../XCharts/Runtime/Helper/FormatterHelper.cs | 277 - .../Runtime/Helper/FormatterHelper.cs.meta | 11 - Assets/XCharts/Runtime/Helper/SerieHelper.cs | 783 - .../Runtime/Helper/SerieHelper.cs.meta | 11 - .../Runtime/Helper/SerieLabelHelper.cs | 216 - .../Runtime/Helper/SerieLabelHelper.cs.meta | 11 - Assets/XCharts/Runtime/Helper/SeriesHelper.cs | 452 - .../Runtime/Helper/SeriesHelper.cs.meta | 11 - Assets/XCharts/Runtime/I18n.meta | 8 - Assets/XCharts/Runtime/I18n/Lang.cs | 137 - Assets/XCharts/Runtime/I18n/Lang.cs.meta | 11 - Assets/XCharts/Runtime/Internal.meta | 8 - .../XCharts/Runtime/Internal/Attributes.meta | 8 - .../Attributes/ComponentHandlerAttribute.cs | 23 - .../ComponentHandlerAttribute.cs.meta | 11 - .../Attributes/CoordOptionsAttribute.cs | 42 - .../Attributes/CoordOptionsAttribute.cs.meta | 11 - .../Attributes/DefaultAnimationAttribute.cs | 15 - .../DefaultAnimationAttribute.cs.meta | 11 - .../Internal/Attributes/IgnoreDocAttribute.cs | 12 - .../Attributes/IgnoreDocAttribute.cs.meta | 11 - .../Internal/Attributes/ListForAttribute.cs | 15 - .../Attributes/ListForAttribute.cs.meta | 11 - .../Attributes/ListForComponentAttribute.cs | 11 - .../ListForComponentAttribute.cs.meta | 11 - .../Attributes/ListForSerieAttribute.cs | 11 - .../Attributes/ListForSerieAttribute.cs.meta | 11 - .../RequireChartComponentAttribute.cs | 28 - .../RequireChartComponentAttribute.cs.meta | 11 - .../Attributes/SerieConvertAttribute.cs | 49 - .../Attributes/SerieConvertAttribute.cs.meta | 11 - .../SerieDataExtraComponentAttribute.cs | 80 - .../SerieDataExtraComponentAttribute.cs.meta | 11 - .../SerieDataExtraFieldAttribute.cs | 75 - .../SerieDataExtraFieldAttribute.cs.meta | 11 - .../SerieExtraComponentAttribute.cs | 80 - .../SerieExtraComponentAttribute.cs.meta | 11 - .../Attributes/SerieHandlerAttribute.cs | 22 - .../Attributes/SerieHandlerAttribute.cs.meta | 11 - .../XCharts/Runtime/Internal/BaseChart.API.cs | 542 - .../Runtime/Internal/BaseChart.API.cs.meta | 11 - .../Runtime/Internal/BaseChart.Component.cs | 427 - .../Internal/BaseChart.Component.cs.meta | 11 - .../Runtime/Internal/BaseChart.Custom.cs | 32 - .../Runtime/Internal/BaseChart.Custom.cs.meta | 11 - .../Runtime/Internal/BaseChart.Draw.cs | 134 - .../Runtime/Internal/BaseChart.Draw.cs.meta | 11 - .../Runtime/Internal/BaseChart.Serie.cs | 985 - .../Runtime/Internal/BaseChart.Serie.cs.meta | 11 - Assets/XCharts/Runtime/Internal/BaseChart.cs | 698 - .../Runtime/Internal/BaseChart.cs.meta | 11 - .../XCharts/Runtime/Internal/BaseGraph.API.cs | 169 - .../Runtime/Internal/BaseGraph.API.cs.meta | 11 - Assets/XCharts/Runtime/Internal/BaseGraph.cs | 318 - .../Runtime/Internal/BaseGraph.cs.meta | 11 - Assets/XCharts/Runtime/Internal/Basic.meta | 8 - .../Runtime/Internal/Basic/BaseSerie.cs | 88 - .../Runtime/Internal/Basic/BaseSerie.cs.meta | 11 - .../Runtime/Internal/Basic/ChildComponent.cs | 63 - .../Internal/Basic/ChildComponent.cs.meta | 11 - .../Runtime/Internal/Basic/CoordSystem.cs | 13 - .../Internal/Basic/CoordSystem.cs.meta | 11 - .../Runtime/Internal/Basic/MainComponent.cs | 123 - .../Internal/Basic/MainComponent.cs.meta | 11 - .../Internal/Basic/MainComponentContext.cs | 7 - .../Basic/MainComponentContext.cs.meta | 11 - Assets/XCharts/Runtime/Internal/Misc.meta | 8 - .../Runtime/Internal/Misc/DelegateFunction.cs | 23 - .../Internal/Misc/DelegateFunction.cs.meta | 11 - Assets/XCharts/Runtime/Internal/Misc/Enums.cs | 18 - .../Runtime/Internal/Misc/Enums.cs.meta | 11 - .../Internal/Misc/INeedSerieContainer.cs | 13 - .../Internal/Misc/INeedSerieContainer.cs.meta | 11 - .../Runtime/Internal/Misc/IPropertyChanged.cs | 10 - .../Internal/Misc/IPropertyChanged.cs.meta | 11 - .../Runtime/Internal/Misc/ISerieContainer.cs | 9 - .../Internal/Misc/ISerieContainer.cs.meta | 11 - .../Internal/Misc/ISerieDataComponent.cs | 9 - .../Internal/Misc/ISerieDataComponent.cs.meta | 11 - .../Internal/Misc/ISerieExtraComponent.cs | 11 - .../Misc/ISerieExtraComponent.cs.meta | 11 - .../Runtime/Internal/Misc/ISimplifiedSerie.cs | 9 - .../Internal/Misc/ISimplifiedSerie.cs.meta | 11 - .../Runtime/Internal/Misc/ITooltipView.cs | 0 .../Internal/Misc/ITooltipView.cs.meta | 11 - .../Internal/Misc/IUpdateRuntimeData.cs | 11 - .../Internal/Misc/IUpdateRuntimeData.cs.meta | 11 - Assets/XCharts/Runtime/Internal/Object.meta | 8 - .../Runtime/Internal/Object/ChartLabel.cs | 340 - .../Internal/Object/ChartLabel.cs.meta | 11 - .../Runtime/Internal/Object/ChartObject.cs | 14 - .../Internal/Object/ChartObject.cs.meta | 11 - .../Runtime/Internal/Object/ChartText.cs | 319 - .../Runtime/Internal/Object/ChartText.cs.meta | 11 - .../Runtime/Internal/Object/LegendItem.cs | 213 - .../Internal/Object/LegendItem.cs.meta | 11 - Assets/XCharts/Runtime/Internal/Painter.cs | 72 - .../XCharts/Runtime/Internal/Painter.cs.meta | 11 - Assets/XCharts/Runtime/Internal/Pools.meta | 8 - .../Runtime/Internal/Pools/ListPool.cs | 35 - .../Runtime/Internal/Pools/ListPool.cs.meta | 11 - .../Runtime/Internal/Pools/ObjectPool.cs | 57 - .../Runtime/Internal/Pools/ObjectPool.cs.meta | 11 - .../Runtime/Internal/Pools/SerieDataPool.cs | 26 - .../Internal/Pools/SerieDataPool.cs.meta | 11 - .../Runtime/Internal/Pools/SerieLabelPool.cs | 74 - .../Internal/Pools/SerieLabelPool.cs.meta | 11 - .../XCharts/Runtime/Internal/Utilities.meta | 8 - .../Runtime/Internal/Utilities/ChartCached.cs | 174 - .../Internal/Utilities/ChartCached.cs.meta | 11 - .../Runtime/Internal/Utilities/ChartConst.cs | 11 - .../Internal/Utilities/ChartConst.cs.meta | 11 - .../Runtime/Internal/Utilities/ChartDrawer.cs | 151 - .../Internal/Utilities/ChartDrawer.cs.meta | 11 - .../Runtime/Internal/Utilities/ChartHelper.cs | 883 - .../Internal/Utilities/ChartHelper.cs.meta | 11 - .../Internal/Utilities/ComponentHelper.cs | 75 - .../Utilities/ComponentHelper.cs.meta | 11 - .../Runtime/Internal/Utilities/DataHelper.cs | 110 - .../Internal/Utilities/DataHelper.cs.meta | 11 - .../Internal/Utilities/LayoutHelper.cs | 226 - .../Internal/Utilities/LayoutHelper.cs.meta | 11 - .../Runtime/Internal/Utilities/MathUtil.cs | 45 - .../Internal/Utilities/MathUtil.cs.meta | 11 - .../Runtime/Internal/XCResourcesImporter.cs | 168 - .../Internal/XCResourcesImporter.cs.meta | 11 - Assets/XCharts/Runtime/Internal/XCSettings.cs | 207 - .../Runtime/Internal/XCSettings.cs.meta | 11 - Assets/XCharts/Runtime/Internal/XCThemeMgr.cs | 153 - .../Runtime/Internal/XCThemeMgr.cs.meta | 11 - Assets/XCharts/Runtime/Internal/XChartsMgr.cs | 317 - .../Runtime/Internal/XChartsMgr.cs.meta | 11 - Assets/XCharts/Runtime/Serie.meta | 8 - Assets/XCharts/Runtime/Serie/Bar.meta | 8 - Assets/XCharts/Runtime/Serie/Bar/Bar.cs | 32 - Assets/XCharts/Runtime/Serie/Bar/Bar.cs.meta | 11 - .../XCharts/Runtime/Serie/Bar/BarHandler.cs | 436 - .../Runtime/Serie/Bar/BarHandler.cs.meta | 11 - .../Runtime/Serie/Bar/SimplifiedBar.cs | 41 - .../Runtime/Serie/Bar/SimplifiedBar.cs.meta | 11 - .../Runtime/Serie/Bar/SimplifiedBarHandler.cs | 368 - .../Serie/Bar/SimplifiedBarHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Candlestick.meta | 8 - .../Runtime/Serie/Candlestick/Candlestick.cs | 30 - .../Serie/Candlestick/Candlestick.cs.meta | 11 - .../Serie/Candlestick/CandlestickHandler.cs | 213 - .../Candlestick/CandlestickHandler.cs.meta | 11 - .../Candlestick/SimplifiedCandlestick.cs | 39 - .../Candlestick/SimplifiedCandlestick.cs.meta | 11 - .../SimplifiedCandlestickHandler.cs | 214 - .../SimplifiedCandlestickHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Heatmap.meta | 8 - .../XCharts/Runtime/Serie/Heatmap/Heatmap.cs | 30 - .../Runtime/Serie/Heatmap/Heatmap.cs.meta | 11 - .../Runtime/Serie/Heatmap/HeatmapHandler.cs | 236 - .../Serie/Heatmap/HeatmapHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Line.meta | 8 - Assets/XCharts/Runtime/Serie/Line/Line.cs | 45 - .../XCharts/Runtime/Serie/Line/Line.cs.meta | 11 - .../Serie/Line/LineHandler.GridCoord.cs | 436 - .../Serie/Line/LineHandler.GridCoord.cs.meta | 11 - .../Serie/Line/LineHandler.PolarCoord.cs | 262 - .../Serie/Line/LineHandler.PolarCoord.cs.meta | 11 - .../XCharts/Runtime/Serie/Line/LineHandler.cs | 99 - .../Runtime/Serie/Line/LineHandler.cs.meta | 11 - .../XCharts/Runtime/Serie/Line/LineHelper.cs | 551 - .../Runtime/Serie/Line/LineHelper.cs.meta | 11 - .../Runtime/Serie/Line/SimplifiedLine.cs | 41 - .../Runtime/Serie/Line/SimplifiedLine.cs.meta | 11 - .../Serie/Line/SimplifiedLineHandler.cs | 280 - .../Serie/Line/SimplifiedLineHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Parallel.meta | 8 - .../Runtime/Serie/Parallel/Parallel.cs | 36 - .../Runtime/Serie/Parallel/Parallel.cs.meta | 11 - .../Runtime/Serie/Parallel/ParallelHandler.cs | 150 - .../Serie/Parallel/ParallelHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Pie.meta | 8 - Assets/XCharts/Runtime/Serie/Pie/Pie.cs | 30 - Assets/XCharts/Runtime/Serie/Pie/Pie.cs.meta | 11 - .../XCharts/Runtime/Serie/Pie/PieHandler.cs | 564 - .../Runtime/Serie/Pie/PieHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Radar.meta | 8 - Assets/XCharts/Runtime/Serie/Radar/Radar.cs | 35 - .../XCharts/Runtime/Serie/Radar/Radar.cs.meta | 11 - .../Runtime/Serie/Radar/RadarHandler.cs | 504 - .../Runtime/Serie/Radar/RadarHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Ring.meta | 8 - Assets/XCharts/Runtime/Serie/Ring/Ring.cs | 44 - .../XCharts/Runtime/Serie/Ring/Ring.cs.meta | 11 - .../XCharts/Runtime/Serie/Ring/RingHandler.cs | 323 - .../Runtime/Serie/Ring/RingHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Scatter.meta | 8 - .../Runtime/Serie/Scatter/BaseScatter.cs | 9 - .../Runtime/Serie/Scatter/BaseScatter.cs.meta | 11 - .../Serie/Scatter/BaseScatterHandler.cs | 350 - .../Serie/Scatter/BaseScatterHandler.cs.meta | 11 - .../Runtime/Serie/Scatter/EffectScatter.cs | 27 - .../Serie/Scatter/EffectScatter.cs.meta | 11 - .../Serie/Scatter/EffectScatterHandler.cs | 25 - .../Scatter/EffectScatterHandler.cs.meta | 11 - .../XCharts/Runtime/Serie/Scatter/Scatter.cs | 27 - .../Runtime/Serie/Scatter/Scatter.cs.meta | 11 - .../Runtime/Serie/Scatter/ScatterHandler.cs | 6 - .../Serie/Scatter/ScatterHandler.cs.meta | 11 - .../Runtime/Serie/Serie.ExtraComponent.cs | 150 - .../Serie/Serie.ExtraComponent.cs.meta | 11 - Assets/XCharts/Runtime/Serie/Serie.cs | 1765 - Assets/XCharts/Runtime/Serie/Serie.cs.meta | 11 - Assets/XCharts/Runtime/Serie/SerieContext.cs | 109 - .../Runtime/Serie/SerieContext.cs.meta | 11 - Assets/XCharts/Runtime/Serie/SerieData.cs | 565 - .../XCharts/Runtime/Serie/SerieData.cs.meta | 11 - .../XCharts/Runtime/Serie/SerieDataContext.cs | 84 - .../Runtime/Serie/SerieDataContext.cs.meta | 11 - Assets/XCharts/Runtime/Serie/SerieHandler.cs | 579 - .../Runtime/Serie/SerieHandler.cs.meta | 11 - Assets/XCharts/Runtime/Serie/SerieParams.cs | 24 - .../XCharts/Runtime/Serie/SerieParams.cs.meta | 11 - Assets/XCharts/Runtime/Theme.meta | 8 - Assets/XCharts/Runtime/Theme/AxisTheme.cs | 247 - .../XCharts/Runtime/Theme/AxisTheme.cs.meta | 11 - .../XCharts/Runtime/Theme/ComponentTheme.cs | 102 - .../Runtime/Theme/ComponentTheme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/DataZoomTheme.cs | 125 - .../Runtime/Theme/DataZoomTheme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/LegendTheme.cs | 36 - .../XCharts/Runtime/Theme/LegendTheme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/SerieTheme.cs | 152 - .../XCharts/Runtime/Theme/SerieTheme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/SubTitleTheme.cs | 25 - .../Runtime/Theme/SubTitleTheme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/Theme.cs | 407 - Assets/XCharts/Runtime/Theme/Theme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/ThemeStyle.cs | 236 - .../XCharts/Runtime/Theme/ThemeStyle.cs.meta | 11 - Assets/XCharts/Runtime/Theme/TitleTheme.cs | 24 - .../XCharts/Runtime/Theme/TitleTheme.cs.meta | 11 - Assets/XCharts/Runtime/Theme/TooltipTheme.cs | 118 - .../Runtime/Theme/TooltipTheme.cs.meta | 11 - .../XCharts/Runtime/Theme/VisualMapTheme.cs | 86 - .../Runtime/Theme/VisualMapTheme.cs.meta | 11 - Assets/XCharts/Runtime/Utilities.meta | 8 - Assets/XCharts/Runtime/Utilities/ColorUtil.cs | 22 - .../Runtime/Utilities/ColorUtil.cs.meta | 11 - .../XCharts/Runtime/Utilities/DateTimeUtil.cs | 166 - .../Runtime/Utilities/DateTimeUtil.cs.meta | 11 - .../Runtime/Utilities/DefineSymbolsUtil.cs | 89 - .../Utilities/DefineSymbolsUtil.cs.meta | 11 - .../XCharts/Runtime/Utilities/PropertyUtil.cs | 52 - .../Runtime/Utilities/PropertyUtil.cs.meta | 11 - .../Runtime/Utilities/ReflectionUtil.cs | 133 - .../Runtime/Utilities/ReflectionUtil.cs.meta | 11 - .../XCharts/Runtime/Utilities/RuntimeUtil.cs | 87 - .../Runtime/Utilities/RuntimeUtil.cs.meta | 11 - Assets/XCharts/Runtime/Widgets.meta | 8 - Assets/XCharts/Runtime/Widgets/ProgressBar.cs | 51 - .../Runtime/Widgets/ProgressBar.cs.meta | 11 - Assets/XCharts/Runtime/Widgets/SVGImage.cs | 33 - .../XCharts/Runtime/Widgets/SVGImage.cs.meta | 11 - Assets/XCharts/Runtime/XCharts.Runtime.asmdef | 13 - .../Runtime/XCharts.Runtime.asmdef.meta | 7 - Assets/XCharts/Runtime/XUGL.meta | 8 - Assets/XCharts/Runtime/XUGL/SVG.meta | 8 - Assets/XCharts/Runtime/XUGL/SVG/SVG.cs | 39 - Assets/XCharts/Runtime/XUGL/SVG/SVG.cs.meta | 11 - Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs | 202 - .../XCharts/Runtime/XUGL/SVG/SVGPath.cs.meta | 11 - Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs | 36 - .../Runtime/XUGL/SVG/SVGPathSeg.cs.meta | 11 - .../Runtime/XUGL/SVG/SVGPathSegType.cs | 51 - .../Runtime/XUGL/SVG/SVGPathSegType.cs.meta | 11 - Assets/XCharts/Runtime/XUGL/UGL.cs | 1901 - Assets/XCharts/Runtime/XUGL/UGL.cs.meta | 11 - Assets/XCharts/Runtime/XUGL/UGLExample.cs | 55 - .../XCharts/Runtime/XUGL/UGLExample.cs.meta | 11 - Assets/XCharts/Runtime/XUGL/UGLHelper.cs | 389 - Assets/XCharts/Runtime/XUGL/UGLHelper.cs.meta | 11 - Assets/XCharts/package.json | 27 - Assets/XCharts/package.json.meta | 7 - Packages/manifest.json | 3 +- Packages/packages-lock.json | 9 +- UserSettings/EditorUserSettings.asset | 3 + 835 files changed, 91897 insertions(+), 70660 deletions(-) rename Assets/{XCharts/Documentation.meta => FreeFlyCamera.meta} (77%) rename Assets/{XCharts/Documentation/res.meta => FreeFlyCamera/Demo.meta} (57%) rename Assets/{XCharts/Editor.meta => FreeFlyCamera/Demo/Materials.meta} (57%) create mode 100644 Assets/FreeFlyCamera/Demo/Materials/Material1.mat create mode 100644 Assets/FreeFlyCamera/Demo/Materials/Material1.mat.meta create mode 100644 Assets/FreeFlyCamera/Demo/Materials/Material2.mat create mode 100644 Assets/FreeFlyCamera/Demo/Materials/Material2.mat.meta create mode 100644 Assets/FreeFlyCamera/Demo/Materials/Material3.mat create mode 100644 Assets/FreeFlyCamera/Demo/Materials/Material3.mat.meta rename Assets/{XCharts/Editor/Attributes.meta => FreeFlyCamera/Demo/Scenes.meta} (57%) create mode 100644 Assets/FreeFlyCamera/Demo/Scenes/Demo.unity create mode 100644 Assets/FreeFlyCamera/Demo/Scenes/Demo.unity.meta create mode 100644 Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting create mode 100644 Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting.meta create mode 100644 Assets/FreeFlyCamera/Demo/Scripts.meta create mode 100644 Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs rename Assets/{XCharts/Editor/Attributes/SerieEditorAttribute.cs.meta => FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs.meta} (68%) create mode 100644 Assets/FreeFlyCamera/Documentation.meta create mode 100644 Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf create mode 100644 Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf.meta create mode 100644 Assets/FreeFlyCamera/Documentation/FreeFlyCamera_ru.pdf create mode 100644 Assets/FreeFlyCamera/Documentation/FreeFlyCamera_ru.pdf.meta create mode 100644 Assets/FreeFlyCamera/Scripts.meta create mode 100644 Assets/FreeFlyCamera/Scripts/FreeFlyCamera.cs rename Assets/{XCharts/Editor/Attributes/ComponentEditorAttribute.cs.meta => FreeFlyCamera/Scripts/FreeFlyCamera.cs.meta} (74%) create mode 100644 Assets/FreeFlyCamera/readme.txt rename Assets/{XCharts/Documentation/README-EN.md.meta => FreeFlyCamera/readme.txt.meta} (54%) delete mode 100644 Assets/Prefeb/MessageContents.prefab delete mode 100644 Assets/Prefeb/MessageContents.prefab.meta delete mode 100644 Assets/XCharts/CHANGELOG.md delete mode 100644 Assets/XCharts/CHANGELOG.md.meta delete mode 100644 Assets/XCharts/Documentation/CHANGELOG-EN.md delete mode 100644 Assets/XCharts/Documentation/CHANGELOG-EN.md.meta delete mode 100644 Assets/XCharts/Documentation/README-EN.md delete mode 100644 Assets/XCharts/Documentation/SUPPORT.md delete mode 100644 Assets/XCharts/Documentation/SUPPORT.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsAPI-EN.md delete mode 100644 Assets/XCharts/Documentation/XChartsAPI-EN.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsAPI-ZH.md delete mode 100644 Assets/XCharts/Documentation/XChartsAPI-ZH.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsConfiguration-EN.md delete mode 100644 Assets/XCharts/Documentation/XChartsConfiguration-EN.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsConfiguration-ZH.md delete mode 100644 Assets/XCharts/Documentation/XChartsConfiguration-ZH.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsFAQ-EN.md delete mode 100644 Assets/XCharts/Documentation/XChartsFAQ-EN.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsFAQ-ZH.md delete mode 100644 Assets/XCharts/Documentation/XChartsFAQ-ZH.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsTutorial01-EN.md delete mode 100644 Assets/XCharts/Documentation/XChartsTutorial01-EN.md.meta delete mode 100644 Assets/XCharts/Documentation/XChartsTutorial01-ZH.md delete mode 100644 Assets/XCharts/Documentation/XChartsTutorial01-ZH.md.meta delete mode 100644 Assets/XCharts/Documentation/res/alipay.png delete mode 100644 Assets/XCharts/Documentation/res/alipay.png.meta delete mode 100644 Assets/XCharts/Documentation/res/linechart-simple.png delete mode 100644 Assets/XCharts/Documentation/res/linechart-simple.png.meta delete mode 100644 Assets/XCharts/Documentation/res/linechart.png delete mode 100644 Assets/XCharts/Documentation/res/linechart.png.meta delete mode 100644 Assets/XCharts/Documentation/res/linechart1.png delete mode 100644 Assets/XCharts/Documentation/res/linechart1.png.meta delete mode 100644 Assets/XCharts/Documentation/res/linechart2.png delete mode 100644 Assets/XCharts/Documentation/res/linechart2.png.meta delete mode 100644 Assets/XCharts/Documentation/res/linechart3.png delete mode 100644 Assets/XCharts/Documentation/res/linechart3.png.meta delete mode 100644 Assets/XCharts/Documentation/res/linechart4.png delete mode 100644 Assets/XCharts/Documentation/res/linechart4.png.meta delete mode 100644 Assets/XCharts/Documentation/res/op_addcomponent.png delete mode 100644 Assets/XCharts/Documentation/res/op_addcomponent.png.meta delete mode 100644 Assets/XCharts/Documentation/res/op_addserie.png delete mode 100644 Assets/XCharts/Documentation/res/op_addserie.png.meta delete mode 100644 Assets/XCharts/Documentation/res/op_addseriecomponent.png delete mode 100644 Assets/XCharts/Documentation/res/op_addseriecomponent.png.meta delete mode 100644 Assets/XCharts/Documentation/res/op_addseriedatacomponent.png delete mode 100644 Assets/XCharts/Documentation/res/op_addseriedatacomponent.png.meta delete mode 100644 Assets/XCharts/Documentation/res/op_textmeshpro.png delete mode 100644 Assets/XCharts/Documentation/res/op_textmeshpro.png.meta delete mode 100644 Assets/XCharts/Documentation/res/op_textmeshpro3.png delete mode 100644 Assets/XCharts/Documentation/res/op_textmeshpro3.png.meta delete mode 100644 Assets/XCharts/Documentation/res/wechat.png delete mode 100644 Assets/XCharts/Documentation/res/wechat.png.meta delete mode 100644 Assets/XCharts/Editor/Attributes/ComponentEditorAttribute.cs delete mode 100644 Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs delete mode 100644 Assets/XCharts/Editor/Charts.meta delete mode 100644 Assets/XCharts/Editor/Charts/BaseChartEditor.cs delete mode 100644 Assets/XCharts/Editor/Charts/BaseChartEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LineDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LineDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs delete mode 100644 Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/AxisEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/AxisEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/CommentEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/CommentEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/LegendEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/LegendEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/ThemeEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/ThemeEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/TitleEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/TitleEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/TooltipEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/TooltipEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs delete mode 100644 Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series.meta delete mode 100644 Assets/XCharts/Editor/Series/BarEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/BarEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/CandlestickEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/CandlestickEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/EffectScatterEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/EffectScatterEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/HeatmapEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/HeatmapEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/LineEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/LineEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/ParallelEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/ParallelEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/PieEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/PieEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/RadarEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/RadarEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/RingEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/RingEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/ScatterEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/ScatterEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/SerieBaseEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/SerieBaseEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/SerieEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/SerieEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/SerieListEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/SerieListEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs delete mode 100644 Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Utilities.meta delete mode 100644 Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs delete mode 100644 Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs.meta delete mode 100644 Assets/XCharts/Editor/Utilities/EditorStyles.cs delete mode 100644 Assets/XCharts/Editor/Utilities/EditorStyles.cs.meta delete mode 100644 Assets/XCharts/Editor/Utilities/ThemeCheck.cs delete mode 100644 Assets/XCharts/Editor/Utilities/ThemeCheck.cs.meta delete mode 100644 Assets/XCharts/Editor/Widgets.meta delete mode 100644 Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs delete mode 100644 Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Windows.meta delete mode 100644 Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs delete mode 100644 Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Windows/XCSettingsEditor.cs delete mode 100644 Assets/XCharts/Editor/Windows/XCSettingsEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/Windows/XChartsEditor.cs delete mode 100644 Assets/XCharts/Editor/Windows/XChartsEditor.cs.meta delete mode 100644 Assets/XCharts/Editor/XCharts.Editor.asmdef delete mode 100644 Assets/XCharts/Editor/XCharts.Editor.asmdef.meta delete mode 100644 Assets/XCharts/Examples.meta delete mode 100644 Assets/XCharts/Examples/Example00_CheatSheet.cs delete mode 100644 Assets/XCharts/Examples/Example00_CheatSheet.cs.meta delete mode 100644 Assets/XCharts/Examples/Example01_UpdateData.cs delete mode 100644 Assets/XCharts/Examples/Example01_UpdateData.cs.meta delete mode 100644 Assets/XCharts/Examples/Example02_ChartEvent.cs delete mode 100644 Assets/XCharts/Examples/Example02_ChartEvent.cs.meta delete mode 100644 Assets/XCharts/Examples/Example03_ChartAnimation.cs delete mode 100644 Assets/XCharts/Examples/Example03_ChartAnimation.cs.meta delete mode 100644 Assets/XCharts/Examples/Example10_LineChart.cs delete mode 100644 Assets/XCharts/Examples/Example10_LineChart.cs.meta delete mode 100644 Assets/XCharts/Examples/Example11_AddSinCurve.cs delete mode 100644 Assets/XCharts/Examples/Example11_AddSinCurve.cs.meta delete mode 100644 Assets/XCharts/Examples/Example12_CustomDrawing.cs delete mode 100644 Assets/XCharts/Examples/Example12_CustomDrawing.cs.meta delete mode 100644 Assets/XCharts/Examples/Example13_LineSimple.cs delete mode 100644 Assets/XCharts/Examples/Example13_LineSimple.cs.meta delete mode 100644 Assets/XCharts/Examples/Example20_BarChart.cs delete mode 100644 Assets/XCharts/Examples/Example20_BarChart.cs.meta delete mode 100644 Assets/XCharts/Examples/Example21_BarRace.cs delete mode 100644 Assets/XCharts/Examples/Example21_BarRace.cs.meta delete mode 100644 Assets/XCharts/Examples/Example30_PieChart.cs delete mode 100644 Assets/XCharts/Examples/Example30_PieChart.cs.meta delete mode 100644 Assets/XCharts/Examples/Example31_PieUpdateName.cs delete mode 100644 Assets/XCharts/Examples/Example31_PieUpdateName.cs.meta delete mode 100644 Assets/XCharts/Examples/Example40_Radar.cs delete mode 100644 Assets/XCharts/Examples/Example40_Radar.cs.meta delete mode 100644 Assets/XCharts/Examples/Example41_RadarUpdate.cs delete mode 100644 Assets/XCharts/Examples/Example41_RadarUpdate.cs.meta delete mode 100644 Assets/XCharts/Examples/Example50_Scatter.cs delete mode 100644 Assets/XCharts/Examples/Example50_Scatter.cs.meta delete mode 100644 Assets/XCharts/Examples/Example60_Heatmap.cs delete mode 100644 Assets/XCharts/Examples/Example60_Heatmap.cs.meta delete mode 100644 Assets/XCharts/Examples/Example80_Polar.cs delete mode 100644 Assets/XCharts/Examples/Example80_Polar.cs.meta delete mode 100644 Assets/XCharts/Examples/Example90_Candlestick.cs delete mode 100644 Assets/XCharts/Examples/Example90_Candlestick.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_AddChart.cs delete mode 100644 Assets/XCharts/Examples/Example_AddChart.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_Component.cs delete mode 100644 Assets/XCharts/Examples/Example_Component.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_Dynamic.cs delete mode 100644 Assets/XCharts/Examples/Example_Dynamic.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_LargeData.cs delete mode 100644 Assets/XCharts/Examples/Example_LargeData.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_PieChart.cs delete mode 100644 Assets/XCharts/Examples/Example_PieChart.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_Test.cs delete mode 100644 Assets/XCharts/Examples/Example_Test.cs.meta delete mode 100644 Assets/XCharts/Examples/Example_TestTime.cs delete mode 100644 Assets/XCharts/Examples/Example_TestTime.cs.meta delete mode 100644 Assets/XCharts/Examples/XCharts.Examples.asmdef delete mode 100644 Assets/XCharts/Examples/XCharts.Examples.asmdef.meta delete mode 100644 Assets/XCharts/LICENSE.md delete mode 100644 Assets/XCharts/LICENSE.md.meta delete mode 100644 Assets/XCharts/README.md delete mode 100644 Assets/XCharts/README.md.meta delete mode 100644 Assets/XCharts/Runtime.meta delete mode 100644 Assets/XCharts/Runtime/Chart.meta delete mode 100644 Assets/XCharts/Runtime/Chart/BarChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/BarChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/CandlestickChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/CandlestickChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/HeatmapChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/HeatmapChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/LineChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/LineChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/ParallelChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/ParallelChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/PieChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/PieChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/PolarChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/PolarChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/RadarChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/RadarChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/RingChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/RingChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/ScatterChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/ScatterChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs delete mode 100644 Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component.meta delete mode 100644 Assets/XCharts/Runtime/Component/Animation.meta delete mode 100644 Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AngleAxis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/Axis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/Axis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisLine.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisName.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisName.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisTick.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/AxisTick.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/ParallelAxis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/RadiusAxis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/SingleAxis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/XAxis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/YAxis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs delete mode 100644 Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Background.meta delete mode 100644 Assets/XCharts/Runtime/Component/Background/Background.cs delete mode 100644 Assets/XCharts/Runtime/Component/Background/Background.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/AreaStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/AreaStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/BaseLine.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/BaseLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/IconStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/IconStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/ImageStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/ImageStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/ItemStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/ItemStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/LevelStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/LevelStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/LineArrow.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/LineArrow.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/LineStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/LineStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/Location.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/Location.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/StageColor.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/StageColor.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/TextLimit.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/TextLimit.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/TextPadding.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/TextPadding.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Child/TextStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Child/TextStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Comment.meta delete mode 100644 Assets/XCharts/Runtime/Component/Comment/Comment.cs delete mode 100644 Assets/XCharts/Runtime/Component/Comment/Comment.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Comment/CommentHander.cs delete mode 100644 Assets/XCharts/Runtime/Component/Comment/CommentHander.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Comment/CommentItem.cs delete mode 100644 Assets/XCharts/Runtime/Component/Comment/CommentItem.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom.meta delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Debug.meta delete mode 100644 Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs delete mode 100644 Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis.meta delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Interaction.meta delete mode 100644 Assets/XCharts/Runtime/Component/Interaction/InteractData.cs delete mode 100644 Assets/XCharts/Runtime/Component/Interaction/InteractData.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Label.meta delete mode 100644 Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Label/LabelLine.cs delete mode 100644 Assets/XCharts/Runtime/Component/Label/LabelLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Label/LabelStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Label/LabelStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Legend.meta delete mode 100644 Assets/XCharts/Runtime/Component/Legend/Legend.cs delete mode 100644 Assets/XCharts/Runtime/Component/Legend/Legend.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Legend/LegendContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/Legend/LegendContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Mark.meta delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkArea.cs delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkArea.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkLine.cs delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Radar.meta delete mode 100644 Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs delete mode 100644 Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Settings.meta delete mode 100644 Assets/XCharts/Runtime/Component/Settings/Settings.cs delete mode 100644 Assets/XCharts/Runtime/Component/Settings/Settings.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Title.meta delete mode 100644 Assets/XCharts/Runtime/Component/Title/Title.cs delete mode 100644 Assets/XCharts/Runtime/Component/Title/Title.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Title/TitleHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Title/TitleHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Title/TitleStyle.cs delete mode 100644 Assets/XCharts/Runtime/Component/Title/TitleStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip.meta delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs delete mode 100644 Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap.meta delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs delete mode 100644 Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Calendar.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Grid.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Polar.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs delete mode 100644 Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Coord/SingleAxis.meta delete mode 100644 Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs delete mode 100644 Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Helper.meta delete mode 100644 Assets/XCharts/Runtime/Helper/CheckHelper.cs delete mode 100644 Assets/XCharts/Runtime/Helper/CheckHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Helper/FormatterHelper.cs delete mode 100644 Assets/XCharts/Runtime/Helper/FormatterHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Helper/SerieHelper.cs delete mode 100644 Assets/XCharts/Runtime/Helper/SerieHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs delete mode 100644 Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Helper/SeriesHelper.cs delete mode 100644 Assets/XCharts/Runtime/Helper/SeriesHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/I18n.meta delete mode 100644 Assets/XCharts/Runtime/I18n/Lang.cs delete mode 100644 Assets/XCharts/Runtime/I18n/Lang.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.API.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.API.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Component.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Component.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseChart.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseGraph.API.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseGraph.API.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/BaseGraph.cs delete mode 100644 Assets/XCharts/Runtime/Internal/BaseGraph.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Basic.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/Enums.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/Enums.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Object.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Object/ChartObject.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Object/ChartObject.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Object/ChartText.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Object/ChartText.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Object/LegendItem.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Object/LegendItem.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Painter.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Painter.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Pools.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/ListPool.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/ListPool.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs delete mode 100644 Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs delete mode 100644 Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/XCSettings.cs delete mode 100644 Assets/XCharts/Runtime/Internal/XCSettings.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/XCThemeMgr.cs delete mode 100644 Assets/XCharts/Runtime/Internal/XCThemeMgr.cs.meta delete mode 100644 Assets/XCharts/Runtime/Internal/XChartsMgr.cs delete mode 100644 Assets/XCharts/Runtime/Internal/XChartsMgr.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Bar.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/Bar.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/Bar.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Heatmap.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/Line.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/Line.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHelper.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/LineHelper.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Parallel.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Pie.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Pie/Pie.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Pie/Pie.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Radar.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Radar/Radar.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Radar/Radar.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Ring.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Ring/Ring.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Ring/Ring.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/Serie.cs delete mode 100644 Assets/XCharts/Runtime/Serie/Serie.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/SerieContext.cs delete mode 100644 Assets/XCharts/Runtime/Serie/SerieContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/SerieData.cs delete mode 100644 Assets/XCharts/Runtime/Serie/SerieData.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/SerieDataContext.cs delete mode 100644 Assets/XCharts/Runtime/Serie/SerieDataContext.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/SerieHandler.cs delete mode 100644 Assets/XCharts/Runtime/Serie/SerieHandler.cs.meta delete mode 100644 Assets/XCharts/Runtime/Serie/SerieParams.cs delete mode 100644 Assets/XCharts/Runtime/Serie/SerieParams.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme.meta delete mode 100644 Assets/XCharts/Runtime/Theme/AxisTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/AxisTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/ComponentTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/ComponentTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/DataZoomTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/DataZoomTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/LegendTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/LegendTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/SerieTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/SerieTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/SubTitleTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/SubTitleTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/Theme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/Theme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/ThemeStyle.cs delete mode 100644 Assets/XCharts/Runtime/Theme/ThemeStyle.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/TitleTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/TitleTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/TooltipTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/TooltipTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Theme/VisualMapTheme.cs delete mode 100644 Assets/XCharts/Runtime/Theme/VisualMapTheme.cs.meta delete mode 100644 Assets/XCharts/Runtime/Utilities.meta delete mode 100644 Assets/XCharts/Runtime/Utilities/ColorUtil.cs delete mode 100644 Assets/XCharts/Runtime/Utilities/ColorUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs delete mode 100644 Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs delete mode 100644 Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Utilities/PropertyUtil.cs delete mode 100644 Assets/XCharts/Runtime/Utilities/PropertyUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs delete mode 100644 Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs delete mode 100644 Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs.meta delete mode 100644 Assets/XCharts/Runtime/Widgets.meta delete mode 100644 Assets/XCharts/Runtime/Widgets/ProgressBar.cs delete mode 100644 Assets/XCharts/Runtime/Widgets/ProgressBar.cs.meta delete mode 100644 Assets/XCharts/Runtime/Widgets/SVGImage.cs delete mode 100644 Assets/XCharts/Runtime/Widgets/SVGImage.cs.meta delete mode 100644 Assets/XCharts/Runtime/XCharts.Runtime.asmdef delete mode 100644 Assets/XCharts/Runtime/XCharts.Runtime.asmdef.meta delete mode 100644 Assets/XCharts/Runtime/XUGL.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVG.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVG.cs.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/UGL.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/UGL.cs.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/UGLExample.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/UGLExample.cs.meta delete mode 100644 Assets/XCharts/Runtime/XUGL/UGLHelper.cs delete mode 100644 Assets/XCharts/Runtime/XUGL/UGLHelper.cs.meta delete mode 100644 Assets/XCharts/package.json delete mode 100644 Assets/XCharts/package.json.meta diff --git a/Assets/EnviromentUIControl.cs b/Assets/EnviromentUIControl.cs index d527040..ba3b2bb 100644 --- a/Assets/EnviromentUIControl.cs +++ b/Assets/EnviromentUIControl.cs @@ -1,14 +1,22 @@ +using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; +using XCharts.Runtime; public class EnviromentUIControl : MonoBehaviour { public GameObject agentObj; public TextMeshProUGUI remainTimeText; + public TextMeshProUGUI winLoseText; private AgentWithGun agentScript; + public LineChart realTimeRewardChart; + public GameObject chartContainer; + private float overTime = 0f; + private int step = 0; + private bool resultActive = false; // Start is called before the first frame update void Start() @@ -20,6 +28,44 @@ void Start() void Update() { int remainTime = agentScript.remainTime; + int finishedState = agentScript.finishedState;// 1 = win,2 = lose,0 = not dont remainTimeText.text = "RemainTime:" + remainTime.ToString(); + if (finishedState == 1) + { + //Win + Debug.Log("win"); + winLoseText.text = "Win"; + winLoseText.color = Color.green; + overTime = Time.time; + resultActive = true; + } + else if (finishedState == 2) + { + //lose + Debug.Log("lose"); + winLoseText.text = "Lose"; + winLoseText.color = Color.red; + overTime = Time.time; + resultActive = true; + } + else if (finishedState == 0 && resultActive && Time.time - overTime >= 1) + { + Debug.Log("clear"); + winLoseText.text = ""; + winLoseText.color = Color.white; + resultActive = false; + } + } + public void updateChart(float reward) + { + step += 1; + realTimeRewardChart.AddXAxisData(Convert.ToString(step)); + realTimeRewardChart.AddData(0, reward); + } + + public void initChart() + { + realTimeRewardChart.RemoveData(); + realTimeRewardChart.AddSerie("Rewards"); } } diff --git a/Assets/XCharts/Documentation.meta b/Assets/FreeFlyCamera.meta similarity index 77% rename from Assets/XCharts/Documentation.meta rename to Assets/FreeFlyCamera.meta index 2cab140..60e909a 100644 --- a/Assets/XCharts/Documentation.meta +++ b/Assets/FreeFlyCamera.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0793c29ff7adb422fb93f9f4e29d5a06 +guid: 21e5013de49708245ad4d80e73f0b443 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/XCharts/Documentation/res.meta b/Assets/FreeFlyCamera/Demo.meta similarity index 57% rename from Assets/XCharts/Documentation/res.meta rename to Assets/FreeFlyCamera/Demo.meta index 46be5fd..7cdaa7b 100644 --- a/Assets/XCharts/Documentation/res.meta +++ b/Assets/FreeFlyCamera/Demo.meta @@ -1,8 +1,9 @@ fileFormatVersion: 2 -guid: 377ae219d15f048108309cb7a04de87e +guid: b6ab6d67676e28543bdc43ea7e5dd167 folderAsset: yes +timeCreated: 1550898439 +licenseType: Store DefaultImporter: - externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/XCharts/Editor.meta b/Assets/FreeFlyCamera/Demo/Materials.meta similarity index 57% rename from Assets/XCharts/Editor.meta rename to Assets/FreeFlyCamera/Demo/Materials.meta index 792fad1..28c3123 100644 --- a/Assets/XCharts/Editor.meta +++ b/Assets/FreeFlyCamera/Demo/Materials.meta @@ -1,8 +1,9 @@ fileFormatVersion: 2 -guid: 98b750952a34c427693ac70f09008bae +guid: 5f1c1a5a0e0e3bb459b888a9f0457379 folderAsset: yes +timeCreated: 1550898844 +licenseType: Store DefaultImporter: - externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Materials/Material1.mat b/Assets/FreeFlyCamera/Demo/Materials/Material1.mat new file mode 100644 index 0000000..5ee317a --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Materials/Material1.mat @@ -0,0 +1,74 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Material1 + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0.274 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.054681636, g: 0.24264705, b: 0.039251722, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/FreeFlyCamera/Demo/Materials/Material1.mat.meta b/Assets/FreeFlyCamera/Demo/Materials/Material1.mat.meta new file mode 100644 index 0000000..0f0a664 --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Materials/Material1.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3a271669d58f0234e89082b60f2cc74d +timeCreated: 1549511206 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Materials/Material2.mat b/Assets/FreeFlyCamera/Demo/Materials/Material2.mat new file mode 100644 index 0000000..0a3b959 --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Materials/Material2.mat @@ -0,0 +1,74 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Material2 + m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0.274 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/FreeFlyCamera/Demo/Materials/Material2.mat.meta b/Assets/FreeFlyCamera/Demo/Materials/Material2.mat.meta new file mode 100644 index 0000000..38c1c7d --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Materials/Material2.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 040a3537ac934fb4f802f61d64b1df96 +timeCreated: 1550135995 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Materials/Material3.mat b/Assets/FreeFlyCamera/Demo/Materials/Material3.mat new file mode 100644 index 0000000..2d046fc --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Materials/Material3.mat @@ -0,0 +1,74 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Material3 + m_Shader: {fileID: 10755, guid: 0000000000000000f000000000000000, type: 0} + m_ShaderKeywords: + m_LightmapFlags: 5 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _Glossiness: 0.5 + - _Metallic: 0.274 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/FreeFlyCamera/Demo/Materials/Material3.mat.meta b/Assets/FreeFlyCamera/Demo/Materials/Material3.mat.meta new file mode 100644 index 0000000..16685ed --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Materials/Material3.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8b7360170dc9e0247bd14673208f98db +timeCreated: 1551271332 +licenseType: Store +NativeFormatImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XCharts/Editor/Attributes.meta b/Assets/FreeFlyCamera/Demo/Scenes.meta similarity index 57% rename from Assets/XCharts/Editor/Attributes.meta rename to Assets/FreeFlyCamera/Demo/Scenes.meta index b4b5c1a..d40c324 100644 --- a/Assets/XCharts/Editor/Attributes.meta +++ b/Assets/FreeFlyCamera/Demo/Scenes.meta @@ -1,8 +1,9 @@ fileFormatVersion: 2 -guid: 8e7c19967ca244147b0fcbb129201b46 +guid: 143a3ca44a81328478016ed474fafd7c folderAsset: yes +timeCreated: 1550898794 +licenseType: Store DefaultImporter: - externalObjects: {} userData: assetBundleName: assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Scenes/Demo.unity b/Assets/FreeFlyCamera/Demo/Scenes/Demo.unity new file mode 100644 index 0000000..7a17b4c --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Scenes/Demo.unity @@ -0,0 +1,919 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 0 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 0 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 1024 + m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 512 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 0 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 4890085278179872738, guid: 0c8f3c56faaf72640a28c9f610a57874, type: 2} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &149445736 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 149445738} + - component: {fileID: 149445737} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &149445737 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149445736} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &149445738 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149445736} + m_LocalRotation: {x: 0.40821794, y: -0.23456973, z: 0.109381676, w: 0.87542605} + m_LocalPosition: {x: 0, y: 5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2064642210} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &334844700 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 334844703} + - component: {fileID: 334844702} + - component: {fileID: 334844701} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &334844701 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 334844700} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &334844702 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 334844700} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 5 +--- !u!4 &334844703 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 334844700} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1013428291 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1013428295} + - component: {fileID: 1013428294} + - component: {fileID: 1013428293} + - component: {fileID: 1013428292} + - component: {fileID: 1013428296} + m_Layer: 8 + m_Name: Canvas + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1013428292 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1013428291} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &1013428293 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1013428291} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &1013428294 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1013428291} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 25 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &1013428295 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1013428291} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 1819996184} + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &1013428296 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1013428291} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: b34e588539c7fec4593542da18a65bc5, type: 3} + m_Name: + m_EditorClassIdentifier: + _go: {fileID: 1819996183} +--- !u!1 &1333535851 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1333535855} + - component: {fileID: 1333535854} + - component: {fileID: 1333535853} + - component: {fileID: 1333535852} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &1333535852 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1333535851} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 040a3537ac934fb4f802f61d64b1df96, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!65 &1333535853 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1333535851} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!33 &1333535854 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1333535851} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1333535855 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1333535851} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0.9, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2064642210} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1374784049 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1374784054} + - component: {fileID: 1374784053} + - component: {fileID: 1374784051} + - component: {fileID: 1374784050} + - component: {fileID: 1374784055} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1374784050 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1374784049} + m_Enabled: 1 +--- !u!124 &1374784051 +Behaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1374784049} + m_Enabled: 1 +--- !u!20 &1374784053 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1374784049} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0.019607844} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1374784054 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1374784049} + m_LocalRotation: {x: 0.043619394, y: 0, z: 0, w: 0.99904823} + m_LocalPosition: {x: 0, y: 5, z: -15} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 5, y: 0, z: 0} +--- !u!114 &1374784055 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1374784049} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 436275a13d4459746955fc6db5953473, type: 3} + m_Name: + m_EditorClassIdentifier: + _active: 1 + _enableRotation: 1 + _mouseSense: 1.8 + _enableTranslation: 1 + _translationSpeed: 55 + _enableMovement: 1 + _movementSpeed: 10 + _boostedSpeed: 50 + _boostSpeed: 304 + _moveUp: 101 + _moveDown: 113 + _enableSpeedAcceleration: 1 + _speedAccelerationFactor: 1.5 + _initPositonButton: 114 +--- !u!1 &1819996183 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1819996184} + - component: {fileID: 1819996186} + - component: {fileID: 1819996185} + m_Layer: 5 + m_Name: Panel + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1819996184 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819996183} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1875036768} + m_Father: {fileID: 1013428295} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -10, y: -10} + m_SizeDelta: {x: 325, y: 256} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1819996185 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819996183} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.07682743, g: 0.14550178, b: 0.21323532, a: 0.591} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1819996186 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1819996183} + m_CullTransparentMesh: 1 +--- !u!1 &1848224981 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1848224985} + - component: {fileID: 1848224984} + - component: {fileID: 1848224983} + - component: {fileID: 1848224982} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!23 &1848224982 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1848224981} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 3a271669d58f0234e89082b60f2cc74d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 1 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!65 &1848224983 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1848224981} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!33 &1848224984 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1848224981} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1848224985 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1848224981} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 10, y: 1, z: 10} + m_Children: [] + m_Father: {fileID: 2064642210} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1875036767 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1875036768} + - component: {fileID: 1875036770} + - component: {fileID: 1875036769} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1875036768 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1875036767} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1819996184} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -2.5} + m_SizeDelta: {x: -30, y: -25} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1875036769 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1875036767} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: 'Control tips (toggle H to hide/show this panel) + + + Use: + + > ''MouseMove'' + to rotate; + + > ''W'',''A'',''S'',''D'',''Q'',''E'' to move; + + > ''Left + Shift'' to accelerate the movement speed; + + > ''Mouse Scroll Wheel'' to zoom + in/out; + + > ''Escape'' to unlock control and show the pointer; + + > ''Left + Mouse Button'' click on in-game screen (in play mode) to lock control and hide + the pointer; + + > ''R'' to return camera into initial position. + +' +--- !u!222 &1875036770 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1875036767} + m_CullTransparentMesh: 1 +--- !u!1 &2064642209 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2064642210} + m_Layer: 0 + m_Name: Map + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &2064642210 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2064642209} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 149445738} + - {fileID: 1848224985} + - {fileID: 1333535855} + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/FreeFlyCamera/Demo/Scenes/Demo.unity.meta b/Assets/FreeFlyCamera/Demo/Scenes/Demo.unity.meta new file mode 100644 index 0000000..a349127 --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Scenes/Demo.unity.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 76846e8e140c969489cb8cecd8dfa198 +timeCreated: 1550898786 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting b/Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting new file mode 100644 index 0000000..13a5071 --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting @@ -0,0 +1,63 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!850595691 &4890085278179872738 +LightingSettings: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: DemoSettings + serializedVersion: 3 + m_GIWorkflowMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 1 + m_RealtimeEnvironmentLighting: 1 + m_BounceScale: 1 + m_AlbedoBoost: 1 + m_IndirectOutputScale: 1 + m_UsingShadowmask: 0 + m_BakeBackend: 0 + m_LightmapMaxSize: 1024 + m_BakeResolution: 40 + m_Padding: 2 + m_TextureCompression: 1 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 0 + m_CompAOExponentDirect: 0 + m_ExtractAO: 0 + m_MixedBakeMode: 1 + m_LightmapsBakeMode: 0 + m_FilterMode: 1 + m_LightmapParameters: {fileID: 15204, guid: 0000000000000000f000000000000000, type: 0} + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_RealtimeResolution: 2 + m_ForceWhiteAlbedo: 0 + m_ForceUpdates: 0 + m_FinalGather: 0 + m_FinalGatherRayCount: 1024 + m_FinalGatherFiltering: 1 + m_PVRCulling: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVREnvironmentSampleCount: 512 + m_PVREnvironmentReferencePointCount: 2048 + m_LightProbeSampleCountMultiplier: 4 + m_PVRBounces: 2 + m_PVRMinBounces: 2 + m_PVREnvironmentMIS: 0 + m_PVRFilteringMode: 0 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 diff --git a/Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting.meta b/Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting.meta new file mode 100644 index 0000000..ebb8a4f --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Scenes/DemoSettings.lighting.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0c8f3c56faaf72640a28c9f610a57874 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 4890085278179872738 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Scripts.meta b/Assets/FreeFlyCamera/Demo/Scripts.meta new file mode 100644 index 0000000..ad925de --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Scripts.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: c71ec374f199933419b2652507dbd746 +folderAsset: yes +timeCreated: 1550899852 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs b/Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs new file mode 100644 index 0000000..95fa764 --- /dev/null +++ b/Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs @@ -0,0 +1,18 @@ +using UnityEngine; + +public class ToggleGameObjectEnable : MonoBehaviour +{ + [SerializeField] + private GameObject _go; + + private bool _enabled = true; + + private void Update() + { + if (Input.GetKeyDown(KeyCode.H)) + { + _enabled = !_enabled; + _go.SetActive(_enabled); + } + } +} diff --git a/Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs.meta b/Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs.meta similarity index 68% rename from Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs.meta rename to Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs.meta index a94ad04..f7b4b94 100644 --- a/Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs.meta +++ b/Assets/FreeFlyCamera/Demo/Scripts/ToggleGameObjectEnable.cs.meta @@ -1,7 +1,8 @@ fileFormatVersion: 2 -guid: dcdc7a72224af419d96584fa40f822c9 +guid: b34e588539c7fec4593542da18a65bc5 +timeCreated: 1550899868 +licenseType: Store MonoImporter: - externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/FreeFlyCamera/Documentation.meta b/Assets/FreeFlyCamera/Documentation.meta new file mode 100644 index 0000000..ca7b1da --- /dev/null +++ b/Assets/FreeFlyCamera/Documentation.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1894414b42fe5e343b181b818b714b55 +folderAsset: yes +timeCreated: 1552910252 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf b/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf new file mode 100644 index 0000000000000000000000000000000000000000..170d1ac6a8693cded437c3c681df5ec0369e7155 GIT binary patch literal 258436 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

Z!4 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�*P3=5rulkx|c{s)){56THf#h=E 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 literal 0 HcmV?d00001 diff --git a/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf.meta b/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf.meta new file mode 100644 index 0000000..8fd1cfd --- /dev/null +++ b/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_en.pdf.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e77f4846974bc9a4f8d3e01f6b2653c3 +timeCreated: 1556081593 +licenseType: Store +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_ru.pdf b/Assets/FreeFlyCamera/Documentation/FreeFlyCamera_ru.pdf new file mode 100644 index 0000000000000000000000000000000000000000..81bb3e709b0367c93e352b6dd7c5bc343a20c0e7 GIT binary patch literal 263092 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

ue=gDcq)vW0LTNO)-+X3z<|s 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

FjP`^f_7R%|4~fQ&Dx{mL>l>Xg$v3 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

T5U)g;p}J*SK=!)$~*_V>c;2 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̈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 rayScript = GetComponent(); // give default Reward to Reward value will be used. nonReward = nonRewardDefault; @@ -107,6 +112,7 @@ private void Start() winReward = winRewardDefault; loseReward = loseRewardDefault; killReward = killRewardDefault; + killBonusReward = killBonusRewardDefault; //initialize remainTime remainTime = (int)(timeLimit - Time.time + startTime); @@ -399,6 +405,9 @@ public float rewardCalculate() for (int i = 0; i < enemyKillCount; i++) { epreward += killReward; + nonReward += killBonusReward; + shootReward += killBonusReward; + shootWithoutReadyReward += killBonusReward; } enemyKillCount = 0; } @@ -428,6 +437,16 @@ public override void OnEpisodeBegin() randomInitAgent(); randomInitEnemys(enemyNum); nowEnemyNum = getEnemyNum(); // Reset Enemy number + // give default Reward to Reward value will be used. + EnvUICon.initChart(); + nonReward = nonRewardDefault; + shootReward = shootRewardDefault; + shootWithoutReadyReward = shootWithoutReadyRewardDefault; + hitReward = hitRewardDefault; + winReward = winRewardDefault; + loseReward = loseRewardDefault; + killReward = killRewardDefault; + killBonusReward = killBonusRewardDefault; } // ML-AGENTS处理-------------------------------------------------------------------------------------------ML-AGENTS @@ -475,20 +494,21 @@ public override void OnActionReceived(ActionBuffers actionBuffers) float thisRoundReward = rewardCalculate(); //判断结束 - int finished = checkFinish(); - if (finished == 1) + finishedState = checkFinish(); + if (finishedState == 1) { //Win Finished EP += 1; + EnvUICon.updateChart(winReward); SetReward(winReward); Debug.Log("reward = " + winReward); EndEpisode(); } - else if (finished == 2) + else if (finishedState == 2) { //Lose Finished - EP += 1; + EnvUICon.updateChart(loseReward); SetReward(loseReward); Debug.Log("reward = " + loseReward); EndEpisode(); @@ -497,6 +517,7 @@ public override void OnActionReceived(ActionBuffers actionBuffers) { // game not over yet step += 1; + EnvUICon.updateChart(thisRoundReward); SetReward(thisRoundReward); Debug.Log("reward = " + thisRoundReward); } @@ -506,7 +527,6 @@ public override void OnActionReceived(ActionBuffers actionBuffers) // 控制调试 public override void Heuristic(in ActionBuffers actionsOut) { - // //-------------------BUILD ActionSegment continuousActions = actionsOut.ContinuousActions; ActionSegment discreteActions = actionsOut.DiscreteActions; diff --git a/Assets/Script/InGame/RaySensors.cs b/Assets/Script/InGame/RaySensors.cs index 49f6e48..b05937e 100644 --- a/Assets/Script/InGame/RaySensors.cs +++ b/Assets/Script/InGame/RaySensors.cs @@ -9,6 +9,7 @@ public class RaySensors : MonoBehaviour { public Camera agentCam; + public Camera TPSCam; public Material lineMeterial; public GameObject rayInfoPrefab; public GameObject agentCanvas; @@ -125,7 +126,7 @@ private void singleRaycastUpdate(Ray ray,LineRenderer thisLineRenderer,rayInfoUI turnOffLine(thisLineRenderer, rayColor); } // drawRay in game - if (showInGameRayInfo) thisRayInfoUI.updateInfo(rayInfoText, rayInfoPosition, rayColor); + if (showInGameRayInfo) thisRayInfoUI.updateInfo(rayInfoText, rayInfoPosition, rayColor,TPSCam); // Show log if (showDebugRay) Debug.DrawRay(ray.origin, ray.direction * viewDistance, rayColor); // drawRay in debug // Debug.Log(ray.origin + ray.direction); diff --git a/Assets/Script/InGame/rayInfoUI.cs b/Assets/Script/InGame/rayInfoUI.cs index 7ac7b72..05ea6eb 100644 --- a/Assets/Script/InGame/rayInfoUI.cs +++ b/Assets/Script/InGame/rayInfoUI.cs @@ -5,21 +5,33 @@ public class rayInfoUI : MonoBehaviour { TextMeshProUGUI infoText; - + bool infoTextReady = false; // Start is called before the first frame update void Start() { - infoText = transform.GetChild(0).gameObject.GetComponent(); + try + { + infoText = transform.GetChild(0).gameObject.GetComponent(); + infoTextReady = true; + } + catch (UnityException) + { + infoTextReady = false; + } } - public void updateInfo(string info,Vector3 infoPosition, Color infoColor) + public void updateInfo(string info,Vector3 infoPosition, Color infoColor,Camera facetoCamera) { + if (!infoTextReady) + { + infoText = transform.GetChild(0).gameObject.GetComponent(); + } infoText.text = info; infoText.color = infoColor; transform.position = infoPosition; - Vector3 v = Camera.main.transform.position - infoPosition; + Vector3 v = facetoCamera.transform.position - infoPosition; v.x = v.z = 0.0f; - transform.LookAt(Camera.main.transform.position - v); + transform.LookAt(facetoCamera.transform.position - v); transform.Rotate(0, 180, 0); } } diff --git a/Assets/XCharts/CHANGELOG.md b/Assets/XCharts/CHANGELOG.md deleted file mode 100644 index 4975545..0000000 --- a/Assets/XCharts/CHANGELOG.md +++ /dev/null @@ -1,705 +0,0 @@ - -# 更新日志 - -[master](#master) -[v3.0.1](#v3.0.1) -[v3.0.0](#v3.0.0) -[v3.0.0-preivew9](#v3.0.0-preivew9) -[v3.0.0-preivew8](#v3.0.0-preivew8) -[v3.0.0-preivew7](#v3.0.0-preivew7) -[v3.0.0-preivew6](#v3.0.0-preivew6) -[v3.0.0-preivew5](#v3.0.0-preivew5) -[v3.0.0-preivew4](#v3.0.0-preivew4) -[v3.0.0-preivew3](#v3.0.0-preivew3) -[v3.0.0-preivew2](#v3.0.0-preivew2) -[v3.0.0-preivew1](#v3.0.0-preivew1) -[v2.7.0](#v2.7.0) -[v2.6.0](#v2.6.0) -[v2.5.0](#v2.5.0) -[v2.4.0](#v2.4.0) -[v2.3.0](#v2.3.0) -[v2.2.3](#v2.2.3) -[v2.2.2](#v2.2.2) -[v2.2.1](#v2.2.1) -[v2.2.0](#v2.2.0) -[v2.1.1](#v2.1.1) -[v2.1.0](#v2.1.0) -[v2.0.1](#v2.0.1) -[v2.0.0](#v2.0.0) -[v2.0.0-preview.2](#v2.0.0-preview.2) -[v2.0.0-preview.1](#v2.0.0-preview.1) -[v1.6.3](#v1.6.3) -[v1.6.1](#v1.6.1) -[v1.6.0](#v1.6.0) -[v1.5.2](#v1.5.2) -[v1.5.1](#v1.5.1) -[v1.5.0](#v1.5.0) -[v1.4.0](#v1.4.0) -[v1.3.1](#v1.3.1) -[v1.3.0](#v1.3.0) -[v1.2.0](#v1.2.0) -[v1.1.0](#v1.1.0) -[v1.0.5](#v1.0.5) -[v1.0.4](#v1.0.4) -[v1.0.3](#v1.0.3) -[v1.0.2](#v1.0.2) -[v1.0.1](#v1.0.1) -[v1.0.0](#v1.0.0) -[v0.8.3](#v0.8.3) -[v0.8.2](#v0.8.2) -[v0.8.1](#v0.8.1) -[v0.8.0](#v0.8.0) -[v0.5.0](#v0.5.0) -[v0.1.0](#v0.1.0) - -## master - -## v3.0.1 - -* (2022.06.16) 发布`v3.0.1`版本 -* (2022.06.16) 修复`Inspector`上部分`foldout`箭头点击无法展开的问题 -* (2022.06.16) 修复`Inspector`上部分`foldout`箭头点击无法展开的问题 -* (2022.06.15) 优化`Doc`自动生成,完善代码注释和配置项手册文档 -* (2022.06.14) 优化`SerieLabelStyle`,支持动态调整`Icon` -* (2022.06.13) 优化`Background`背景设置 -* (2022.06.10) 增加`Legend`的`AxisLabel`支持`autoColor` -* (2022.06.08) 修复`Axis`的`AxisLabel`在设置不显示时还显示首尾两个`label`的问题 - -## v3.0.0 - -* 更健壮的底层框架。 -* 更强大的性能。 -* 更小的序列化文件。 -* 更好的交互体验。 -* 更多的组件支持。 -* 更强大的文本自述能力。 -* 更合理的组件调整。 -* 更灵活的组件插拔。 -* 更高效的二次开发。 -* 更丰富的Demo示例。 -* 增加`Time`时间轴。 -* 增加`SingleAxis`单轴。 -* 增加`Comment`文本组件。 -* 增加`Widgets`小组件。 -* 增加多种坐标系:`Grid`、`Polar`、`Radar`、`SingleAxis`。 -* 增加多种动画方式。 -* 增加多种图表交互。 -* 增加国际化支持。 -* 增加多种扩展图表。 - -## v3.0.0-preivew9 - -* (2022.05.06) 发布`v3.0.0-preivew9`版本 -* (2022.05.05) 优化`ItemStyle`设置`color`时的一致性 -* (2022.05.05) 增加`Line`对`Dash`,`Dot`等的支持 (#197) -* (2022.05.04) 增加`Legend`的委托回调 -* (2022.05.04) 优化`Symbol`和`Label` -* (2022.05.01) 增加`Bar`对`clip`的支持 (#196) -* (2022.05.01) 修复`RingChart`的`Label`不刷新的问题 (#195) -* (2022.04.29) 增加`Tooltip`支持自定义背景图 -* (2022.04.27) 修复`ItemStyle`代码修改`color`不刷新的问题 - -## v3.0.0-preivew8 - -* (2022.04.26) 发布`v3.0.0-preivew8`版本 -* (2022.04.23) 移除`Serie`的`IconStyle`组件 -* (2022.04.23) 强化`LabelStyle`,所有组件的`TextStyle`都升级为`LabelStyle` -* (2022.04.19) 增加`Label`的`rotate`支持设置旋转 -* (2022.04.17) 修复`Bar`在数值为负数时动画无效的问题 -* (2022.04.17) 增加`ItemStyle`的`BorderGap`支持设置边框间距 -* (2022.04.16) 优化`Bar`的`Border`和`Capsule`胶囊柱图 -* (2022.04.15) 增加`Liquid`对`Round Rect`圆角矩形水位图的支持 -* (2022.04.14) 增加`Line`对`EndLabel`的支持 -* (2022.04.13) 增加`VisualMap`的`workOnLine`和`workOnArea`支持折线和区域映射功能 (#191) -* (2022.04.12) 优化`Radar`支持`Area`区域触发`Tooltip` -* (2022.04.09) 优化`VisualMap` -* (2022.04.09) 优化`Tooltip` - -## v3.0.0-preivew7 - -* (2022.04.07) 发布`v3.0.0-preivew7`版本 -* (2022.04.07) 修复`Pie`颜色不刷新的问题 -* (2022.03.31) 修复`Add Main Component`添加组件异常的问题 -* (2022.03.30) 修复`Axis`无法自定义`Label`颜色的问题 - -## v3.0.0-preivew6 - -* (2022.03.30) 发布`v3.0.0-preivew6`版本 - -## v3.0.0-preivew5 - -* (2022.03.26) 发布`v3.0.0-preivew5`版本 - -## v3.0.0-preivew4 - -* (2022.03.21) 发布`v3.0.0-preivew4`版本 - -## v3.0.0-preivew3 - -* (2022.03.09) 发布`v3.0.0-preivew3`版本 - -## v3.0.0-preivew2 - -* (2022.01.08) 发布`v3.0.0-preivew2`版本 - -## v3.0.0-preivew1 - -* (2022.01.07) 发布`v3.0.0-preivew1`版本 - -## v2.7.0 - -* (2022.03.20) 发布`v2.7.0`版本 -* (2022.02.21) 修复`Chart`的`chartName`重复检测问题 #183 -* (2022.02.17) 修复`Axis`的`SplitLine`可能会显示在坐标系外的问题 #181 -* (2022.02.08) 修复数据全0时`{d}`显示不正确的问题 -* (2022.02.08) 修复`YAxis`的`AxisLabel`的`onZero`参数不生效的问题 -* (2022.01.06) 优化`Zebra`斑马柱图 - -## v2.6.0 - -* (2021.12.30) 发布`v2.6.0`版本 -* (2021.12.21) 修复`Emphasis`不生效的问题 -* (2021.12.17) 修复`MarkLine`在运行时`Label`不自动刷新显示隐藏的问题 #178 -* (2021.12.10) 完善`Radar`的`AxisLine`和`SplitLine`可单独控制 -* (2021.12.08) 修复`Serie`隐藏后`Y`轴最大值不刷新的问题 -* (2021.12.04) 增加`Symbol`新类型:`EmptyRect`,`EmptyTriangle`,`EmptyDiamond` -* (2021.12.04) 增加`Symbol`的`Empty`区域颜色可通过`ItemStyle`的`backgroundColor`设置的支持 -* (2021.12.03) 修复`Formatter`的`{c}`通配符不生效的问题 #175 -* (2021.12.03) 修复`Axis`的`boundaryGap`某些情况下显示的问题 #174 -* (2021.11.30) 修复`Serie`的`ignore`某些情况下绘制异常的问题 #173 - -## v2.5.0 - -* (2021.11.27) 发布`v2.5.0`版本 -* (2021.11.27) 增加`Tooltip`的`positionFunction`的坐标设置委托函数 -* (2021.10.29) 移除`XCharts`首次导入时`TextMeshPro`的相关设置 -* (2021.10.29) 增加`Tooltip`对通配符`{e}`的支持 #170 -* (2021.09.08) 完善`RadarChart` -* (2021.09.07) 修复`PieChart`渐出动画结束时`label`没有消失的问题 #168 -* (2021.09.06) 修复`GaugeChart`用代码改变`splitNumber`不会刷新`label`的问题 #167 - -## v2.4.0 - -### 版本要点 - -* 折线图支持忽略数据的连线是断开还是连接 -* 折线图支持轨迹匀速动画 -* 其他优化和问题修复 - -### 日志详情 - -* (2021.08.31) 发布`v2.4.0`版本 -* (2021.08.31) 优化`RingChart`的渐变效果 -* (2021.08.31) 修复`DataZoom`拖动时`SerieLabel`不刷新的问题 (#165) -* (2021.08.25) 修复`Theme`主题切换无法保持到场景上的问题 (#166) -* (2021.08.24) 增加`Animation`的`alongWithLinePath`参数设置折线轨迹匀速动画 -* (2021.08.22) 增加`Serie`的`ignoreLineBreak`参数设置忽略数据连线是否断开 (#164) -* (2021.08.22) 修复`Axis`在`DataZoom`开启时`Label`可能不更新的问题 (#164) -* (2021.08.15) 优化`Axis`的`AxisLabel`文本旋转设置,避免在DataZoom开启时偏移不一致 (#163) -* (2021.08.14) 增加`Legend`的`textAutoColor`设置文本颜色和`Serie`一致 (#163) -* (2021.08.12) 优化`BarChart`设置`Corner`时正负柱条圆角对称 -* (2021.08.03) 优化`Serie`的数据全为0时Y轴不显示的问题 -* (2021.07.29) 修复`Serie`开启`ignore`时被忽略的数据还会参与计算的问题 (#161) -* (2021.07.29) 完善`BarChart`的`Zebra`斑马柱图渐变支持 -* (2021.07.26) 修复`TextMeshPro Enable`时找不到`XCharts`路径的问题 (#160) - -## v2.3.0 - -### 版本要点 - -* 数据存储由`float`升级为`double` -* 新增`MarkLine`标线 -* `Serie`下可用`IconStyle`统一配置图标 -* `Label`支持用代码自定义显示样式 -* `DataZoom`完善 -* `PieChart`优化 -* 问题修复 - -### 升级注意 - -由于数据类型升级为了`double`,`float`隐式转`double`可能有精度问题,所以建议之前为`float`的数据类型都手动改为`double`类型。 - -### 日志详情 - -* (2021.07.24) 发布`v2.3.0`版本 -* (2021.07.22) 完善`SerieSymbol`以支持象形柱图`PictorialBarChart`扩展 -* (2021.07.19) 修复`WdbGL`平台上`Tooltip`不显示的问题 -* (2021.07.18) 增加`Serie`的`iconStyle`统一配置图标 -* (2021.07.15) 增加`MarkLine`标线 (#142) -* (2021.07.09) 优化`BarChart`可通过`serieData.show`设置是否显示柱条 -* (2021.07.08) 优化`data`数据存储类型由`float`全部转为`double` -* (2021.07.05) 修复`PieChart`的`avoidLabelOverlap`参数不生效的问题 -* (2021.07.04) 修复`PieChart`选中扇区后鼠标区域指示不准确的问题 -* (2021.07.04) 优化`PieChart`的`Label`为`Inside`时可通过参数`Margin`调节偏移 -* (2021.07.01) 增加`DataZoom`的`supportInsideScroll`和`supportInsideDrag`参数设置坐标系内是否支持滚动和拖拽 -* (2021.06.27) 增加`AxisLabel`的`showStartLabel`和`showEndLabel`参数设置首尾的`Label`是否显示 -* (2021.06.27) 增加`AxisLabel`和`SerieLabel`的`formatter`委托方法 (#145) -* (2021.06.27) 增加`DataZoom`的`orient`参数设置水平或垂直样式 -* (2021.06.21) 增加`IconStyle`的`autoHideWhenLabelEmpty`参数设置当`label`为空时是否自动隐藏图标 - -## v2.2.3 - -* (2021.06.20) 发布`v2.2.3`版本 -* (2021.06.20) 修复`Axis`的`Icon`默认显示出来的问题 - -## v2.2.2 - -* (2021.06.18) 发布`v2.2.2`版本 -* (2021.06.18) 优化`Axis`的`Label`为空时自动隐藏`Icon` -* (2021.06.17) 修复`maxCache`设置时实际数据个数多一个的问题 -* (2021.06.17) 修复`TextMeshPro`的开启和关闭不及时刷新的问题 -* (2021.06.17) 修复`XCharts`导入时总是弹出`XCharts Importer`的问题 - -## v2.2.1 - -* (2021.06.13) 发布`v2.2.1`版本 -* (2021.06.13) 完善对多屏幕的支持 -* (2021.06.12) 增加`IconStyle`的`align`参数设置图标的水平对齐 -* (2021.06.12) 完善`Theme`主题导入 (#148) -* (2021.06.10) 修复`Unity`版本兼容问题 (#154) -* (2021.06.05) 完善`CandlestickChart`对`inverse`的支持 (#152) -* (2021.06.04) 修复`Gauge`在最小值为负数时指针指示位置异常的问题 (#153) - -## v2.2.0 - -* (2021.05.30) 发布`v2.2.0`版本 -* (2021.05.25) 完善`TextStyle`的`alignment`的支持 (#150) -* (2021.05.24) 修复`PieChart`数据全为`0`时`Label`无法正常显示的问题 -* (2021.05.24) 修复`Add Serie`面板上`Serie Name`不生效的问题 (#149) -* (2021.05.23) 增加`TextStyle`的`autoWrap`设置是否自动换行 -* (2021.05.23) 增加`TextStyle`的`autoAlign`设置是否让系统自动设置对齐方式 -* (2021.05.23) 增加`AxisLabel`的`width`和`height`支持自定义文本的长宽 -* (2021.05.23) 增加`Axis`的`iconStyle`和`icons`支持设置坐标轴标签显示图标 -* (2021.05.20) 增加`Serie`和`Axis`的`insertDataToHead`参数控制数据插入头部还是尾部 -* (2021.05.18) 优化`Editor`下的图表创建 #147 -* (2021.05.16) 抽离`GanttChart`甘特图,通过扩展模块的方式来提供 -* (2021.05.11) 增加`VisualMap`对`Piecewise`分段设置颜色的支持 -* (2021.05.09) 修复`RingChart`无法设置环形的背景色的问题 #141 -* (2021.05.08) 增加`LiquidChart`的方形水位图支持 -* (2021.05.07) 优化`Axis`的刻度表现 #135 -* (2021.05.01) 增加`Settings`中关于关于材质球设置的参数 #140 -* (2021.05.01) 修复无法正确表示部分超大或超小数值的问题 -* (2021.04.29) 修复`Radar`切换到`Circle`异常的问题 #139 -* (2021.04.29) 增加`Settings`的`reversePainter`可设置`Serie`的绘制是否逆序 -* (2021.04.28) 增加`SerieData`的`ignore`可忽略当前数据项 -* (2021.04.28) 修复`DataZoom`下`AxisLabel`显示不准确的问题 #138 -* (2021.04.26) 修复运行时动态创建图表会异常的问题 #137 -* (2021.04.26) 增加`BarChart`绘制渐变边框的支持 -* (2021.04.23) 增加自定义图表支持 -* (2021.04.22) 修复`Gauge`的`AxisLabel`和文字颜色无法调整的问题 -* (2021.04.13) 增加`AxisTick`的`ShowStartTick`和`ShowEndTick`参数控制第一个和最后一个刻度是否显示 -* (2021.04.13) 完善多坐标轴的支持 #132 - -## v2.1.1 - -* (2021.04.13) 整理代码,清除`Warning` -* (2021.04.13) 修复`Unity`版本兼容问题 -* (2021.04.12) 修复`Theme`重构后引起的`missing class attribute 'ExtensionOfNativeClass'`的问题 #131 - -## v2.1.0 - -* (2021.04.07) 发布`v2.1.0`版本 -* (2021.03.31) 优化和重构`Theme`,解决引用相同或丢失的问题 #118 -* (2021.03.30) 优化`Tooltip`支持设置不同的类目轴数据 #129 -* (2021.03.29) 优化自定义绘制回调接口,增加`onCustomDrawBeforeSerie`、`onCustomDrawAfterSerie`和`onCustomDrawTop` -* (2021.03.25) 增加`GanttChart`甘特图 -* (2021.03.22) 增加`Theme`的`Unbind`按钮用于解绑复制图表时的主题 #118 -* (2021.03.18) 修复`Inspector`下`Foldout`后的勾选框无法选中的问题 -* (2021.03.18) 修复`BarChart`在`0`数值时显示异常的问题 -* (2021.03.14) 修复`Tooltip`的指示器在某些情况下指示位置不准的问题 -* (2021.03.13) 优化`MultiComponentMode`开启后的编辑体验和组件刷新 #128 -* (2021.03.10) 增加`CandlestickChart`K线图 #124 -* (2021.03.06) 增加`PieChart`的`minAngle`参数支持设置最小扇区角度 #117 -* (2021.03.05) 增加`Legend`几种内置图标的支持 #90 -* (2021.03.02) 增加`DataZoom`对数值轴的支持 #71 -* (2021.03.02) 优化`TextMeshPro`兼容问题 #125 -* (2021.03.01) 修复隐藏和显示图表时部分已隐藏的节点显示异常的问题 #125 - -## v2.0.1 - -* (2021.02.26) 修复`HeatmapChart`的`Tooltip`指示的位置不准的问题 #123 -* (2021.02.22) 修复`Unity`版本兼容问题 -* (2021.02.21) 增加`Tooltip`的`ignoreDataShow`参数 -* (2021.02.19) 修复图表在`LayoutGroup`控制下时可能显示错乱的问题 #121 -* (2021.02.18) 修复`Radar`参数变更后无法自刷新的问题 #122 - -## v2.0.0 - -* (2021.02.05) 发布`v2.0.0`版本 -* (2021.02.03) 修复`AxisLine`的`OnZero`对`YAxis`不生效的问题 #116 -* (2021.01.29) 修复`Category`轴在`BoundaryGap`和`AlignWithLabel`为`True`时`Tick`显示效果不对的问题 #115 -* (2021.01.25) 优化一些细节 -* (2021.01.22) 修复`Inpsector`上部分属性显示异常的问题 - -## v2.0.0-preview.2 - -* (2021.01.21) 发布`v2.0.0-preview.2`版本 -* (2021.01.21) 修复`Inpsector`上展开`AxisTick`时报错问题 -* (2021.01.21) 修复打包兼容报错问题 -* (2021.01.19) 增加`XChartsSettings`的`editorShowAllListData`参数配置是否在`Inspector`中显示列表的所有数据 - -## v2.0.0-preview.1 - -* (2021.01.19) 发布`v2.0.0-preview.1`版本 - -## v1.6.3 - -* (2021.01.02) 发布`v1.6.3`版本 -* (2020.12.18) 修复`Animation`不启用时更新数据会导致图表一直刷新的问题 -* (2020.12.01) 修复`Unity2020`上新创建的图表无法正常绘制的问题 -* (2020.11.22) 发布`v1.6.2`版本 -* (2020.11.22) 修复`LineChart`在数据过于密集时折线绘制异常的问题 #99 -* (2020.11.21) 修复`LineChart`的刻度位置在`alignWithLabel`为`true`时可能异常的问题 -* (2020.11.21) 修复`Unity5`兼容报错的问题 -* (2020.11.13) 完善`RadarChart`的`Indicator`对`\n`换行的支持 -* (2020.11.12) 修复`LineChart`当类型为`Smooth`时数据过密情况下报错的问题 #100 -* (2020.10.22) 完善`HeatmapChart`中`VisualMap`对`Piecewise`的支持 -* (2020.09.22) 修复`PieChart`边框大小不一致的问题 - -## v1.6.1 - -* (2020.09.19) 发布`v1.6.1`版本 -* (2020.09.19) 增加`Remove All Chart Object`移除图表下的所有子节点(会自动重新初始化) -* (2020.09.18) 修复`SerieLabel`在点击图例隐藏`Serie`后还显示的问题#94 -* (2020.09.18) 优化`Axis`的类目轴刻度和文本显示#93 -* (2020.09.17) 修复`Package`导入时缺失`meta`文件导致失败的问题#92 -* (2020.09.08) 优化`Legend`的颜色可自动匹配`ItemStyle`的自定义颜色#89 -* (2020.09.05) 优化`LineChart`在不使用`XAxis1`时也能显示`XAxis1` -* (2020.08.29) 增加`LineStyle`的`toColor`和`toColor2`设置`LineChart`的水平渐变,取消通过`ItemStyle`设置`LineChart`的水平渐变 -* (2020.08.29) 增加`PieChart`的`onPointerClickPie`点击扇形图扇区回调 -* (2020.08.29) 增加`BarChart`的`onPointerClickBar`点击柱形图柱条回调 - -## v1.6.0 - -* (2020.08.24) 发布`v1.6.0`版本 -* (2020.08.23) 重构代码,将与绘制相关的`Color`改为`Color32`,减少隐式转换(更新后会导致自定义的颜色丢失,可参考[问答29](https://github.com/XCharts-Team/XCharts/blob/master/Assets/XCharts/Documentation/XChartsFAQ-ZH.md)进行升级) -* (2020.08.15) 优化`PieChart`绘制表现效果#85 -* (2020.08.11) 增加`LiquidChart`数据变更动画#83 -* (2020.08.11) 优化`PieChart`文本堆叠和引线效果#85 -* (2020.08.08) 优化`LineChart`密集数据的绘制表现效果 -* (2020.07.30) 增加`LineChart`可通过`VisualMap`或`ItemStyle`配置渐变#78 -* (2020.07.25) 修复`LineChart`渐出动画绘制异常的问题#79 -* (2020.07.25) 修复`LiquidChart`在`100%`时渐变色会失效的问题#80 -* (2020.07.25) 增加`RadarChart`对`Tooltip`的`formatter`支持#77 -* (2020.07.23) 增加`RingChart`环形渐变支持#75 -* (2020.07.21) 增加`AxisLabel`和`SerieLabel`的`formatter`可单独配置数值格式化#68 -* (2020.07.17) 增加`SerieAnimation`动画完成回调接口 -* (2020.07.17) 优化`Chart`放在`ScrollView`下时不影响`ScrollView`的滚动和拖动 -* (2020.07.16) 修复`Tooltip`在上层有遮挡还会显示的问题#74 -* (2020.07.08) 优化`Scatter`类型`Serie`支持`Log`轴#70 -* (2020.07.07) 修复`SerieLabel`位置错乱的问题 -* (2020.07.07) 增加`Tooltip`的`offset`参数配置偏移 -* (2020.07.06) 增加`LiquidChart`水位图 -* (2020.07.01) 增加`PolarChart`极坐标图表 - -## v1.5.2 - -* (2020.06.25) 发布`v1.5.2`版本 -* (2020.06.25) 修复`BarChart`在数值为`0`时还会绘制一小部分柱条的问题 -* (2020.06.24) 修复`PieChart`在设置`clockwise`后绘制异常的问题#65 -* (2020.06.23) 优化`LineChart`在峰谷差异过大时的绘制效果#64 -* (2020.06.18) 修复`SerieLabel`在重新添加数据时可能不显示的问题 -* (2020.06.17) 增加`SerieData`可单独设置`SerieSymbol`#66 -* (2020.06.17) 修复`Check For Update`在`Unity 2018`部分版本报错的问题#63 -* (2020.06.16) 增加`Serie`的`avoidLabelOverlap`参数避免饼图标签堆叠的情况#56 -* (2020.06.15) 修复`SerieLabel`单独控制显示时可能错乱的问题 -* (2020.06.11) 修复`Check warning`不生效的问题 -* (2020.06.11) 修复`PieChart`和`RingChart`在数据占比很小时不显示的问题 -* (2020.06.11) 增加`Tooltip`的`titleFormatter`支持配置占位符`{i}`表示忽略不显示标题 -* (2020.06.07) 增加`Animation`的`customFadeInDelay`等自定义数据项延时和时长回调函数#58 -* (2020.06.07) 优化`PieChart`在数据全为`0`时的显示为等份的效果#59 -* (2020.06.04) 增加`SerieLabel`的`autoOffset`参数设置是否自动判断上下偏移 -* (2020.06.04) 增加`Tooltip`的`alwayShow`参数设置触发后一直显示 -* (2020.06.04) 优化`Tooltip`的`formatter`支持`{.1}`通配符 -* (2020.06.04) 优化`Legend`数量过多时自动换行显示#53 - -## v1.5.1 - -* (2020.06.03) 发布`v1.5.1`版本 -* (2020.06.02) 增加`Radar`的`ceilRate`,设置最大最小值的取整倍率 -* (2020.06.02) 优化`Tooltip`的`formatter`,支持`{c1:1-1:f1}`格式配置 -* (2020.05.31) 优化`Background`组件的生效条件,需要有单独的父节点(升级前需要自己处理旧的背景节点) -* (2020.05.30) 优化`PieChart`支持设置`ignoreValue`不显示指定数据 -* (2020.05.30) 修复`RadarChart`为`Circle`时不绘制`SplitArea`的问题 -* (2020.05.30) 优化`RadarChart`在设置`max`为`0`时可自动刷新最大值 -* (2020.05.29) 修复`PieChart`设置`gap`时只有一个数据时绘制异常的问题 -* (2020.05.27) 修复调用`UpdateDataName()`接口时不会自动刷新的问题 -* (2020.05.27) 优化`柱状图`的渐变色效果 -* (2020.05.24) 修复`Axis`同时设置`boundaryGap`和`alignWithLabel`时`Tick`绘制异常的问题 -* (2020.05.24) 优化版本更新检测 - -## v1.5.0 - -* (2020.05.22) 发布`v1.5.0`版本 -* (2020.05.21) 增加`圆角柱图`支持渐变 -* (2020.05.21) 增加`Background`背景组件 -* (2020.05.19) 隐藏`Hierarchy`试图下自动生成的子节点 -* (2020.05.18) 增加`chartName`属性可指定图表的别称,可通过`XChartMgr.Instance.GetChart(chartName)`获取图表 -* (2020.05.16) 增加部分鼠标事件回调 -* (2020.05.15) 优化自带例子,`Demo`改名为`Example` -* (2020.05.13) 增加`Serie`的`large`和`largeThreshold`参数配置折线图和柱状图的性能模式 -* (2020.05.13) 完善Demo,增加性能演示Demo -* (2020.05.13) 优化性能,优化大数据绘制,重构代码 -* (2020.05.04) 增加`numericFormatter`参数可配置数值格式化显示,去掉`forceENotation`参数 -* (2020.04.28) 增加`自由锚点`支持,任意对齐方式 -* (2020.04.23) 优化`ScatterChart`的`Tooltip`显示效果 -* (2020.04.23) 增加`Tooltip`的`formatter`对`{.}`、`{c:0}`、`{c1:1}`的支持 -* (2020.04.19) 优化`LineChart`折线图的区域填充渐变效果 -* (2020.04.19) 增加`AxisLabel`的`onZero`参数可将`Label`显示在`0`刻度上 -* (2020.04.19) 增加`Serie`和`AxisLabel`的`showAsPositiveNumber`参数将负数数值显示为正数 -* (2020.04.18) 增加`Covert XY Axis`互换XY轴配置 -* (2020.04.17) 增加`Axis`可通过`inverse`参数设置坐标轴反转 -* (2020.04.16) 修复`Check warning`在`Unity2019.3`上的显示问题 -* (2020.04.16) 修复`PieChart`在设置`Space`参数后动画绘制异常的问题 - -## v1.4.0 - -* (2020.04.11) 发布`v1.4.0`版本 -* (2020.04.11) 增加`Check warning`检测功能 -* (2020.04.09) 修复`Legend`初始化异常的问题 -* (2020.04.08) 增加`PieChart`通过`ItemStyle`设置边框的支持 -* (2020.03.29) 增加`Axis`的`ceilRate`设置最大最小值的取整倍率 -* (2020.03.29) 增加`BarChart`可通过`itemStyle`的`cornerRadius`设置`圆角柱图` -* (2020.03.29) 增加`itemStyle`的`cornerRadius`支持圆角矩形 -* (2020.03.24) 优化`Editor`参数编辑,兼容`Unity2019.3`及以上版本 -* (2020.03.24) 增加`Serie`在`inspector`上可进行调整顺序、添加和删除操作 -* (2020.03.23) 修复`Title`的`textStyle`和`subTextStyle`无效的问题 -* (2020.03.22) 增加`BarChart`通过`barType`参数设置`胶囊柱状图` -* (2020.03.21) 增加`BarChart`和`HeatmapChart`可通过`ignore`参数设置忽略数据的支持 -* (2020.03.21) 增加`ItemStyle`的`tooltipFormatter`参数可单独配置`Serie`的`Tooltip`显示 -* (2020.03.20) 修复`X Axis 1`和`Y Axis 1`配置变更时不会自动刷新的问题 -* (2020.03.20) 增加`AxisTick`的`width`参数可单独设置坐标轴刻度的宽度 -* (2020.03.20) 增加`Serie`的`radarType`参数设置`多圈`和`单圈`雷达图 -* (2020.03.17) 增加`BarChart`可用`ItemStyle`的`backgroundColor`设置数据项背景颜色 -* (2020.03.17) 增加`SerieData`的`ItemStyle`和`Emphasis`可单独配置数据项样式的支持 -* (2020.03.15) 重构`EmptyCricle`类型的`Symbol`边宽取自`ItemStyle`的`borderWidth`参数 -* (2020.03.15) 重构`SerieSymbol`,去掉`color`和`opacity`参数,取自`ItemStyle` - -## v1.3.1 - -* (2020.03.14) 发布`v1.3.1`版本 -* (2020.03.14) 修复`LineChart`开启`ingore`时部分数据可能绘制异常的问题 -* (2020.03.13) 修复`LineChart`的`label`偏移显示异常的问题 - -## v1.3.0 - -* (2020.03.11) 发布`v1.3.0`版本 -* (2020.03.11) 优化`LineChart`的`label`偏移显示 -* (2020.03.11) 优化清空并重新添加数据后的自动刷新问题 -* (2020.03.10) 增加`LineChart`的普通折线图可通过`ignore`参数设置忽略数据的支持 -* (2020.03.09) 增加`BarChart`可通过`ItemStyle`配置边框的支持 -* (2020.03.08) 增加`RingChart`环形图 -* (2020.03.05) 调整`Serie`的`arcShaped`参数重命名为`roundCap` -* (2020.03.05) 增加运行时和非运行时参数变更自动刷新图表 -* (2020.02.26) 重构`Legend`图例,改变样式,增加自定义图标等设置 -* (2020.02.23) 增加`BaseChart.AnimationFadeOut()`渐出动画,重构动画系统 -* (2020.02.13) 增加`BaseChart.RefreshTooltip()`接口立即重新初始化`Tooltip`组件 -* (2020.02.13) 增加`Tooltip`的`textStyle`参数配置内容文本样式,去掉`fontSize`和`fontStyle`参数 -* (2020.02.13) 增加`TextStyle`的`lineSpacing`参数配置行间距 -* (2020.02.11) 增加`Radar`的`splitLine`参数配置分割线,去掉`lineStyle`参数 -* (2020.02.11) 增加`Tooltip`的`backgroundImage`参数配置背景图 -* (2020.02.11) 增加`Tooltip`的`paddingLeftRight`和`paddingTopBottom`参数配置文字和边框的间距 -* (2020.02.11) 增加`Tooltip`的`lineStyle`参数配置指示线样式 -* (2020.02.11) 增加`Axis`的`splitLine`参数控制分割线,去掉`showSplitLine`和`splitLineType`参数(更新时需要重新设置分割线相关设置) -* (2020.02.10) 增加`Serie`的`clip`参数控制是否超出坐标系外裁剪(只适用于折线图、柱状图、散点图) -* (2020.02.08) 增加`SerieSymbol`的`gap`参数控制图形标记的外留白距离 -* (2020.01.26) 增加`TextLimit`组件可以设置`AxisLabel`的文本自适应 -* (2020.01.20) 优化`Tooltip`设置`itemFormatter`时显示系列颜色 -* (2020.01.20) 增加`Radar`雷达图在`inspector`配置`areaStyle`的支持 - -## v1.2.0 - -* (2020.01.15) 发布`v1.2.0`版本 -* (2020.01.15) 增加`AxisLabel`格式化为整数的支持(`{value:f0}`) -* (2020.01.15) 增加折线图对数轴`Log`的支持 -* (2020.01.09) 修复当设置`DataZoom`的`minShowNum`时可能异常的问题 -* (2020.01.08) 修复当设置`AxisLine`的`onZero`时刻度显示异常的问题 -* (2020.01.08) 增加`Mask`遮罩遮挡支持 -* (2019.12.21) 增加`Tooltip`的单个数据项和标题的字符串模版格式器 -* (2019.12.21) 增加`DataZoom`的最小显示数据个数`minShowNum` -* (2019.12.20) 增加`Demo40_Radar.cs`雷达图代码操作`Demo` -* (2019.12.20) 添加`RadarChart`相关API接口 - -## v1.1.0 - -* (2019.12.17) 发布`v1.1.0`版本 -* (2019.12.16) 修复`Overlay`模式下不显示`Tooltip`的问题 -* (2019.12.15) 增加`Title`的`TextStyle`支持 -* (2019.12.11) 修复`Legend`都隐藏时`Value轴`还显示数值的问题 -* (2019.12.11) 修复`Series->Data->Size`重置为0后设置无效的问题 -* (2019.12.06) 修复数据过小时`AxisLabel`直接科学计数法显示的问题 -* (2019.12.04) 优化和完善数据更新`UpdateData`接口 -* (2019.12.03) 增加圆环饼图的圆角支持,参数:`serie.arcShaped` -* (2019.12.03) 增加数据更新动画,参数:`serie.animation.dataChangeEnable` -* (2019.11.30) 增加`GaugeChart`仪表盘 -* (2019.11.22) 修复`BarChart`清空数据重新赋值后`SerieLabel`显示异常的问题 -* (2019.11.16) 修复`SerieLabel`设置`color`等参数不生效的问题 - -## v1.0.5 - -* (2019.11.12) 发布`v1.0.5`版本 -* (2019.11.12) 修复`2018.3`以下版本打开项目报错的问题 -* (2019.11.12) 增加`IconStyle`子组件,优化`SerieData`的图标配置 -* (2019.11.11) 修复`Serie`的图标显示在上层遮挡`Label`的问题 -* (2019.11.11) 修复饼图当数据过小时视觉引导线会穿透的的问题 -* (2019.11.09) 修复饼图添加数据时`Label`异常的问题 -* (2019.11.09) 优化结构,分离为`XCharts`和`XChartsDemo`两部分 - -## v1.0.4 - -* (2019.11.05) 发布`v1.0.4`版本 -* (2019.11.05) 增加`Radar`雷达组件文本样式参数配置支持 -* (2019.11.04) 修复`Unity2018.3`以下版本代码不兼容的问题 -* (2019.11.04) 优化`SerieLabel`过多时引起的性能问题 - -## v1.0.3 - -* (2019.11.03) 发布`v1.0.3`版本 -* (2019.11.03) 增加`Editor`快捷添加图表:`Hierarchy`试图下右键`XCharts->LineChart` -* (2019.11.02) 优化非配置参数变量命名和访问权限,简化`API` - -## v1.0.2 - -* (2019.10.31) 发布`v1.0.2`版本 -* (2019.10.31) 修复`prefab`预设制作报错的问题 -* (2019.10.31) 增加访问主题组件API:`BaseChart.theme` - -## v1.0.1 - -* (2019.10.26) 发布`v1.0.1`版本 -* (2019.10.26) 修复版本检查功能在非运行时异常的问题 -* (2019.10.26) 增加科学计数法显示数值的支持(查阅`forceENotation`参数) -* (2019.10.26) 增加`Axis`类目轴数据为空时的默认显示支持 -* (2019.10.26) 增加`Axis`数值轴的最大最小值可设置为小数的支持,优化极小数图表的表现效果 - -## v1.0.0 - -* (2019.10.25) 发布`v1.0.0`版本 -* (2019.10.23) 增加版本检测功能:`Component -> XCharts -> Check For Update` -* (2019.10.22) 增加`Package Manager`安装的支持 -* (2019.10.20) 增加`Demo`首页`BarChart`的代码动态控制效果 -* (2019.10.18) 增加`Serie`的`barType`参数,可配置`斑马柱状图` -* (2019.10.18) 增加`Serie`的`barPercentStack`参数,可配置`百分比堆叠柱状图` -* (2019.10.16) 增加`Demo`首页`LineChart`的代码动态控制效果 -* (2019.10.15) 移除`Pie`组件,相关参数放到`Settings`中配置 -* (2019.10.15) 增加`Demo`首页,展示代码动态控制效果 -* (2019.10.14) 增加`RadarChart`、`ScatterChart`和`HeatmapChart`的起始动画效果 -* (2019.10.14) 增加`SerieData`的`radius`自定义数据项的半径 -* (2019.10.14) 增加`HeatmapChart`热力图 -* (2019.10.14) 增加`VisualMap`视觉映射组件 -* (2019.10.14) 增加`ItemStyle`数据项样式组件 -* (2019.10.14) 增加`Emphasis`高亮样式组件 -* (2019.10.10) 增加`Settings`全局参数配置组件,开放更多参数可配置 -* (2019.10.09) 增加`AreaStyle`的高亮相关参数配置鼠标悬浮时高亮之前区域 -* (2019.10.09) 优化`DataZoom`组件,增加双指缩放 -* (2019.10.05) 增加`SerieLabel`的`LineType`给饼图配置不同类型的视觉引导线 -* (2019.10.02) 增加`ScatterChart`同时对`Scatter`和`Line`的支持,实现折线图和散点图的组合图 -* (2019.10.01) 重构代码,废弃`Series.series`接口,用`Series.list`代替 -* (2019.10.01) 增加`customDrawCallback`自定义绘制回调 -* (2019.10.01) 增加`SmoothDash`平滑虚线的支持 -* (2019.09.30) 增加`Serie`采样类型`sampleType`的相关配置 -* (2019.09.29) 增加`SerieSymbol`关于显示间隔的相关配置 -* (2019.09.29) 重构代码: - * `BaseChart`的`sampleDist`删除,`Serie`增加`lineSampleDist` - * `BaseChart`的`minShowDataNumber`删除,`Serie`增加`minShow` - * `BaseChart`的`maxShowDataNumber`删除,`Serie`增加`maxShow` - * `BaseChart`的`maxCacheDataNumber`删除,`Serie`增加`maxCache` - * `BaseChart`的`AddSerie()`接口参数调整 - * `BaseChart`的`UpdateData()`接口参数调整 - * `Axis`增加`maxCache` -* (2019.09.28) 增加`LineChart`和`BarChart`同时对`Line`、`Bar`类型`Serie`的支持,实现折线图和柱状图的组合图 -* (2019.09.27) 增加`Axis`的`splitNumber`设置为`0`时表示绘制所有类目数据 -* (2019.09.27) 增加`SampleDist`采样距离的配置,对过密的曲线开启采样,优化绘制效率 -* (2019.09.27) 增加`XCharts问答`、`XChartsAPI接口`、`XCharts配置项手册`等文档 -* (2019.09.26) 增加`AnimationReset()`重置初始化动画接口 -* (2019.09.26) 优化`LineChart`的密集数据的曲线效果 -* (2019.09.25) 优化`SerieData`的自定义图标不与`SerieLabel`关联,可单独控制是否显示 -* (2019.09.24) 增加`SerieData`的自定义图标相关配置支持 -* (2019.09.23) 增加`Formatter`配置`Axis`的`AxisLabel`的格式化输出 -* (2019.09.23) 增加`Tooltip`的`FontSize`、`FontStyle`配置字体大小和样式 -* (2019.09.23) 增加`Formatter`配置`SerieLabel`、`Legend`、`Tooltip`的格式化输出 -* (2019.09.19) 增加`LineArrow`配置带箭头曲线 -* (2019.09.19) 增加`Tooltip`的`FixedWidth`、`FixedHeight`、`MinWidth`、`MinHeight`设置支持 -* (2019.09.18) 增加单条堆叠柱状图 -* (2019.09.18) 增加虚线`Dash`、点线`Dot`、点划线`DashDot`、双点划线`DashDotDot`等类型的折线图支持 -* (2019.09.17) 增加`AnimationEnabel()`启用或取消起始动画接口 -* (2019.09.17) 增加`Axis`的`Interval`强制设置坐标轴分割间隔 -* (2019.09.16) 去掉`Serie`中的旧版本数据兼容,不再支持`xData`和`yData` -* (2019.09.06) 增加`Animation`在重新初始化数据时自启动功能 -* (2019.09.06) 增加`SerieLabel`的`Border`边框相关配置支持 -* (2019.09.05) 增加`PieChart`的`Animation`初始化动画配置支持 -* (2019.09.03) 增加`BarChart`的`Animation`初始化动画配置支持 -* (2019.09.02) 增加`LineChart`的`Animation`初始化动画配置支持 -* (2019.08.22) 增加`AxisName`的`Offset`偏移配置支持 -* (2019.08.22) 增加`AxisLine`的`Width`配置支持 -* (2019.08.20) 增加`SerieLabel`的背景宽高、文字边距、文字旋转的配置 -* (2019.08.20) 增加`BarChart`的`Label`配置支持 -* (2019.08.15) 增加`LineChart`的`Label`配置 -* (2019.08.15) 重构`BarChart`,移除`Bar`组件,相关参数统一放到`Serie`中配置 -* (2019.08.15) 重构`LineChart`,移除`Line`组件,相关参数统一放到`Serie`中配置 - -## v0.8.3 - -* (2019.08.15) 发布`v0.8.3`版本 -* (2019.08.14) 修复`PieChart`的`Label`无法自动更新的问题 -* (2019.08.13) 修复`UpdateData`接口无法更新数据的问题 -* (2019.08.07) 增加`SerieSymbol`的`Color`、`Opacity`配置 - -## v0.8.2 - -* (2019.08.07) 发布`v0.8.2`版本 -* (2019.08.07) 修复区域平滑折线图显示异常的问题 -* (2019.08.06) 修复`serie`系列数超过调色盘颜色数时获取的颜色异常的问题 -* (2019.08.06) 修复当`Axis`的`minMaxType`为`Custom`时`max`设置为`100`不生效的问题 - -## v0.8.1 - -* (2019.08.04) 发布`v0.8.1`版本 -* (2019.08.04) 修复`Inspector`中修改数据不生效的问题 - -## v0.8.0 - -* (2019.08.04) 发布`v0.8.0`版本 -* (2019.08.04) 优化`RadarChart`雷达图,增加多雷达图支持 -* (2019.08.01) 增加代码API注释文档,整理代码 -* (2019.07.29) 增加`Radius`、`Area`两种南丁格尔玫瑰图展示类型 -* (2019.07.29) 增加`SerieLabel`配置饼图标签,支持`Center`、`Inside`、`Outside`等显示位置 -* (2019.07.28) 增加`PieChart`多饼图支持 -* (2019.07.23) 优化`Theme`主题的自定义,切换主题时自定义配置不受影响 -* (2019.07.22) 增加`EffectScatter`类型的散点图 -* (2019.07.21) 增加`ScatterChart`散点图 -* (2019.07.21) 增加`SerieData`支持多维数据配置 -* (2019.07.20) 增加`Symbol`配置`Serie`标志图形的显示 -* (2019.07.19) 增加用代码添加动态正弦曲线的示例`Demo11_AddSinCurve` -* (2019.07.19) 优化`Legend`的显示和控制 -* (2019.07.18) 优化抗锯齿,曲线更平滑 -* (2019.07.18) 增加`Tooltip`指示器类型,优化显示控制 -* (2019.07.15) 增加`Size`设置图表尺寸 -* (2019.07.14) 增加`二维数据`支持,XY轴都可以设置为数值轴 -* (2019.07.13) 增加`双坐标轴`支持,代码改动较大 - -## v0.5.0 - -* (2019.07.10) 发布`v0.5.0`版本 -* (2019.07.09) 增加`AxisLine`配置坐标轴轴线和箭头 -* (2019.07.03) 增加`AxisLabel`配置坐标轴`刻度标签` -* (2019.07.02) 增加`selected`等相关参数配置`PieChart`的选中效果 -* (2019.06.30) 增加`SplitArea`配置坐标轴`分割区域` -* (2019.06.29) 增加`AxisName`配置坐标轴`名称` -* (2019.06.20) 增加`AreaAlpha`控制`RadarChart`的`Area`透明度 -* (2019.06.13) 增加`DataZoom`实现`区域缩放` -* (2019.06.01) 增加`stepType`实现`LineChart`的`阶梯线图` -* (2019.05.29) 增加`InSameBar`实现`BarChart`的`非堆叠同柱` -* (2019.05.29) 增加`crossLabel`控制`Tooltip`的`十字准星指示器` -* (2019.05.24) 增加`堆叠区域图` -* (2019.05.16) 增加`AxisMinMaxType`控制坐标轴最大最小刻度 -* (2019.05.15) 完善数据接口 -* (2019.05.14) 增加X轴`AxisType.Value`模式支持 -* (2019.05.13) 增加负数数值轴支持 -* (2019.05.11) 增加自定义`Editor`编辑 -* (2019.03.21) 增加`Tooltip` -* (2018.11.01) 增加`Default`、`Light`、`Dark`三种默认主题 - -## v0.1.0 - -* (2018.09.05) 发布`v0.1.0`版本 diff --git a/Assets/XCharts/CHANGELOG.md.meta b/Assets/XCharts/CHANGELOG.md.meta deleted file mode 100644 index 1582ca4..0000000 --- a/Assets/XCharts/CHANGELOG.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: e66d91d4c396b46bf87034c47ca3b43d -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/CHANGELOG-EN.md b/Assets/XCharts/Documentation/CHANGELOG-EN.md deleted file mode 100644 index 443f195..0000000 --- a/Assets/XCharts/Documentation/CHANGELOG-EN.md +++ /dev/null @@ -1,570 +0,0 @@ - -# 更新日志 - -[master](#master) -[v3.0.1](#v3.0.1) -[v3.0.0](#v3.0.0) -[v2.3.0](#v2.3.0) -[v2.2.3](#v2.2.3) -[v2.2.2](#v2.2.2) -[v2.2.1](#v2.2.1) -[v2.2.0](#v2.2.0) -[v2.1.1](#v2.1.1) -[v2.1.0](#v2.1.0) -[v2.0.1](#v2.0.1) -[v2.0.0](#v2.0.0) -[v2.0.0-preview.2](#v2.0.0-preview.2) -[v2.0.0-preview.1](#v2.0.0-preview.1) -[v1.6.3](#v1.6.3) -[v1.6.1](#v1.6.1) -[v1.6.0](#v1.6.0) -[v1.5.2](#v1.5.2) -[v1.5.1](#v1.5.1) -[v1.5.0](#v1.5.0) -[v1.4.0](#v1.4.0) -[v1.3.1](#v1.3.1) -[v1.3.0](#v1.3.0) -[v1.2.0](#v1.2.0) -[v1.1.0](#v1.1.0) -[v1.0.5](#v1.0.5) -[v1.0.4](#v1.0.4) -[v1.0.3](#v1.0.3) -[v1.0.2](#v1.0.2) -[v1.0.1](#v1.0.1) -[v1.0.0](#v1.0.0) -[v0.8.3](#v0.8.3) -[v0.8.2](#v0.8.2) -[v0.8.1](#v0.8.1) -[v0.8.0](#v0.8.0) -[v0.5.0](#v0.5.0) -[v0.1.0](#v0.1.0) - -## v3.0.1 - -* (2022.06.16) Release `v3.0.1` version -* (2022.06.16) Fixed an issue where the `foldout` arrow on `Inspector` could not be expanded -* (2022.06.15) Optimized `Doc` auto-generation, improved code comments and configuration item manual documentation -* (2022.06.14) Optimized `SerieLabelStyle` to support dynamic adjustment of `Icon` -* (2022.06.13) Optimized `Background` setting -* (2022.06.10) Added `Legend` AxisLabel support for `autoColor` -* (2022.06.08) Fixed issue where `Axis` `AxisLabel` still shows the first and last two labels when not displayed - -## v3.0.0 - -* More robust underlying framework. -* More powerful performance. -* Smaller serialized files. -* Better interactive experience. -* More component support. -* More powerful ability to self-report text. -* More reasonable component adjustments. -* More flexible component insertion and removal. -* More efficient secondary development. -* Richer Demo examples. -* Added `Time` axis. -* Added `SingleAxis`. -* Added multiple coordinate systems: `Grid`, `Polar`, `Radar`, `SingleAxis`. -* Added multiple animation methods. -* Added multiple chart interactions. -* Added internationalization support. -* Added `Widgets`. -* Added multiple extension charts. - -## v2.3.0 - -### Main points - -* Data store upgraded from `float` to `double` -* Added `MarkLine` -* `Serie` can use `IconStyle` to configure ICONS uniformly -* `Label` supports custom display styles with code -* `DataZoom` is perfect -* `PieChart` optimization -* Problem fixes - -### Upgrade Note - -Since the data type is upgraded to `double`, the implicit conversion of `float` to `double` may have precision problems, so it is recommended that all previous data types of `float` be manually changed to `double`. - -### Details - -* (2021.07.24) Release `v2.3.0` version -* (2021.07.22) Improved `SerieSymbol` to support `PictorialBarchart` extension -* (2021.07.19) Fixed issue where `Tooltip` was not displayed on `WdbGL` platform -* (2021.07.18) Added `iconStyle` for serie -* (2021.07.15) Added `MarkLine` (#142) -* (2021.07.09) Optimize `BarChart` to set whether to show bars via `seriedata.show` -* (2021.07.08) Optimize data storage type from `float` to `double` -* (2021.07.05) Fixed `Piechart` `avoidLabelOverlap` parameter not working -* (2021.07.04) Fixed incorrect mouse area indication after `PieChart` selected sector -* (2021.07.04) Optimize when the `Label` of `PieChart` is `Inside`, the offset can be adjusted by the parameter `Margin` -* (2021.07.01) Added `DataZoom` arguments to `supportInsideScroll` and `supportInsideDrag` to set whether scrolling and dragging are supported in the coordinate system -* (2021.06.27) Add `showStartLabel` and `showEndLabel` arguments to `AxisLabel` to set whether the `Label` should be displayed at the beginning and end of the `AxisLabel` -* (2021.06.27) Added `formatter` delegate method to `AxisLabel` and `SerieLabel` (#145) -* (2021.06.27) Added `DataZoom`'s `orient` parameter to set horizontal or vertical styles -* (2021.06.21) Added `iconStyle`'s `AutoHideWhenLabelEmpty` to set whether the icon is automatically hidden when `label` is empty - -# # v2.2.3 - -* (2021.06.20) Release `v2.2.3` version -* (2021.06.20) Fixed the default display of `Icon` in `Axis` - -## v2.2.2 - -* (2021.06.18) Release `v2.2.2` version -* (2021.06.18) Optimize `Axis` to automatically hide `Icon` when `Label` is empty -* (2021.06.17) Fixed an issue where `maxCache` was set to one more number of actual data -* (2021.06.17) Fixed an issue where `TextMeshPro` could not be opened and closed in time to refresh -* (2021.06.17) Fixed an issue where `XCharts` always pops up when importing `XCharts` - -## v2.2.1 - -* (2021.06.13) Release `v2.2.1` version -* (2021.06.13) Improved support for multiple screens -* (2021.06.12) Added `iconStyle` `align` parameter to set the horizontal alignment of the icon -* (2021.06.12) Improve `Theme` import (#148) -* (2021.06.10) Fixed compatibility issues with `Unity` version (#154) -* (2021.06.05) Improved Candlestickchart support for inverse (#152) -* (2021.06.04) Fixed `Gauge` having an abnormal pointer position when the minimum value is negative (#153) - -## v2.2.0 - -* (2021.05.30) Release `v2.2.0` version -* (2021.05.25) Improved `TextStyle` support for `alignment` -* (2021.05.24) Fixed the problem that `Label` could not display properly when `PieChart` data were all `0` -* (2021.05.24) Fixed an issue where `Serie Name` was not working on the `Add Serie` panel (#149) -* (2021.05.23) Added `TextStyle` `autoWrap` to set whether to wrap lines -* (2021.05.23) Added `TextStyle` `autoAlign` whether to set alignment automatically -* (2021.05.23) Added `width` and `height` of `axisLabel` to support custom text length and width -* (2021.05.23) Added `Axis` `iconStyle` and `icons` to support setting coordinate Axis labels to display icons -* (2021.05.20) Added the `insertDataHead` parameter to `Serie` and `Axis` to control whether data is inserted into the head or tail -* (2021.05.18) Optimize chart creation under `Editor` #147 -* (2021.05.16) Pull out the `Ganttchart` chart and provide it as an extension module -* (2021.05.11) Added support for `VisualMap` to set color by `Piecewise` -* (2021.05.09) Fixed an issue where `RingChart` could not set the background color of the ring #141 -* (2021.05.08) Added `Liquidchart` support for `Rect` shape -* (2021.05.07) Improved the `Axis` scale performance #135 -* (2021.05.01) Added `Settings` parameters for painter's material #140 -* (2021.05.01) Fixed an issue where some super large or super small values could not be properly represented -* (2021.04.29) Fixed an issue with `Radar` switching to `Circle` anomaly #139 -* (2021.04.29) Added `Settings`'s `reversePainter` to set whether or not `Serie` is drawn in reverse order -* (2021.04.28) Fixed bug where `AxisLabel` displayed incorrectly with `DataRoom` (#138) -* (2021.04.26) Fixed dynamically creating chart at runtime would be abnormal #137 -* (2021.04.26) Added support for `Barchart` to draw gradient borders -* (2021.04.23) Added support for custom charts -* (2021.04.22) Fixed bug where `Gauge` `axisLabel`'s text color could not be adjusted -* (2021.04.13) Add the `ShowStarttick` and '`ShowEndTick` parameters of 'AxisTick' to control whether the first and last ticks are displayed -* (2021.04.13) Improved multi-axis support #132 - -## v2.1.1 - -* (2021.04.13) Define the code and clear `Warning` -* (2021.04.13) Fixed compatibility issues with `Unity` version -* (2021.04.12) Fixed problem `missing class attribute 'ExtensionOfNativeClass'` after Theme refactoring #131 - -## v2.1.0 - -* (2021.04.07) Release `v2.1.0` version -* (2021.03.31) Optimized and refactor `Theme` to solve problems with the same or missing references #118 -* (2021.03.30) Optimized `Tooltip` to support setting different category axis data #129 -* (2021.03.29) Optimized the custom draw callback API -* (2021.03.25) Added `Ganttchart` -* (2021.03.22) Added `Theme` `Unbind` button to unbind theme when copying chart #118 -* (2021.03.18) Fixed an issue where the check box after `Foldout` in `Inspector` could not be checked -* (2021.03.18) Fixed an issue with `BarChart` displaying an exception in the `0` value -* (2021.03.14) Fixed `Tooltip` indicator was not indicating the correct location in some cases -* (2021.03.13) Optimized the editing experience and component refresh after `MulticomponentMode` is enabled #128 -* (2021.03.10) Added `CandlestickChart` #124 -* (2021.03.06) Added `PieChart`'s `minAngle` parameter to support setting minimum sector angle #117 -* (2021.03.05) Added support for `Legend` for several built-in ICONS #90 -* (2021.03.02) Added `DataRoom` support for value axes #71 -* (2021.03.02) Optimized `TextMeshPro` compatibility issue #125 -* (2021.03.01) Fixed display exception of hidden gameObjects when enabling and disabling a chart #125 - -## v2.0.1 - -* (2021.02.26) Fixed incorrect position of `Tooltip` in `HeatmapChart` #123 -* (2021.02.22) Fixed compatibility issues with `Unity` version -* (2021.02.21) Added `Tooltip` parameter `ignoreDataShow` -* (2021.02.19) Fixed an issue where charts could appear abnormal when under `LayoutGroup` control #121 -* (2021.02.18) Fixed an issue where the `Radar` could not refresh itself after parameter changing #122 - -## v2.0.0 - -* (2021.02.05) Release `v2.0.0` version -* (2021.02.03) Fixed an issue where `Axisline` `OnZero` did not work on `YAxis` #116 -* (2021.01.29) Fixed incorrect display of `Tick` on `Category` axis when `BoundaryGap` and `alignWithLabel` are `True` #115 -* (2021.01.25) Optimized some details -* (2021.01.22) Fixed a `Inpsector` displayed error - -## v2.0.0-preview.2 - -* (2021.01.21) Release `v2.0.0-preview.2` version -* (2021.01.21) Fixed an error about `AxisTick` in `Inpsector` -* (2021.01.21) Fixed a build compatibility error -* (2021.01.19) Added `XChartsSettings` `editorShowAllListData` parameter to configure whether to display all the list's data in Inspector - -## v2.0.0-preview.1 - -* (2021.01.19) Release `v2.0.0-preview.1` version - -## v1.6.3 - -* (2021.01.02) Release `v1.6.3` version -* (2020.12.18) fixed an issue where updating data when `Animation` was not enabled caused the chart to keep refreshing -* (2020.12.01) fixed an issue where a newly created chart on `Unity2020` could not be drawn properly - -## v1.6.2 - -* (2020.11.22) Release `v1.6.2` version -* (2020.11.22) Fixed an issue where `LineChart` draws an exception when the data is too dense #99 -* (2020.11.21) Fixed an issue where the scale position of `LineChart` could be abnormal if `alignWithLabel` was `true` -* (2020.11.21) Fixed `Unity5` compatibility error reporting problem -* (2020.11.13) Improved `RadarChart` `Indicator` support for `\n` line feed -* (2020.11.12) Fixed `LineChart` reporting errors when the type was `Smooth` when the data was too secure #100 -* (2020.10.22) Optimized the support of `VisualMap` for `Piecewise` in `HeatmapChart` -* (2020.09.22) Fixed `PieChart` inconsistent border size -* (2020.09.18) Added `Remove All Chart Object` to Remove All child nodes under the Chart (automatically reinitialized) -* (2020.09.18) Fixed `SerieLabel` also displayed after hided `Serie` by clicked the legend #94 -* (2020.09.18) Optimized coordinate axis calibration and text display #93 -* (2020.09.17) Fixed `Package` import missing `meta` file causing failure #92 -* (2020.09.08) Optimized the color of `Legend` to automatically match the custom color of `ItemStyle` -* (2020.09.05) Optimized `LineChart` to display `XAxis1` without using `XAxis1`. -* (2020.08.29) Added `toColor` and `toColor2` of `LineStyle` to set the horizontal gradient of `LineChart`. Cancel `ItemStyle` to set the horizontal gradient of `LineChart`. -* (2020.08.29) Added the `onPointerClickPie` of `PieChart`, a callback function of click pie area. -* (2020.08.29) Added the `onPointerClickBar` of `BarChart`, a callback function of click bar. - -## v1.6.0 - -* (2020.08.24) Release `v1.6.0` version -* (2020.08.23) Refactor code, replace `Color` with `Color32` for reduce implicit conversion (Can cause custom colors to lose, reference [FAQ 29](https://github.com/XCharts-Team/XCharts/blob/master/Assets/XCharts/Documentation/XChartsFAQ-ZH.md) to upgrade) -* (2020.08.15) Optimized `PieChart` drawing performance effect #85 -* (2020.08.11) Added `LiquidChart` data change animation#83 -* (2020.08.11) Optimized `PieChart` text stack and lead line effects#85 -* (2020.08.08) Optimized `LineChart` the rendering performance of dense data -* (2020.07.30) Added `LineChart` to configure gradient through `VisualMap` or `ItemStyle`#78 -* (2020.07.25) Fixed a problem with `LineChart` emerging abnormal in animation drawing#79 -* (2020.07.25) Fixed a problem with gradual discoloration on `LiquidChart` at `100%`#80 -* (2020.07.25) Added `RadarChart` support for `formatter` of `Tooltip`#77 -* (2020.07.23) Added `RingChart` ring gradient support#75 -* (2020.07.21) Added `formatter` of `AxisLabel` and `SerieLabel` to configure numeric formatting separately. -* (2020.07.17) Added animation completion callback interface for `SerieAnimation`. -* (2020.07.17) Optimized `Chart` under `ScrollView` without affecting the scrolling and dragging of `ScrollView`. -* (2020.07.16) Fixed a problem with `Tooltip` that would also show up if it was blocked on top. #74 -* (2020.07.07) Fixed issue where `SerieLabel` position was out of order -* (2020.07.07) Added `Tooltip` to the `offset` parameter -* (2020.07.06) Added `Liquidchart` -* (2020.07.01) Added `PolarChart` - -## v1.5.2 - -* (2020.06.25) Fixed an issue where `BarChart` would draw a small number of bars when the value was `0` -* (2020.06.24) Fixed an issue where `PieChart` was drawing abnormally after setting `Clockwise` #65 -* (2020.06.23) Optimized the drawing effect of `LineChart` when the difference between peak and valley is too large #64 -* (2020.06.18) Fixed an issue where `SerieLabel` might not be displayed when adding data again -* (2020.06.17) Added `SerieData` to `serieSymbol` #66 -* (2020.06.17) Fixed `Check For Update` bug in `Unity 2018` version #63 -* (2020.06.16) Added `Serie` `avoidLabelOverlap` parameter to avoid pie chart TAB stacking #56 -* (2020.06.15) Fixed an issue where the `SerieLabel` control display could be deranged -* (2020.06.11) Fixed `Check warning` not working -* (2020.06.11) Fixed issue where `Piechart` and `Ringchart` were not displayed when data fraction was very small -* (2020.06.11) Added `Tooltip` to `titleFormatter` to support configuration placeholder `{i}` to ignore not showing titles -* (2020.06.07) Added `customFadeInDelay` and other custom data item delay and duration callback function #58 -* (2020.06.07) Optimized `Piechart` to display equal parts when all the data are `0` #59 -* (2020.06.04) Added `autoOffset` parameter setting for `SerieLabel` to determine whether the up and down offset is automatically determined -* (2020.06.04) Added `Tooltip` to `AlwayShow` parameter setting to always show after triggering -* (2020.06.04) Tooltip's `formatter` supports `{.1}` wildcards -* (2020.06.04) Optimizes the number of `Legend` to automatically wrap to display #53 - -## v1.5.1 - -* (2020.06.03) 发布`v1.5.1`版本 -* (2020.06.02) 增加`Radar`的`ceilRate`,设置最大最小值的取整倍率 -* (2020.06.02) 优化`Tooltip`的`formatter`,支持`{c1:1-1:f1}`格式配置 -* (2020.05.31) 优化`Background`组件的生效条件,需要有单独的父节点(升级前需要自己处理旧的背景节点) -* (2020.05.30) 优化`PieChart`支持设置`ignoreValue`不显示指定数据 -* (2020.05.30) 修复`RadarChart`为`Circle`时不绘制`SplitArea`的问题 -* (2020.05.30) 优化`RadarChart`在设置`max`为`0`时可自动刷新最大值 -* (2020.05.29) 修复`PieChart`设置`gap`时只有一个数据时绘制异常的问题 -* (2020.05.27) 修复调用`UpdateDataName()`接口时不会自动刷新的问题 -* (2020.05.27) 优化`柱状图`的渐变色效果 -* (2020.05.24) 修复`Axis`同时设置`boundaryGap`和`alignWithLabel`时`Tick`绘制异常的问题 -* (2020.05.24) 优化版本更新检测 -* (2020.06.25) release `v1.5.2` - - -## v1.5.0 - -* (2020.05.22) 发布`v1.5.0`版本 -* (2020.05.21) 增加`圆角柱图`支持渐变 -* (2020.05.21) 增加`Background`背景组件 -* (2020.05.19) 隐藏`Hierarchy`试图下自动生成的子节点 -* (2020.05.18) 增加`chartName`属性可指定图表的别称,可通过`XChartMgr.Instance.GetChart(chartName)`获取图表 -* (2020.05.16) 增加部分鼠标事件回调 -* (2020.05.15) 优化自带例子,`Demo`改名为`Example` -* (2020.05.13) 增加`Serie`的`large`和`largeThreshold`参数配置折线图和柱状图的性能模式 -* (2020.05.13) 完善Demo,增加性能演示Demo -* (2020.05.13) 优化性能,优化大数据绘制,重构代码 -* (2020.05.04) 增加`numericFormatter`参数可配置数值格式化显示,去掉`forceENotation`参数 -* (2020.04.28) 增加`自由锚点`支持,任意对齐方式 -* (2020.04.23) 优化`ScatterChart`的`Tooltip`显示效果 -* (2020.04.23) 增加`Tooltip`的`formatter`对`{.}`、`{c:0}`、`{c1:1}`的支持 -* (2020.04.19) 优化`LineChart`折线图的区域填充渐变效果 -* (2020.04.19) 增加`AxisLabel`的`onZero`参数可将`Label`显示在`0`刻度上 -* (2020.04.19) 增加`Serie`和`AxisLabel`的`showAsPositiveNumber`参数将负数数值显示为正数 -* (2020.04.18) 增加`Covert XY Axis`互换XY轴配置 -* (2020.04.17) 增加`Axis`可通过`inverse`参数设置坐标轴反转 -* (2020.04.16) 修复`Check warning`在`Unity2019.3`上的显示问题 -* (2020.04.16) 修复`PieChart`在设置`Space`参数后动画绘制异常的问题 - -## v1.4.0 - -* (2020.04.11) 发布`v1.4.0`版本 -* (2020.04.11) 增加`Check warning`检测功能 -* (2020.04.09) 修复`Legend`初始化异常的问题 -* (2020.04.08) 增加`PieChart`通过`ItemStyle`设置边框的支持 -* (2020.03.29) 增加`Axis`的`ceilRate`设置最大最小值的取整倍率 -* (2020.03.29) 增加`BarChart`可通过`itemStyle`的`cornerRadius`设置`圆角柱图` -* (2020.03.29) 增加`itemStyle`的`cornerRadius`支持圆角矩形 -* (2020.03.24) 优化`Editor`参数编辑,兼容`Unity2019.3`及以上版本 -* (2020.03.24) 增加`Serie`在`inspector`上可进行调整顺序、添加和删除操作 -* (2020.03.23) 修复`Title`的`textStyle`和`subTextStyle`无效的问题 -* (2020.03.22) 增加`BarChart`通过`barType`参数设置`胶囊柱状图` -* (2020.03.21) 增加`BarChart`和`HeatmapChart`可通过`ignore`参数设置忽略数据的支持 -* (2020.03.21) 增加`ItemStyle`的`tooltipFormatter`参数可单独配置`Serie`的`Tooltip`显示 -* (2020.03.20) 修复`X Axis 1`和`Y Axis 1`配置变更时不会自动刷新的问题 -* (2020.03.20) 增加`AxisTick`的`width`参数可单独设置坐标轴刻度的宽度 -* (2020.03.20) 增加`Serie`的`radarType`参数设置`多圈`和`单圈`雷达图 -* (2020.03.17) 增加`BarChart`可用`ItemStyle`的`backgroundColor`设置数据项背景颜色 -* (2020.03.17) 增加`SerieData`的`ItemStyle`和`Emphasis`可单独配置数据项样式的支持 -* (2020.03.15) 重构`EmptyCricle`类型的`Symbol`边宽取自`ItemStyle`的`borderWidth`参数 -* (2020.03.15) 重构`SerieSymbol`,去掉`color`和`opacity`参数,取自`ItemStyle` - -## v1.3.1 - -* (2020.03.14) 发布`v1.3.1`版本 -* (2020.03.14) 修复`LineChart`开启`ingore`时部分数据可能绘制异常的问题 -* (2020.03.13) 修复`LineChart`的`label`偏移显示异常的问题 - -## v1.3.0 - -* (2020.03.11) 发布`v1.3.0`版本 -* (2020.03.11) 优化`LineChart`的`label`偏移显示 -* (2020.03.11) 优化清空并重新添加数据后的自动刷新问题 -* (2020.03.10) 增加`LineChart`的普通折线图可通过`ignore`参数设置忽略数据的支持 -* (2020.03.09) 增加`BarChart`可通过`ItemStyle`配置边框的支持 -* (2020.03.08) 增加`RingChart`环形图 -* (2020.03.05) 调整`Serie`的`arcShaped`参数重命名为`roundCap` -* (2020.03.05) 增加运行时和非运行时参数变更自动刷新图表 -* (2020.02.26) 重构`Legend`图例,改变样式,增加自定义图标等设置 -* (2020.02.23) 增加`BaseChart.AnimationFadeOut()`渐出动画,重构动画系统 -* (2020.02.13) 增加`BaseChart.RefreshTooltip()`接口立即重新初始化`Tooltip`组件 -* (2020.02.13) 增加`Tooltip`的`textStyle`参数配置内容文本样式,去掉`fontSize`和`fontStyle`参数 -* (2020.02.13) 增加`TextStyle`的`lineSpacing`参数配置行间距 -* (2020.02.11) 增加`Radar`的`splitLine`参数配置分割线,去掉`lineStyle`参数 -* (2020.02.11) 增加`Tooltip`的`backgroundImage`参数配置背景图 -* (2020.02.11) 增加`Tooltip`的`paddingLeftRight`和`paddingTopBottom`参数配置文字和边框的间距 -* (2020.02.11) 增加`Tooltip`的`lineStyle`参数配置指示线样式 -* (2020.02.11) 增加`Axis`的`splitLine`参数控制分割线,去掉`showSplitLine`和`splitLineType`参数(更新时需要重新设置分割线相关设置) -* (2020.02.10) 增加`Serie`的`clip`参数控制是否超出坐标系外裁剪(只适用于折线图、柱状图、散点图) -* (2020.02.08) 增加`SerieSymbol`的`gap`参数控制图形标记的外留白距离 -* (2020.01.26) 增加`TextLimit`组件可以设置`AxisLabel`的文本自适应 -* (2020.01.20) 优化`Tooltip`设置`itemFormatter`时显示系列颜色 -* (2020.01.20) 增加`Radar`雷达图在`inspector`配置`areaStyle`的支持 - -## v1.2.0 - -* (2020.01.15) 发布`v1.2.0`版本 -* (2020.01.15) 增加`AxisLabel`格式化为整数的支持(`{value:f0}`) -* (2020.01.15) 增加折线图对数轴`Log`的支持 -* (2020.01.09) 修复当设置`DataZoom`的`minShowNum`时可能异常的问题 -* (2020.01.08) 修复当设置`AxisLine`的`onZero`时刻度显示异常的问题 -* (2020.01.08) 增加`Mask`遮罩遮挡支持 -* (2019.12.21) 增加`Tooltip`的单个数据项和标题的字符串模版格式器 -* (2019.12.21) 增加`DataZoom`的最小显示数据个数`minShowNum` -* (2019.12.20) 增加`Demo40_Radar.cs`雷达图代码操作`Demo` -* (2019.12.20) 添加`RadarChart`相关API接口 - -## v1.1.0 - -* (2019.12.17) 发布`v1.1.0`版本 -* (2019.12.16) 修复`Overlay`模式下不显示`Tooltip`的问题 -* (2019.12.15) 增加`Title`的`TextStyle`支持 -* (2019.12.11) 修复`Legend`都隐藏时`Value轴`还显示数值的问题 -* (2019.12.11) 修复`Series->Data->Size`重置为0后设置无效的问题 -* (2019.12.06) 修复数据过小时`AxisLabel`直接科学计数法显示的问题 -* (2019.12.04) 优化和完善数据更新`UpdateData`接口 -* (2019.12.03) 增加圆环饼图的圆角支持,参数:`serie.arcShaped` -* (2019.12.03) 增加数据更新动画,参数:`serie.animation.dataChangeEnable` -* (2019.11.30) 增加`GaugeChart`仪表盘 -* (2019.11.22) 修复`BarChart`清空数据重新赋值后`SerieLabel`显示异常的问题 -* (2019.11.16) 修复`SerieLabel`设置`color`等参数不生效的问题 - -## v1.0.5 - -* (2019.11.12) 发布`v1.0.5`版本 -* (2019.11.12) 修复`2018.3`以下版本打开项目报错的问题 -* (2019.11.12) 增加`IconStyle`子组件,优化`SerieData`的图标配置 -* (2019.11.11) 修复`Serie`的图标显示在上层遮挡`Label`的问题 -* (2019.11.11) 修复饼图当数据过小时视觉引导线会穿透的的问题 -* (2019.11.09) 修复饼图添加数据时`Label`异常的问题 -* (2019.11.09) 优化结构,分离为`XCharts`和`XChartsDemo`两部分 - -## v1.0.4 - -* (2019.11.05) 发布`v1.0.4`版本 -* (2019.11.05) 增加`Radar`雷达组件文本样式参数配置支持 -* (2019.11.04) 修复`Unity2018.3`以下版本代码不兼容的问题 -* (2019.11.04) 优化`SerieLabel`过多时引起的性能问题 - -## v1.0.3 - -* (2019.11.03) 发布`v1.0.3`版本 -* (2019.11.03) 增加`Editor`快捷添加图表:`Hierarchy`试图下右键`XCharts->LineChart` -* (2019.11.02) 优化非配置参数变量命名和访问权限,简化`API` - -## v1.0.2 - -* (2019.10.31) 发布`v1.0.2`版本 -* (2019.10.31) 修复`prefab`预设制作报错的问题 -* (2019.10.31) 增加访问主题组件API:`BaseChart.theme` - -## v1.0.1 - -* (2019.10.26) 发布`v1.0.1`版本 -* (2019.10.26) 修复版本检查功能在非运行时异常的问题 -* (2019.10.26) 增加科学计数法显示数值的支持(查阅`forceENotation`参数) -* (2019.10.26) 增加`Axis`类目轴数据为空时的默认显示支持 -* (2019.10.26) 增加`Axis`数值轴的最大最小值可设置为小数的支持,优化极小数图表的表现效果 - -## v1.0.0 - -* (2019.10.25) 发布`v1.0.0`版本 -* (2019.10.23) 增加版本检测功能:`Component -> XCharts -> Check For Update` -* (2019.10.22) 增加`Package Manager`安装的支持 -* (2019.10.20) 增加`Demo`首页`BarChart`的代码动态控制效果 -* (2019.10.18) 增加`Serie`的`barType`参数,可配置`斑马柱状图` -* (2019.10.18) 增加`Serie`的`barPercentStack`参数,可配置`百分比堆叠柱状图` -* (2019.10.16) 增加`Demo`首页`LineChart`的代码动态控制效果 -* (2019.10.15) 移除`Pie`组件,相关参数放到`Settings`中配置 -* (2019.10.15) 增加`Demo`首页,展示代码动态控制效果 -* (2019.10.14) 增加`RadarChart`、`ScatterChart`和`HeatmapChart`的起始动画效果 -* (2019.10.14) 增加`SerieData`的`radius`自定义数据项的半径 -* (2019.10.14) 增加`HeatmapChart`热力图 -* (2019.10.14) 增加`VisualMap`视觉映射组件 -* (2019.10.14) 增加`ItemStyle`数据项样式组件 -* (2019.10.14) 增加`Emphasis`高亮样式组件 -* (2019.10.10) 增加`Settings`全局参数配置组件,开放更多参数可配置 -* (2019.10.09) 增加`AreaStyle`的高亮相关参数配置鼠标悬浮时高亮之前区域 -* (2019.10.09) 优化`DataZoom`组件,增加双指缩放 -* (2019.10.05) 增加`SerieLabel`的`LineType`给饼图配置不同类型的视觉引导线 -* (2019.10.02) 增加`ScatterChart`同时对`Scatter`和`Line`的支持,实现折线图和散点图的组合图 -* (2019.10.01) 重构代码,废弃`Series.series`接口,用`Series.list`代替 -* (2019.10.01) 增加`customDrawCallback`自定义绘制回调 -* (2019.10.01) 增加`SmoothDash`平滑虚线的支持 -* (2019.09.30) 增加`Serie`采样类型`sampleType`的相关配置 -* (2019.09.29) 增加`SerieSymbol`关于显示间隔的相关配置 -* (2019.09.29) 重构代码: - * `BaseChart`的`sampleDist`删除,`Serie`增加`lineSampleDist` - * `BaseChart`的`minShowDataNumber`删除,`Serie`增加`minShow` - * `BaseChart`的`maxShowDataNumber`删除,`Serie`增加`maxShow` - * `BaseChart`的`maxCacheDataNumber`删除,`Serie`增加`maxCache` - * `BaseChart`的`AddSerie()`接口参数调整 - * `BaseChart`的`UpdateData()`接口参数调整 - * `Axis`增加`maxCache` -* (2019.09.28) 增加`LineChart`和`BarChart`同时对`Line`、`Bar`类型`Serie`的支持,实现折线图和柱状图的组合图 -* (2019.09.27) 增加`Axis`的`splitNumber`设置为`0`时表示绘制所有类目数据 -* (2019.09.27) 增加`SampleDist`采样距离的配置,对过密的曲线开启采样,优化绘制效率 -* (2019.09.27) 增加`XCharts问答`、`XChartsAPI接口`、`XCharts配置项手册`等文档 -* (2019.09.26) 增加`AnimationReset()`重置初始化动画接口 -* (2019.09.26) 优化`LineChart`的密集数据的曲线效果 -* (2019.09.25) 优化`SerieData`的自定义图标不与`SerieLabel`关联,可单独控制是否显示 -* (2019.09.24) 增加`SerieData`的自定义图标相关配置支持 -* (2019.09.23) 增加`Formatter`配置`Axis`的`AxisLabel`的格式化输出 -* (2019.09.23) 增加`Tooltip`的`FontSize`、`FontStyle`配置字体大小和样式 -* (2019.09.23) 增加`Formatter`配置`SerieLabel`、`Legend`、`Tooltip`的格式化输出 -* (2019.09.19) 增加`LineArrow`配置带箭头曲线 -* (2019.09.19) 增加`Tooltip`的`FixedWidth`、`FixedHeight`、`MinWidth`、`MinHeight`设置支持 -* (2019.09.18) 增加单条堆叠柱状图 -* (2019.09.18) 增加虚线`Dash`、点线`Dot`、点划线`DashDot`、双点划线`DashDotDot`等类型的折线图支持 -* (2019.09.17) 增加`AnimationEnabel()`启用或取消起始动画接口 -* (2019.09.17) 增加`Axis`的`Interval`强制设置坐标轴分割间隔 -* (2019.09.16) 去掉`Serie`中的旧版本数据兼容,不再支持`xData`和`yData` -* (2019.09.06) 增加`Animation`在重新初始化数据时自启动功能 -* (2019.09.06) 增加`SerieLabel`的`Border`边框相关配置支持 -* (2019.09.05) 增加`PieChart`的`Animation`初始化动画配置支持 -* (2019.09.03) 增加`BarChart`的`Animation`初始化动画配置支持 -* (2019.09.02) 增加`LineChart`的`Animation`初始化动画配置支持 -* (2019.08.22) 增加`AxisName`的`Offset`偏移配置支持 -* (2019.08.22) 增加`AxisLine`的`Width`配置支持 -* (2019.08.20) 增加`SerieLabel`的背景宽高、文字边距、文字旋转的配置 -* (2019.08.20) 增加`BarChart`的`Label`配置支持 -* (2019.08.15) 增加`LineChart`的`Label`配置 -* (2019.08.15) 重构`BarChart`,移除`Bar`组件,相关参数统一放到`Serie`中配置 -* (2019.08.15) 重构`LineChart`,移除`Line`组件,相关参数统一放到`Serie`中配置 - -## v0.8.3 - -* (2019.08.15) 发布`v0.8.3`版本 -* (2019.08.14) 修复`PieChart`的`Label`无法自动更新的问题 -* (2019.08.13) 修复`UpdateData`接口无法更新数据的问题 -* (2019.08.07) 增加`SerieSymbol`的`Color`、`Opacity`配置 - -## v0.8.2 - -* (2019.08.07) 发布`v0.8.2`版本 -* (2019.08.07) 修复区域平滑折线图显示异常的问题 -* (2019.08.06) 修复`serie`系列数超过调色盘颜色数时获取的颜色异常的问题 -* (2019.08.06) 修复当`Axis`的`minMaxType`为`Custom`时`max`设置为`100`不生效的问题 - -## v0.8.1 - -* (2019.08.04) 发布`v0.8.1`版本 -* (2019.08.04) 修复`Inspector`中修改数据不生效的问题 - -## v0.8.0 - -* (2019.08.04) 发布`v0.8.0`版本 -* (2019.08.04) 优化`RadarChart`雷达图,增加多雷达图支持 -* (2019.08.01) 增加代码API注释文档,整理代码 -* (2019.07.29) 增加`Radius`、`Area`两种南丁格尔玫瑰图展示类型 -* (2019.07.29) 增加`SerieLabel`配置饼图标签,支持`Center`、`Inside`、`Outside`等显示位置 -* (2019.07.28) 增加`PieChart`多饼图支持 -* (2019.07.23) 优化`Theme`主题的自定义,切换主题时自定义配置不受影响 -* (2019.07.22) 增加`EffectScatter`类型的散点图 -* (2019.07.21) 增加`ScatterChart`散点图 -* (2019.07.21) 增加`SerieData`支持多维数据配置 -* (2019.07.20) 增加`Symbol`配置`Serie`标志图形的显示 -* (2019.07.19) 增加用代码添加动态正弦曲线的示例`Demo11_AddSinCurve` -* (2019.07.19) 优化`Legend`的显示和控制 -* (2019.07.18) 优化抗锯齿,曲线更平滑 -* (2019.07.18) 增加`Tooltip`指示器类型,优化显示控制 -* (2019.07.15) 增加`Size`设置图表尺寸 -* (2019.07.14) 增加`二维数据`支持,XY轴都可以设置为数值轴 -* (2019.07.13) 增加`双坐标轴`支持,代码改动较大 - -## v0.5.0 - -* (2019.07.10) 发布`v0.5.0`版本 -* (2019.07.09) 增加`AxisLine`配置坐标轴轴线和箭头 -* (2019.07.03) 增加`AxisLabel`配置坐标轴`刻度标签` -* (2019.07.02) 增加`selected`等相关参数配置`PieChart`的选中效果 -* (2019.06.30) 增加`SplitArea`配置坐标轴`分割区域` -* (2019.06.29) 增加`AxisName`配置坐标轴`名称` -* (2019.06.20) 增加`AreaAlpha`控制`RadarChart`的`Area`透明度 -* (2019.06.13) 增加`DataZoom`实现`区域缩放` -* (2019.06.01) 增加`stepType`实现`LineChart`的`阶梯线图` -* (2019.05.29) 增加`InSameBar`实现`BarChart`的`非堆叠同柱` -* (2019.05.29) 增加`crossLabel`控制`Tooltip`的`十字准星指示器` -* (2019.05.24) 增加`堆叠区域图` -* (2019.05.16) 增加`AxisMinMaxType`控制坐标轴最大最小刻度 -* (2019.05.15) 完善数据接口 -* (2019.05.14) 增加X轴`AxisType.Value`模式支持 -* (2019.05.13) 增加负数数值轴支持 -* (2019.05.11) 增加自定义`Editor`编辑 -* (2019.03.21) 增加`Tooltip` -* (2018.11.01) 增加`Default`、`Light`、`Dark`三种默认主题 - -## v0.1.0 - -* (2018.09.05) 发布`v0.1.0`版本 diff --git a/Assets/XCharts/Documentation/CHANGELOG-EN.md.meta b/Assets/XCharts/Documentation/CHANGELOG-EN.md.meta deleted file mode 100644 index 979167c..0000000 --- a/Assets/XCharts/Documentation/CHANGELOG-EN.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 01f7eaa065d094f1f8955111a9bc447b -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/README-EN.md b/Assets/XCharts/Documentation/README-EN.md deleted file mode 100644 index 6f989d3..0000000 --- a/Assets/XCharts/Documentation/README-EN.md +++ /dev/null @@ -1,141 +0,0 @@ - -

XCharts

-

- A powerful, easy-to-use, configurable charting and data visualization library for Unity. -
- Unity数据可视化图表插件。 -
- 中文 -

-

- - - - - - - - - - - - - - - - - - -

-

- - - - - - - - - -

- -A powerful, easy-to-use, configurable charting and data visualization library for Unity. Supporting line, bar, pie, radar, scatter, heatmap, ring, candlestick, polar, liquid and other common chart. Also support 3d pie, 3d bar, 3d pyramid, funnel, gauge, liquid, pictorialbar, gantt, treemap and ther extended chart. - -[XCharts3.0 Tutorial](XChartsTutorial01-EN.md) -[XCharts3.0 API](XChartsAPI-EN.md) -[XCharts3.0 FAQ](XChartsFAQ-EN.md) -[XCharts3.0 Configurate](XChartsConfiguration-EN.md) -[XCharts3.0 Changelog](../CHANGELOG.md) -[XCharts3.0 Support](SUPPORT.md) - -## Features - -* Rich built-in examples and templates, parameter visualization configuration, effect real-time preview, pure code drawing. -* Support line, bar, pie, radar, scatter, heatmaps, gauge, ring, polar, liquid and other common chart. -* Support line graph, curve graph, area graph, step graph and other LineChart. -* Support parallel bar, stack bar, stack percentage bar, zebra bar and other BarChart. -* Support ring, rose and other PieChart. -* Support line-bar chart, scatter-line chart and other combination chart. -* Support solid line, curve, ladder line, dotted line, dash line, dot line, double dot line and other lines. -* Support custom theme, built-in theme switching. -* Support custom chart content drawing, drawing points, line, curve, triangle, quadrilateral, circle, ring, sector, border, arrow and other drawing API. -* Support interactive operations such as data filtering, view zooming and detail display on PC and mobile terminals. -* Support 10,000-level big data rendering. -* Support TextMeshPro. - -## XCharts3.0 new feature - -* Added `Time` axis. -* Added `SingleAxis`. -* Added multiple coordinate systems: `Grid`, `Polar`, `Radar`, `SingleAxis`. -* Added multiple animation methods. -* Added multiple chart interactions. -* Added internationalization support. -* Added `Widgets`. -* Added multiple extension charts. - -## XCharts3.0 improvements over XCharts2.0 - -* More robust underlying framework. -* More powerful performance. -* Smaller serialized files. -* Better interactive experience. -* More component support. -* More powerful ability to self-report text. -* More reasonable component adjustments. -* More flexible component insertion and removal. -* More efficient secondary development. -* Richer Demo examples. - -## XCharts3.0 and 2.0 data comparison - -| Case | XCharts2.0 | XCharts3.0 | Note | -| -- | -- | -- | -- | -| Fps of 2000 data line chart | ` 20 ` | ` 83 ` | Performance improvements `3` times | -| Vertices of 2000 data line chart | ` 36.5 k ` | ` 6.7 k ` | Vertices reduce `4` times | -| Prefab size of 2000 data line chart | ` 11.1 MB ` | ` 802 KB ` | Serialized file size to reduce `10` times | -| Max data of a single line chart | ` 4.1 k ` | ` 19 k ` | Single Serie data capacity improvement `4` times | -| Num of chart support | ` 11 ` | ` 23 ` | More than `1` times as many chart are supported | - -## Screenshots - -![buildinchart](https://github.com/XCharts-Team/XCharts-Demo/blob/master/buildinchart.png) - -![extendchart](https://github.com/XCharts-Team/XCharts-Demo/blob/master/extendchart.png) - -For more examples, see [XCharts-Demo](https://github.com/XCharts-Team/XCharts-Demo), You can also go to [Online Demo](https://xcharts-team.github.io/demo/) to see the running effect of `WebGL`. - -## Use - -1. Import `XCharts` unitypackage or source code into the project. -2. Right-click `Hierarchy` view and choose `XCharts->LineChart` to create a default LineChart. -3. You can adjust the parameters of each component in `Inspector` and see the real-time effects in `Game` view. - -See more tutorial: [XCharts tutorial: 5 minutes overhand tutorial](XChartsTutorial01-EN.md) - -## FAQ - -1. Is `XCharts` free to use? -A: `XCharts` uses the `MIT` licence and is free to use. You can also subscribe to `VIP` to enjoy more value-added services. - -2. Does `XCharts` support code to dynamically add and modify data? Does it support getting data from `Excel` or a database? -A: Support code to dynamically add and modify data, but data needs to be parsed or retrieved by itself, and then added to `XCharts` by calling the public interface of `XCharts`. - -3. Does this plugin work on other platforms (e.g. Winform or WPF) besides Unity? -A: It is currently only supported on Unity. Theoretically any version of Unity that supports `UGUI` can run `XCharts`. - -## Changelog - -[Changelog](CHANGELOG.md) - -## Licenses - -[MIT License](LICENSE.md) - -## Other - -email: `monitor1394@gmail.com` \ No newline at end of file diff --git a/Assets/XCharts/Documentation/SUPPORT.md b/Assets/XCharts/Documentation/SUPPORT.md deleted file mode 100644 index 585df8e..0000000 --- a/Assets/XCharts/Documentation/SUPPORT.md +++ /dev/null @@ -1,76 +0,0 @@ -# 订阅服务 - -如需技术支持,可订阅`个人VIP`服务。扫后面的二维码后可加VIP群`867291970`,验证信息请输入付费的账号。 企业商务合作可联系QQ:3525422251(XCharts技术支持)。 - -## 订阅VIP服务 - -订阅服务分个人订阅和企业订阅: - -- 个人订阅:个人VIP属于个人,不可转让,`XCharts`团队只服务于订阅当事人。 -- 企业订阅:企业VIP属于企业,席位内可安排固定职员,职员离职可重新安排,`XCharts`团队通过专属企业群为企业服务。 - -订阅服务的优势? - -- 提高工作效率,节省时间成本。一方面,`XCharts`功能强大,相关配置项非常多,`VIP`服务可快速帮您定位,节省去查找和核对的时间;另一方面,`VIP`的即时回答服务可快速为您答疑解惑,避免中断开发流程。总之,订阅`VIP`可让您能快速上手,快速处理问题,至少能提高`10`倍以上的工作效率。 -- 更多技术交流,更多经验交流。`XCharts`团队成员从业多年,有丰富的技术和工作经验。`VIP`服务不仅可以交流`XCharts`相关的内容,也可以咨询其他方面的技术。`VIP`群也有更多的交流。 -- 扩展图表的需要订阅`VIP`服务后才能购买,扩展图表超过1年后的更新支持也需要持续订阅`VIP`服务。 -- `VIP`用户可加入`XCharts`的`GitHub`组织,参与`XCharts`社区构建,访问专有仓库。 - -| |免费用户|付费咨询|个人`VIP` | 个人`SVIP` | 企业`VIP` | -| ----- |--|--|--|--|--| -| 订阅费用 | -- | `98`¥ | `298`¥ | 首年`1298`¥
后续`298¥`* | `联系我们` | -| 订阅时长 | -- | `7`天* | `1`年 | `1`年* | `1`年 -| 订阅席位 | -- | `1`个席位 | `1`个席位 |`1`个席位|`5`个以上席位| -| __`服务方式:`__| -| 官方QQ群交流 | √ | √ | √ | √ | √ | -| 即时一对一交流 | | √ | √ | √ | √ | -| 专属VIP群交流 | | | √ | √ | √(专属企业群) | -| __`服务内容:`__| -| 可商用 | √ | √ | √ | √ | √ | -| 可二次开发 | √ | √ | √ | √ | √ | -| 有问必答 | | √ | √ | √ | √ | -| 即时回答 | | √ | √ | √ | √ | -| 新手指导 | | √ | √ | √ | √ | -| 开发指导 | | √ | √ | √ | √ | -| 优化指导 | | √ | √ | √ | √ | -| 其他技术支持 | | | √ | √ | √ | -| 问题及时处理 | | | √ | √ | √ | -| 需求优先考虑 | | | √ | √ | √ | -| 可另付费定制 | | | √ | √ | √ | -| 可另付费加急 | | | √ | √ | √ | -| VIP专有功能教程和文档 | | | √待开放 | √待开放 | √待开放 | -| 扩展图表购买 | | | 按需购买 | 全部免费 | 按需购买 | -| 扩展图表源码 | | | 永久持有 | 永久持有 | 永久持有 | -| 扩展图表更新 | | | 1年持续更新
1年后需订阅 | 1年持续更新
1年后需订阅 | 1年持续更新
1年后需订阅 | - -## 购买扩展图表 - -扩展图表为另付费购买图表,只对订阅了`VIP`服务的用户开放购买。对于`SVIP`的订阅用户,所有扩展图表仓库可免费使用,不用再单独购买。 - -对所有已购买的扩展图表,源码可永久持有,并获得持续一年的更新支持,超过一年后想要更新支持需要继续订阅`VIP`服务,如不继续订阅`VIP`服务,会从`GitHub`的`Team`中移除,不再能访问扩展图表的源码仓库。 - -|编号|扩展图表|价格|备注| -|--|--|--|--| -| 101 | PictorialBarChart | 98¥ | 象形柱图 | -| 102 | FunnelChart | 98¥ | 漏斗图 | -| 103 | PyramidChart | 98¥ | 3D金字塔 | -| 104 | TreemapChart | 98¥ | 树形矩图 | -| 201 | Bar3DChart | 198¥ | 3D柱图 | -| 202 | Pie3DChart | 198¥ | 3D饼图 | -| 203 | GanttChart | 198¥ | 甘特图 | -| 204 | GaugeChart | 198¥ | 仪表盘 | -| 205 | LiquidChart | 198¥ | 水位图 | - -## 备注说明 - -1. __`付费定制`__ 是指用户可根据自己的需求定制不同的图表或新功能,只有`VIP`用户才享有`付费定制`权利。 -2. __`付费加急`__ 是指用户可对自己非常紧急的需求进行付费,将开发优先级提到最高,并可要求在`Deadline`内交付,只有`VIP`用户才享有`付费加急`权利。 -3. __`付费咨询`__ 付费咨询有效期`7`天,且总咨询时长不超过`7`个小时。 -4. __`扩展图表`__ 购买后代码可永久持有和商用,更新支持1年。超过1年后还需要更新支持的话,需要订阅`VIP`服务。 - -## 捐助支持 - -如果这个项目对您有帮助,请右上方点 `Star` 予以支持!也欢迎任意金额的捐助,非常您的支持! - -![alipay-qrcode](res/alipay.png) -![wechat-qrcode](res/wechat.png) diff --git a/Assets/XCharts/Documentation/SUPPORT.md.meta b/Assets/XCharts/Documentation/SUPPORT.md.meta deleted file mode 100644 index 588d0ee..0000000 --- a/Assets/XCharts/Documentation/SUPPORT.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 40051c210ea1244a99317f3264ac567f -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsAPI-EN.md b/Assets/XCharts/Documentation/XChartsAPI-EN.md deleted file mode 100644 index 17c7136..0000000 --- a/Assets/XCharts/Documentation/XChartsAPI-EN.md +++ /dev/null @@ -1,1075 +0,0 @@ -# Chart API - -[XCharts Homepage](https://github.com/XCharts-Team/XCharts)
-[XCharts Configuration](XChartsConfiguration-EN.md)
-[XCharts FAQ](XChartsFAQ-EN.md) - -## Class - -- [AnimationStyleHelper](#AnimationStyleHelper) -- [AxisContext](#AxisContext) -- [AxisHandler](#AxisHandler) -- [AxisHelper](#AxisHelper) -- [BarChart](#BarChart) -- [BaseChart](#BaseChart) -- [BaseGraph](#BaseGraph) -- [CandlestickChart](#CandlestickChart) -- [ChartCached](#ChartCached) -- [ChartConst](#ChartConst) -- [ChartDrawer](#ChartDrawer) -- [ChartHelper](#ChartHelper) -- [ChartLabel](#ChartLabel) -- [ChartObject](#ChartObject) -- [CheckHelper](#CheckHelper) -- [ColorUtil](#ColorUtil) -- [ComponentHandlerAttribute](#ComponentHandlerAttribute) -- [ComponentHelper](#ComponentHelper) -- [CoordOptionsAttribute](#CoordOptionsAttribute) -- [DataZoomContext](#DataZoomContext) -- [DataZoomHelper](#DataZoomHelper) -- [DateTimeUtil](#DateTimeUtil) -- [DefaultAnimationAttribute](#DefaultAnimationAttribute) -- [DefineSymbolsUtil](#DefineSymbolsUtil) -- [FormatterHelper](#FormatterHelper) -- [GridCoordContext](#GridCoordContext) -- [HeatmapChart](#HeatmapChart) -- [IgnoreDoc](#IgnoreDoc) -- [InteractData](#InteractData) -- [LayerHelper](#LayerHelper) -- [LegendContext](#LegendContext) -- [LegendHelper](#LegendHelper) -- [LegendItem](#LegendItem) -- [LineChart](#LineChart) -- [ListFor](#ListFor) -- [ListForComponent](#ListForComponent) -- [ListForSerie](#ListForSerie) -- [MainComponentContext](#MainComponentContext) -- [MainComponentHandler](#MainComponentHandler) -- [MainComponentHandler](#MainComponentHandler) -- [MathUtil](#MathUtil) -- [ObjectPool where T](#ObjectPool where T) -- [Painter](#Painter) -- [ParallelChart](#ParallelChart) -- [ParallelCoordContext](#ParallelCoordContext) -- [PieChart](#PieChart) -- [PolarChart](#PolarChart) -- [PolarCoordContext](#PolarCoordContext) -- [ProgressBar](#ProgressBar) -- [PropertyUtil](#PropertyUtil) -- [RadarChart](#RadarChart) -- [RadarCoordContext](#RadarCoordContext) -- [ReflectionUtil](#ReflectionUtil) -- [RequireChartComponentAttribute](#RequireChartComponentAttribute) -- [RingChart](#RingChart) -- [RuntimeUtil](#RuntimeUtil) -- [ScatterChart](#ScatterChart) -- [SerieContext](#SerieContext) -- [SerieConvertAttribute](#SerieConvertAttribute) -- [SerieDataContext](#SerieDataContext) -- [SerieDataExtraComponentAttribute](#SerieDataExtraComponentAttribute) -- [SerieDataExtraFieldAttribute](#SerieDataExtraFieldAttribute) -- [SerieExtraComponentAttribute](#SerieExtraComponentAttribute) -- [SerieHandler](#SerieHandler) -- [SerieHandler](#SerieHandler) -- [SerieHandlerAttribute](#SerieHandlerAttribute) -- [SerieHelper](#SerieHelper) -- [SerieLabelHelper](#SerieLabelHelper) -- [SerieLabelPool](#SerieLabelPool) -- [SerieParams](#SerieParams) -- [SeriesHelper](#SeriesHelper) -- [SimplifiedBarChart](#SimplifiedBarChart) -- [SimplifiedCandlestickChart](#SimplifiedCandlestickChart) -- [SimplifiedLineChart](#SimplifiedLineChart) -- [SVG](#SVG) -- [SVGImage](#SVGImage) -- [SVGPath](#SVGPath) -- [SVGPathSeg](#SVGPathSeg) -- [TooltipContext](#TooltipContext) -- [TooltipData](#TooltipData) -- [TooltipHelper](#TooltipHelper) -- [TooltipView](#TooltipView) -- [TooltipViewItem](#TooltipViewItem) -- [UGL](#UGL) -- [UGLExample](#UGLExample) -- [UGLHelper](#UGLHelper) -- [VisualMapContext](#VisualMapContext) -- [VisualMapHelper](#VisualMapHelper) -- [XChartsMgr](#XChartsMgr) -- [XCResourceImporterWindow](#XCResourceImporterWindow) -- [XCThemeMgr](#XCThemeMgr) - -## `AnimationStyleHelper` - -|public method|description| -|--|--| -| `CheckDataAnimation()` |public static float CheckDataAnimation(BaseChart chart, Serie serie, int dataIndex, float destProgress, float startPorgress = 0)
| -| `GetAnimationPosition()` |public static bool GetAnimationPosition(AnimationStyle animation, bool isY, Vector3 lp, Vector3 cp, float progress, ref Vector3 ip)
| -| `UpdateAnimationType()` |public static void UpdateAnimationType(AnimationStyle animation, AnimationType defaultType)
| -| `UpdateSerieAnimation()` |public static void UpdateSerieAnimation(Serie serie)
| - -## `AxisContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `AxisHandler` - -Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) - -## `AxisHelper` - -|public method|description| -|--|--| -| `AdjustCircleLabelPos()` |public static void AdjustCircleLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
| -| `AdjustMinMaxValue()` |public static void AdjustMinMaxValue(Axis axis, ref double minValue, ref double maxValue, bool needFormat, int ceilRate = 0)
调整最大最小值 | -| `AdjustRadiusAxisLabelPos()` |public static void AdjustRadiusAxisLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
| -| `GetAxisLineArrowOffset()` |public static float GetAxisLineArrowOffset(Axis axis)
包含箭头偏移的轴线长度 | -| `GetAxisPosition()` |public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
| -| `GetAxisPositionValue()` |public static double GetAxisPositionValue(float xy, float axisLength, double axisRange, float axisStart, float axisOffset)
| -| `GetAxisPositionValue()` |public static double GetAxisPositionValue(GridCoord grid, Axis axis, Vector3 pos)
| -| `GetAxisValueDistance()` |public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上相对起点的距离 | -| `GetAxisValueLength()` |public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上对应的长度 | -| `GetAxisValuePosition()` |public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上的坐标位置 | -| `GetDataWidth()` |public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
获得一个类目数据在坐标系中代表的宽度 | -| `GetEachWidth()` |public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
| -| `GetScaleNumber()` |public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
获得分割线条数 | -| `GetScaleWidth()` |public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
获得分割段宽度 | -| `GetSplitNumber()` |public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
获得分割段数 | -| `NeedShowSplit()` |public static bool NeedShowSplit(Axis axis)
| - -## `BarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `BaseChart` - -Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver](#ISerializationCallbackReceiver) - -|public method|description| -|--|--| -| `AddChartComponent()` |public MainComponent AddChartComponent(Type type)
| -| `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)
Add a (time,y) data to serie. | -| `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)
Add a data to serie. | -| `AddData()` |public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| -| `AddData()` |public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null)
Add a (x,y) data to serie. | -| `AddData()` |public SerieData AddData(int serieIndex, List 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, DateTime time, double yValue, string dataName = null, string dataId = null)
Add a (time,y) data to serie. | -| `AddData()` |public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null)
Add a data to serie. | -| `AddData()` |public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| -| `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 multidimensionalData, string dataName = null, string dataId = null)
Add an arbitray dimension data to serie,such as (x,y,z,...). | -| `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. | -| `AddYAxisData()` |public void AddYAxisData(string category, int yAxisIndex = 0)
Add a category data to yAxis. | -| `AddYAxisIcon()` |public void AddYAxisIcon(Sprite icon, int yAxisIndex = 0)
Add an icon to yAxis. | -| `AnimationEnable()` |public void AnimationEnable(bool flag)
Whether series animation enabel. | -| `AnimationFadeIn()` |public void AnimationFadeIn()
fadeIn animation. | -| `AnimationFadeOut()` |public void AnimationFadeOut()
fadeIn animation. | -| `AnimationPause()` |public void AnimationPause()
Pause animation. | -| `AnimationReset()` |public void AnimationReset()
Reset animation. | -| `AnimationResume()` |public void AnimationResume()
Stop play animation. | -| `CanAddChartComponent()` |public bool CanAddChartComponent(Type type)
| -| `CanAddSerie()` |public bool CanAddSerie(Type type)
| -| `CanMultipleComponent()` |public bool CanMultipleComponent(Type type)
| -| `ClampInChart()` |public void ClampInChart(ref Vector3 pos)
| -| `ClampInGrid()` |public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)
| -| `ClearData()` |public virtual void ClearData()
Remove all series and legend data. | -| `ClickLegendButton()` |public void ClickLegendButton(int legendIndex, string legendName, bool show)
点击图例按钮 | -| `CovertSerie()` |public bool CovertSerie(Serie serie, Type type)
| -| `CovertXYAxis()` |public void CovertXYAxis(int index)
转换X轴和Y轴的配置 | -| `GenerateDefaultSerieName()` |public string GenerateDefaultSerieName()
| -| `GetAllSerieDataCount()` |public int GetAllSerieDataCount()
| -| `GetChartBackgroundColor()` |public Color32 GetChartBackgroundColor()
| -| `GetChartComponentNum()` |public int GetChartComponentNum(Type type)
| -| `GetData()` |public double GetData(int serieIndex, int dataIndex, int dimension = 1)
| -| `GetData()` |public double GetData(string serieName, int dataIndex, int dimension = 1)
| -| `GetDataZoomOfAxis()` |public DataZoom GetDataZoomOfAxis(Axis axis)
| -| `GetDataZoomOfSerie()` |public void GetDataZoomOfSerie(Serie serie, out DataZoom xDataZoom, out DataZoom yDataZoom)
| -| `GetGrid()` |public GridCoord GetGrid(Vector2 local)
| -| `GetGridOfDataZoom()` |public GridCoord GetGridOfDataZoom(DataZoom dataZoom)
| -| `GetItemColor()` |public Color32 GetItemColor(Serie serie, bool highlight = false)
| -| `GetItemColor()` |public Color32 GetItemColor(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetLegendRealShowNameColor()` |public Color32 GetLegendRealShowNameColor(string name)
| -| `GetLegendRealShowNameIndex()` |public int GetLegendRealShowNameIndex(string name)
| -| `GetPainter()` |public Painter GetPainter(int index)
| -| `GetSerie()` |public Serie GetSerie(int serieIndex)
| -| `GetSerie()` |public Serie GetSerie(string serieName)
| -| `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)
| -| `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)
| -| `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)
| -| `GetXLerpColor()` |public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| -| `GetYLerpColor()` |public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| -| `HasChartComponent()` |public bool HasChartComponent(Type type)
| -| `HasChartComponent()` |public bool HasChartComponent()
| -| `HasSerie()` |public bool HasSerie(Type type)
| -| `Init()` |public void Init(bool defaultChart = true)
| -| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis)
| -| `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)
| -| `Internal_CheckAnimation()` |public void Internal_CheckAnimation()
| -| `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)
Whether serie is activated. | -| `IsAllAxisCategory()` |public bool IsAllAxisCategory()
纯类目轴。 | -| `IsAllAxisValue()` |public bool IsAllAxisValue()
reutrn true when all the show axis is `Value` type. | -| `IsInAnyGrid()` |public bool IsInAnyGrid(Vector2 local)
| -| `IsInChart()` |public bool IsInChart(float x, float y)
| -| `IsInChart()` |public bool IsInChart(Vector2 local)
坐标是否在图表范围内 | -| `IsSerieName()` |public bool IsSerieName(string name)
| -| `MoveDownSerie()` |public bool MoveDownSerie(int serieIndex)
| -| `MoveUpSerie()` |public bool MoveUpSerie(int serieIndex)
| -| `OnAfterDeserialize()` |public void OnAfterDeserialize()
| -| `OnBeforeSerialize()` |public void OnBeforeSerialize()
| -| `OnBeginDrag()` |public override void OnBeginDrag(PointerEventData eventData)
| -| `OnDataZoomRangeChanged()` |public virtual void OnDataZoomRangeChanged(DataZoom dataZoom)
| -| `OnDrag()` |public override void OnDrag(PointerEventData eventData)
| -| `OnEndDrag()` |public override void OnEndDrag(PointerEventData eventData)
| -| `OnLegendButtonClick()` |public virtual void OnLegendButtonClick(int index, string legendName, bool show)
| -| `OnLegendButtonEnter()` |public virtual void OnLegendButtonEnter(int index, string legendName)
| -| `OnLegendButtonExit()` |public virtual void OnLegendButtonExit(int index, string legendName)
| -| `OnPointerClick()` |public override void OnPointerClick(PointerEventData eventData)
| -| `OnPointerDown()` |public override void OnPointerDown(PointerEventData eventData)
| -| `OnPointerEnter()` |public override void OnPointerEnter(PointerEventData eventData)
| -| `OnPointerExit()` |public override void OnPointerExit(PointerEventData eventData)
| -| `OnPointerUp()` |public override void OnPointerUp(PointerEventData eventData)
| -| `OnScroll()` |public override void OnScroll(PointerEventData eventData)
| -| `RefreshBasePainter()` |public void RefreshBasePainter()
| -| `RefreshChart()` |public void RefreshChart()
Redraw chart in next frame. | -| `RefreshChart()` |public void RefreshChart(int serieIndex)
Redraw chart serie in next frame. | -| `RefreshChart()` |public void RefreshChart(Serie serie)
Redraw chart serie in next frame. | -| `RefreshDataZoom()` |public void RefreshDataZoom()
在下一帧刷新DataZoom | -| `RefreshPainter()` |public void RefreshPainter(int index)
| -| `RefreshPainter()` |public void RefreshPainter(Serie serie)
| -| `RefreshTopPainter()` |public void RefreshTopPainter()
| -| `RemoveAllChartComponent()` |public void RemoveAllChartComponent()
| -| `RemoveChartComponent()` |public bool RemoveChartComponent(MainComponent component)
| -| `RemoveChartComponent()` |public bool RemoveChartComponent(Type type, int index = 0)
| -| `RemoveChartComponent()` |public bool RemoveChartComponent(int index = 0)
| -| `RemoveChartComponents()` |public int RemoveChartComponents(Type type)
| -| `RemoveChartComponents()` |public int RemoveChartComponents()
| -| `RemoveData()` |public virtual void RemoveData()
Remove all data from series and legend. | -| `RemoveData()` |public virtual void RemoveData(string serieName)
Remove legend and serie by name. | -| `RemoveSerie()` |public void RemoveSerie(int serieIndex)
| -| `RemoveSerie()` |public void RemoveSerie(Serie serie)
| -| `RemoveSerie()` |public void RemoveSerie(string serieName)
| -| `ReplaceSerie()` |public bool ReplaceSerie(Serie oldSerie, Serie newSerie)
| -| `SetBasePainterMaterial()` |public void SetBasePainterMaterial(Material material)
设置Base Painter的材质球 | -| `SetMaxCache()` |public void SetMaxCache(int maxCache)
设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 | -| `SetPainterActive()` |public void SetPainterActive(int index, bool flag)
| -| `SetSerieActive()` |public void SetSerieActive(int serieIndex, bool active)
Whether to show serie. | -| `SetSerieActive()` |public void SetSerieActive(Serie serie, bool active)
| -| `SetSerieActive()` |public void SetSerieActive(string serieName, bool active)
Whether to show serie. | -| `SetSeriePainterMaterial()` |public void SetSeriePainterMaterial(Material material)
设置Serie Painter的材质球 | -| `SetTopPainterMaterial()` |public void SetTopPainterMaterial(Material material)
设置Top Painter的材质球 | -| `TryAddChartComponent()` |public bool TryAddChartComponent(Type type)
| -| `TryGetChartComponent()` |public bool TryGetChartComponent(out T component, int index = 0)
| -| `UdpateXAxisIcon()` |public void UdpateXAxisIcon(int index, Sprite icon, int xAxisIndex = 0)
Update xAxis icon. | -| `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, double value)
Update serie data by serie index. | -| `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, int dimension, double value)
更新指定系列指定索引指定维数的数据。维数从0开始。 | -| `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, List multidimensionalData)
更新指定系列指定索引的数据项的多维数据。 | -| `UpdateData()` |public bool UpdateData(string serieName, int dataIndex, double value)
Update serie data by serie name. | -| `UpdateData()` |public bool UpdateData(string serieName, int dataIndex, int dimension, double value)
更新指定系列指定索引指定维数的数据。维数从0开始。 | -| `UpdateData()` |public bool UpdateData(string serieName, int dataIndex, List multidimensionalData)
更新指定系列指定索引的数据项的多维数据。 | -| `UpdateDataName()` |public bool UpdateDataName(int serieIndex, int dataIndex, string dataName)
Update serie data name. | -| `UpdateDataName()` |public bool UpdateDataName(string serieName, int dataIndex, string dataName)
Update serie data name. | -| `UpdateLegendColor()` |public virtual void UpdateLegendColor(string legendName, bool active)
| -| `UpdateTheme()` |public bool UpdateTheme(ThemeType theme)
Update chart theme. | -| `UpdateTheme()` |public void UpdateTheme(Theme theme)
Update chart theme info. | -| `UpdateXAxisData()` |public void UpdateXAxisData(int index, string category, int xAxisIndex = 0)
Update category data. | -| `UpdateYAxisData()` |public void UpdateYAxisData(int index, string category, int yAxisIndex = 0)
Update category data. | -| `UpdateYAxisIcon()` |public void UpdateYAxisIcon(int index, Sprite icon, int yAxisIndex = 0)
更新Y轴图标。 | - -## `BaseGraph` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic),[IPointerDownHandler](#IPointerDownHandler),[IPointerUpHandler](#IPointerUpHandler),[](#) - -|public method|description| -|--|--| -| `CheckWarning()` |public string CheckWarning()
检测警告信息。 | -| `OnBeginDrag()` |public virtual void OnBeginDrag(PointerEventData eventData)
| -| `OnDrag()` |public virtual void OnDrag(PointerEventData eventData)
| -| `OnEndDrag()` |public virtual void OnEndDrag(PointerEventData eventData)
| -| `OnPointerClick()` |public virtual void OnPointerClick(PointerEventData eventData)
| -| `OnPointerDown()` |public virtual void OnPointerDown(PointerEventData eventData)
| -| `OnPointerEnter()` |public virtual void OnPointerEnter(PointerEventData eventData)
| -| `OnPointerExit()` |public virtual void OnPointerExit(PointerEventData eventData)
| -| `OnPointerUp()` |public virtual void OnPointerUp(PointerEventData eventData)
| -| `OnScroll()` |public virtual void OnScroll(PointerEventData eventData)
| -| `RebuildChartObject()` |public void RebuildChartObject()
移除并重新创建所有图表的Object。 | -| `RefreshAllComponent()` |public void RefreshAllComponent()
| -| `RefreshGraph()` |public void RefreshGraph()
Redraw graph in next frame. | -| `ScreenPointToChartPoint()` |public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint)
| -| `SetPainterDirty()` |public void SetPainterDirty()
重新初始化Painter | -| `SetSize()` |public virtual void SetSize(float width, float height)
设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform) | - -## `CandlestickChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `ChartCached` - -|public method|description| -|--|--| -| `ColorToDotStr()` |public static string ColorToDotStr(Color color)
| -| `ColorToStr()` |public static string ColorToStr(Color color)
| -| `FloatToStr()` |public static string FloatToStr(double value, string numericFormatter = "F", int precision = 0)
| -| `GetSerieLabelName()` |public static string GetSerieLabelName(string prefix, int i, int j)
| -| `IntToStr()` |public static string IntToStr(int value, string numericFormatter = "")
| -| `NumberToStr()` |public static string NumberToStr(double value, string formatter)
| - -## `ChartConst` - -## `ChartDrawer` - -## `ChartHelper` - -|public method|description| -|--|--| -| `ActiveAllObject()` |public static void ActiveAllObject(Transform parent, bool active, string match = null)
| -| `AddIcon()` |public static Image AddIcon(string name, Transform parent, IconStyle iconStyle)
| -| `Cancat()` |public static string Cancat(string str1, int i)
| -| `Cancat()` |public static string Cancat(string str1, string str2)
| -| `ClearEventListener()` |public static void ClearEventListener(GameObject obj)
| -| `CopyArray()` |public static bool CopyArray(T[] toList, T[] fromList)
| -| `CopyList()` |public static bool CopyList(List toList, List fromList)
| -| `DestoryGameObject()` |public static void DestoryGameObject(GameObject go)
| -| `DestoryGameObject()` |public static void DestoryGameObject(Transform parent, string childName)
| -| `DestoryGameObjectByMatch()` |public static void DestoryGameObjectByMatch(Transform parent, string match)
| -| `DestroyAllChildren()` |public static void DestroyAllChildren(Transform parent)
| -| `GetActualValue()` |public static float GetActualValue(float valueOrRate, float total, float maxRate = 1.5f)
| -| `GetAngle360()` |public static float GetAngle360(Vector2 from, Vector2 to)
获得0-360的角度(12点钟方向为0度) | -| `GetColor()` |public static Color32 GetColor(string hexColorStr)
| -| `GetDire()` |public static Vector3 GetDire(float angle, bool isDegree = false)
| -| `GetFloatAccuracy()` |public static int GetFloatAccuracy(double value)
| -| `GetFullName()` |public static string GetFullName(Transform transform)
| -| `GetHighlightColor()` |public static Color32 GetHighlightColor(Color32 color, float rate = 0.8f)
| -| `GetLastValue()` |public static Vector3 GetLastValue(List list)
| -| `GetMaxDivisibleValue()` |public static double GetMaxDivisibleValue(double max, int ceilRate)
| -| `GetMaxLogValue()` |public static double GetMaxLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| -| `GetMinDivisibleValue()` |public static double GetMinDivisibleValue(double min, int ceilRate)
| -| `GetMinLogValue()` |public static double GetMinLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| -| `GetPointList()` |public static void GetPointList(ref List posList, Vector3 sp, Vector3 ep, float k = 30f)
| -| `GetPos()` |public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
| -| `GetPosition()` |public static Vector3 GetPosition(Vector3 center, float angle, float radius)
| -| `GetVertialDire()` |public static Vector3 GetVertialDire(Vector3 dire)
| -| `HideAllObject()` |public static void HideAllObject(GameObject obj, string match = null)
| -| `HideAllObject()` |public static void HideAllObject(Transform parent, string match = null)
| -| `IsClearColor()` |public static bool IsClearColor(Color color)
| -| `IsClearColor()` |public static bool IsClearColor(Color32 color)
| -| `IsColorAlphaZero()` |public static bool IsColorAlphaZero(Color color)
| -| `IsEquals()` |public static bool IsEquals(double d1, double d2)
| -| `IsEquals()` |public static bool IsEquals(float d1, float d2)
| -| `IsIngore()` |public static bool IsIngore(Vector3 pos)
| -| `IsInRect()` |public static bool IsInRect(Vector3 pos, float xMin, float xMax, float yMin, float yMax)
| -| `IsPointInQuadrilateral()` |public static bool IsPointInQuadrilateral(Vector3 P, Vector3 A, Vector3 B, Vector3 C, Vector3 D)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color color1, Color color2)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
| -| `IsValueEqualsList()` |public static bool IsValueEqualsList(List list1, List list2)
| -| `IsValueEqualsString()` |public static bool IsValueEqualsString(string str1, string str2)
| -| `IsValueEqualsVector2()` |public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2)
| -| `IsValueEqualsVector3()` |public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2)
| -| `IsZeroVector()` |public static bool IsZeroVector(Vector3 pos)
| -| `ParseFloatFromString()` |public static List ParseFloatFromString(string jsonData)
| -| `ParseStringFromString()` |public static List ParseStringFromString(string jsonData)
| -| `RemoveComponent()` |public static void RemoveComponent(GameObject gameObject)
| -| `RotateRound()` |public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
| -| `SetActive()` |public static void SetActive(GameObject gameObject, bool active)
| -| `SetActive()` |public static void SetActive(Image image, bool active)
| -| `SetActive()` |public static void SetActive(Text text, bool active)
| -| `SetActive()` |public static void SetActive(Transform transform, bool active)
通过设置scale实现是否显示,优化性能,减少GC | -| `SetColorOpacity()` |public static void SetColorOpacity(ref Color32 color, float opacity)
| - -## `ChartLabel` - -Inherits or Implemented: [Image](#Image) - -|public method|description| -|--|--| -| `GetHeight()` |public float GetHeight()
| -| `GetPosition()` |public Vector3 GetPosition()
| -| `GetTextHeight()` |public float GetTextHeight()
| -| `GetTextWidth()` |public float GetTextWidth()
| -| `GetWidth()` |public float GetWidth()
| -| `SetActive()` |public void SetActive(bool flag)
| -| `SetIcon()` |public void SetIcon(Image image)
| -| `SetIconActive()` |public void SetIconActive(bool flag)
| -| `SetIconSize()` |public void SetIconSize(float width, float height)
| -| `SetIconSprite()` |public void SetIconSprite(Sprite sprite)
| -| `SetPadding()` |public void SetPadding(float[] padding)
| -| `SetPosition()` |public void SetPosition(Vector3 position)
| -| `SetRectPosition()` |public void SetRectPosition(Vector3 position)
| -| `SetSize()` |public void SetSize(float width, float height)
| -| `SetText()` |public bool SetText(string text)
| -| `SetTextActive()` |public void SetTextActive(bool flag)
| -| `SetTextColor()` |public void SetTextColor(Color color)
| -| `SetTextPadding()` |public void SetTextPadding(TextPadding padding)
| -| `SetTextRotate()` |public void SetTextRotate(float rotate)
| -| `UpdateIcon()` |public void UpdateIcon(IconStyle iconStyle, Sprite sprite = null)
| - -## `ChartObject` - -|public method|description| -|--|--| -| `Destroy()` |public virtual void Destroy()
| - -## `CheckHelper` - -|public method|description| -|--|--| -| `CheckChart()` |public static string CheckChart(BaseChart chart)
| -| `CheckChart()` |public static string CheckChart(BaseGraph chart)
| - -## `ColorUtil` - -|public method|description| -|--|--| -| `GetColor()` |public static Color32 GetColor(string hexColorStr)
Convert the html string to color. | - -## `ComponentHandlerAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `ComponentHandlerAttribute()` |public ComponentHandlerAttribute(Type handler)
| -| `ComponentHandlerAttribute()` |public ComponentHandlerAttribute(Type handler, bool allowMultiple)
| - -## `ComponentHelper` - -|public method|description| -|--|--| -| `GetAngleAxis()` |public static AngleAxis GetAngleAxis(List components, int polarIndex)
| -| `GetRadiusAxis()` |public static RadiusAxis GetRadiusAxis(List components, int polarIndex)
| -| `GetXAxisOnZeroOffset()` |public static float GetXAxisOnZeroOffset(List components, XAxis axis)
| -| `GetYAxisOnZeroOffset()` |public static float GetYAxisOnZeroOffset(List components, YAxis axis)
| -| `IsAnyCategoryOfYAxis()` |public static bool IsAnyCategoryOfYAxis(List components)
| - -## `CoordOptionsAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord)
| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2)
| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2, Type coord3)
| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2, Type coord3, Type coord4)
| - -## `DataZoomContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `DataZoomHelper` - -|public method|description| -|--|--| -| `UpdateDataZoomRuntimeStartEndValue()` |public static void UpdateDataZoomRuntimeStartEndValue(DataZoom dataZoom, Serie serie)
| - -## `DateTimeUtil` - -|public method|description| -|--|--| -| `GetDateTime()` |public static DateTime GetDateTime(int timestamp)
| -| `GetTimestamp()` |public static int GetTimestamp()
| -| `GetTimestamp()` |public static int GetTimestamp(DateTime time)
| - -## `DefaultAnimationAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `DefaultAnimationAttribute()` |public DefaultAnimationAttribute(AnimationType handler)
| - -## `DefineSymbolsUtil` - -|public method|description| -|--|--| -| `AddGlobalDefine()` |public static void AddGlobalDefine(string symbol)
| -| `RemoveGlobalDefine()` |public static void RemoveGlobalDefine(string symbol)
| - -## `FormatterHelper` - -|public method|description| -|--|--| -| `NeedFormat()` |public static bool NeedFormat(string content)
| -| `ReplaceAxisLabelContent()` |public static void ReplaceAxisLabelContent(ref string content, string numericFormatter, double value)
| -| `ReplaceAxisLabelContent()` |public static void ReplaceAxisLabelContent(ref string content, string value)
| -| `TrimAndReplaceLine()` |public static string TrimAndReplaceLine(string content)
| -| `TrimAndReplaceLine()` |public static string TrimAndReplaceLine(StringBuilder sb)
| - -## `GridCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `HeatmapChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `IgnoreDoc` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `IgnoreDoc()` |public IgnoreDoc()
| - -## `InteractData` - -|public method|description| -|--|--| -| `Reset()` |public void Reset()
| -| `SetColor()` |public void SetColor(ref bool needInteract, Color32 color)
| -| `SetColor()` |public void SetColor(ref bool needInteract, Color32 color, Color32 toColor)
| -| `SetValue()` |public void SetValue(ref bool needInteract, float size)
| -| `SetValue()` |public void SetValue(ref bool needInteract, float size, bool highlight, float rate = 1.3f)
| -| `SetValueAndColor()` |public void SetValueAndColor(ref bool needInteract, float value, Color32 color)
| -| `SetValueAndColor()` |public void SetValueAndColor(ref bool needInteract, float value, Color32 color, Color32 toColor)
| -| `TryGetColor()` |public bool TryGetColor(ref Color32 color, ref bool interacting, float animationDuration = 250)
| -| `TryGetColor()` |public bool TryGetColor(ref Color32 color, ref Color32 toColor, ref bool interacting, float animationDuration = 250)
| -| `TryGetValue()` |public bool TryGetValue(ref float value, ref bool interacting, float animationDuration = 250)
| -| `TryGetValueAndColor()` |public bool TryGetValueAndColor(ref float value, ref Color32 color, ref Color32 toColor, ref bool interacting, float animationDuration = 250)
| - -## `LayerHelper` - -|public method|description| -|--|--| -| `IsFixedWidthHeight()` |public static bool IsFixedWidthHeight(RectTransform rt)
| -| `IsStretchPivot()` |public static bool IsStretchPivot(RectTransform rt)
| - -## `LegendContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `LegendHelper` - -|public method|description| -|--|--| -| `CheckDataHighlighted()` |public static bool CheckDataHighlighted(Serie serie, string legendName, bool heighlight)
| -| `CheckDataShow()` |public static bool CheckDataShow(Serie serie, string legendName, bool show)
| -| `GetContentColor()` |public static Color GetContentColor(BaseChart chart, int legendIndex, string legendName, Legend legend, ThemeStyle theme, bool active)
| -| `GetIconColor()` |public static Color GetIconColor(BaseChart chart, Legend legend, int readIndex, string legendName, bool active)
| -| `ResetItemPosition()` |public static void ResetItemPosition(Legend legend, Vector3 chartPos, float chartWidth, float chartHeight)
| - -## `LegendItem` - -|public method|description| -|--|--| -| `GetIconColor()` |public Color GetIconColor()
| -| `GetIconRect()` |public Rect GetIconRect()
| -| `SetActive()` |public void SetActive(bool active)
| -| `SetButton()` |public void SetButton(Button button)
| -| `SetContent()` |public bool SetContent(string content)
| -| `SetContentBackgroundColor()` |public void SetContentBackgroundColor(Color color)
| -| `SetContentColor()` |public void SetContentColor(Color color)
| -| `SetContentPosition()` |public void SetContentPosition(Vector3 offset)
| -| `SetIcon()` |public void SetIcon(Image icon)
| -| `SetIconActive()` |public void SetIconActive(bool active)
| -| `SetIconColor()` |public void SetIconColor(Color color)
| -| `SetIconImage()` |public void SetIconImage(Sprite image)
| -| `SetIconSize()` |public void SetIconSize(float width, float height)
| -| `SetObject()` |public void SetObject(GameObject obj)
| -| `SetPosition()` |public void SetPosition(Vector3 position)
| -| `SetText()` |public void SetText(ChartText text)
| -| `SetTextBackground()` |public void SetTextBackground(Image image)
| - -## `LineChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `ListFor` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `ListFor()` |public ListFor(Type type)
| - -## `ListForComponent` - -Inherits or Implemented: [ListFor](#ListFor) - -|public method|description| -|--|--| -| `ListForComponent()` |public ListForComponent(Type type) : base(type)
| - -## `ListForSerie` - -Inherits or Implemented: [ListFor](#ListFor) - -|public method|description| -|--|--| -| `ListForSerie()` |public ListForSerie(Type type) : base(type)
| - -## `MainComponentContext` - -## `MainComponentHandler` - -## `MainComponentHandler` - -Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) - -## `MathUtil` - -|public method|description| -|--|--| -| `Abs()` |public static double Abs(double d)
| -| `Approximately()` |public static bool Approximately(double a, double b)
| -| `Clamp()` |public static double Clamp(double d, double min, double max)
| -| `Clamp01()` |public static double Clamp01(double value)
| -| `Lerp()` |public static double Lerp(double a, double b, double t)
| - -## `ObjectPool where T` - -Inherits or Implemented: [new()](#new()) - -|public method|description| -|--|--| -| `ClearAll()` |public void ClearAll()
| -| `Get()` |public T Get()
| -| `new()` |public class ObjectPool where T : new()
| -| `ObjectPool()` |public ObjectPool(UnityAction actionOnGet, UnityAction actionOnRelease, bool newIfEmpty = true)
| -| `Release()` |public void Release(T element)
| - -## `Painter` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic) - -|public method|description| -|--|--| -| `Init()` |public void Init()
| -| `Refresh()` |public void Refresh()
| -| `SetActive()` |public void SetActive(bool flag, bool isDebugMode = false)
| - -## `ParallelChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `ParallelCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `PieChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `PolarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `PolarCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `ProgressBar` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `PropertyUtil` - -|public method|description| -|--|--| -| `SetColor()` |public static bool SetColor(ref Color currentValue, Color newValue)
| -| `SetColor()` |public static bool SetColor(ref Color32 currentValue, Color32 newValue)
| - -## `RadarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `RadarCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `ReflectionUtil` - -|public method|description| -|--|--| -| `DeepCloneSerializeField()` |public static object DeepCloneSerializeField(object obj)
| -| `InvokeListAdd()` |public static void InvokeListAdd(object obj, FieldInfo field, object item)
| -| `InvokeListAddTo()` |public static void InvokeListAddTo(object obj, FieldInfo field, Action callback)
| -| `InvokeListClear()` |public static void InvokeListClear(object obj, FieldInfo field)
| -| `InvokeListCount()` |public static int InvokeListCount(object obj, FieldInfo field)
| -| `InvokeListGet()` |public static T InvokeListGet(object obj, FieldInfo field, int i)
| - -## `RequireChartComponentAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `RequireChartComponentAttribute()` |public RequireChartComponentAttribute(Type requiredComponent)
| -| `RequireChartComponentAttribute()` |public RequireChartComponentAttribute(Type requiredComponent, Type requiredComponent2)
| -| `RequireChartComponentAttribute()` |public RequireChartComponentAttribute(Type requiredComponent, Type requiredComponent2, Type requiredComponent3)
| - -## `RingChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `RuntimeUtil` - -|public method|description| -|--|--| -| `GetAllAssemblyTypes()` |public static IEnumerable GetAllAssemblyTypes()
| -| `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom(Type type)
| -| `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom()
| -| `HasSubclass()` |public static bool HasSubclass(Type type)
| - -## `ScatterChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SerieContext` - -## `SerieConvertAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(Type type)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2, Type serie3)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2, Type serie3, Type serie4)
| - -## `SerieDataContext` - -|public method|description| -|--|--| -| `Reset()` |public void Reset()
| - -## `SerieDataExtraComponentAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(Type type)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute()
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7)
| - -## `SerieDataExtraFieldAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(string field)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute()
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2, string field3)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5)
| -| `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)
| - -## `SerieExtraComponentAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(Type type)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute()
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7)
| - -## `SerieHandler` - -## `SerieHandler` - -Inherits or Implemented: [SerieHandler where T](#SerieHandler where T),[Serie](#Serie) - -|public method|description| -|--|--| -| `GetSerieDataAutoColor()` |public virtual Color GetSerieDataAutoColor(SerieData serieData)
| -| `GetSerieDataLabelOffset()` |public virtual Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label)
| -| `GetSerieDataLabelPosition()` |public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
| -| `GetSerieDataTitlePosition()` |public virtual Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle)
| -| `InitComponent()` |public override void InitComponent()
| -| `OnLegendButtonClick()` |public override void OnLegendButtonClick(int index, string legendName, bool show)
| -| `OnLegendButtonEnter()` |public override void OnLegendButtonEnter(int index, string legendName)
| -| `OnLegendButtonExit()` |public override void OnLegendButtonExit(int index, string legendName)
| -| `RefreshEndLabelInternal()` |public virtual void RefreshEndLabelInternal()
| -| `RefreshLabelInternal()` |public override void RefreshLabelInternal()
| -| `RefreshLabelNextFrame()` |public override void RefreshLabelNextFrame()
| -| `RemoveComponent()` |public override void RemoveComponent()
| -| `Update()` |public override void Update()
| - -## `SerieHandlerAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `SerieHandlerAttribute()` |public SerieHandlerAttribute(Type handler)
| -| `SerieHandlerAttribute()` |public SerieHandlerAttribute(Type handler, bool allowMultiple)
| - -## `SerieHelper` - -|public method|description| -|--|--| -| `CopySerie()` |public static void CopySerie(Serie oldSerie, Serie newSerie)
| -| `GetAllMinMaxData()` |public static void GetAllMinMaxData(Serie serie, int ceilRate = 0, DataZoom dataZoom = null)
| -| `GetAreaColor()` |public static Color32 GetAreaColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
| -| `GetAreaStyle()` |public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData)
| -| `GetAreaToColor()` |public static Color32 GetAreaToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
| -| `GetAverageData()` |public static double GetAverageData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetItemColor()` |public static Color32 GetItemColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true)
| -| `GetItemColor0()` |public static Color32 GetItemColor0(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, Color32 defaultColor)
| -| `GetItemFormatter()` |public static string GetItemFormatter(Serie serie, SerieData serieData, string defaultFormatter = null)
| -| `GetItemMarker()` |public static string GetItemMarker(Serie serie, SerieData serieData, string defaultMarker = null)
| -| `GetItemStyle()` |public static ItemStyle GetItemStyle(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetItemStyleEmphasis()` |public static ItemStyle GetItemStyleEmphasis(Serie serie, SerieData serieData)
| -| `GetItemToColor()` |public static Color32 GetItemToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true)
| -| `GetLineColor()` |public static Color32 GetLineColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
| -| `GetLineStyle()` |public static LineStyle GetLineStyle(Serie serie, SerieData serieData)
| -| `GetMaxData()` |public static double GetMaxData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMaxSerieData()` |public static SerieData GetMaxSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMedianData()` |public static double GetMedianData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMinData()` |public static double GetMinData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMinMaxData()` |public static void GetMinMaxData(Serie serie, out double min, out double max, DataZoom dataZoom = null, int dimension = 0)
Gets the maximum and minimum values of all data in the serie. | -| `GetMinSerieData()` |public static SerieData GetMinSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetNumericFormatter()` |public static string GetNumericFormatter(Serie serie, SerieData serieData, string defaultFormatter = null)
| -| `GetSerieEmphasisLabel()` |public static LabelStyle GetSerieEmphasisLabel(Serie serie, SerieData serieData)
| -| `GetSerieLabel()` |public static LabelStyle GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetSerieLabelLine()` |public static LabelLine GetSerieLabelLine(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetSerieSymbol()` |public static SerieSymbol GetSerieSymbol(Serie serie, SerieData serieData)
| -| `GetSymbolBorder()` |public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight)
| -| `GetSymbolBorder()` |public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, float defaultWidth)
| -| `GetSymbolBorderColor()` |public static Color32 GetSymbolBorderColor(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight)
| -| `GetSymbolCornerRadius()` |public static float[] GetSymbolCornerRadius(Serie serie, SerieData serieData, bool highlight)
| -| `GetTitleStyle()` |public static TitleStyle GetTitleStyle(Serie serie, SerieData serieData)
| -| `IsAllZeroValue()` |public static bool IsAllZeroValue(Serie serie, int dimension = 1)
Whether the data for the specified dimension of serie are all 0. | -| `IsDownPoint()` |public static bool IsDownPoint(Serie serie, int index)
| -| `UpdateCenter()` |public static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
更新运行时中心点和半径 | -| `UpdateFilterData()` |public static void UpdateFilterData(Serie serie, DataZoom dataZoom)
根据dataZoom更新数据列表缓存 | -| `UpdateMinMaxData()` |public static void UpdateMinMaxData(Serie serie, int dimension, int ceilRate = 0, DataZoom dataZoom = null)
获得指定维数的最大最小值 | -| `UpdateRect()` |public static void UpdateRect(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
| -| `UpdateSerieRuntimeFilterData()` |public static void UpdateSerieRuntimeFilterData(Serie serie, bool filterInvisible = true)
| - -## `SerieLabelHelper` - -|public method|description| -|--|--| -| `AvoidLabelOverlap()` |public static void AvoidLabelOverlap(Serie serie, ComponentTheme theme)
| -| `CanShowLabel()` |public static bool CanShowLabel(Serie serie, SerieData serieData, LabelStyle label, int dimesion)
| -| `GetLabelColor()` |public static Color GetLabelColor(Serie serie, ThemeStyle theme, int index)
| -| `GetRealLabelPosition()` |public static Vector3 GetRealLabelPosition(Serie serie, SerieData serieData, LabelStyle label, LabelLine labelLine)
| -| `SetGaugeLabelText()` |public static void SetGaugeLabelText(Serie serie)
| -| `UpdatePieLabelPosition()` |public static void UpdatePieLabelPosition(Serie serie, SerieData serieData)
| - -## `SerieLabelPool` - -|public method|description| -|--|--| -| `ClearAll()` |public static void ClearAll()
| -| `Release()` |public static void Release(GameObject element)
| -| `ReleaseAll()` |public static void ReleaseAll(Transform parent)
| - -## `SerieParams` - -## `SeriesHelper` - -|public method|description| -|--|--| -| `GetLastStackSerie()` |public static Serie GetLastStackSerie(List series, Serie serie)
获得上一个同堆叠且显示的serie。 | -| `GetLegalSerieNameList()` |public static List GetLegalSerieNameList(List series)
| -| `GetMaxSerieDataCount()` |public static int GetMaxSerieDataCount(List series)
| -| `GetNameColor()` |public static Color GetNameColor(BaseChart chart, int index, string name)
| -| `GetSerieByVesselIndex()` |public static Serie GetSerieByVesselIndex(List series, int vesselIndex)
| -| `GetStackSeries()` |public static void GetStackSeries(List series, ref Dictionary> stackSeries)
获得堆叠系列列表 | -| `IsAnyClipSerie()` |public static bool IsAnyClipSerie(List series)
是否有需裁剪的serie。 | -| `IsLegalLegendName()` |public static bool IsLegalLegendName(string name)
| -| `IsStack()` |public static bool IsStack(List series)
是否由数据堆叠 | -| `UpdateSerieNameList()` |public static void UpdateSerieNameList(BaseChart chart, ref List serieNameList)
获得所有系列名,不包含空名字。 | -| `UpdateStackDataList()` |public static void UpdateStackDataList(List series, Serie currSerie, DataZoom dataZoom, List> dataList)
| - -## `SimplifiedBarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SimplifiedCandlestickChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SimplifiedLineChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SVG` - -|public method|description| -|--|--| -| `DrawPath()` |public static void DrawPath(VertexHelper vh, string path)
| -| `DrawPath()` |public static void DrawPath(VertexHelper vh, SVGPath path)
| -| `Test()` |public static void Test(VertexHelper vh)
| - -## `SVGImage` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic) - -## `SVGPath` - -|public method|description| -|--|--| -| `AddSegment()` |public void AddSegment(SVGPathSeg seg)
| -| `Draw()` |public void Draw(VertexHelper vh)
| -| `Parse()` |public static SVGPath Parse(string path)
| - -## `SVGPathSeg` - -|public method|description| -|--|--| -| `SVGPathSeg()` |public SVGPathSeg(SVGPathSegType type)
| - -## `TooltipContext` - -## `TooltipData` - -## `TooltipHelper` - -|public method|description| -|--|--| -| `GetItemNumericFormatter()` |public static string GetItemNumericFormatter(Tooltip tooltip, Serie serie, SerieData serieData)
| -| `GetLineColor()` |public static Color32 GetLineColor(Tooltip tooltip, ThemeStyle theme)
| -| `IsIgnoreItemFormatter()` |public static bool IsIgnoreItemFormatter(string itemFormatter)
| -| `LimitInRect()` |public static void LimitInRect(Tooltip tooltip, Rect chartRect)
| - -## `TooltipView` - -|public method|description| -|--|--| -| `CreateView()` |public static TooltipView CreateView(Tooltip tooltip, ThemeStyle theme, Transform parent)
| -| `GetCurrentPos()` |public Vector3 GetCurrentPos()
| -| `GetTargetPos()` |public Vector3 GetTargetPos()
| -| `Refresh()` |public void Refresh()
| -| `SetActive()` |public void SetActive(bool flag)
| -| `Update()` |public void Update()
| -| `UpdatePosition()` |public void UpdatePosition(Vector3 pos)
| - -## `TooltipViewItem` - -## `UGL` - -|public method|description| -|--|--| -| `DrawDiamond()` |public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color)
Draw a diamond. 画菱形(钻石形状) | -| `DrawDiamond()` |public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color, Color32 toColor)
Draw a diamond. 画菱形(钻石形状) | -| `DrawEllipse()` |public static void DrawEllipse(VertexHelper vh, Vector3 center, float w, float h, Color32 color, float smoothness = 1)
| -| `DrawLine()` |public static void DrawLine(VertexHelper vh, List points, float width, Color32 color, bool smooth, bool closepath = false)
| -| `DrawLine()` |public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color)
Draw a line. 画直线 | -| `DrawLine()` |public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color, Color32 toColor)
Draw a line. 画直线 | -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color, Color32 toColor)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color, Color32 toColor)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color)
Draw a rectangle. 画带长方形 | -| `DrawSquare()` |public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color)
Draw a square. 画正方形 | -| `DrawSvgPath()` |public static void DrawSvgPath(VertexHelper vh, string path)
| -| `DrawTriangle()` |public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color)
| -| `DrawTriangle()` |public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color, Color32 toColor)
| - -## `UGLExample` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic) - -## `UGLHelper` - -|public method|description| -|--|--| -| `GetAngle360()` |public static float GetAngle360(Vector2 from, Vector2 to)
获得0-360的角度(12点钟方向为0度) | -| `GetBezier()` |public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep)
| -| `GetBezier2()` |public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep)
| -| `GetBezierList()` |public static List GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp)
| -| `GetDire()` |public static Vector3 GetDire(float angle, bool isDegree = false)
| -| `GetIntersection()` |public static bool GetIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, ref Vector3 intersection)
获得两直线的交点 | -| `GetPos()` |public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
| -| `GetVertialDire()` |public static Vector3 GetVertialDire(Vector3 dire)
| -| `IsClearColor()` |public static bool IsClearColor(Color color)
| -| `IsClearColor()` |public static bool IsClearColor(Color32 color)
| -| `IsPointInPolygon()` |public static bool IsPointInPolygon(Vector3 p, List polyons)
| -| `IsPointInPolygon()` |public static bool IsPointInPolygon(Vector3 p, List polyons)
| -| `IsPointInTriangle()` |public static bool IsPointInTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 check)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color color1, Color color2)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
| -| `IsValueEqualsList()` |public static bool IsValueEqualsList(List list1, List list2)
| -| `IsValueEqualsString()` |public static bool IsValueEqualsString(string str1, string str2)
| -| `IsValueEqualsVector2()` |public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2)
| -| `IsValueEqualsVector3()` |public static bool IsValueEqualsVector3(Vector3 v1, Vector2 v2)
| -| `IsValueEqualsVector3()` |public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2)
| -| `IsZeroVector()` |public static bool IsZeroVector(Vector3 pos)
| -| `RotateRound()` |public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
| - -## `VisualMapContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `VisualMapHelper` - -|public method|description| -|--|--| -| `AutoSetLineMinMax()` |public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)
| -| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int serieDataCount)
| -| `IsNeedAreaGradient()` |public static bool IsNeedAreaGradient(VisualMap visualMap)
| -| `IsNeedGradient()` |public static bool IsNeedGradient(VisualMap visualMap)
| -| `IsNeedLineGradient()` |public static bool IsNeedLineGradient(VisualMap visualMap)
| -| `SetMinMax()` |public static void SetMinMax(VisualMap visualMap, double min, double max)
| - -## `XChartsMgr` - -|public method|description| -|--|--| -| `AddChart()` |public static void AddChart(BaseChart chart)
| -| `ContainsChart()` |public static bool ContainsChart(BaseChart chart)
| -| `ContainsChart()` |public static bool ContainsChart(string chartName)
| -| `DisableTextMeshPro()` |public static void DisableTextMeshPro()
| -| `EnableTextMeshPro()` |public static void EnableTextMeshPro()
| -| `GetChart()` |public static BaseChart GetChart(string chartName)
| -| `GetCharts()` |public static List GetCharts(string chartName)
| -| `GetPackageFullPath()` |public static string GetPackageFullPath()
| -| `GetRepeatChartNameInfo()` |public static string GetRepeatChartNameInfo(BaseChart chart, string chartName)
| -| `IsExistTMPAssembly()` |public static bool IsExistTMPAssembly()
| -| `IsRepeatChartName()` |public static bool IsRepeatChartName(BaseChart chart, string chartName = null)
| -| `ModifyTMPRefence()` |public static bool ModifyTMPRefence(bool removeTMP = false)
| -| `RemoveAllChartObject()` |public static void RemoveAllChartObject()
| -| `RemoveChart()` |public static void RemoveChart(string chartName)
| - -## `XCResourceImporterWindow` - -Inherits or Implemented: [UnityEditor.EditorWindow](#UnityEditor.EditorWindow) - -|public method|description| -|--|--| -| `ShowPackageImporterWindow()` |public static void ShowPackageImporterWindow()
| - -## `XCThemeMgr` - -|public method|description| -|--|--| -| `AddTheme()` |public static void AddTheme(Theme theme)
| -| `CheckReloadTheme()` |public static void CheckReloadTheme()
| -| `ContainsTheme()` |public static bool ContainsTheme(string themeName)
| -| `ExportTheme()` |public static bool ExportTheme(Theme theme)
| -| `ExportTheme()` |public static bool ExportTheme(Theme theme, string themeNewName)
| -| `GetAllThemeNames()` |public static List GetAllThemeNames()
| -| `GetTheme()` |public static Theme GetTheme(string themeName)
| -| `GetTheme()` |public static Theme GetTheme(ThemeType type)
| -| `GetThemeAssetPath()` |public static string GetThemeAssetPath(string themeName)
| -| `GetThemeList()` |public static List GetThemeList()
| -| `LoadTheme()` |public static Theme LoadTheme(string themeName)
| -| `LoadTheme()` |public static Theme LoadTheme(ThemeType type)
| -| `ReloadThemeList()` |public static void ReloadThemeList()
重新加载主题列表 | -| `SwitchTheme()` |public static void SwitchTheme(BaseChart chart, string themeName)
| - -[XCharts Homepage](https://github.com/XCharts-Team/XCharts)
-[XCharts Configuration](XChartsConfiguration-EN.md)
-[XCharts FAQ](XChartsFAQ-EN.md) diff --git a/Assets/XCharts/Documentation/XChartsAPI-EN.md.meta b/Assets/XCharts/Documentation/XChartsAPI-EN.md.meta deleted file mode 100644 index 335be9a..0000000 --- a/Assets/XCharts/Documentation/XChartsAPI-EN.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 002217c6b4b5348bd86b5a6b881d2622 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsAPI-ZH.md b/Assets/XCharts/Documentation/XChartsAPI-ZH.md deleted file mode 100644 index f7603f0..0000000 --- a/Assets/XCharts/Documentation/XChartsAPI-ZH.md +++ /dev/null @@ -1,1075 +0,0 @@ -# API - -[XCharts主页](https://github.com/XCharts-Team/XCharts)
-[XCharts配置项手册](XChartsConfiguration-ZH.md)
-[XCharts问答](XChartsFAQ-ZH.md) - -## Class - -- [AnimationStyleHelper](#AnimationStyleHelper) -- [AxisContext](#AxisContext) -- [AxisHandler](#AxisHandler) -- [AxisHelper](#AxisHelper) -- [BarChart](#BarChart) -- [BaseChart](#BaseChart) -- [BaseGraph](#BaseGraph) -- [CandlestickChart](#CandlestickChart) -- [ChartCached](#ChartCached) -- [ChartConst](#ChartConst) -- [ChartDrawer](#ChartDrawer) -- [ChartHelper](#ChartHelper) -- [ChartLabel](#ChartLabel) -- [ChartObject](#ChartObject) -- [CheckHelper](#CheckHelper) -- [ColorUtil](#ColorUtil) -- [ComponentHandlerAttribute](#ComponentHandlerAttribute) -- [ComponentHelper](#ComponentHelper) -- [CoordOptionsAttribute](#CoordOptionsAttribute) -- [DataZoomContext](#DataZoomContext) -- [DataZoomHelper](#DataZoomHelper) -- [DateTimeUtil](#DateTimeUtil) -- [DefaultAnimationAttribute](#DefaultAnimationAttribute) -- [DefineSymbolsUtil](#DefineSymbolsUtil) -- [FormatterHelper](#FormatterHelper) -- [GridCoordContext](#GridCoordContext) -- [HeatmapChart](#HeatmapChart) -- [IgnoreDoc](#IgnoreDoc) -- [InteractData](#InteractData) -- [LayerHelper](#LayerHelper) -- [LegendContext](#LegendContext) -- [LegendHelper](#LegendHelper) -- [LegendItem](#LegendItem) -- [LineChart](#LineChart) -- [ListFor](#ListFor) -- [ListForComponent](#ListForComponent) -- [ListForSerie](#ListForSerie) -- [MainComponentContext](#MainComponentContext) -- [MainComponentHandler](#MainComponentHandler) -- [MainComponentHandler](#MainComponentHandler) -- [MathUtil](#MathUtil) -- [ObjectPool where T](#ObjectPool where T) -- [Painter](#Painter) -- [ParallelChart](#ParallelChart) -- [ParallelCoordContext](#ParallelCoordContext) -- [PieChart](#PieChart) -- [PolarChart](#PolarChart) -- [PolarCoordContext](#PolarCoordContext) -- [ProgressBar](#ProgressBar) -- [PropertyUtil](#PropertyUtil) -- [RadarChart](#RadarChart) -- [RadarCoordContext](#RadarCoordContext) -- [ReflectionUtil](#ReflectionUtil) -- [RequireChartComponentAttribute](#RequireChartComponentAttribute) -- [RingChart](#RingChart) -- [RuntimeUtil](#RuntimeUtil) -- [ScatterChart](#ScatterChart) -- [SerieContext](#SerieContext) -- [SerieConvertAttribute](#SerieConvertAttribute) -- [SerieDataContext](#SerieDataContext) -- [SerieDataExtraComponentAttribute](#SerieDataExtraComponentAttribute) -- [SerieDataExtraFieldAttribute](#SerieDataExtraFieldAttribute) -- [SerieExtraComponentAttribute](#SerieExtraComponentAttribute) -- [SerieHandler](#SerieHandler) -- [SerieHandler](#SerieHandler) -- [SerieHandlerAttribute](#SerieHandlerAttribute) -- [SerieHelper](#SerieHelper) -- [SerieLabelHelper](#SerieLabelHelper) -- [SerieLabelPool](#SerieLabelPool) -- [SerieParams](#SerieParams) -- [SeriesHelper](#SeriesHelper) -- [SimplifiedBarChart](#SimplifiedBarChart) -- [SimplifiedCandlestickChart](#SimplifiedCandlestickChart) -- [SimplifiedLineChart](#SimplifiedLineChart) -- [SVG](#SVG) -- [SVGImage](#SVGImage) -- [SVGPath](#SVGPath) -- [SVGPathSeg](#SVGPathSeg) -- [TooltipContext](#TooltipContext) -- [TooltipData](#TooltipData) -- [TooltipHelper](#TooltipHelper) -- [TooltipView](#TooltipView) -- [TooltipViewItem](#TooltipViewItem) -- [UGL](#UGL) -- [UGLExample](#UGLExample) -- [UGLHelper](#UGLHelper) -- [VisualMapContext](#VisualMapContext) -- [VisualMapHelper](#VisualMapHelper) -- [XChartsMgr](#XChartsMgr) -- [XCResourceImporterWindow](#XCResourceImporterWindow) -- [XCThemeMgr](#XCThemeMgr) - -## `AnimationStyleHelper` - -|public method|description| -|--|--| -| `CheckDataAnimation()` |public static float CheckDataAnimation(BaseChart chart, Serie serie, int dataIndex, float destProgress, float startPorgress = 0)
| -| `GetAnimationPosition()` |public static bool GetAnimationPosition(AnimationStyle animation, bool isY, Vector3 lp, Vector3 cp, float progress, ref Vector3 ip)
| -| `UpdateAnimationType()` |public static void UpdateAnimationType(AnimationStyle animation, AnimationType defaultType)
| -| `UpdateSerieAnimation()` |public static void UpdateSerieAnimation(Serie serie)
| - -## `AxisContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `AxisHandler` - -Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) - -## `AxisHelper` - -|public method|description| -|--|--| -| `AdjustCircleLabelPos()` |public static void AdjustCircleLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
| -| `AdjustMinMaxValue()` |public static void AdjustMinMaxValue(Axis axis, ref double minValue, ref double maxValue, bool needFormat, int ceilRate = 0)
调整最大最小值 | -| `AdjustRadiusAxisLabelPos()` |public static void AdjustRadiusAxisLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
| -| `GetAxisLineArrowOffset()` |public static float GetAxisLineArrowOffset(Axis axis)
包含箭头偏移的轴线长度 | -| `GetAxisPosition()` |public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
| -| `GetAxisPositionValue()` |public static double GetAxisPositionValue(float xy, float axisLength, double axisRange, float axisStart, float axisOffset)
| -| `GetAxisPositionValue()` |public static double GetAxisPositionValue(GridCoord grid, Axis axis, Vector3 pos)
| -| `GetAxisValueDistance()` |public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上相对起点的距离 | -| `GetAxisValueLength()` |public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上对应的长度 | -| `GetAxisValuePosition()` |public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)
获得数值value在坐标轴上的坐标位置 | -| `GetDataWidth()` |public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
获得一个类目数据在坐标系中代表的宽度 | -| `GetEachWidth()` |public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
| -| `GetScaleNumber()` |public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
获得分割线条数 | -| `GetScaleWidth()` |public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
获得分割段宽度 | -| `GetSplitNumber()` |public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
获得分割段数 | -| `NeedShowSplit()` |public static bool NeedShowSplit(Axis axis)
| - -## `BarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `BaseChart` - -Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver](#ISerializationCallbackReceiver) - -|public method|description| -|--|--| -| `AddChartComponent()` |public MainComponent AddChartComponent(Type type)
| -| `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)
添加(time,y)数据到指定的系列中。 | -| `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)
添加一个数据到指定的系列中。 | -| `AddData()` |public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| -| `AddData()` |public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null)
添加(x,y)数据到指定系列中。 | -| `AddData()` |public SerieData AddData(int serieIndex, List multidimensionalData, string dataName = null, string dataId = null)
添加多维数据(x,y,z...)到指定的系列中。 | -| `AddData()` |public SerieData AddData(string serieName, DateTime time, double yValue, string dataName = null, string dataId = null)
添加(time,y)数据到指定的系列中。 | -| `AddData()` |public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null)
If serieName doesn't exist in legend,will be add to legend. | -| `AddData()` |public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)
| -| `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 multidimensionalData, string dataName = null, string dataId = null)
添加多维数据(x,y,z...)到指定的系列中。 | -| `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)
添加一个类目数据到指定的x轴。 | -| `AddXAxisIcon()` |public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0)
添加一个图标到指定的x轴。 | -| `AddYAxisData()` |public void AddYAxisData(string category, int yAxisIndex = 0)
添加一个类目数据到指定的y轴。 | -| `AddYAxisIcon()` |public void AddYAxisIcon(Sprite icon, int yAxisIndex = 0)
添加一个图标到指定的y轴。 | -| `AnimationEnable()` |public void AnimationEnable(bool flag)
启用或关闭起始动画。 | -| `AnimationFadeIn()` |public void AnimationFadeIn()
开始渐入动画。 | -| `AnimationFadeOut()` |public void AnimationFadeOut()
开始渐出动画。 | -| `AnimationPause()` |public void AnimationPause()
暂停动画。 | -| `AnimationReset()` |public void AnimationReset()
重置动画。 | -| `AnimationResume()` |public void AnimationResume()
继续动画。 | -| `CanAddChartComponent()` |public bool CanAddChartComponent(Type type)
| -| `CanAddSerie()` |public bool CanAddSerie(Type type)
| -| `CanMultipleComponent()` |public bool CanMultipleComponent(Type type)
| -| `ClampInChart()` |public void ClampInChart(ref Vector3 pos)
| -| `ClampInGrid()` |public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)
| -| `ClearData()` |public virtual void ClearData()
It just emptying all of serie's data without emptying the list of series. | -| `ClickLegendButton()` |public void ClickLegendButton(int legendIndex, string legendName, bool show)
点击图例按钮 | -| `CovertSerie()` |public bool CovertSerie(Serie serie, Type type)
| -| `CovertXYAxis()` |public void CovertXYAxis(int index)
转换X轴和Y轴的配置 | -| `GenerateDefaultSerieName()` |public string GenerateDefaultSerieName()
| -| `GetAllSerieDataCount()` |public int GetAllSerieDataCount()
| -| `GetChartBackgroundColor()` |public Color32 GetChartBackgroundColor()
| -| `GetChartComponentNum()` |public int GetChartComponentNum(Type type)
| -| `GetData()` |public double GetData(int serieIndex, int dataIndex, int dimension = 1)
| -| `GetData()` |public double GetData(string serieName, int dataIndex, int dimension = 1)
| -| `GetDataZoomOfAxis()` |public DataZoom GetDataZoomOfAxis(Axis axis)
| -| `GetDataZoomOfSerie()` |public void GetDataZoomOfSerie(Serie serie, out DataZoom xDataZoom, out DataZoom yDataZoom)
| -| `GetGrid()` |public GridCoord GetGrid(Vector2 local)
| -| `GetGridOfDataZoom()` |public GridCoord GetGridOfDataZoom(DataZoom dataZoom)
| -| `GetItemColor()` |public Color32 GetItemColor(Serie serie, bool highlight = false)
| -| `GetItemColor()` |public Color32 GetItemColor(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetLegendRealShowNameColor()` |public Color32 GetLegendRealShowNameColor(string name)
| -| `GetLegendRealShowNameIndex()` |public int GetLegendRealShowNameIndex(string name)
| -| `GetPainter()` |public Painter GetPainter(int index)
| -| `GetSerie()` |public Serie GetSerie(int serieIndex)
| -| `GetSerie()` |public Serie GetSerie(string serieName)
| -| `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)
| -| `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)
| -| `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)
| -| `GetXLerpColor()` |public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| -| `GetYLerpColor()` |public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)
| -| `HasChartComponent()` |public bool HasChartComponent(Type type)
| -| `HasChartComponent()` |public bool HasChartComponent()
| -| `HasSerie()` |public bool HasSerie(Type type)
| -| `Init()` |public void Init(bool defaultChart = true)
| -| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis)
| -| `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)
| -| `Internal_CheckAnimation()` |public void Internal_CheckAnimation()
| -| `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)
获得指定图例名字的系列是否显示。 | -| `IsAllAxisCategory()` |public bool IsAllAxisCategory()
纯类目轴。 | -| `IsAllAxisValue()` |public bool IsAllAxisValue()
纯数值坐标轴(数值轴或对数轴)。 | -| `IsInAnyGrid()` |public bool IsInAnyGrid(Vector2 local)
| -| `IsInChart()` |public bool IsInChart(float x, float y)
| -| `IsInChart()` |public bool IsInChart(Vector2 local)
坐标是否在图表范围内 | -| `IsSerieName()` |public bool IsSerieName(string name)
| -| `MoveDownSerie()` |public bool MoveDownSerie(int serieIndex)
| -| `MoveUpSerie()` |public bool MoveUpSerie(int serieIndex)
| -| `OnAfterDeserialize()` |public void OnAfterDeserialize()
| -| `OnBeforeSerialize()` |public void OnBeforeSerialize()
| -| `OnBeginDrag()` |public override void OnBeginDrag(PointerEventData eventData)
| -| `OnDataZoomRangeChanged()` |public virtual void OnDataZoomRangeChanged(DataZoom dataZoom)
| -| `OnDrag()` |public override void OnDrag(PointerEventData eventData)
| -| `OnEndDrag()` |public override void OnEndDrag(PointerEventData eventData)
| -| `OnLegendButtonClick()` |public virtual void OnLegendButtonClick(int index, string legendName, bool show)
| -| `OnLegendButtonEnter()` |public virtual void OnLegendButtonEnter(int index, string legendName)
| -| `OnLegendButtonExit()` |public virtual void OnLegendButtonExit(int index, string legendName)
| -| `OnPointerClick()` |public override void OnPointerClick(PointerEventData eventData)
| -| `OnPointerDown()` |public override void OnPointerDown(PointerEventData eventData)
| -| `OnPointerEnter()` |public override void OnPointerEnter(PointerEventData eventData)
| -| `OnPointerExit()` |public override void OnPointerExit(PointerEventData eventData)
| -| `OnPointerUp()` |public override void OnPointerUp(PointerEventData eventData)
| -| `OnScroll()` |public override void OnScroll(PointerEventData eventData)
| -| `RefreshBasePainter()` |public void RefreshBasePainter()
| -| `RefreshChart()` |public void RefreshChart()
在下一帧刷新整个图表。 | -| `RefreshChart()` |public void RefreshChart(int serieIndex)
在下一帧刷新图表的指定serie。 | -| `RefreshChart()` |public void RefreshChart(Serie serie)
在下一帧刷新图表的指定serie。 | -| `RefreshDataZoom()` |public void RefreshDataZoom()
在下一帧刷新DataZoom | -| `RefreshPainter()` |public void RefreshPainter(int index)
| -| `RefreshPainter()` |public void RefreshPainter(Serie serie)
| -| `RefreshTopPainter()` |public void RefreshTopPainter()
| -| `RemoveAllChartComponent()` |public void RemoveAllChartComponent()
| -| `RemoveChartComponent()` |public bool RemoveChartComponent(MainComponent component)
| -| `RemoveChartComponent()` |public bool RemoveChartComponent(Type type, int index = 0)
| -| `RemoveChartComponent()` |public bool RemoveChartComponent(int index = 0)
| -| `RemoveChartComponents()` |public int RemoveChartComponents(Type type)
| -| `RemoveChartComponents()` |public int RemoveChartComponents()
| -| `RemoveData()` |public virtual void RemoveData()
The series list is also cleared. | -| `RemoveData()` |public virtual void RemoveData(string serieName)
清除指定系列名称的数据。 | -| `RemoveSerie()` |public void RemoveSerie(int serieIndex)
| -| `RemoveSerie()` |public void RemoveSerie(Serie serie)
| -| `RemoveSerie()` |public void RemoveSerie(string serieName)
| -| `ReplaceSerie()` |public bool ReplaceSerie(Serie oldSerie, Serie newSerie)
| -| `SetBasePainterMaterial()` |public void SetBasePainterMaterial(Material material)
设置Base Painter的材质球 | -| `SetMaxCache()` |public void SetMaxCache(int maxCache)
设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 | -| `SetPainterActive()` |public void SetPainterActive(int index, bool flag)
| -| `SetSerieActive()` |public void SetSerieActive(int serieIndex, bool active)
设置指定系列是否显示。 | -| `SetSerieActive()` |public void SetSerieActive(Serie serie, bool active)
| -| `SetSerieActive()` |public void SetSerieActive(string serieName, bool active)
设置指定系列是否显示。 | -| `SetSeriePainterMaterial()` |public void SetSeriePainterMaterial(Material material)
设置Serie Painter的材质球 | -| `SetTopPainterMaterial()` |public void SetTopPainterMaterial(Material material)
设置Top Painter的材质球 | -| `TryAddChartComponent()` |public bool TryAddChartComponent(Type type)
| -| `TryGetChartComponent()` |public bool TryGetChartComponent(out T component, int index = 0)
| -| `UdpateXAxisIcon()` |public void UdpateXAxisIcon(int index, Sprite icon, int xAxisIndex = 0)
更新X轴图标。 | -| `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, double value)
更新指定系列中的指定索引数据。 | -| `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, int dimension, double value)
更新指定系列指定索引指定维数的数据。维数从0开始。 | -| `UpdateData()` |public bool UpdateData(int serieIndex, int dataIndex, List multidimensionalData)
更新指定系列指定索引的数据项的多维数据。 | -| `UpdateData()` |public bool UpdateData(string serieName, int dataIndex, double value)
更新指定系列中的指定索引数据。 | -| `UpdateData()` |public bool UpdateData(string serieName, int dataIndex, int dimension, double value)
更新指定系列指定索引指定维数的数据。维数从0开始。 | -| `UpdateData()` |public bool UpdateData(string serieName, int dataIndex, List multidimensionalData)
更新指定系列指定索引的数据项的多维数据。 | -| `UpdateDataName()` |public bool UpdateDataName(int serieIndex, int dataIndex, string dataName)
更新指定系列中的指定索引数据名称。 | -| `UpdateDataName()` |public bool UpdateDataName(string serieName, int dataIndex, string dataName)
更新指定系列中的指定索引数据名称。 | -| `UpdateLegendColor()` |public virtual void UpdateLegendColor(string legendName, bool active)
| -| `UpdateTheme()` |public bool UpdateTheme(ThemeType theme)
切换内置主题。 | -| `UpdateTheme()` |public void UpdateTheme(Theme theme)
切换图表主题。 | -| `UpdateXAxisData()` |public void UpdateXAxisData(int index, string category, int xAxisIndex = 0)
更新X轴类目数据。 | -| `UpdateYAxisData()` |public void UpdateYAxisData(int index, string category, int yAxisIndex = 0)
更新Y轴类目数据。 | -| `UpdateYAxisIcon()` |public void UpdateYAxisIcon(int index, Sprite icon, int yAxisIndex = 0)
更新Y轴图标。 | - -## `BaseGraph` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic),[IPointerDownHandler](#IPointerDownHandler),[IPointerUpHandler](#IPointerUpHandler),[](#) - -|public method|description| -|--|--| -| `CheckWarning()` |public string CheckWarning()
检测警告信息。 | -| `OnBeginDrag()` |public virtual void OnBeginDrag(PointerEventData eventData)
| -| `OnDrag()` |public virtual void OnDrag(PointerEventData eventData)
| -| `OnEndDrag()` |public virtual void OnEndDrag(PointerEventData eventData)
| -| `OnPointerClick()` |public virtual void OnPointerClick(PointerEventData eventData)
| -| `OnPointerDown()` |public virtual void OnPointerDown(PointerEventData eventData)
| -| `OnPointerEnter()` |public virtual void OnPointerEnter(PointerEventData eventData)
| -| `OnPointerExit()` |public virtual void OnPointerExit(PointerEventData eventData)
| -| `OnPointerUp()` |public virtual void OnPointerUp(PointerEventData eventData)
| -| `OnScroll()` |public virtual void OnScroll(PointerEventData eventData)
| -| `RebuildChartObject()` |public void RebuildChartObject()
移除并重新创建所有图表的Object。 | -| `RefreshAllComponent()` |public void RefreshAllComponent()
| -| `RefreshGraph()` |public void RefreshGraph()
在下一帧刷新图形。 | -| `ScreenPointToChartPoint()` |public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint)
| -| `SetPainterDirty()` |public void SetPainterDirty()
重新初始化Painter | -| `SetSize()` |public virtual void SetSize(float width, float height)
设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform) | - -## `CandlestickChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `ChartCached` - -|public method|description| -|--|--| -| `ColorToDotStr()` |public static string ColorToDotStr(Color color)
| -| `ColorToStr()` |public static string ColorToStr(Color color)
| -| `FloatToStr()` |public static string FloatToStr(double value, string numericFormatter = "F", int precision = 0)
| -| `GetSerieLabelName()` |public static string GetSerieLabelName(string prefix, int i, int j)
| -| `IntToStr()` |public static string IntToStr(int value, string numericFormatter = "")
| -| `NumberToStr()` |public static string NumberToStr(double value, string formatter)
| - -## `ChartConst` - -## `ChartDrawer` - -## `ChartHelper` - -|public method|description| -|--|--| -| `ActiveAllObject()` |public static void ActiveAllObject(Transform parent, bool active, string match = null)
| -| `AddIcon()` |public static Image AddIcon(string name, Transform parent, IconStyle iconStyle)
| -| `Cancat()` |public static string Cancat(string str1, int i)
| -| `Cancat()` |public static string Cancat(string str1, string str2)
| -| `ClearEventListener()` |public static void ClearEventListener(GameObject obj)
| -| `CopyArray()` |public static bool CopyArray(T[] toList, T[] fromList)
| -| `CopyList()` |public static bool CopyList(List toList, List fromList)
| -| `DestoryGameObject()` |public static void DestoryGameObject(GameObject go)
| -| `DestoryGameObject()` |public static void DestoryGameObject(Transform parent, string childName)
| -| `DestoryGameObjectByMatch()` |public static void DestoryGameObjectByMatch(Transform parent, string match)
| -| `DestroyAllChildren()` |public static void DestroyAllChildren(Transform parent)
| -| `GetActualValue()` |public static float GetActualValue(float valueOrRate, float total, float maxRate = 1.5f)
| -| `GetAngle360()` |public static float GetAngle360(Vector2 from, Vector2 to)
获得0-360的角度(12点钟方向为0度) | -| `GetColor()` |public static Color32 GetColor(string hexColorStr)
| -| `GetDire()` |public static Vector3 GetDire(float angle, bool isDegree = false)
| -| `GetFloatAccuracy()` |public static int GetFloatAccuracy(double value)
| -| `GetFullName()` |public static string GetFullName(Transform transform)
| -| `GetHighlightColor()` |public static Color32 GetHighlightColor(Color32 color, float rate = 0.8f)
| -| `GetLastValue()` |public static Vector3 GetLastValue(List list)
| -| `GetMaxDivisibleValue()` |public static double GetMaxDivisibleValue(double max, int ceilRate)
| -| `GetMaxLogValue()` |public static double GetMaxLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| -| `GetMinDivisibleValue()` |public static double GetMinDivisibleValue(double min, int ceilRate)
| -| `GetMinLogValue()` |public static double GetMinLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber)
| -| `GetPointList()` |public static void GetPointList(ref List posList, Vector3 sp, Vector3 ep, float k = 30f)
| -| `GetPos()` |public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
| -| `GetPosition()` |public static Vector3 GetPosition(Vector3 center, float angle, float radius)
| -| `GetVertialDire()` |public static Vector3 GetVertialDire(Vector3 dire)
| -| `HideAllObject()` |public static void HideAllObject(GameObject obj, string match = null)
| -| `HideAllObject()` |public static void HideAllObject(Transform parent, string match = null)
| -| `IsClearColor()` |public static bool IsClearColor(Color color)
| -| `IsClearColor()` |public static bool IsClearColor(Color32 color)
| -| `IsColorAlphaZero()` |public static bool IsColorAlphaZero(Color color)
| -| `IsEquals()` |public static bool IsEquals(double d1, double d2)
| -| `IsEquals()` |public static bool IsEquals(float d1, float d2)
| -| `IsIngore()` |public static bool IsIngore(Vector3 pos)
| -| `IsInRect()` |public static bool IsInRect(Vector3 pos, float xMin, float xMax, float yMin, float yMax)
| -| `IsPointInQuadrilateral()` |public static bool IsPointInQuadrilateral(Vector3 P, Vector3 A, Vector3 B, Vector3 C, Vector3 D)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color color1, Color color2)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
| -| `IsValueEqualsList()` |public static bool IsValueEqualsList(List list1, List list2)
| -| `IsValueEqualsString()` |public static bool IsValueEqualsString(string str1, string str2)
| -| `IsValueEqualsVector2()` |public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2)
| -| `IsValueEqualsVector3()` |public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2)
| -| `IsZeroVector()` |public static bool IsZeroVector(Vector3 pos)
| -| `ParseFloatFromString()` |public static List ParseFloatFromString(string jsonData)
| -| `ParseStringFromString()` |public static List ParseStringFromString(string jsonData)
| -| `RemoveComponent()` |public static void RemoveComponent(GameObject gameObject)
| -| `RotateRound()` |public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
| -| `SetActive()` |public static void SetActive(GameObject gameObject, bool active)
| -| `SetActive()` |public static void SetActive(Image image, bool active)
| -| `SetActive()` |public static void SetActive(Text text, bool active)
| -| `SetActive()` |public static void SetActive(Transform transform, bool active)
通过设置scale实现是否显示,优化性能,减少GC | -| `SetColorOpacity()` |public static void SetColorOpacity(ref Color32 color, float opacity)
| - -## `ChartLabel` - -Inherits or Implemented: [Image](#Image) - -|public method|description| -|--|--| -| `GetHeight()` |public float GetHeight()
| -| `GetPosition()` |public Vector3 GetPosition()
| -| `GetTextHeight()` |public float GetTextHeight()
| -| `GetTextWidth()` |public float GetTextWidth()
| -| `GetWidth()` |public float GetWidth()
| -| `SetActive()` |public void SetActive(bool flag)
| -| `SetIcon()` |public void SetIcon(Image image)
| -| `SetIconActive()` |public void SetIconActive(bool flag)
| -| `SetIconSize()` |public void SetIconSize(float width, float height)
| -| `SetIconSprite()` |public void SetIconSprite(Sprite sprite)
| -| `SetPadding()` |public void SetPadding(float[] padding)
| -| `SetPosition()` |public void SetPosition(Vector3 position)
| -| `SetRectPosition()` |public void SetRectPosition(Vector3 position)
| -| `SetSize()` |public void SetSize(float width, float height)
| -| `SetText()` |public bool SetText(string text)
| -| `SetTextActive()` |public void SetTextActive(bool flag)
| -| `SetTextColor()` |public void SetTextColor(Color color)
| -| `SetTextPadding()` |public void SetTextPadding(TextPadding padding)
| -| `SetTextRotate()` |public void SetTextRotate(float rotate)
| -| `UpdateIcon()` |public void UpdateIcon(IconStyle iconStyle, Sprite sprite = null)
| - -## `ChartObject` - -|public method|description| -|--|--| -| `Destroy()` |public virtual void Destroy()
| - -## `CheckHelper` - -|public method|description| -|--|--| -| `CheckChart()` |public static string CheckChart(BaseChart chart)
| -| `CheckChart()` |public static string CheckChart(BaseGraph chart)
| - -## `ColorUtil` - -|public method|description| -|--|--| -| `GetColor()` |public static Color32 GetColor(string hexColorStr)
将字符串颜色值转成Color。 | - -## `ComponentHandlerAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `ComponentHandlerAttribute()` |public ComponentHandlerAttribute(Type handler)
| -| `ComponentHandlerAttribute()` |public ComponentHandlerAttribute(Type handler, bool allowMultiple)
| - -## `ComponentHelper` - -|public method|description| -|--|--| -| `GetAngleAxis()` |public static AngleAxis GetAngleAxis(List components, int polarIndex)
| -| `GetRadiusAxis()` |public static RadiusAxis GetRadiusAxis(List components, int polarIndex)
| -| `GetXAxisOnZeroOffset()` |public static float GetXAxisOnZeroOffset(List components, XAxis axis)
| -| `GetYAxisOnZeroOffset()` |public static float GetYAxisOnZeroOffset(List components, YAxis axis)
| -| `IsAnyCategoryOfYAxis()` |public static bool IsAnyCategoryOfYAxis(List components)
| - -## `CoordOptionsAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord)
| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2)
| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2, Type coord3)
| -| `CoordOptionsAttribute()` |public CoordOptionsAttribute(Type coord, Type coord2, Type coord3, Type coord4)
| - -## `DataZoomContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `DataZoomHelper` - -|public method|description| -|--|--| -| `UpdateDataZoomRuntimeStartEndValue()` |public static void UpdateDataZoomRuntimeStartEndValue(DataZoom dataZoom, Serie serie)
| - -## `DateTimeUtil` - -|public method|description| -|--|--| -| `GetDateTime()` |public static DateTime GetDateTime(int timestamp)
| -| `GetTimestamp()` |public static int GetTimestamp()
| -| `GetTimestamp()` |public static int GetTimestamp(DateTime time)
| - -## `DefaultAnimationAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `DefaultAnimationAttribute()` |public DefaultAnimationAttribute(AnimationType handler)
| - -## `DefineSymbolsUtil` - -|public method|description| -|--|--| -| `AddGlobalDefine()` |public static void AddGlobalDefine(string symbol)
| -| `RemoveGlobalDefine()` |public static void RemoveGlobalDefine(string symbol)
| - -## `FormatterHelper` - -|public method|description| -|--|--| -| `NeedFormat()` |public static bool NeedFormat(string content)
| -| `ReplaceAxisLabelContent()` |public static void ReplaceAxisLabelContent(ref string content, string numericFormatter, double value)
| -| `ReplaceAxisLabelContent()` |public static void ReplaceAxisLabelContent(ref string content, string value)
| -| `TrimAndReplaceLine()` |public static string TrimAndReplaceLine(string content)
| -| `TrimAndReplaceLine()` |public static string TrimAndReplaceLine(StringBuilder sb)
| - -## `GridCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `HeatmapChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `IgnoreDoc` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `IgnoreDoc()` |public IgnoreDoc()
| - -## `InteractData` - -|public method|description| -|--|--| -| `Reset()` |public void Reset()
| -| `SetColor()` |public void SetColor(ref bool needInteract, Color32 color)
| -| `SetColor()` |public void SetColor(ref bool needInteract, Color32 color, Color32 toColor)
| -| `SetValue()` |public void SetValue(ref bool needInteract, float size)
| -| `SetValue()` |public void SetValue(ref bool needInteract, float size, bool highlight, float rate = 1.3f)
| -| `SetValueAndColor()` |public void SetValueAndColor(ref bool needInteract, float value, Color32 color)
| -| `SetValueAndColor()` |public void SetValueAndColor(ref bool needInteract, float value, Color32 color, Color32 toColor)
| -| `TryGetColor()` |public bool TryGetColor(ref Color32 color, ref bool interacting, float animationDuration = 250)
| -| `TryGetColor()` |public bool TryGetColor(ref Color32 color, ref Color32 toColor, ref bool interacting, float animationDuration = 250)
| -| `TryGetValue()` |public bool TryGetValue(ref float value, ref bool interacting, float animationDuration = 250)
| -| `TryGetValueAndColor()` |public bool TryGetValueAndColor(ref float value, ref Color32 color, ref Color32 toColor, ref bool interacting, float animationDuration = 250)
| - -## `LayerHelper` - -|public method|description| -|--|--| -| `IsFixedWidthHeight()` |public static bool IsFixedWidthHeight(RectTransform rt)
| -| `IsStretchPivot()` |public static bool IsStretchPivot(RectTransform rt)
| - -## `LegendContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `LegendHelper` - -|public method|description| -|--|--| -| `CheckDataHighlighted()` |public static bool CheckDataHighlighted(Serie serie, string legendName, bool heighlight)
| -| `CheckDataShow()` |public static bool CheckDataShow(Serie serie, string legendName, bool show)
| -| `GetContentColor()` |public static Color GetContentColor(BaseChart chart, int legendIndex, string legendName, Legend legend, ThemeStyle theme, bool active)
| -| `GetIconColor()` |public static Color GetIconColor(BaseChart chart, Legend legend, int readIndex, string legendName, bool active)
| -| `ResetItemPosition()` |public static void ResetItemPosition(Legend legend, Vector3 chartPos, float chartWidth, float chartHeight)
| - -## `LegendItem` - -|public method|description| -|--|--| -| `GetIconColor()` |public Color GetIconColor()
| -| `GetIconRect()` |public Rect GetIconRect()
| -| `SetActive()` |public void SetActive(bool active)
| -| `SetButton()` |public void SetButton(Button button)
| -| `SetContent()` |public bool SetContent(string content)
| -| `SetContentBackgroundColor()` |public void SetContentBackgroundColor(Color color)
| -| `SetContentColor()` |public void SetContentColor(Color color)
| -| `SetContentPosition()` |public void SetContentPosition(Vector3 offset)
| -| `SetIcon()` |public void SetIcon(Image icon)
| -| `SetIconActive()` |public void SetIconActive(bool active)
| -| `SetIconColor()` |public void SetIconColor(Color color)
| -| `SetIconImage()` |public void SetIconImage(Sprite image)
| -| `SetIconSize()` |public void SetIconSize(float width, float height)
| -| `SetObject()` |public void SetObject(GameObject obj)
| -| `SetPosition()` |public void SetPosition(Vector3 position)
| -| `SetText()` |public void SetText(ChartText text)
| -| `SetTextBackground()` |public void SetTextBackground(Image image)
| - -## `LineChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `ListFor` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `ListFor()` |public ListFor(Type type)
| - -## `ListForComponent` - -Inherits or Implemented: [ListFor](#ListFor) - -|public method|description| -|--|--| -| `ListForComponent()` |public ListForComponent(Type type) : base(type)
| - -## `ListForSerie` - -Inherits or Implemented: [ListFor](#ListFor) - -|public method|description| -|--|--| -| `ListForSerie()` |public ListForSerie(Type type) : base(type)
| - -## `MainComponentContext` - -## `MainComponentHandler` - -## `MainComponentHandler` - -Inherits or Implemented: [MainComponentHandler](#MainComponentHandler) - -## `MathUtil` - -|public method|description| -|--|--| -| `Abs()` |public static double Abs(double d)
| -| `Approximately()` |public static bool Approximately(double a, double b)
| -| `Clamp()` |public static double Clamp(double d, double min, double max)
| -| `Clamp01()` |public static double Clamp01(double value)
| -| `Lerp()` |public static double Lerp(double a, double b, double t)
| - -## `ObjectPool where T` - -Inherits or Implemented: [new()](#new()) - -|public method|description| -|--|--| -| `ClearAll()` |public void ClearAll()
| -| `Get()` |public T Get()
| -| `new()` |public class ObjectPool where T : new()
| -| `ObjectPool()` |public ObjectPool(UnityAction actionOnGet, UnityAction actionOnRelease, bool newIfEmpty = true)
| -| `Release()` |public void Release(T element)
| - -## `Painter` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic) - -|public method|description| -|--|--| -| `Init()` |public void Init()
| -| `Refresh()` |public void Refresh()
| -| `SetActive()` |public void SetActive(bool flag, bool isDebugMode = false)
| - -## `ParallelChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `ParallelCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `PieChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `PolarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `PolarCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `ProgressBar` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `PropertyUtil` - -|public method|description| -|--|--| -| `SetColor()` |public static bool SetColor(ref Color currentValue, Color newValue)
| -| `SetColor()` |public static bool SetColor(ref Color32 currentValue, Color32 newValue)
| - -## `RadarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `RadarCoordContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `ReflectionUtil` - -|public method|description| -|--|--| -| `DeepCloneSerializeField()` |public static object DeepCloneSerializeField(object obj)
| -| `InvokeListAdd()` |public static void InvokeListAdd(object obj, FieldInfo field, object item)
| -| `InvokeListAddTo()` |public static void InvokeListAddTo(object obj, FieldInfo field, Action callback)
| -| `InvokeListClear()` |public static void InvokeListClear(object obj, FieldInfo field)
| -| `InvokeListCount()` |public static int InvokeListCount(object obj, FieldInfo field)
| -| `InvokeListGet()` |public static T InvokeListGet(object obj, FieldInfo field, int i)
| - -## `RequireChartComponentAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `RequireChartComponentAttribute()` |public RequireChartComponentAttribute(Type requiredComponent)
| -| `RequireChartComponentAttribute()` |public RequireChartComponentAttribute(Type requiredComponent, Type requiredComponent2)
| -| `RequireChartComponentAttribute()` |public RequireChartComponentAttribute(Type requiredComponent, Type requiredComponent2, Type requiredComponent3)
| - -## `RingChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `RuntimeUtil` - -|public method|description| -|--|--| -| `GetAllAssemblyTypes()` |public static IEnumerable GetAllAssemblyTypes()
| -| `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom(Type type)
| -| `GetAllTypesDerivedFrom()` |public static IEnumerable GetAllTypesDerivedFrom()
| -| `HasSubclass()` |public static bool HasSubclass(Type type)
| - -## `ScatterChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SerieContext` - -## `SerieConvertAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(Type type)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2, Type serie3)
| -| `SerieConvertAttribute()` |public SerieConvertAttribute(Type serie, Type serie2, Type serie3, Type serie4)
| - -## `SerieDataContext` - -|public method|description| -|--|--| -| `Reset()` |public void Reset()
| - -## `SerieDataExtraComponentAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(Type type)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute()
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6)
| -| `SerieDataExtraComponentAttribute()` |public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7)
| - -## `SerieDataExtraFieldAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(string field)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute()
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2, string field3)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4)
| -| `SerieDataExtraFieldAttribute()` |public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5)
| -| `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)
| - -## `SerieExtraComponentAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `Contains()` |public bool Contains(Type type)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute()
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6)
| -| `SerieExtraComponentAttribute()` |public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7)
| - -## `SerieHandler` - -## `SerieHandler` - -Inherits or Implemented: [SerieHandler where T](#SerieHandler where T),[Serie](#Serie) - -|public method|description| -|--|--| -| `GetSerieDataAutoColor()` |public virtual Color GetSerieDataAutoColor(SerieData serieData)
| -| `GetSerieDataLabelOffset()` |public virtual Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label)
| -| `GetSerieDataLabelPosition()` |public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
| -| `GetSerieDataTitlePosition()` |public virtual Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle)
| -| `InitComponent()` |public override void InitComponent()
| -| `OnLegendButtonClick()` |public override void OnLegendButtonClick(int index, string legendName, bool show)
| -| `OnLegendButtonEnter()` |public override void OnLegendButtonEnter(int index, string legendName)
| -| `OnLegendButtonExit()` |public override void OnLegendButtonExit(int index, string legendName)
| -| `RefreshEndLabelInternal()` |public virtual void RefreshEndLabelInternal()
| -| `RefreshLabelInternal()` |public override void RefreshLabelInternal()
| -| `RefreshLabelNextFrame()` |public override void RefreshLabelNextFrame()
| -| `RemoveComponent()` |public override void RemoveComponent()
| -| `Update()` |public override void Update()
| - -## `SerieHandlerAttribute` - -Inherits or Implemented: [Attribute](#Attribute) - -|public method|description| -|--|--| -| `SerieHandlerAttribute()` |public SerieHandlerAttribute(Type handler)
| -| `SerieHandlerAttribute()` |public SerieHandlerAttribute(Type handler, bool allowMultiple)
| - -## `SerieHelper` - -|public method|description| -|--|--| -| `CopySerie()` |public static void CopySerie(Serie oldSerie, Serie newSerie)
| -| `GetAllMinMaxData()` |public static void GetAllMinMaxData(Serie serie, int ceilRate = 0, DataZoom dataZoom = null)
| -| `GetAreaColor()` |public static Color32 GetAreaColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
| -| `GetAreaStyle()` |public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData)
| -| `GetAreaToColor()` |public static Color32 GetAreaToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
| -| `GetAverageData()` |public static double GetAverageData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetItemColor()` |public static Color32 GetItemColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true)
| -| `GetItemColor0()` |public static Color32 GetItemColor0(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, Color32 defaultColor)
| -| `GetItemFormatter()` |public static string GetItemFormatter(Serie serie, SerieData serieData, string defaultFormatter = null)
| -| `GetItemMarker()` |public static string GetItemMarker(Serie serie, SerieData serieData, string defaultMarker = null)
| -| `GetItemStyle()` |public static ItemStyle GetItemStyle(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetItemStyleEmphasis()` |public static ItemStyle GetItemStyleEmphasis(Serie serie, SerieData serieData)
| -| `GetItemToColor()` |public static Color32 GetItemToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true)
| -| `GetLineColor()` |public static Color32 GetLineColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight)
| -| `GetLineStyle()` |public static LineStyle GetLineStyle(Serie serie, SerieData serieData)
| -| `GetMaxData()` |public static double GetMaxData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMaxSerieData()` |public static SerieData GetMaxSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMedianData()` |public static double GetMedianData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMinData()` |public static double GetMinData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetMinMaxData()` |public static void GetMinMaxData(Serie serie, out double min, out double max, DataZoom dataZoom = null, int dimension = 0)
获得系列所有数据的最大最小值。 | -| `GetMinSerieData()` |public static SerieData GetMinSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null)
| -| `GetNumericFormatter()` |public static string GetNumericFormatter(Serie serie, SerieData serieData, string defaultFormatter = null)
| -| `GetSerieEmphasisLabel()` |public static LabelStyle GetSerieEmphasisLabel(Serie serie, SerieData serieData)
| -| `GetSerieLabel()` |public static LabelStyle GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetSerieLabelLine()` |public static LabelLine GetSerieLabelLine(Serie serie, SerieData serieData, bool highlight = false)
| -| `GetSerieSymbol()` |public static SerieSymbol GetSerieSymbol(Serie serie, SerieData serieData)
| -| `GetSymbolBorder()` |public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight)
| -| `GetSymbolBorder()` |public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, float defaultWidth)
| -| `GetSymbolBorderColor()` |public static Color32 GetSymbolBorderColor(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight)
| -| `GetSymbolCornerRadius()` |public static float[] GetSymbolCornerRadius(Serie serie, SerieData serieData, bool highlight)
| -| `GetTitleStyle()` |public static TitleStyle GetTitleStyle(Serie serie, SerieData serieData)
| -| `IsAllZeroValue()` |public static bool IsAllZeroValue(Serie serie, int dimension = 1)
系列指定维数的数据是否全部为0。 | -| `IsDownPoint()` |public static bool IsDownPoint(Serie serie, int index)
| -| `UpdateCenter()` |public static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
更新运行时中心点和半径 | -| `UpdateFilterData()` |public static void UpdateFilterData(Serie serie, DataZoom dataZoom)
根据dataZoom更新数据列表缓存 | -| `UpdateMinMaxData()` |public static void UpdateMinMaxData(Serie serie, int dimension, int ceilRate = 0, DataZoom dataZoom = null)
获得指定维数的最大最小值 | -| `UpdateRect()` |public static void UpdateRect(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
| -| `UpdateSerieRuntimeFilterData()` |public static void UpdateSerieRuntimeFilterData(Serie serie, bool filterInvisible = true)
| - -## `SerieLabelHelper` - -|public method|description| -|--|--| -| `AvoidLabelOverlap()` |public static void AvoidLabelOverlap(Serie serie, ComponentTheme theme)
| -| `CanShowLabel()` |public static bool CanShowLabel(Serie serie, SerieData serieData, LabelStyle label, int dimesion)
| -| `GetLabelColor()` |public static Color GetLabelColor(Serie serie, ThemeStyle theme, int index)
| -| `GetRealLabelPosition()` |public static Vector3 GetRealLabelPosition(Serie serie, SerieData serieData, LabelStyle label, LabelLine labelLine)
| -| `SetGaugeLabelText()` |public static void SetGaugeLabelText(Serie serie)
| -| `UpdatePieLabelPosition()` |public static void UpdatePieLabelPosition(Serie serie, SerieData serieData)
| - -## `SerieLabelPool` - -|public method|description| -|--|--| -| `ClearAll()` |public static void ClearAll()
| -| `Release()` |public static void Release(GameObject element)
| -| `ReleaseAll()` |public static void ReleaseAll(Transform parent)
| - -## `SerieParams` - -## `SeriesHelper` - -|public method|description| -|--|--| -| `GetLastStackSerie()` |public static Serie GetLastStackSerie(List series, Serie serie)
获得上一个同堆叠且显示的serie。 | -| `GetLegalSerieNameList()` |public static List GetLegalSerieNameList(List series)
| -| `GetMaxSerieDataCount()` |public static int GetMaxSerieDataCount(List series)
| -| `GetNameColor()` |public static Color GetNameColor(BaseChart chart, int index, string name)
| -| `GetSerieByVesselIndex()` |public static Serie GetSerieByVesselIndex(List series, int vesselIndex)
| -| `GetStackSeries()` |public static void GetStackSeries(List series, ref Dictionary> stackSeries)
获得堆叠系列列表 | -| `IsAnyClipSerie()` |public static bool IsAnyClipSerie(List series)
是否有需裁剪的serie。 | -| `IsLegalLegendName()` |public static bool IsLegalLegendName(string name)
| -| `IsStack()` |public static bool IsStack(List series)
是否由数据堆叠 | -| `UpdateSerieNameList()` |public static void UpdateSerieNameList(BaseChart chart, ref List serieNameList)
获得所有系列名,不包含空名字。 | -| `UpdateStackDataList()` |public static void UpdateStackDataList(List series, Serie currSerie, DataZoom dataZoom, List> dataList)
| - -## `SimplifiedBarChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SimplifiedCandlestickChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SimplifiedLineChart` - -Inherits or Implemented: [BaseChart](#BaseChart) - -## `SVG` - -|public method|description| -|--|--| -| `DrawPath()` |public static void DrawPath(VertexHelper vh, string path)
| -| `DrawPath()` |public static void DrawPath(VertexHelper vh, SVGPath path)
| -| `Test()` |public static void Test(VertexHelper vh)
| - -## `SVGImage` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic) - -## `SVGPath` - -|public method|description| -|--|--| -| `AddSegment()` |public void AddSegment(SVGPathSeg seg)
| -| `Draw()` |public void Draw(VertexHelper vh)
| -| `Parse()` |public static SVGPath Parse(string path)
| - -## `SVGPathSeg` - -|public method|description| -|--|--| -| `SVGPathSeg()` |public SVGPathSeg(SVGPathSegType type)
| - -## `TooltipContext` - -## `TooltipData` - -## `TooltipHelper` - -|public method|description| -|--|--| -| `GetItemNumericFormatter()` |public static string GetItemNumericFormatter(Tooltip tooltip, Serie serie, SerieData serieData)
| -| `GetLineColor()` |public static Color32 GetLineColor(Tooltip tooltip, ThemeStyle theme)
| -| `IsIgnoreItemFormatter()` |public static bool IsIgnoreItemFormatter(string itemFormatter)
| -| `LimitInRect()` |public static void LimitInRect(Tooltip tooltip, Rect chartRect)
| - -## `TooltipView` - -|public method|description| -|--|--| -| `CreateView()` |public static TooltipView CreateView(Tooltip tooltip, ThemeStyle theme, Transform parent)
| -| `GetCurrentPos()` |public Vector3 GetCurrentPos()
| -| `GetTargetPos()` |public Vector3 GetTargetPos()
| -| `Refresh()` |public void Refresh()
| -| `SetActive()` |public void SetActive(bool flag)
| -| `Update()` |public void Update()
| -| `UpdatePosition()` |public void UpdatePosition(Vector3 pos)
| - -## `TooltipViewItem` - -## `UGL` - -|public method|description| -|--|--| -| `DrawDiamond()` |public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color)
Draw a diamond. 画菱形(钻石形状) | -| `DrawDiamond()` |public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color, Color32 toColor)
Draw a diamond. 画菱形(钻石形状) | -| `DrawEllipse()` |public static void DrawEllipse(VertexHelper vh, Vector3 center, float w, float h, Color32 color, float smoothness = 1)
| -| `DrawLine()` |public static void DrawLine(VertexHelper vh, List points, float width, Color32 color, bool smooth, bool closepath = false)
| -| `DrawLine()` |public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color)
Draw a line. 画直线 | -| `DrawLine()` |public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color, Color32 toColor)
Draw a line. 画直线 | -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color, Color32 toColor)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color, Color32 toColor)
| -| `DrawRectangle()` |public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color)
Draw a rectangle. 画带长方形 | -| `DrawSquare()` |public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color)
Draw a square. 画正方形 | -| `DrawSvgPath()` |public static void DrawSvgPath(VertexHelper vh, string path)
| -| `DrawTriangle()` |public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color)
| -| `DrawTriangle()` |public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color, Color32 toColor)
| - -## `UGLExample` - -Inherits or Implemented: [MaskableGraphic](#MaskableGraphic) - -## `UGLHelper` - -|public method|description| -|--|--| -| `GetAngle360()` |public static float GetAngle360(Vector2 from, Vector2 to)
获得0-360的角度(12点钟方向为0度) | -| `GetBezier()` |public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep)
| -| `GetBezier2()` |public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep)
| -| `GetBezierList()` |public static List GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp)
| -| `GetDire()` |public static Vector3 GetDire(float angle, bool isDegree = false)
| -| `GetIntersection()` |public static bool GetIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, ref Vector3 intersection)
获得两直线的交点 | -| `GetPos()` |public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
| -| `GetVertialDire()` |public static Vector3 GetVertialDire(Vector3 dire)
| -| `IsClearColor()` |public static bool IsClearColor(Color color)
| -| `IsClearColor()` |public static bool IsClearColor(Color32 color)
| -| `IsPointInPolygon()` |public static bool IsPointInPolygon(Vector3 p, List polyons)
| -| `IsPointInPolygon()` |public static bool IsPointInPolygon(Vector3 p, List polyons)
| -| `IsPointInTriangle()` |public static bool IsPointInTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 check)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color color1, Color color2)
| -| `IsValueEqualsColor()` |public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
| -| `IsValueEqualsList()` |public static bool IsValueEqualsList(List list1, List list2)
| -| `IsValueEqualsString()` |public static bool IsValueEqualsString(string str1, string str2)
| -| `IsValueEqualsVector2()` |public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2)
| -| `IsValueEqualsVector3()` |public static bool IsValueEqualsVector3(Vector3 v1, Vector2 v2)
| -| `IsValueEqualsVector3()` |public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2)
| -| `IsZeroVector()` |public static bool IsZeroVector(Vector3 pos)
| -| `RotateRound()` |public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
| - -## `VisualMapContext` - -Inherits or Implemented: [MainComponentContext](#MainComponentContext) - -## `VisualMapHelper` - -|public method|description| -|--|--| -| `AutoSetLineMinMax()` |public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)
| -| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int serieDataCount)
| -| `IsNeedAreaGradient()` |public static bool IsNeedAreaGradient(VisualMap visualMap)
| -| `IsNeedGradient()` |public static bool IsNeedGradient(VisualMap visualMap)
| -| `IsNeedLineGradient()` |public static bool IsNeedLineGradient(VisualMap visualMap)
| -| `SetMinMax()` |public static void SetMinMax(VisualMap visualMap, double min, double max)
| - -## `XChartsMgr` - -|public method|description| -|--|--| -| `AddChart()` |public static void AddChart(BaseChart chart)
| -| `ContainsChart()` |public static bool ContainsChart(BaseChart chart)
| -| `ContainsChart()` |public static bool ContainsChart(string chartName)
| -| `DisableTextMeshPro()` |public static void DisableTextMeshPro()
| -| `EnableTextMeshPro()` |public static void EnableTextMeshPro()
| -| `GetChart()` |public static BaseChart GetChart(string chartName)
| -| `GetCharts()` |public static List GetCharts(string chartName)
| -| `GetPackageFullPath()` |public static string GetPackageFullPath()
| -| `GetRepeatChartNameInfo()` |public static string GetRepeatChartNameInfo(BaseChart chart, string chartName)
| -| `IsExistTMPAssembly()` |public static bool IsExistTMPAssembly()
| -| `IsRepeatChartName()` |public static bool IsRepeatChartName(BaseChart chart, string chartName = null)
| -| `ModifyTMPRefence()` |public static bool ModifyTMPRefence(bool removeTMP = false)
| -| `RemoveAllChartObject()` |public static void RemoveAllChartObject()
| -| `RemoveChart()` |public static void RemoveChart(string chartName)
| - -## `XCResourceImporterWindow` - -Inherits or Implemented: [UnityEditor.EditorWindow](#UnityEditor.EditorWindow) - -|public method|description| -|--|--| -| `ShowPackageImporterWindow()` |public static void ShowPackageImporterWindow()
| - -## `XCThemeMgr` - -|public method|description| -|--|--| -| `AddTheme()` |public static void AddTheme(Theme theme)
| -| `CheckReloadTheme()` |public static void CheckReloadTheme()
| -| `ContainsTheme()` |public static bool ContainsTheme(string themeName)
| -| `ExportTheme()` |public static bool ExportTheme(Theme theme)
| -| `ExportTheme()` |public static bool ExportTheme(Theme theme, string themeNewName)
| -| `GetAllThemeNames()` |public static List GetAllThemeNames()
| -| `GetTheme()` |public static Theme GetTheme(string themeName)
| -| `GetTheme()` |public static Theme GetTheme(ThemeType type)
| -| `GetThemeAssetPath()` |public static string GetThemeAssetPath(string themeName)
| -| `GetThemeList()` |public static List GetThemeList()
| -| `LoadTheme()` |public static Theme LoadTheme(string themeName)
| -| `LoadTheme()` |public static Theme LoadTheme(ThemeType type)
| -| `ReloadThemeList()` |public static void ReloadThemeList()
重新加载主题列表 | -| `SwitchTheme()` |public static void SwitchTheme(BaseChart chart, string themeName)
| - -[XCharts主页](https://github.com/XCharts-Team/XCharts)
-[XCharts配置项手册](XChartsConfiguration-ZH.md)
-[XCharts问答](XChartsFAQ-ZH.md) diff --git a/Assets/XCharts/Documentation/XChartsAPI-ZH.md.meta b/Assets/XCharts/Documentation/XChartsAPI-ZH.md.meta deleted file mode 100644 index 79944bc..0000000 --- a/Assets/XCharts/Documentation/XChartsAPI-ZH.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 2c38d275e62c6471ea2f4ef69b87b220 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsConfiguration-EN.md b/Assets/XCharts/Documentation/XChartsConfiguration-EN.md deleted file mode 100644 index 8a251fc..0000000 --- a/Assets/XCharts/Documentation/XChartsConfiguration-EN.md +++ /dev/null @@ -1,1528 +0,0 @@ -# Chart Configuration - -[XCharts Homepage](https://github.com/XCharts-Team/XCharts)
-[XCharts API](XChartsAPI-EN.md)
-[XCharts FAQ](XChartsFAQ-EN.md) - -## Serie - -- [Bar](#Bar) -- [BaseScatter](#BaseScatter) -- [Candlestick](#Candlestick) -- [EffectScatter](#EffectScatter) -- [Heatmap](#Heatmap) -- [Line](#Line) -- [Parallel](#Parallel) -- [Pie](#Pie) -- [Radar](#Radar) -- [Ring](#Ring) -- [Scatter](#Scatter) -- [Serie](#Serie) -- [SimplifiedBar](#SimplifiedBar) -- [SimplifiedCandlestick](#SimplifiedCandlestick) -- [SimplifiedLine](#SimplifiedLine) - -## Theme - -- [AngleAxisTheme](#AngleAxisTheme) -- [AxisTheme](#AxisTheme) -- [BaseAxisTheme](#BaseAxisTheme) -- [ComponentTheme](#ComponentTheme) -- [DataZoomTheme](#DataZoomTheme) -- [LegendTheme](#LegendTheme) -- [PolarAxisTheme](#PolarAxisTheme) -- [RadarAxisTheme](#RadarAxisTheme) -- [RadiusAxisTheme](#RadiusAxisTheme) -- [SerieTheme](#SerieTheme) -- [SubTitleTheme](#SubTitleTheme) -- [Theme](#Theme) -- [ThemeStyle](#ThemeStyle) -- [TitleTheme](#TitleTheme) -- [TooltipTheme](#TooltipTheme) -- [VisualMapTheme](#VisualMapTheme) - -## MainComponent - -- [AngleAxis](#AngleAxis) -- [Axis](#Axis) -- [Background](#Background) -- [CalendarCoord](#CalendarCoord) -- [Comment](#Comment) -- [CoordSystem](#CoordSystem) -- [DataZoom](#DataZoom) -- [GridCoord](#GridCoord) -- [Legend](#Legend) -- [MarkArea](#MarkArea) -- [MarkLine](#MarkLine) -- [ParallelAxis](#ParallelAxis) -- [ParallelCoord](#ParallelCoord) -- [PolarCoord](#PolarCoord) -- [RadarCoord](#RadarCoord) -- [RadiusAxis](#RadiusAxis) -- [Settings](#Settings) -- [SingleAxis](#SingleAxis) -- [SingleAxisCoord](#SingleAxisCoord) -- [Title](#Title) -- [Tooltip](#Tooltip) -- [VisualMap](#VisualMap) -- [XAxis](#XAxis) -- [YAxis](#YAxis) - -## ChildComponent - -- [AngleAxisTheme](#AngleAxisTheme) -- [AnimationStyle](#AnimationStyle) -- [AreaStyle](#AreaStyle) -- [ArrowStyle](#ArrowStyle) -- [AxisLabel](#AxisLabel) -- [AxisLine](#AxisLine) -- [AxisName](#AxisName) -- [AxisSplitArea](#AxisSplitArea) -- [AxisSplitLine](#AxisSplitLine) -- [AxisTheme](#AxisTheme) -- [AxisTick](#AxisTick) -- [BaseAxisTheme](#BaseAxisTheme) -- [BaseLine](#BaseLine) -- [CommentItem](#CommentItem) -- [CommentMarkStyle](#CommentMarkStyle) -- [ComponentTheme](#ComponentTheme) -- [DataZoomTheme](#DataZoomTheme) -- [Emphasis](#Emphasis) -- [EmphasisItemStyle](#EmphasisItemStyle) -- [EmphasisLabelLine](#EmphasisLabelLine) -- [EmphasisLabelStyle](#EmphasisLabelStyle) -- [EndLabelStyle](#EndLabelStyle) -- [IconStyle](#IconStyle) -- [ImageStyle](#ImageStyle) -- [ItemStyle](#ItemStyle) -- [LabelLine](#LabelLine) -- [LabelStyle](#LabelStyle) -- [LegendTheme](#LegendTheme) -- [Level](#Level) -- [LevelStyle](#LevelStyle) -- [LineArrow](#LineArrow) -- [LineStyle](#LineStyle) -- [Location](#Location) -- [MarkAreaData](#MarkAreaData) -- [MarkLineData](#MarkLineData) -- [PolarAxisTheme](#PolarAxisTheme) -- [RadarAxisTheme](#RadarAxisTheme) -- [RadiusAxisTheme](#RadiusAxisTheme) -- [SerieData](#SerieData) -- [SerieSymbol](#SerieSymbol) -- [SerieTheme](#SerieTheme) -- [StageColor](#StageColor) -- [SubTitleTheme](#SubTitleTheme) -- [SymbolStyle](#SymbolStyle) -- [TextLimit](#TextLimit) -- [TextPadding](#TextPadding) -- [TextStyle](#TextStyle) -- [ThemeStyle](#ThemeStyle) -- [TitleStyle](#TitleStyle) -- [TitleTheme](#TitleTheme) -- [TooltipTheme](#TooltipTheme) -- [VisualMapRange](#VisualMapRange) -- [VisualMapTheme](#VisualMapTheme) - -## ISerieExtraComponent - -- [AreaStyle](#AreaStyle) -- [Emphasis](#Emphasis) -- [EmphasisItemStyle](#EmphasisItemStyle) -- [EmphasisLabelLine](#EmphasisLabelLine) -- [EmphasisLabelStyle](#EmphasisLabelStyle) -- [ImageStyle](#ImageStyle) -- [LabelLine](#LabelLine) -- [LabelStyle](#LabelStyle) -- [LineArrow](#LineArrow) -- [TitleStyle](#TitleStyle) - -## ISerieDataComponent - -- [AreaStyle](#AreaStyle) -- [Emphasis](#Emphasis) -- [EmphasisItemStyle](#EmphasisItemStyle) -- [EmphasisLabelLine](#EmphasisLabelLine) -- [EmphasisLabelStyle](#EmphasisLabelStyle) -- [ImageStyle](#ImageStyle) -- [ItemStyle](#ItemStyle) -- [LabelLine](#LabelLine) -- [LabelStyle](#LabelStyle) -- [LineStyle](#LineStyle) -- [SerieSymbol](#SerieSymbol) -- [TitleStyle](#TitleStyle) - -## Other - -- [BaseSerie](#BaseSerie) -- [ChartText](#ChartText) -- [ChildComponent](#ChildComponent) -- [DebugInfo](#DebugInfo) -- [Indicator](#Indicator) -- [Lang](#Lang) -- [LangCandlestick](#LangCandlestick) -- [LangTime](#LangTime) -- [MainComponent](#MainComponent) -- [XCResourcesImporter](#XCResourcesImporter) -- [XCSettings](#XCSettings) - -## `AngleAxis` - -Inherits or Implemented: [Axis](#Axis) - -Angle axis of Polar Coordinate. - -|field|default|comment| -|--|--|--| -| `startAngle` |0 | Starting angle of axis. 0 degrees by default, standing for right position of center. | - -## `AngleAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `AnimationStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -the animation of serie. - -|field|default|comment| -|--|--|--| -| `enable` |true | Whether to enable animation. | -| `type` | | The type of animation.
`AnimationType`:
- `Default`: he default. An animation playback mode will be selected according to the actual situation.
- `LeftToRight`: Play the animation from left to right.
- `BottomToTop`: Play the animation from bottom to top.
- `InsideOut`: Play animations from the inside out.
- `AlongPath`: Play the animation along the path.
- `Clockwise`: Play the animation clockwise.
| -| `easting` | | Easing method used for the first animation.
`AnimationEasing`:
- `Linear`:
| -| `threshold` |2000 | Whether to set graphic number threshold to animation. Animation will be disabled when graphic number is larger than threshold. | -| `fadeInDuration` |1000 | The milliseconds duration of the fadeIn animation. | -| `fadeInDelay` |0 | The milliseconds delay before updating the first animation. | -| `fadeOutDuration` |1000f | The milliseconds duration of the fadeOut animation. | -| `fadeOutDelay` |0 | 渐出动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeOutDelay。 | -| `dataChangeEnable` |true | 是否开启数据变更动画。 | -| `dataChangeDuration` |500 | The milliseconds duration of the data change animation. | -| `actualDuration` | | The milliseconds actual duration of the first animation. | - -## `AreaStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -The style of area. - -|field|default|comment| -|--|--|--| -| `show` |true | Set this to false to prevent the areafrom showing. | -| `origin` | | the origin of area.
`AreaStyle.AreaOrigin`:
- `Auto`: to fill between axis line to data.
- `Start`: to fill between min axis value (when not inverse) to data.
- `End`: to fill between max axis value (when not inverse) to data.
| -| `color` | | the color of area,default use serie color. | -| `toColor` | | Gradient color, start color to toColor. | -| `opacity` |0.6f | Opacity of the component. Supports value from 0 to 1, and the component will not be drawn when set to 0. | -| `highlightColor` | | the color of area,default use serie color. | -| `highlightToColor` | | Gradient color, start highlightColor to highlightToColor. | - -## `ArrowStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `width` |10 | The widht of arrow. | -| `height` |15 | The height of arrow. | -| `offset` |0 | The offset of arrow. | -| `dent` |3 | The dent of arrow. | -| `color` |Color.clear | the color of arrow. | - -## `Axis` - -Inherits or Implemented: [MainComponent](#MainComponent) - -The axis in rectangular coordinate. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to show axis. | -| `type` | | the type of axis.
`Axis.AxisType`:
- `Value`: Numerical axis, suitable for continuous data.
- `Category`: Category axis, suitable for discrete category data. Data should only be set via data for this type.
- `Log`: Log axis, suitable for log data.
- `Time`: Time axis, suitable for continuous time series data.
| -| `minMaxType` | | the type of axis minmax.
`Axis.AxisMinMaxType`:
- `Default`: 0 - maximum.
- `MinMax`: minimum - maximum.
- `Custom`: Customize the minimum and maximum.
| -| `gridIndex` | | The index of the grid on which the axis are located, by default, is in the first grid. | -| `polarIndex` | | The index of the polar on which the axis are located, by default, is in the first polar. | -| `parallelIndex` | | The index of the parallel on which the axis are located, by default, is in the first parallel. | -| `position` | | the position of axis in grid.
`Axis.AxisPosition`:
- `Left`: the position of axis in grid.
- `Right`: the position of axis in grid.
- `Bottom`: the position of axis in grid.
- `Top`: the position of axis in grid.
| -| `offset` | | the offset of axis from the default position. Useful when the same position has multiple axes. | -| `min` | | The minimun value of axis.Valid when `minMaxType` is `Custom` | -| `max` | | The maximum value of axis.Valid when `minMaxType` is `Custom` | -| `splitNumber` |0 | Number of segments that the axis is split into. | -| `interval` |0 | Compulsively set segmentation interval for axis.This is unavailable for category axis. | -| `boundaryGap` |true | The boundary gap on both sides of a coordinate axis, which is valid only for category axis with type: 'Category'. | -| `maxCache` |0 | The max number of axis data cache. | -| `logBase` |10 | Base of logarithm, which is valid only for numeric axes with type: 'Log'. | -| `logBaseE` |false | On the log axis, if base e is the natural number, and is true, logBase fails. | -| `ceilRate` |0 | The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated. | -| `inverse` |false | Whether the axis are reversed or not. Invalid in `Category` axis. | -| `clockwise` |true | Whether the positive position of axis is in clockwise. True for clockwise by default. | -| `insertDataToHead` | | Whether to add new data at the head or at the end of the list. | -| `icons` | | 类目数据对应的图标。 | -| `data` | | Category data, available in type: 'Category' axis. | -| `axisLine` | | axis Line. [AxisLine](AxisLine)| -| `axisName` | | axis name. [AxisName](AxisName)| -| `axisTick` | | axis tick. [AxisTick](AxisTick)| -| `axisLabel` | | axis label. [AxisLabel](AxisLabel)| -| `splitLine` | | axis split line. [AxisSplitLine](AxisSplitLine)| -| `splitArea` | | axis split area. [AxisSplitArea](AxisSplitArea)| - -## `AxisLabel` - -Inherits or Implemented: [LabelStyle](#LabelStyle) - -Settings related to axis label. - -|field|default|comment| -|--|--|--| -| `interval` |0 | The display interval of the axis label. | -| `inside` |false | Set this to true so the axis labels face the inside direction. | -| `showAsPositiveNumber` |false | Show negative number as positive number. | -| `onZero` |false | 刻度标签显示在0刻度上。 | -| `showStartLabel` |true | Whether to display the first label. | -| `showEndLabel` |true | Whether to display the last label. | -| `textLimit` | | 文本限制。 [TextLimit](TextLimit)| - -## `AxisLine` - -Inherits or Implemented: [BaseLine](#BaseLine) - -Settings related to axis line. - -|field|default|comment| -|--|--|--| -| `onZero` | | When mutiple axes exists, this option can be used to specify which axis can be "onZero" to. | -| `showArrow` | | Whether to show the arrow symbol of axis. | -| `arrow` | | the arrow of line. [ArrowStyle](ArrowStyle)| - -## `AxisName` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -the name of axis. - -|field|default|comment| -|--|--|--| -| `show` | | Whether to show axis name. | -| `name` | | the name of axis. | -| `labelStyle` | | The text style of axis name. [LabelStyle](LabelStyle)| - -## `AxisSplitArea` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Split area of axis in grid area, not shown by default. - -|field|default|comment| -|--|--|--| -| `show` | | Set this to true to show the splitArea. | -| `color` | | Color of split area. SplitArea color could also be set in color array, which the split lines would take as their colors in turns. Dark and light colors in turns are used by default. | - -## `AxisSplitLine` - -Inherits or Implemented: [BaseLine](#BaseLine) - -Split line of axis in grid area. - -|field|default|comment| -|--|--|--| -| `interval` | | Interval of Axis splitLine. | -| `distance` | | The distance between the split line and axis line. | -| `autoColor` | | auto color. | - -## `AxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `AxisTick` - -Inherits or Implemented: [BaseLine](#BaseLine) - -Settings related to axis tick. - -|field|default|comment| -|--|--|--| -| `alignWithLabel` | | Align axis tick with label, which is available only when boundaryGap is set to be true in category axis. | -| `inside` | | Set this to true so the axis labels face the inside direction. | -| `showStartTick` | | Whether to display the first tick. | -| `showEndTick` | | Whether to display the last tick. | -| `distance` | | The distance between the tick line and axis line. | -| `splitNumber` |0 | Number of segments that the axis is split into. | -| `autoColor` | | | - -## `Background` - -Inherits or Implemented: [MainComponent](#MainComponent) - -Background component. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to enable the background component. | -| `image` | | the image of background. | -| `imageType` | | the fill type of background image. | -| `imageColor` | | 背景图颜色。 | -| `autoColor` |true | Whether to use theme background color for component color when the background component is on. | - -## `Bar` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `BaseAxisTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `lineType` | | the type of line. | -| `lineWidth` |1f | the width of line. | -| `lineLength` |0f | the length of line. | -| `lineColor` | | the color of line. | -| `splitLineType` | | the type of split line. | -| `splitLineWidth` |1f | the width of split line. | -| `splitLineLength` |0f | the length of split line. | -| `splitLineColor` | | the color of line. | -| `tickWidth` |1f | the width of tick. | -| `tickLength` |5f | the length of tick. | -| `tickColor` | | the color of tick. | -| `splitAreaColors` | | | - -## `BaseLine` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Settings related to base line. - -|field|default|comment| -|--|--|--| -| `show` | | Set this to false to prevent the axis line from showing. | -| `lineStyle` | | 线条样式 [LineStyle](LineStyle)| - -## `BaseScatter` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `BaseSerie` - - -## `CalendarCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[IUpdateRuntimeData](#IUpdateRuntimeData),[ISerieContainer](#ISerieContainer) - - -## `Candlestick` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `ChartText` - - -## `ChildComponent` - - -## `Comment` - -Inherits or Implemented: [MainComponent](#MainComponent) - -comment of chart. - -|field|default|comment| -|--|--|--| -| `show` |true | Set this to false to prevent the comment from showing. | -| `labelStyle` | | The text style of all comments. [LabelStyle](LabelStyle)| -| `markStyle` | | The text style of all comments. [CommentMarkStyle](CommentMarkStyle)| -| `items` | | | - -## `CommentItem` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -comment of chart. - -|field|default|comment| -|--|--|--| -| `show` |true | Set this to false to prevent this comment item from showing. | -| `content` | | content of comment. | -| `position` | | position of comment. | -| `markRect` | | the mark rect of comment. | -| `markStyle` | | the mark rect style. [CommentMarkStyle](CommentMarkStyle)| -| `labelStyle` | | The text style of all comments. [LabelStyle](LabelStyle)| - -## `CommentMarkStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -the comment mark style. - -|field|default|comment| -|--|--|--| -| `show` |true | Set this to false to prevent this comment item from showing. | -| `lineStyle` | | line style of comment mark area. [LineStyle](LineStyle)| - -## `ComponentTheme` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `font` | | the font of text. | -| `textColor` | | the color of text. | -| `textBackgroundColor` | | the color of text. | -| `fontSize` |18 | the font size of text. | -| `tMPFont` | | the font of chart text。 | - -## `CoordSystem` - -Inherits or Implemented: [MainComponent](#MainComponent) - -Coordinate system component. - - -## `DataZoom` - -Inherits or Implemented: [MainComponent](#MainComponent),[IUpdateRuntimeData](#IUpdateRuntimeData) - -DataZoom component is used for zooming a specific area, which enables user to investigate data in detail, or get an overview of the data, or get rid of outlier points. - -|field|default|comment| -|--|--|--| -| `enable` |true | Whether to show dataZoom. | -| `filterMode` | | The mode of data filter.
`DataZoom.FilterMode`:
- `Filter`: data that outside the window will be filtered, which may lead to some changes of windows of other axes. For each data item, it will be filtered if one of the relevant dimensions is out of the window.
- `WeakFilter`: data that outside the window will be filtered, which may lead to some changes of windows of other axes. For each data item, it will be filtered only if all of the relevant dimensions are out of the same side of the window.
- `Empty`: data that outside the window will be set to NaN, which will not lead to changes of windows of other axes.
- `None`: Do not filter data.
| -| `xAxisIndexs` | | Specify which xAxis is controlled by the dataZoom. | -| `yAxisIndexs` | | Specify which yAxis is controlled by the dataZoom. | -| `supportInside` | | Whether built-in support is supported. Built into the coordinate system to allow the user to zoom in and out of the coordinate system by mouse dragging, mouse wheel, finger swiping (on the touch screen). | -| `supportInsideScroll` |true | 是否支持坐标系内滚动 | -| `supportInsideDrag` |true | 是否支持坐标系内拖拽 | -| `supportSlider` | | Whether a slider is supported. There are separate sliders on which the user zooms or roams. | -| `supportSelect` | | 是否支持框选。提供一个选框进行数据区域缩放。 | -| `showDataShadow` | | Whether to show data shadow, to indicate the data tendency in brief. | -| `showDetail` | | Whether to show detail, that is, show the detailed data information when dragging. | -| `zoomLock` | | Specify whether to lock the size of window (selected area). | -| `fillerColor` | | the color of dataZoom data area. | -| `borderColor` | | the color of dataZoom border. | -| `borderWidth` | | 边框宽。 | -| `backgroundColor` | | The background color of the component. | -| `left` | | Distance between dataZoom component and the left side of the container. left value is a instant pixel value like 10 or float value [0-1]. | -| `right` | | Distance between dataZoom component and the right side of the container. right value is a instant pixel value like 10 or float value [0-1]. | -| `top` | | Distance between dataZoom component and the top side of the container. top value is a instant pixel value like 10 or float value [0-1]. | -| `bottom` | | Distance between dataZoom component and the bottom side of the container. bottom value is a instant pixel value like 10 or float value [0-1]. | -| `rangeMode` | | Use absolute value or percent value in DataZoom.start and DataZoom.end.
`DataZoom.RangeMode`:
- `//Value`: The value type of start and end.取值类型
- `Percent`: percent value.
| -| `start` | | The start percentage of the window out of the data extent, in the range of 0 ~ 100. | -| `end` | | The end percentage of the window out of the data extent, in the range of 0 ~ 100. | -| `minShowNum` |1 | Minimum number of display data. Minimum number of data displayed when DataZoom is enlarged to maximum. | -| `scrollSensitivity` |1.1f | The sensitivity of dataZoom scroll. The larger the number, the more sensitive it is. | -| `orient` | | Specify whether the layout of dataZoom component is horizontal or vertical. What's more, it indicates whether the horizontal axis or vertical axis is controlled by default in catesian coordinate system.
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `labelStyle` | | label style. [LabelStyle](LabelStyle)| -| `lineStyle` | | 阴影线条样式。 [LineStyle](LineStyle)| -| `areaStyle` | | 阴影填充样式。 [AreaStyle](AreaStyle)| - -## `DataZoomTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `borderWidth` | | the width of border line. | -| `dataLineWidth` | | the width of data line. | -| `fillerColor` | | the color of dataZoom data area. | -| `borderColor` | | the color of dataZoom border. | -| `dataLineColor` | | the color of data area line. | -| `dataAreaColor` | | the color of data area line. | -| `backgroundColor` | | the background color of datazoom. | - -## `DebugInfo` - -|field|default|comment| -|--|--|--| -| `show` |true | | -| `showDebugInfo` |false | | -| `showAllChartObject` |false | | -| `foldSeries` |false | | -| `labelStyle` | | [LabelStyle](LabelStyle)| - -## `EffectScatter` - -Inherits or Implemented: [BaseScatter](#BaseScatter) - - -## `Emphasis` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的图形样式和文本标签样式。 - -|field|default|comment| -|--|--|--| -| `show` | | 是否启用高亮样式。 | -| `label` | | 图形文本标签。 [LabelStyle](LabelStyle)| -| `labelLine` | | 图形文本引导线样式。 [LabelLine](LabelLine)| -| `itemStyle` | | 图形样式。 [ItemStyle](ItemStyle)| - -## `EmphasisItemStyle` - -Inherits or Implemented: [ItemStyle](#ItemStyle),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的图形样式 - - -## `EmphasisLabelLine` - -Inherits or Implemented: [LabelLine](#LabelLine),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的标签引导线样式 - - -## `EmphasisLabelStyle` - -Inherits or Implemented: [LabelStyle](#LabelStyle),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的标签样式 - - -## `EndLabelStyle` - -Inherits or Implemented: [LabelStyle](#LabelStyle) - - -## `GridCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[IUpdateRuntimeData](#IUpdateRuntimeData),[ISerieContainer](#ISerieContainer) - -Grid component. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to show the grid in rectangular coordinate. | -| `left` |0.1f | Distance between grid component and the left side of the container. | -| `right` |0.08f | Distance between grid component and the right side of the container. | -| `top` |0.22f | Distance between grid component and the top side of the container. | -| `bottom` |0.12f | Distance between grid component and the bottom side of the container. | -| `backgroundColor` | | Background color of grid, which is transparent by default. | -| `showBorder` |false | Whether to show the grid border. | -| `borderWidth` |0f | Border width of grid. | -| `borderColor` | | The color of grid border. | - -## `Heatmap` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `IconStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `show` |false | Whether the data icon is show. | -| `layer` | | 显示在上层还是在下层。
`IconStyle.Layer`:
- `UnderText`: The icon is display under the label text. 图标在标签文字下
- `AboveText`: The icon is display above the label text. 图标在标签文字上
| -| `align` | | 水平方向对齐方式。
`Align`:
- `Center`: 对齐方式
- `Left`: 对齐方式
- `Right`: 对齐方式
| -| `sprite` | | The image of icon. | -| `type` | | How to display the icon. | -| `color` | | 图标颜色。 | -| `width` |20 | 图标宽。 | -| `height` |20 | 图标高。 | -| `offset` | | 图标偏移。 | -| `autoHideWhenLabelEmpty` |false | 当label内容为空时是否自动隐藏图标 | - -## `ImageStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -|field|default|comment| -|--|--|--| -| `show` |true | Whether the data icon is show. | -| `sprite` | | The image of icon. | -| `type` | | How to display the image. | -| `autoColor` | | 是否自动颜色。 | -| `color` | | 图标颜色。 | -| `width` |0 | 图标宽。 | -| `height` |0 | 图标高。 | - -## `Indicator` - -Indicator of radar chart, which is used to assign multiple variables(dimensions) in radar chart. - -|field|default|comment| -|--|--|--| -| `name` | | | -| `max` | | The maximum value of indicator, with default value of 0, but we recommend to set it manually. | -| `min` | | The minimum value of indicator, with default value of 0. | -| `range` | | Normal range. When the value is outside this range, the display color is automatically changed. | -| `show` | | [default:true] Set this to false to prevent the radar from showing. | -| `shape` | | Radar render type, in which 'Polygon' and 'Circle' are supported.
`RadarCoord.Shape`:
- `Polygon`: Radar render type, in which 'Polygon' and 'Circle' are supported.
- `Circle`: Radar render type, in which 'Polygon' and 'Circle' are supported.
| -| `radius` |100 | the radius of radar. | -| `splitNumber` |5 | Segments of indicator axis. | -| `center` | | the center of radar chart. | -| `axisLine` | | axis line. [AxisLine](AxisLine)| -| `axisName` | | Name options for radar indicators. [AxisName](AxisName)| -| `splitLine` | | split line. [AxisSplitLine](AxisSplitLine)| -| `splitArea` | | Split area of axis in grid area. [AxisSplitArea](AxisSplitArea)| -| `indicator` |true | Whether to show indicator. | -| `positionType` | | The position type of indicator.
`RadarCoord.PositionType`:
- `Vertice`: Display at the vertex.
- `Between`: Display at the middle of line.
| -| `indicatorGap` |10 | The gap of indicator and radar. | -| `ceilRate` |0 | The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated. | -| `isAxisTooltip` | | 是否Tooltip显示轴线上的所有数据。 | -| `outRangeColor` |Color.red | The color displayed when data out of range. | -| `connectCenter` |false | Whether serie data connect to radar center with line. | -| `lineGradient` |true | Whether need gradient for data line. | -| `indicatorList` | | the indicator list. | - -## `ItemStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieDataComponent](#ISerieDataComponent) - -图形样式。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否启用。 | -| `color` | | 数据项颜色。 | -| `color0` | | 数据项颜色。 | -| `toColor` | | Gradient color1. | -| `toColor2` | | Gradient color2.Only valid in line diagrams. | -| `backgroundColor` | | 数据项背景颜色。 | -| `backgroundWidth` | | 数据项背景宽度。 | -| `centerColor` | | 中心区域颜色。 | -| `centerGap` | | 中心区域间隙。 | -| `borderWidth` |0 | 边框宽。 | -| `borderGap` |0 | 边框间隙。 | -| `borderColor` | | 边框的颜色。 | -| `borderColor0` | | 边框的颜色。 | -| `borderToColor` | | 边框的渐变色。 | -| `opacity` |1 | 透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 | -| `itemMarker` | | 提示框单项的字符标志。用在Tooltip中。 | -| `itemFormatter` | | 提示框单项的字符串模版格式器。具体配置参考`Tooltip`的`formatter` | -| `numericFormatter` | | Standard numeric format strings. | -| `cornerRadius` | | The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)). | - -## `LabelLine` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -标签的引导线 - -|field|default|comment| -|--|--|--| -| `show` |true | Whether the label line is showed. | -| `lineType` | | the type of visual guide line.
`LineType`:
- `Normal`: the normal line chart,
- `Smooth`: the smooth line chart,
- `StepStart`: step line.
- `StepMiddle`: step line.
- `StepEnd`: step line.
| -| `lineColor` |ChartConst.clearColor32 | the color of visual guild line. | -| `lineAngle` |0 | the angle of visual guild line. | -| `lineWidth` |1.0f | the width of visual guild line. | -| `lineGap` |1.0f | the gap of container and guild line. | -| `lineLength1` |25f | The length of the first segment of visual guide line. | -| `lineLength2` |15f | The length of the second segment of visual guide line. | -| `startSymbol` | | The symbol of the start point of labelline. [SymbolStyle](SymbolStyle)| -| `endSymbol` | | The symbol of the end point of labelline. [SymbolStyle](SymbolStyle)| - -## `LabelStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -Text label of chart, to explain some data information about graphic item like value, name and so on. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether the label is showed. | -| `Position` | | The position of label. | -| `autoOffset` |false | 是否开启自动偏移。当开启时,Y的偏移会自动判断曲线的开口来决定向上还是向下偏移。 | -| `offset` | | offset to the host graphic element. | -| `rotate` | | Rotation of label. | -| `distance` | | 距离轴线的距离。 | -| `formatter` | | formatter of label. | -| `numericFormatter` | | Standard numeric format strings. | -| `width` |0 | the width of label. If set as default value 0, it means than the label width auto set as the text width. | -| `height` |0 | the height of label. If set as default value 0, it means than the label height auto set as the text height. | -| `icon` | | the sytle of icon. [IconStyle](IconStyle)| -| `background` | | the sytle of background. [ImageStyle](ImageStyle)| -| `textPadding` | | the text padding of label. [TextPadding](TextPadding)| -| `textStyle` | | the sytle of text. [TextStyle](TextStyle)| - -## `Lang` - -Inherits or Implemented: [ScriptableObject](#ScriptableObject) - -Language. - - -## `LangCandlestick` - - -## `LangTime` - - -## `Legend` - -Inherits or Implemented: [MainComponent](#MainComponent),[IPropertyChanged](#IPropertyChanged) - -Legend component.The legend component shows different sets of tags, colors, and names. You can control which series are not displayed by clicking on the legend. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to show legend component. | -| `iconType` | | Type of legend.
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `selectedMode` | | Selected mode of legend, which controls whether series can be toggled displaying by clicking legends.
`VisualMap.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
| -| `orient` | | Specify whether the layout of legend component is horizontal or vertical.
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `location` | | The location of legend. [Location](Location)| -| `itemWidth` |25.0f | Image width of legend symbol. | -| `itemHeight` |12.0f | Image height of legend symbol. | -| `itemGap` |10f | The distance between each legend, horizontal distance in horizontal layout, and vertical distance in vertical layout. | -| `itemAutoColor` |true | Whether the legend symbol matches the color automatically. | -| `itemOpacity` |1 | the opacity of item color. | -| `formatter` | | Legend content string template formatter. Support for wrapping lines with \n. Template:{value}. | -| `numericFormatter` | | Standard numeric format strings. | -| `labelStyle` | | the style of text. [LabelStyle](LabelStyle)| -| `data` | | Data array of legend. An array item is usually a name representing string. (If it is a pie chart, it could also be the name of a single data in the pie chart) of a series. | -| `icons` | | 自定义的图例标记图形。 | -| `colors` | | the colors of legend item. 图例标记的颜色列表。 | - -## `LegendTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `unableColor` | | the color of text. | - -## `Level` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `label` | | 文本标签样式。 [LabelStyle](LabelStyle)| -| `upperLabel` | | 上方的文本标签样式。 [LabelStyle](LabelStyle)| -| `itemStyle` | | 数据项样式。 [ItemStyle](ItemStyle)| - -## `LevelStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `show` |false | 是否启用LevelStyle | -| `levels` | | 各层节点对应的配置。当enableLevels为true时生效,levels[0]对应的第一层的配置,levels[1]对应第二层,依次类推。当levels中没有对应层时用默认的设置。 | - -## `Line` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `LineArrow` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent) - -|field|default|comment| -|--|--|--| -| `show` | | Whether to show the arrow. | -| `position` | | The position of arrow.
`LabelStyle.Position`:
- `Default`: The position of label.
- `Outside`: Outside of sectors of pie chart, which relates to corresponding sector through visual guide line.
- `Inside`: Inside the sectors of pie chart.
- `Center`: In the center of pie chart.
- `Top`: top of symbol.
- `Bottom`: the bottom of symbol.
- `Left`: the left of symbol.
- `Right`: the right of symbol.
- `Start`: the start of line.
- `Middle`: the middle of line.
- `End`: the end of line.
| -| `arrow` | | the arrow of line. [ArrowStyle](ArrowStyle)| - -## `LineStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieDataComponent](#ISerieDataComponent) - -The style of line. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether show line. | -| `type` | | the type of line.
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `color` | | the color of line, default use serie color. | -| `toColor` | | the middle color of line, default use serie color. | -| `toColor2` | | the end color of line, default use serie color. | -| `width` |0 | the width of line. | -| `length` |0 | the length of line. | -| `opacity` |1 | Opacity of the line. Supports value from 0 to 1, and the line will not be drawn when set to 0. | - -## `Location` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[IPropertyChanged](#IPropertyChanged) - -Location type. Quick to set the general location. - -|field|default|comment| -|--|--|--| -| `align` | | 对齐方式。
`Align`:
- `Center`: 对齐方式
- `Left`: 对齐方式
- `Right`: 对齐方式
| -| `left` | | Distance between component and the left side of the container. | -| `right` | | Distance between component and the left side of the container. | -| `top` | | Distance between component and the left side of the container. | -| `bottom` | | Distance between component and the left side of the container. | - -## `MainComponent` - -Inherits or Implemented: [IComparable](#IComparable) - - -## `MarkArea` - -Inherits or Implemented: [MainComponent](#MainComponent) - -Used to mark an area in chart. For example, mark a time interval. - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示标域。 | -| `text` | | The text of markArea. 标域显示的文本。 | -| `serieIndex` |0 | Serie index of markArea. 标域影响的Serie索引。 | -| `start` | | 标域范围的起始数据。 [MarkAreaData](MarkAreaData)| -| `end` | | 标域范围的结束数据。 [MarkAreaData](MarkAreaData)| -| `itemStyle` | | 标域样式。 [ItemStyle](ItemStyle)| -| `label` | | 标域文本样式。 [LabelStyle](LabelStyle)| - -## `MarkAreaData` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -标域的数据。 - -|field|default|comment| -|--|--|--| -| `type` | | Special markArea types, are used to label maximum value, minimum value and so on.
`MarkAreaType`:
- `None`: 标域类型
- `Min`: 最小值。
- `Max`: 最大值。
- `Average`: 平均值。
- `Median`: 中位数。
| -| `name` | | Name of the marker, which will display as a label. | -| `dimension` |1 | From which dimension of data to calculate the maximum and minimum value and so on. | -| `xPosition` | | The x coordinate relative to the origin, in pixels. | -| `yPosition` | | The y coordinate relative to the origin, in pixels. | -| `xValue` | | The value specified on the X-axis. A value specified when the X-axis is the category axis represents the index of the category axis data, otherwise a specific value. | -| `yValue` | | That's the value on the Y-axis. The value specified when the Y axis is the category axis represents the index of the category axis data, otherwise the specific value. | - -## `MarkLine` - -Inherits or Implemented: [MainComponent](#MainComponent) - -Use a line in the chart to illustrate. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to display the marking line. | -| `serieIndex` |0 | The serie index of markLine. | -| `animation` | | The animation of markline. [AnimationStyle](AnimationStyle)| -| `data` | | A list of marked data. When the group of data item is 0, each data item represents a line; When the group is not 0, two data items of the same group represent the starting point and the ending point of the line respectively to form a line. In this case, the relevant style parameters of the line are the parameters of the starting point. | - -## `MarkLineData` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Data of marking line. - -|field|default|comment| -|--|--|--| -| `type` | | Special label types, are used to label maximum value, minimum value and so on.
`MarkLineType`:
- `None`: 标线类型
- `Min`: 最小值。
- `Max`: 最大值。
- `Average`: 平均值。
- `Median`: 中位数。
| -| `name` | | Name of the marker, which will display as a label. | -| `dimension` |1 | From which dimension of data to calculate the maximum and minimum value and so on. | -| `xPosition` | | The x coordinate relative to the origin, in pixels. | -| `yPosition` | | The y coordinate relative to the origin, in pixels. | -| `xValue` | | The value specified on the X-axis. A value specified when the X-axis is the category axis represents the index of the category axis data, otherwise a specific value. | -| `yValue` | | That's the value on the Y-axis. The value specified when the Y axis is the category axis represents the index of the category axis data, otherwise the specific value. | -| `group` |0 | Grouping. When the group is not 0, it means that this data is the starting point or end point of the marking line. Data consistent with the group form a marking line. | -| `zeroPosition` |false | Is the origin of the coordinate system. | -| `startSymbol` | | The symbol of the start point of markline. [SymbolStyle](SymbolStyle)| -| `endSymbol` | | The symbol of the end point of markline. [SymbolStyle](SymbolStyle)| -| `lineStyle` | | The line style of markline. [LineStyle](LineStyle)| -| `label` | | Text styles of label. You can set position to Start, Middle, and End to display text in different locations. [LabelStyle](LabelStyle)| - -## `Parallel` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `ParallelAxis` - -Inherits or Implemented: [Axis](#Axis) - - -## `ParallelCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[IUpdateRuntimeData](#IUpdateRuntimeData),[ISerieContainer](#ISerieContainer) - -Grid component. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to show the grid in rectangular coordinate. | -| `orient` | | Orientation of the axis. By default, it's 'Vertical'. You can set it to be 'Horizonal' to make a vertical axis.
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `left` |0.1f | Distance between grid component and the left side of the container. | -| `right` |0.08f | Distance between grid component and the right side of the container. | -| `top` |0.22f | Distance between grid component and the top side of the container. | -| `bottom` |0.12f | Distance between grid component and the bottom side of the container. | -| `backgroundColor` | | Background color of grid, which is transparent by default. | - -## `Pie` - -Inherits or Implemented: [Serie](#Serie) - - -## `PolarAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `PolarCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[ISerieContainer](#ISerieContainer) - -Polar coordinate can be used in scatter and line chart. Every polar coordinate has an angleAxis and a radiusAxis. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to show the polor component. | -| `center` | | The center of ploar. The center[0] is the x-coordinate, and the center[1] is the y-coordinate. When value between 0 and 1 represents a percentage relative to the chart. | -| `radius` |0.35f | the radius of polar. | -| `backgroundColor` | | Background color of polar, which is transparent by default. | - -## `Radar` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `RadarAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `RadarCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[ISerieContainer](#ISerieContainer) - -Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适用于雷达图。 - - -## `RadiusAxis` - -Inherits or Implemented: [Axis](#Axis) - -Radial axis of polar coordinate. - - -## `RadiusAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `Ring` - -Inherits or Implemented: [Serie](#Serie) - - -## `Scatter` - -Inherits or Implemented: [BaseScatter](#BaseScatter) - - -## `Serie` - -Inherits or Implemented: [BaseSerie](#BaseSerie),[IComparable](#IComparable) - -系列。 - -|field|default|comment| -|--|--|--| -| `index` | | The index of serie. | -| `show` |true | Whether to show serie in chart. | -| `coordSystem` | | the chart coord system of serie. | -| `serieType` | | the type of serie. | -| `serieName` | | Series name used for displaying in tooltip and filtering with legend. | -| `stack` | | If stack the value. On the same category axis, the series with the same stack name would be put on top of each other. | -| `xAxisIndex` |0 | the index of XAxis. | -| `yAxisIndex` |0 | the index of YAxis. | -| `radarIndex` |0 | Index of radar component that radar chart uses. | -| `vesselIndex` |0 | Index of vesel component that liquid chart uses. | -| `polarIndex` |0 | Index of polar component that serie uses. | -| `singleAxisIndex` |0 | Index of single axis component that serie uses. | -| `parallelIndex` |0 | Index of parallel coord component that serie uses. | -| `minShow` | | The min number of data to show in chart. | -| `maxShow` | | The max number of data to show in chart. | -| `maxCache` | | The max number of serie data cache. The first data will be remove when the size of serie data is larger then maxCache. | -| `sampleDist` |0 | the min pixel dist of sample. | -| `sampleType` | | the type of sample.
`SampleType`:
- `Peak`: Take a peak. When the average value of the filter point is greater than or equal to 'sampleAverage', take the maximum value; If you do it the other way around, you get the minimum.
- `Average`: Take the average of the filter points.
- `Max`: Take the maximum value of the filter point.
- `Min`: Take the minimum value of the filter point.
- `Sum`: Take the sum of the filter points.
| -| `sampleAverage` |0 | 设定的采样平均值。当sampleType 为 Peak 时,用于和过滤数据的平均值做对比是取最大值还是最小值。默认为0时会实时计算所有数据的平均值。 | -| `lineType` | | The type of line chart.
`LineType`:
- `Normal`: the normal line chart,
- `Smooth`: the smooth line chart,
- `StepStart`: step line.
- `StepMiddle`: step line.
- `StepEnd`: step line.
| -| `barType` | | 柱形图类型。
`BarType`:
- `Normal`: normal bar.
- `Zebra`: zebra bar.
- `Capsule`: capsule bar.
| -| `barPercentStack` |false | 柱形图是否为百分比堆积。相同stack的serie只要有一个barPercentStack为true,则就显示成百分比堆叠柱状图。 | -| `barWidth` |0 | The width of the bar. Adaptive when default 0. | -| `barGap` |0.1f | The gap between bars between different series, is a percent value like '0.3f' , which means 30% of the bar width, can be set as a fixed value. Set barGap as '-1' can overlap bars that belong to different series, which is useful when making a series of bar be background. In a single coodinate system, this attribute is shared by multiple 'bar' series. This attribute should be set on the last 'bar' series in the coodinate system, then it will be adopted by all 'bar' series in the coordinate system. | -| `barZebraWidth` |4f | 斑马线的粗细。 | -| `barZebraGap` |2f | 斑马线的间距。 | -| `min` | | 最小值。 | -| `max` | | 最大值。 | -| `minSize` |0f | 数据最小值 min 映射的宽度。 | -| `maxSize` |1f | 数据最大值 max 映射的宽度。 | -| `startAngle` | | 起始角度。和时钟一样,12点钟位置是0度,顺时针到360度。 | -| `endAngle` | | 结束角度。和时钟一样,12点钟位置是0度,顺时针到360度。 | -| `minAngle` | | The minimum angle of sector(0-360). It prevents some sector from being too small when value is small. | -| `clockwise` |true | 是否顺时针。 | -| `roundCap` | | 是否开启圆弧效果。 | -| `splitNumber` | | 刻度分割段数。最大可设置36。 | -| `clickOffset` |true | Whether offset when mouse click pie chart item. | -| `roseType` | | Whether to show as Nightingale chart.
`RoseType`:
- `None`: Don't show as Nightingale chart.
- `Radius`: Use central angle to show the percentage of data, radius to show data size.
- `Area`: All the sectors will share the same central angle, the data size is shown only through radiuses.
| -| `gap` | | gap of item. | -| `center` | | the center of chart. | -| `radius` | | the radius of chart. | -| `showDataDimension` | | 数据项里的数据维数。 | -| `showDataName` | | 在Editor的inpsector上是否显示name参数 | -| `clip` |false | If clip the overflow on the coordinate system. | -| `ignore` |false | 是否开启忽略数据。当为 true 时,数据值为 ignoreValue 时不进行绘制。 | -| `ignoreValue` |0 | 忽略数据的默认值。当ignore为true才有效。 | -| `ignoreLineBreak` |false | 忽略数据时折线是断开还是连接。默认false为连接。 | -| `showAsPositiveNumber` |false | Show negative number as positive number. | -| `large` |true | 是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。 开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。 缺点:优化后不能自定义设置单个数据项的样式,不能显示Label。 | -| `largeThreshold` |200 | 开启大数量优化的阈值。只有当开启了large并且数据量大于该阀值时才进入性能模式。 | -| `avoidLabelOverlap` |false | 在饼图且标签外部显示的情况下,是否启用防止标签重叠策略,默认关闭,在标签拥挤重叠的情况下会挪动各个标签的位置,防止标签间的重叠。 | -| `radarType` | | 雷达图类型。
`RadarType`:
- `Multiple`: multiple radar.
- `Single`: single radar.
| -| `placeHolder` |false | 占位模式。占位模式时,数据有效但不参与渲染和显示。 | -| `dataSortType` | | 组件的数据排序。
`SerieDataSortType`:
- `None`: 按 data 的顺序
- `Ascending`: 升序
- `Descending`: 降序
| -| `orient` | | 组件的朝向。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `align` | | 组件水平方向对齐方式。
`Align`:
- `Center`: 对齐方式
- `Left`: 对齐方式
- `Right`: 对齐方式
| -| `left` | | Distance between component and the left side of the container. | -| `right` | | Distance between component and the right side of the container. | -| `top` | | Distance between component and the top side of the container. | -| `bottom` | | Distance between component and the bottom side of the container. | -| `insertDataToHead` | | Whether to add new data at the head or at the end of the list. | -| `lineStyle` | | The style of line. [LineStyle](LineStyle)| -| `symbol` | | the symbol of serie data item. [SerieSymbol](SerieSymbol)| -| `animation` | | The start animation. [AnimationStyle](AnimationStyle)| -| `itemStyle` | | The style of data item. [ItemStyle](ItemStyle)| -| `data` | | 系列中的数据内容数组。SerieData可以设置1到n维数据。 | - -## `SerieData` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -A data item of serie. - -|field|default|comment| -|--|--|--| -| `index` | | the index of SerieData. | -| `name` | | the name of data item. | -| `id` | | the id of data. | -| `parentId` | | the id of parent SerieData. | -| `ignore` | | 是否忽略数据。当为 true 时,数据不进行绘制。 | -| `selected` | | Whether the data item is selected. | -| `radius` | | 自定义半径。可用在饼图中自定义某个数据项的半径。 | -| `data` | | An arbitrary dimension data list of data item. | - -## `SerieSymbol` - -Inherits or Implemented: [SymbolStyle](#SymbolStyle),[ISerieDataComponent](#ISerieDataComponent) - -系列数据项的标记的图形 - -|field|default|comment| -|--|--|--| -| `sizeType` | | the type of symbol size.
`SymbolSizeType`:
- `Custom`: Specify constant for symbol size.
- `FromData`: Specify the dataIndex and dataScale to calculate symbol size.
- `Function`: Specify function for symbol size.
| -| `selectedSize` |0f | the size of selected symbol. | -| `dataIndex` |1 | whitch data index is when the sizeType assined as FromData. | -| `dataScale` |1 | the scale of data when sizeType assined as FromData. | -| `selectedDataScale` |1.5f | the scale of selected data when sizeType assined as FromData. | -| `sizeFunction` | | the function of size when sizeType assined as Function. | -| `selectedSizeFunction` | | the function of size when sizeType assined as Function. | -| `startIndex` | | the index start to show symbol. | -| `interval` | | the interval of show symbol. | -| `forceShowLast` |false | whether to show the last symbol. | -| `repeat` |false | 图形是否重复。 | - -## `SerieTheme` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `lineWidth` | | the color of text. | -| `lineSymbolSize` | | | -| `scatterSymbolSize` | | | -| `pieTooltipExtraRadius` | | 饼图鼠标移到高亮时的额外半径 | -| `selectedRate` |1.3f | | -| `pieSelectedOffset` | | 饼图选中时的中心点偏移 | -| `candlestickColor` |Color32(235, 84, 84, 255) | K线图阳线(涨)填充色 | -| `candlestickColor0` |Color32(71, 178, 98, 255) | K线图阴线(跌)填充色 | -| `candlestickBorderWidth` |1 | K线图边框宽度 | -| `candlestickBorderColor` |Color32(235, 84, 84, 255) | K线图阳线(跌)边框色 | -| `candlestickBorderColor0` |Color32(71, 178, 98, 255) | K线图阴线(跌)边框色 | - -## `Settings` - -Inherits or Implemented: [MainComponent](#MainComponent) - -Global parameter setting component. The default value can be used in general, and can be adjusted when necessary. - -|field|default|comment| -|--|--|--| -| `show` |true | | -| `maxPainter` |10 | max painter. | -| `reversePainter` |false | Painter是否逆序。逆序时index大的serie最先绘制。 | -| `basePainterMaterial` | | Base Pointer 材质球,设置后会影响Axis等。 | -| `seriePainterMaterial` | | Serie Pointer 材质球,设置后会影响所有Serie。 | -| `topPainterMaterial` | | Top Pointer 材质球,设置后会影响Tooltip等。 | -| `lineSmoothStyle` |3f | Curve smoothing factor. By adjusting the smoothing coefficient, the curvature of the curve can be changed, and different curves with slightly different appearance can be obtained. | -| `lineSmoothness` |2f | Smoothness of curve. The smaller the value, the smoother the curve, but the number of vertices will increase. | -| `lineSegmentDistance` |3f | The partition distance of a line segment. A line in a normal line chart is made up of many segments, the number of which is determined by the change in value. The smaller the number of segments, the higher the number of vertices. When the area with gradient is filled, the larger the value, the worse the transition effect. | -| `cicleSmoothness` |2f | the smoothess of cricle. | -| `legendIconLineWidth` |2 | the width of line serie legend. | -| `legendIconCornerRadius` | | The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)). | - -## `SimplifiedBar` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer),[ISimplifiedSerie](#ISimplifiedSerie) - - -## `SimplifiedCandlestick` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer),[ISimplifiedSerie](#ISimplifiedSerie) - - -## `SimplifiedLine` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer),[ISimplifiedSerie](#ISimplifiedSerie) - - -## `SingleAxis` - -Inherits or Implemented: [Axis](#Axis),[IUpdateRuntimeData](#IUpdateRuntimeData) - -Single axis. - -|field|default|comment| -|--|--|--| -| `orient` | | Orientation of the axis. By default, it's 'Horizontal'. You can set it to be 'Vertical' to make a vertical axis.
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `left` |0.1f | Distance between component and the left side of the container. | -| `right` |0.1f | Distance between component and the right side of the container. | -| `top` |0f | Distance between component and the top side of the container. | -| `bottom` |0.2f | Distance between component and the bottom side of the container. | -| `width` |0 | width of axis. | -| `height` |50 | height of axis. | - -## `SingleAxisCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem) - - -## `StageColor` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `percent` | | 结束位置百分比。 | -| `color` | | 颜色。 | - -## `SubTitleTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - - -## `SymbolStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -系列数据项的标记的图形 - -|field|default|comment| -|--|--|--| -| `show` |true | Whether the symbol is showed. | -| `type` | | the type of symbol.
`SymbolType`:
- `None`: 不显示标记。
- `Custom`: 自定义标记。
- `Circle`: 圆形。
- `EmptyCircle`: 空心圆。
- `Rect`: 正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。
- `EmptyRect`: 空心正方形。
- `Triangle`: 三角形。
- `EmptyTriangle`: 空心三角形。
- `Diamond`: 菱形。
- `EmptyDiamond`: 空心菱形。
- `Arrow`: 箭头。
- `EmptyArrow`: 空心箭头。
| -| `size` |0f | the size of symbol. | -| `gap` |0 | the gap of symbol and line segment. | -| `width` |0f | 图形的宽。 | -| `height` |0f | 图形的高。 | -| `offset` |Vector2.zero | 图形的偏移。 | -| `image` | | 自定义的标记图形。 | -| `imageType` | | the fill type of image. | -| `color` | | 图形的颜色。 | - -## `TextLimit` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Text character limitation and adaptation component. When the length of the text exceeds the set length, it is cropped and suffixes are appended to the end.Only valid in the category axis. - -|field|default|comment| -|--|--|--| -| `enable` |false | Whether to enable text limit. | -| `maxWidth` |0 | Set the maximum width. A default of 0 indicates automatic fetch; otherwise, custom. | -| `gap` |1 | White pixel distance at both ends. | -| `suffix` | | Suffixes when the length exceeds. | - -## `TextPadding` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Settings related to text. - -|field|default|comment| -|--|--|--| -| `show` |true | show padding. 是否显示。 | -| `top` |2 | padding of top. | -| `right` |4 | padding of right. | -| `left` |4 | padding of left. | -| `bottom` |2 | padding of bottom. | - -## `TextStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Settings related to text. - -|field|default|comment| -|--|--|--| -| `show` |true | Settings related to text. | -| `font` | | the font of text. When `null`, the theme's font is used by default. | -| `autoWrap` |false | 是否自动换行。 | -| `autoAlign` |true | 文本是否让系统自动选对齐方式。为false时才会用alignment。 | -| `rotate` |0 | Rotation of text. | -| `autoColor` |false | 是否开启自动颜色。当开启时,会自动设置颜色。 | -| `color` | | the color of text. | -| `fontSize` |0 | font size. | -| `fontStyle` | | font style. | -| `lineSpacing` |1f | text line spacing. | -| `alignment` | | 对齐方式。 | -| `tMPFont` | | the font of textmeshpro. | -| `tMPFontStyle` | | | -| `tMPAlignment` | | | - -## `Theme` - -Inherits or Implemented: [ScriptableObject](#ScriptableObject) - -Theme. - -|field|default|comment| -|--|--|--| -| `themeType` | | the theme of chart.
`ThemeType`:
- `Default`: 默认主题。
- `Light`: 亮主题。
- `Dark`: 暗主题。
- `Custom`: 自定义主题。
| -| `themeName` | | the name of theme. | -| `font` | | the font of chart text。 | -| `tMPFont` | | the font of chart text。 | -| `contrastColor` | | the contrast color of chart. | -| `backgroundColor` | | the background color of chart. | -| `colorPalette` | | The color list of palette. If no color is set in series, the colors would be adopted sequentially and circularly from this list as the colors of series. | -| `common` | | [ComponentTheme](ComponentTheme)| -| `title` | | [TitleTheme](TitleTheme)| -| `subTitle` | | [SubTitleTheme](SubTitleTheme)| -| `legend` | | [LegendTheme](LegendTheme)| -| `axis` | | [AxisTheme](AxisTheme)| -| `tooltip` | | [TooltipTheme](TooltipTheme)| -| `dataZoom` | | [DataZoomTheme](DataZoomTheme)| -| `visualMap` | | [VisualMapTheme](VisualMapTheme)| -| `serie` | | [SerieTheme](SerieTheme)| - -## `ThemeStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -Theme. - -|field|default|comment| -|--|--|--| -| `show` |true | | -| `sharedTheme` | | [Theme](Theme)| -| `transparentBackground` |false | Whether the background color is transparent. When true, the background color is not drawn. |是否透明背景颜色。当设置为true时,不绘制背景颜色。 | -| `enableCustomTheme` |false | Whether to customize theme colors. When set to true, you can use 'sync color to custom' to synchronize the theme color to the custom color. It can also be set manually. | -| `customFont` | | | -| `customBackgroundColor` | | the custom background color of chart. | -| `customColorPalette` | | | - -## `Title` - -Inherits or Implemented: [MainComponent](#MainComponent),[IPropertyChanged](#IPropertyChanged) - -Title component, including main title and subtitle. - -|field|default|comment| -|--|--|--| -| `show` |true | [default:true] Set this to false to prevent the title from showing. | -| `text` | | The main title text, supporting \n for newlines. | -| `subText` | | Subtitle text, supporting for \n for newlines. | -| `labelStyle` | | The text style of main title. [LabelStyle](LabelStyle)| -| `subLabelStyle` | | The text style of sub title. [LabelStyle](LabelStyle)| -| `itemGap` |0 | [default:8] The gap between the main title and subtitle. | -| `location` | | The location of title component. [Location](Location)| - -## `TitleStyle` - -Inherits or Implemented: [LabelStyle](#LabelStyle),[ISerieDataComponent](#ISerieDataComponent),[ISerieExtraComponent](#ISerieExtraComponent) - -the title of serie. - - -## `TitleTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - - -## `Tooltip` - -Inherits or Implemented: [MainComponent](#MainComponent) - -Tooltip component. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to show the tooltip component. | -| `type` | | Indicator type.
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `trigger` | | Type of triggering.
`Tooltip.Trigger`:
- `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.
- `None`: Trigger nothing.
| -| `itemFormatter` | | a string template formatter for a single Serie or data item content. Support for wrapping lines with \n. Template variables are {.}, {a}, {b}, {c}, {d}.
{.} is the dot of the corresponding color of a Serie that is currently indicated or whose index is 0.
{a} is the series name of the serie that is currently indicated or whose index is 0.
{b} is the name of the data item serieData that is currently indicated or whose index is 0, or a category value (such as the X-axis of a line chart).
{c} is the value of a Y-dimension (dimesion is 1) from a Serie that is currently indicated or whose index is 0.
{d} is the percentage value of Y-dimensions (dimesion is 1) from serie that is currently indicated or whose index is 0, with no % sign.
{e} is the name of the data item serieData that is currently indicated or whose index is 0.
{f} is sum of data.
{.1} represents a dot from serie corresponding color that specifies index as 1.
1 in {a1}, {b1}, {c1} represents a serie that specifies an index of 1.
{c1:2} represents the third data from serie's current indication data item indexed to 1 (a data item has multiple data, index 2 represents the third data).
{c1:2-2} represents the third data item from serie's third data item indexed to 1 (i.e., which data item must be specified to specify).
{d1:2: F2} indicates that a formatted string with a value specified separately is F2 (numericFormatter is used when numericFormatter is not specified).
{d:0.##} indicates that a formatted string with a value specified separately is 0.## (used for percentage, reserved 2 valid digits while avoiding the situation similar to "100.00%" when using f2 ).
Example: "{a}, {c}", "{a1}, {c1: f1}", "{a1}, {c1:0: f1}", "{a1} : {c1:1-1: f1}"
| -| `titleFormatter` | | The string template formatter for the tooltip title content. Support for wrapping lines with \n. The placeholder {I} can be set separately to indicate that the title is ignored and not displayed. Template see itemFormatter. | -| `marker` | | the marker of serie. | -| `fixedWidth` |0 | Fixed width. Higher priority than minWidth. | -| `fixedHeight` |0 | Fixed height. Higher priority than minHeight. | -| `minWidth` |0 | Minimum width. If fixedWidth has a value, get fixedWidth first. | -| `minHeight` |0 | Minimum height. If fixedHeight has a value, take priority over fixedHeight. | -| `numericFormatter` | | Standard numeric format string. Used to format numeric values to display as strings. Using 'Axx' form: 'A' is the single character of the format specifier, supporting 'C' currency, 'D' decimal, 'E' exponent, 'F' number of vertices, 'G' regular, 'N' digits, 'P' percentage, 'R' round tripping, 'X' hex etc. 'XX' is the precision specification, from '0' - '99'. | -| `paddingLeftRight` |10 | the text padding of left and right. defaut:5. | -| `paddingTopBottom` |10 | the text padding of top and bottom. defaut:5. | -| `ignoreDataShow` |false | Whether to show ignored data on tooltip. | -| `ignoreDataDefaultContent` | | The default display character information for ignored data. | -| `showContent` |true | 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. | -| `alwayShowContent` |false | Whether to trigger after always display. | -| `offset` |Vector2(18f, -25f) | The position offset of tooltip relative to the mouse position. | -| `backgroundImage` | | The background image of tooltip. | -| `backgroundType` | | The background type of tooltip. | -| `backgroundColor` | | The background color of tooltip. | -| `borderWidth` |2f | the width of tooltip border. | -| `fixedXEnable` |false | enable fixedX. | -| `fixedX` |0f | the x positionn of fixedX. | -| `fixedYEnable` |false | enable fixedY. | -| `fixedY` |0f | the y position of fixedY. | -| `titleHeight` |25f | height of title text. | -| `itemHeight` |25f | height of content text. | -| `borderColor` |Color32(230, 230, 230, 255) | the color of tooltip border. | -| `lineStyle` | | the line style of indicator line. [LineStyle](LineStyle)| -| `indicatorLabelStyle` | | the label style of tooltip axis indicator label. [LabelStyle](LabelStyle)| -| `titleLabelStyle` | | the textstyle of title. [LabelStyle](LabelStyle)| -| `contentLabelStyles` | | the textstyle list of content. | - -## `TooltipTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `lineType` | | the type of line. | -| `lineWidth` |1f | the width of line. | -| `lineColor` | | the color of line. | -| `areaColor` | | the color of line. | -| `labelTextColor` | | the text color of tooltip cross indicator's axis label. | -| `labelBackgroundColor` | | the background color of tooltip cross indicator's axis label. | - -## `VisualMap` - -Inherits or Implemented: [MainComponent](#MainComponent) - -VisualMap component. Mapping data to visual elements such as colors. - -|field|default|comment| -|--|--|--| -| `show` |true | Whether to enable components. | -| `showUI` |false | Whether to display components. If set to false, it will not show up, but the data mapping function still exists. | -| `type` | | the type of visualmap component.
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `selectedMode` | | the selected mode for Piecewise visualMap.
`VisualMap.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
| -| `serieIndex` |0 | the serie index of visualMap. | -| `min` |0 | 范围最小值 | -| `max` |100 | 范围最大值 | -| `range` | | Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max]. | -| `text` | | Text on both ends. | -| `textGap` | | The distance between the two text bodies. | -| `splitNumber` |5 | For continuous data, it is automatically evenly divided into several segments and automatically matches the size of inRange color list when the default is 0. | -| `calculable` |false | Whether the handle used for dragging is displayed (the handle can be dragged to adjust the selected range). | -| `realtime` |true | Whether to update in real time while dragging. | -| `itemWidth` |20f | The width of the figure, that is, the width of the color bar. | -| `itemHeight` |140f | The height of the figure, that is, the height of the color bar. | -| `itemGap` |10f | 每个图元之间的间隔距离。 | -| `borderWidth` |0 | Border line width. | -| `dimension` |-1 | Specifies "which dimension" of the data to map to the visual element. "Data" is series.data. | -| `hoverLink` |true | When the hoverLink function is turned on, when the mouse hovers over the visualMap component, the corresponding value of the mouse position is highlighted in the corresponding graphic element in the diagram. | -| `autoMinMax` |true | Automatically set min, Max value 自动设置min,max的值 | -| `orient` | | Specify whether the layout of component is horizontal or vertical.
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `location` | | The location of component. [Location](Location)| -| `workOnLine` |true | Whether the visualmap is work on linestyle of linechart. | -| `workOnArea` |false | Whether the visualmap is work on areaStyle of linechart. | -| `outOfRange` | | Defines a visual color outside of the selected range. | -| `inRange` | | 分段式每一段的相关配置。 | - -## `VisualMapRange` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `min` | | 范围最小值 | -| `max` | | 范围最大值 | -| `label` | | 文字描述 | -| `color` | | 颜色 | - -## `VisualMapTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `borderWidth` | | the width of border. | -| `borderColor` | | the color of dataZoom border. | -| `backgroundColor` | | the background color of visualmap. | -| `triangeLen` |20f | 可视化组件的调节三角形边长。 | - -## `XAxis` - -Inherits or Implemented: [Axis](#Axis) - -The x axis in cartesian(rectangular) coordinate. - - -## `XCResourcesImporter` - - -## `XCSettings` - -Inherits or Implemented: [ScriptableObject](#ScriptableObject) - -|field|default|comment| -|--|--|--| -| `lang` | | [Lang](Lang)| -| `font` | | | -| `tMPFont` | | | -| `fontSizeLv1` |28 | 一级字体大小。 | -| `fontSizeLv2` |24 | | -| `fontSizeLv3` |20 | | -| `fontSizeLv4` |18 | | -| `axisLineType` | | | -| `axisLineWidth` |0.8f | | -| `axisSplitLineType` | | | -| `axisSplitLineWidth` |0.8f | | -| `axisTickWidth` |0.8f | | -| `axisTickLength` |5f | | -| `gaugeAxisLineWidth` |15f | | -| `gaugeAxisSplitLineWidth` |0.8f | | -| `gaugeAxisSplitLineLength` |15f | | -| `gaugeAxisTickWidth` |0.8f | | -| `gaugeAxisTickLength` |5f | | -| `tootipLineWidth` |0.8f | | -| `dataZoomBorderWidth` |0.5f | | -| `dataZoomDataLineWidth` |0.5f | | -| `visualMapBorderWidth` |0f | | -| `serieLineWidth` |1.8f | | -| `serieLineSymbolSize` |5f | | -| `serieScatterSymbolSize` |20f | | -| `serieSelectedRate` |1.3f | | -| `serieCandlestickBorderWidth` |1f | | -| `editorShowAllListData` |false | | -| `maxPainter` |10 | | -| `lineSmoothStyle` |3f | | -| `lineSmoothness` |2f | | -| `lineSegmentDistance` |3f | | -| `cicleSmoothness` |2f | | -| `visualMapTriangeLen` |20f | | -| `pieTooltipExtraRadius` |8f | | -| `pieSelectedOffset` |8f | | -| `customThemes` | | | - -## `YAxis` - -Inherits or Implemented: [Axis](#Axis) - -The x axis in cartesian(rectangular) coordinate. - - -[XCharts Homepage](https://github.com/XCharts-Team/XCharts)
-[XCharts API](XChartsAPI-EN.md)
-[XCharts FAQ](XChartsFAQ-EN.md) diff --git a/Assets/XCharts/Documentation/XChartsConfiguration-EN.md.meta b/Assets/XCharts/Documentation/XChartsConfiguration-EN.md.meta deleted file mode 100644 index 68d7840..0000000 --- a/Assets/XCharts/Documentation/XChartsConfiguration-EN.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 1fdd2e77324c84364bf033ffefa41123 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsConfiguration-ZH.md b/Assets/XCharts/Documentation/XChartsConfiguration-ZH.md deleted file mode 100644 index dd7d5d4..0000000 --- a/Assets/XCharts/Documentation/XChartsConfiguration-ZH.md +++ /dev/null @@ -1,1528 +0,0 @@ -# 配置项手册 - -[XCharts主页](https://github.com/XCharts-Team/XCharts)
-[XChartsAPI接口](XChartsAPI-ZH.md)
-[XCharts问答](XChartsFAQ-ZH.md) - -## Serie 系列 - -- [Bar](#Bar) -- [BaseScatter](#BaseScatter) -- [Candlestick](#Candlestick) -- [EffectScatter](#EffectScatter) -- [Heatmap](#Heatmap) -- [Line](#Line) -- [Parallel](#Parallel) -- [Pie](#Pie) -- [Radar](#Radar) -- [Ring](#Ring) -- [Scatter](#Scatter) -- [Serie](#Serie) -- [SimplifiedBar](#SimplifiedBar) -- [SimplifiedCandlestick](#SimplifiedCandlestick) -- [SimplifiedLine](#SimplifiedLine) - -## Theme 主题 - -- [AngleAxisTheme](#AngleAxisTheme) -- [AxisTheme](#AxisTheme) -- [BaseAxisTheme](#BaseAxisTheme) -- [ComponentTheme](#ComponentTheme) -- [DataZoomTheme](#DataZoomTheme) -- [LegendTheme](#LegendTheme) -- [PolarAxisTheme](#PolarAxisTheme) -- [RadarAxisTheme](#RadarAxisTheme) -- [RadiusAxisTheme](#RadiusAxisTheme) -- [SerieTheme](#SerieTheme) -- [SubTitleTheme](#SubTitleTheme) -- [Theme](#Theme) -- [ThemeStyle](#ThemeStyle) -- [TitleTheme](#TitleTheme) -- [TooltipTheme](#TooltipTheme) -- [VisualMapTheme](#VisualMapTheme) - -## MainComponent 主组件 - -- [AngleAxis](#AngleAxis) -- [Axis](#Axis) -- [Background](#Background) -- [CalendarCoord](#CalendarCoord) -- [Comment](#Comment) -- [CoordSystem](#CoordSystem) -- [DataZoom](#DataZoom) -- [GridCoord](#GridCoord) -- [Legend](#Legend) -- [MarkArea](#MarkArea) -- [MarkLine](#MarkLine) -- [ParallelAxis](#ParallelAxis) -- [ParallelCoord](#ParallelCoord) -- [PolarCoord](#PolarCoord) -- [RadarCoord](#RadarCoord) -- [RadiusAxis](#RadiusAxis) -- [Settings](#Settings) -- [SingleAxis](#SingleAxis) -- [SingleAxisCoord](#SingleAxisCoord) -- [Title](#Title) -- [Tooltip](#Tooltip) -- [VisualMap](#VisualMap) -- [XAxis](#XAxis) -- [YAxis](#YAxis) - -## ChildComponent 子组件 - -- [AngleAxisTheme](#AngleAxisTheme) -- [AnimationStyle](#AnimationStyle) -- [AreaStyle](#AreaStyle) -- [ArrowStyle](#ArrowStyle) -- [AxisLabel](#AxisLabel) -- [AxisLine](#AxisLine) -- [AxisName](#AxisName) -- [AxisSplitArea](#AxisSplitArea) -- [AxisSplitLine](#AxisSplitLine) -- [AxisTheme](#AxisTheme) -- [AxisTick](#AxisTick) -- [BaseAxisTheme](#BaseAxisTheme) -- [BaseLine](#BaseLine) -- [CommentItem](#CommentItem) -- [CommentMarkStyle](#CommentMarkStyle) -- [ComponentTheme](#ComponentTheme) -- [DataZoomTheme](#DataZoomTheme) -- [Emphasis](#Emphasis) -- [EmphasisItemStyle](#EmphasisItemStyle) -- [EmphasisLabelLine](#EmphasisLabelLine) -- [EmphasisLabelStyle](#EmphasisLabelStyle) -- [EndLabelStyle](#EndLabelStyle) -- [IconStyle](#IconStyle) -- [ImageStyle](#ImageStyle) -- [ItemStyle](#ItemStyle) -- [LabelLine](#LabelLine) -- [LabelStyle](#LabelStyle) -- [LegendTheme](#LegendTheme) -- [Level](#Level) -- [LevelStyle](#LevelStyle) -- [LineArrow](#LineArrow) -- [LineStyle](#LineStyle) -- [Location](#Location) -- [MarkAreaData](#MarkAreaData) -- [MarkLineData](#MarkLineData) -- [PolarAxisTheme](#PolarAxisTheme) -- [RadarAxisTheme](#RadarAxisTheme) -- [RadiusAxisTheme](#RadiusAxisTheme) -- [SerieData](#SerieData) -- [SerieSymbol](#SerieSymbol) -- [SerieTheme](#SerieTheme) -- [StageColor](#StageColor) -- [SubTitleTheme](#SubTitleTheme) -- [SymbolStyle](#SymbolStyle) -- [TextLimit](#TextLimit) -- [TextPadding](#TextPadding) -- [TextStyle](#TextStyle) -- [ThemeStyle](#ThemeStyle) -- [TitleStyle](#TitleStyle) -- [TitleTheme](#TitleTheme) -- [TooltipTheme](#TooltipTheme) -- [VisualMapRange](#VisualMapRange) -- [VisualMapTheme](#VisualMapTheme) - -## ISerieExtraComponent Serie额外组件 - -- [AreaStyle](#AreaStyle) -- [Emphasis](#Emphasis) -- [EmphasisItemStyle](#EmphasisItemStyle) -- [EmphasisLabelLine](#EmphasisLabelLine) -- [EmphasisLabelStyle](#EmphasisLabelStyle) -- [ImageStyle](#ImageStyle) -- [LabelLine](#LabelLine) -- [LabelStyle](#LabelStyle) -- [LineArrow](#LineArrow) -- [TitleStyle](#TitleStyle) - -## ISerieDataComponent SerieData额外组件 - -- [AreaStyle](#AreaStyle) -- [Emphasis](#Emphasis) -- [EmphasisItemStyle](#EmphasisItemStyle) -- [EmphasisLabelLine](#EmphasisLabelLine) -- [EmphasisLabelStyle](#EmphasisLabelStyle) -- [ImageStyle](#ImageStyle) -- [ItemStyle](#ItemStyle) -- [LabelLine](#LabelLine) -- [LabelStyle](#LabelStyle) -- [LineStyle](#LineStyle) -- [SerieSymbol](#SerieSymbol) -- [TitleStyle](#TitleStyle) - -## Other 其他 - -- [BaseSerie](#BaseSerie) -- [ChartText](#ChartText) -- [ChildComponent](#ChildComponent) -- [DebugInfo](#DebugInfo) -- [Indicator](#Indicator) -- [Lang](#Lang) -- [LangCandlestick](#LangCandlestick) -- [LangTime](#LangTime) -- [MainComponent](#MainComponent) -- [XCResourcesImporter](#XCResourcesImporter) -- [XCSettings](#XCSettings) - -## `AngleAxis` - -Inherits or Implemented: [Axis](#Axis) - -极坐标系的角度轴。 - -|field|default|comment| -|--|--|--| -| `startAngle` |0 | 起始刻度的角度,默认为 0 度,即圆心的正右方。 | - -## `AngleAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `AnimationStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -动画表现。 - -|field|default|comment| -|--|--|--| -| `enable` |true | 是否开启动画效果。 | -| `type` | | 动画类型。
`AnimationType`:
- `Default`: 默认。内部会根据实际情况选择一种动画播放方式。
- `LeftToRight`: 从左往右播放动画。
- `BottomToTop`: 从下往上播放动画。
- `InsideOut`: 由内到外播放动画。
- `AlongPath`: 沿着路径播放动画。
- `Clockwise`: 顺时针播放动画。
| -| `easting` | | 动画的缓动效果。
`AnimationEasing`:
- `Linear`:
| -| `threshold` |2000 | 是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。 | -| `fadeInDuration` |1000 | 设定的渐入动画时长(毫秒)。如果要设置单个数据项的渐入时长,可以用代码定制:customFadeInDuration。 | -| `fadeInDelay` |0 | 渐入动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeInDelay。 | -| `fadeOutDuration` |1000f | 设定的渐出动画时长(毫秒)。如果要设置单个数据项的渐出时长,可以用代码定制:customFadeOutDuration。 | -| `fadeOutDelay` |0 | 渐出动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeOutDelay。 | -| `dataChangeEnable` |true | 是否开启数据变更动画。 | -| `dataChangeDuration` |500 | 数据变更的动画时长(毫秒)。 | -| `actualDuration` | | 实际的动画时长(毫秒)。 | - -## `AreaStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -区域填充样式。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示区域填充。 | -| `origin` | | 区域填充的起始位置。
`AreaStyle.AreaOrigin`:
- `Auto`: 填充坐标轴轴线到数据间的区域。
- `Start`: 填充坐标轴底部到数据间的区域。
- `End`: 填充坐标轴顶部到数据间的区域。
| -| `color` | | 区域填充的颜色,如果toColor不是默认值,则表示渐变色的起点颜色。 | -| `toColor` | | 渐变色的终点颜色。 | -| `opacity` |0.6f | 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 | -| `highlightColor` | | 高亮时区域填充的颜色,如果highlightToColor不是默认值,则表示渐变色的起点颜色。 | -| `highlightToColor` | | 高亮时渐变色的终点颜色。 | - -## `ArrowStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `width` |10 | 箭头宽。 | -| `height` |15 | 箭头高。 | -| `offset` |0 | 箭头偏移。 | -| `dent` |3 | 箭头的凹度。 | -| `color` |Color.clear | 箭头颜色。 | - -## `Axis` - -Inherits or Implemented: [MainComponent](#MainComponent) - -直角坐标系的坐标轴组件。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示坐标轴。 | -| `type` | | 坐标轴类型。
`Axis.AxisType`:
- `Value`:
- `Category`:
- `Log`: 对数轴。适用于对数数据。
- `Time`: 时间轴。适用于连续的时序数据。
| -| `minMaxType` | | 坐标轴刻度最大最小值显示类型。
`Axis.AxisMinMaxType`:
- `Default`: 0-最大值。
- `MinMax`: 最小值-最大值。
- `Custom`: 自定义最小值最大值。
| -| `gridIndex` | | 坐标轴所在的 grid 的索引,默认位于第一个 grid。 | -| `polarIndex` | | 坐标轴所在的 ploar 的索引,默认位于第一个 polar。 | -| `parallelIndex` | | 坐标轴所在的 parallel 的索引,默认位于第一个 parallel。 | -| `position` | | 坐标轴在Grid中的位置。
`Axis.AxisPosition`:
- `Left`: 坐标轴在Grid中的位置
- `Right`: 坐标轴在Grid中的位置
- `Bottom`: 坐标轴在Grid中的位置
- `Top`: 坐标轴在Grid中的位置
| -| `offset` | | 坐标轴相对默认位置的偏移。在相同position有多个坐标轴时有用。 | -| `min` | | 设定的坐标轴刻度最小值,当minMaxType为Custom时有效。 | -| `max` | | 设定的坐标轴刻度最大值,当minMaxType为Custom时有效。 | -| `splitNumber` |0 | 坐标轴的期望的分割段数。默认为0表示自动分割。 | -| `interval` |0 | 强制设置坐标轴分割间隔。无法在类目轴中使用。 | -| `boundaryGap` |true | 坐标轴两边是否留白。只对类目轴有效。 | -| `maxCache` |0 | The first data will be remove when the size of axis data is larger then maxCache. | -| `logBase` |10 | 对数轴的底数,只在对数轴(type:'Log')中有效。 | -| `logBaseE` |false | 对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。 | -| `ceilRate` |0 | 最大最小值向上取整的倍率。默认为0时自动计算。 | -| `inverse` |false | 是否反向坐标轴。在类目轴中无效。 | -| `clockwise` |true | 刻度增长是否按顺时针,默认顺时针。 | -| `insertDataToHead` | | 添加新数据时是在列表的头部还是尾部加入。 | -| `icons` | | 类目数据对应的图标。 | -| `data` | | 类目数据,在类目轴(type: 'category')中有效。 | -| `axisLine` | | 坐标轴轴线。 [AxisLine](AxisLine)| -| `axisName` | | 坐标轴名称。 [AxisName](AxisName)| -| `axisTick` | | 坐标轴刻度。 [AxisTick](AxisTick)| -| `axisLabel` | | 坐标轴刻度标签。 [AxisLabel](AxisLabel)| -| `splitLine` | | 坐标轴分割线。 [AxisSplitLine](AxisSplitLine)| -| `splitArea` | | 坐标轴分割区域。 [AxisSplitArea](AxisSplitArea)| - -## `AxisLabel` - -Inherits or Implemented: [LabelStyle](#LabelStyle) - -坐标轴刻度标签的相关设置。 - -|field|default|comment| -|--|--|--| -| `interval` |0 | 坐标轴刻度标签的显示间隔,在类目轴中有效。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 | -| `inside` |false | 刻度标签是否朝内,默认朝外。 | -| `showAsPositiveNumber` |false | 将负数数值显示为正数。一般和`Serie`的`showAsPositiveNumber`配合使用。 | -| `onZero` |false | 刻度标签显示在0刻度上。 | -| `showStartLabel` |true | 是否显示第一个文本。 | -| `showEndLabel` |true | 是否显示最后一个文本。 | -| `textLimit` | | 文本限制。 [TextLimit](TextLimit)| - -## `AxisLine` - -Inherits or Implemented: [BaseLine](#BaseLine) - -坐标轴轴线。 - -|field|default|comment| -|--|--|--| -| `onZero` | | X 轴或者 Y 轴的轴线是否在另一个轴的 0 刻度上,只有在另一个轴为数值轴且包含 0 刻度时有效。 | -| `showArrow` | | 是否显示箭头。 | -| `arrow` | | 轴线箭头。 [ArrowStyle](ArrowStyle)| - -## `AxisName` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -坐标轴名称。 - -|field|default|comment| -|--|--|--| -| `show` | | 是否显示坐标名称。 | -| `name` | | 坐标轴名称。 | -| `labelStyle` | | 文本样式。 [LabelStyle](LabelStyle)| - -## `AxisSplitArea` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -坐标轴在 grid 区域中的分隔区域,默认不显示。 - -|field|default|comment| -|--|--|--| -| `show` | | 是否显示分隔区域。 | -| `color` | | 分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。 | - -## `AxisSplitLine` - -Inherits or Implemented: [BaseLine](#BaseLine) - -坐标轴在 grid 区域中的分隔线。 - -|field|default|comment| -|--|--|--| -| `interval` | | 坐标轴分隔线的显示间隔。 | -| `distance` | | 刻度线与轴线的距离。 | -| `autoColor` | | 自动设置颜色。 | - -## `AxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `AxisTick` - -Inherits or Implemented: [BaseLine](#BaseLine) - -坐标轴刻度相关设置。 - -|field|default|comment| -|--|--|--| -| `alignWithLabel` | | 类目轴中在 boundaryGap 为 true 的时候有效,可以保证刻度线和标签对齐。 | -| `inside` | | 坐标轴刻度是否朝内,默认朝外。 | -| `showStartTick` | | 是否显示第一个刻度。 | -| `showEndTick` | | 是否显示最后一个刻度。 | -| `distance` | | 刻度线与轴线的距离。 | -| `splitNumber` |0 | 分隔线之间分割的刻度数。 | -| `autoColor` | | | - -## `Background` - -Inherits or Implemented: [MainComponent](#MainComponent) - -背景组件。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否启用背景组件。 | -| `image` | | 背景图。 | -| `imageType` | | 背景图填充类型。 | -| `imageColor` | | 背景图颜色。 | -| `autoColor` |true | 当background组件开启时,是否自动使用主题背景色作为backgrounnd组件的颜色。当设置为false时,用imageColor作为颜色。 | - -## `Bar` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `BaseAxisTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `lineType` | | 坐标轴线类型。 | -| `lineWidth` |1f | 坐标轴线宽。 | -| `lineLength` |0f | 坐标轴线长。 | -| `lineColor` | | 坐标轴线颜色。 | -| `splitLineType` | | 分割线线类型。 | -| `splitLineWidth` |1f | 分割线线宽。 | -| `splitLineLength` |0f | 分割线线长。 | -| `splitLineColor` | | 分割线线颜色。 | -| `tickWidth` |1f | 刻度线线宽。 | -| `tickLength` |5f | 刻度线线长。 | -| `tickColor` | | 坐标轴线颜色。 | -| `splitAreaColors` | | | - -## `BaseLine` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -线条基础配置。 - -|field|default|comment| -|--|--|--| -| `show` | | 是否显示坐标轴轴线。 | -| `lineStyle` | | 线条样式 [LineStyle](LineStyle)| - -## `BaseScatter` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `BaseSerie` - - -## `CalendarCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[IUpdateRuntimeData](#IUpdateRuntimeData),[ISerieContainer](#ISerieContainer) - - -## `Candlestick` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `ChartText` - - -## `ChildComponent` - - -## `Comment` - -Inherits or Implemented: [MainComponent](#MainComponent) - -图表注解组件。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示注解组件。 | -| `labelStyle` | | 所有组件的文本样式。 [LabelStyle](LabelStyle)| -| `markStyle` | | 所有组件的文本样式。 [CommentMarkStyle](CommentMarkStyle)| -| `items` | | | - -## `CommentItem` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -注解项。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示当前注解项。 | -| `content` | | 注解的文本内容。支持模板参数,可以参考Tooltip的itemFormatter。 | -| `position` | | 注解项的位置坐标。 | -| `markRect` | | 注解区域。 | -| `markStyle` | | 注解标记区域样式。 [CommentMarkStyle](CommentMarkStyle)| -| `labelStyle` | | 注解项的文本样式。 [LabelStyle](LabelStyle)| - -## `CommentMarkStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -注解项区域样式。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示当前注解项。 | -| `lineStyle` | | 线条样式。 [LineStyle](LineStyle)| - -## `ComponentTheme` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `font` | | 字体。 | -| `textColor` | | 文本颜色。 | -| `textBackgroundColor` | | 文本颜色。 | -| `fontSize` |18 | 文本字体大小。 | -| `tMPFont` | | 字体。 | - -## `CoordSystem` - -Inherits or Implemented: [MainComponent](#MainComponent) - -坐标系系统。 - - -## `DataZoom` - -Inherits or Implemented: [MainComponent](#MainComponent),[IUpdateRuntimeData](#IUpdateRuntimeData) - -DataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。 - -|field|default|comment| -|--|--|--| -| `enable` |true | 是否显示缩放区域。 | -| `filterMode` | | 数据过滤类型。
`DataZoom.FilterMode`:
- `Filter`: 当前数据窗口外的数据,被 过滤掉。即 会 影响其他轴的数据范围。每个数据项,只要有一个维度在数据窗口外,整个数据项就会被过滤掉。
- `WeakFilter`: 当前数据窗口外的数据,被 过滤掉。即 会 影响其他轴的数据范围。每个数据项,只有当全部维度都在数据窗口同侧外部,整个数据项才会被过滤掉。
- `Empty`: 当前数据窗口外的数据,被 设置为空。即 不会 影响其他轴的数据范围。
- `None`: 不过滤数据,只改变数轴范围。
| -| `xAxisIndexs` | | 控制的 x 轴索引列表。 | -| `yAxisIndexs` | | 控制的 y 轴索引列表。 | -| `supportInside` | | 是否支持内置。内置于坐标系中,使用户可以在坐标系上通过鼠标拖拽、鼠标滚轮、手指滑动(触屏上)来缩放或漫游坐标系。 | -| `supportInsideScroll` |true | 是否支持坐标系内滚动 | -| `supportInsideDrag` |true | 是否支持坐标系内拖拽 | -| `supportSlider` | | 是否支持滑动条。有单独的滑动条,用户在滑动条上进行缩放或漫游。 | -| `supportSelect` | | 是否支持框选。提供一个选框进行数据区域缩放。 | -| `showDataShadow` | | 是否显示数据阴影。数据阴影可以简单地反应数据走势。 | -| `showDetail` | | 是否显示detail,即拖拽时候显示详细数值信息。 | -| `zoomLock` | | 是否锁定选择区域(或叫做数据窗口)的大小。 如果设置为 true 则锁定选择区域的大小,也就是说,只能平移,不能缩放。 | -| `fillerColor` | | 数据区域颜色。 | -| `borderColor` | | 边框颜色。 | -| `borderWidth` | | 边框宽。 | -| `backgroundColor` | | 组件的背景颜色。 | -| `left` | | 组件离容器左侧的距离。 | -| `right` | | 组件离容器右侧的距离。 | -| `top` | | 组件离容器上侧的距离。 | -| `bottom` | | 组件离容器下侧的距离。 | -| `rangeMode` | | 取绝对值还是百分比。
`DataZoom.RangeMode`:
- `//Value`: The value type of start and end.取值类型
- `Percent`: 百分比。
| -| `start` | | 数据窗口范围的起始百分比。范围是:0 ~ 100。 | -| `end` | | 数据窗口范围的结束百分比。范围是:0 ~ 100。 | -| `minShowNum` |1 | 最小显示数据个数。当DataZoom放大到最大时,最小显示的数据个数。 | -| `scrollSensitivity` |1.1f | 缩放区域组件的敏感度。值越高每次缩放所代表的数据越多。 | -| `orient` | | 布局方式是横还是竖。不仅是布局方式,对于直角坐标系而言,也决定了,缺省情况控制横向数轴还是纵向数轴。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `labelStyle` | | 文本标签格式。 [LabelStyle](LabelStyle)| -| `lineStyle` | | 阴影线条样式。 [LineStyle](LineStyle)| -| `areaStyle` | | 阴影填充样式。 [AreaStyle](AreaStyle)| - -## `DataZoomTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `borderWidth` | | 边框线宽。 | -| `dataLineWidth` | | 数据阴影线宽。 | -| `fillerColor` | | 数据区域颜色。 | -| `borderColor` | | 边框颜色。 | -| `dataLineColor` | | 数据阴影的线条颜色。 | -| `dataAreaColor` | | 数据阴影的填充颜色。 | -| `backgroundColor` | | 背景颜色。 | - -## `DebugInfo` - -|field|default|comment| -|--|--|--| -| `show` |true | | -| `showDebugInfo` |false | | -| `showAllChartObject` |false | | -| `foldSeries` |false | | -| `labelStyle` | | [LabelStyle](LabelStyle)| - -## `EffectScatter` - -Inherits or Implemented: [BaseScatter](#BaseScatter) - - -## `Emphasis` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的图形样式和文本标签样式。 - -|field|default|comment| -|--|--|--| -| `show` | | 是否启用高亮样式。 | -| `label` | | 图形文本标签。 [LabelStyle](LabelStyle)| -| `labelLine` | | 图形文本引导线样式。 [LabelLine](LabelLine)| -| `itemStyle` | | 图形样式。 [ItemStyle](ItemStyle)| - -## `EmphasisItemStyle` - -Inherits or Implemented: [ItemStyle](#ItemStyle),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的图形样式 - - -## `EmphasisLabelLine` - -Inherits or Implemented: [LabelLine](#LabelLine),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的标签引导线样式 - - -## `EmphasisLabelStyle` - -Inherits or Implemented: [LabelStyle](#LabelStyle),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -高亮的标签样式 - - -## `EndLabelStyle` - -Inherits or Implemented: [LabelStyle](#LabelStyle) - - -## `GridCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[IUpdateRuntimeData](#IUpdateRuntimeData),[ISerieContainer](#ISerieContainer) - -Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart can be drawn in grid. - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示直角坐标系网格。 | -| `left` |0.1f | grid 组件离容器左侧的距离。 | -| `right` |0.08f | grid 组件离容器右侧的距离。 | -| `top` |0.22f | grid 组件离容器上侧的距离。 | -| `bottom` |0.12f | grid 组件离容器下侧的距离。 | -| `backgroundColor` | | 网格背景色,默认透明。 | -| `showBorder` |false | 是否显示网格边框。 | -| `borderWidth` |0f | 网格边框宽。 | -| `borderColor` | | 网格边框颜色。 | - -## `Heatmap` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `IconStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `show` |false | 是否显示图标。 | -| `layer` | | 显示在上层还是在下层。
`IconStyle.Layer`:
- `UnderText`: The icon is display under the label text. 图标在标签文字下
- `AboveText`: The icon is display above the label text. 图标在标签文字上
| -| `align` | | 水平方向对齐方式。
`Align`:
- `Center`: 对齐方式
- `Left`: 对齐方式
- `Right`: 对齐方式
| -| `sprite` | | 图标的图片。 | -| `type` | | 图片的显示类型。 | -| `color` | | 图标颜色。 | -| `width` |20 | 图标宽。 | -| `height` |20 | 图标高。 | -| `offset` | | 图标偏移。 | -| `autoHideWhenLabelEmpty` |false | 当label内容为空时是否自动隐藏图标 | - -## `ImageStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示图标。 | -| `sprite` | | 图标的图片。 | -| `type` | | 图片的显示类型。 | -| `autoColor` | | 是否自动颜色。 | -| `color` | | 图标颜色。 | -| `width` |0 | 图标宽。 | -| `height` |0 | 图标高。 | - -## `Indicator` - -雷达图的指示器,用来指定雷达图中的多个变量(维度)。 - -|field|default|comment| -|--|--|--| -| `name` | | | -| `max` | | 指示器的最大值,默认为 0 无限制。 | -| `min` | | 指示器的最小值,默认为 0 无限制。 | -| `range` | | 正常值范围。当数值不在这个范围时,会自动变更显示颜色。 | -| `show` | | 是否显示雷达坐标系组件。 | -| `shape` | | 雷达图绘制类型,支持 'Polygon' 和 'Circle'。
`RadarCoord.Shape`:
- `Polygon`: 雷达图绘制类型,支持 'Polygon' 和 'Circle'。
- `Circle`: 雷达图绘制类型,支持 'Polygon' 和 'Circle'。
| -| `radius` |100 | 雷达图的半径。 | -| `splitNumber` |5 | 指示器轴的分割段数。 | -| `center` | | 雷达图的中心点。数组的第一项是横坐标,第二项是纵坐标。 当值为0-1之间时表示百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。 | -| `axisLine` | | 轴线。 [AxisLine](AxisLine)| -| `axisName` | | 雷达图每个指示器名称的配置项。 [AxisName](AxisName)| -| `splitLine` | | 分割线。 [AxisSplitLine](AxisSplitLine)| -| `splitArea` | | 分割区域。 [AxisSplitArea](AxisSplitArea)| -| `indicator` |true | 是否显示指示器。 | -| `positionType` | | 显示位置类型。
`RadarCoord.PositionType`:
- `Vertice`: 显示在顶点处。
- `Between`: 显示在两者之间。
| -| `indicatorGap` |10 | 指示器和雷达的间距。 | -| `ceilRate` |0 | 最大最小值向上取整的倍率。默认为0时自动计算。 | -| `isAxisTooltip` | | 是否Tooltip显示轴线上的所有数据。 | -| `outRangeColor` |Color.red | 数值超出范围时显示的颜色。 | -| `connectCenter` |false | 数值是否连线到中心点。 | -| `lineGradient` |true | 数值线段是否需要渐变。 | -| `indicatorList` | | 指示器列表。 | - -## `ItemStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieDataComponent](#ISerieDataComponent) - -图形样式。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否启用。 | -| `color` | | 数据项颜色。 | -| `color0` | | 数据项颜色。 | -| `toColor` | | 渐变色的颜色1。 | -| `toColor2` | | 渐变色的颜色2。只在折线图中有效。 | -| `backgroundColor` | | 数据项背景颜色。 | -| `backgroundWidth` | | 数据项背景宽度。 | -| `centerColor` | | 中心区域颜色。 | -| `centerGap` | | 中心区域间隙。 | -| `borderWidth` |0 | 边框宽。 | -| `borderGap` |0 | 边框间隙。 | -| `borderColor` | | 边框的颜色。 | -| `borderColor0` | | 边框的颜色。 | -| `borderToColor` | | 边框的渐变色。 | -| `opacity` |1 | 透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 | -| `itemMarker` | | 提示框单项的字符标志。用在Tooltip中。 | -| `itemFormatter` | | 提示框单项的字符串模版格式器。具体配置参考`Tooltip`的`formatter` | -| `numericFormatter` | | 标准数字格式字符串。用于将数值格式化显示为字符串。 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings | -| `cornerRadius` | | 圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 | - -## `LabelLine` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -标签的引导线 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示视觉引导线。 | -| `lineType` | | 视觉引导线类型。
`LineType`:
- `Normal`: 普通折线图。
- `Smooth`: 平滑曲线。
- `StepStart`: 阶梯线图:当前点。
- `StepMiddle`: 阶梯线图:当前点和下一个点的中间。
- `StepEnd`: 阶梯线图:下一个拐点。
| -| `lineColor` |ChartConst.clearColor32 | 视觉引导线颜色。默认和serie一致取自调色板。 | -| `lineAngle` |0 | 视觉引导线的固定角度。对折线和曲线有效。 | -| `lineWidth` |1.0f | 视觉引导线的宽度。 | -| `lineGap` |1.0f | 视觉引导线和容器的间距。 | -| `lineLength1` |25f | 视觉引导线第一段的长度。 | -| `lineLength2` |15f | 视觉引导线第二段的长度。 | -| `startSymbol` | | 起始点的图形标记。 [SymbolStyle](SymbolStyle)| -| `endSymbol` | | 结束点的图形标记。 [SymbolStyle](SymbolStyle)| - -## `LabelStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent),[ISerieDataComponent](#ISerieDataComponent) - -图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示文本标签。 | -| `Position` | | 标签的位置。 | -| `autoOffset` |false | 是否开启自动偏移。当开启时,Y的偏移会自动判断曲线的开口来决定向上还是向下偏移。 | -| `offset` | | 距离图形元素的偏移 | -| `rotate` | | 文本的旋转。 | -| `distance` | | 距离轴线的距离。 | -| `formatter` | | 标签内容字符串模版格式器。支持用 \n 换行。 模板变量有: {.}:圆点标记。 {a}:系列名。 {a}:系列名。 {b}:类目值或数据名。 {c}:数据值。 {d}:百分比。 {e}:数据名。 {f}:数据和。 示例:“{b}:{c}” | -| `numericFormatter` | | 标准数字格式字符串。用于将数值格式化显示为字符串。 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings | -| `width` |0 | 标签的宽度。一般不用指定,不指定时则自动是文字的宽度。 | -| `height` |0 | 标签的高度。一般不用指定,不指定时则自动是文字的高度。 | -| `icon` | | 图标样式。 [IconStyle](IconStyle)| -| `background` | | 背景图样式。 [ImageStyle](ImageStyle)| -| `textPadding` | | 文本的边距。 [TextPadding](TextPadding)| -| `textStyle` | | 文本样式。 [TextStyle](TextStyle)| - -## `Lang` - -Inherits or Implemented: [ScriptableObject](#ScriptableObject) - -国际化语言表。 - - -## `LangCandlestick` - - -## `LangTime` - - -## `Legend` - -Inherits or Implemented: [MainComponent](#MainComponent),[IPropertyChanged](#IPropertyChanged) - -图例组件。 图例组件展现了不同系列的标记,颜色和名字。可以通过点击图例控制哪些系列不显示。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示图例组件。 | -| `iconType` | | 图例类型。 [default:Type.Auto]
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `selectedMode` | | 选择模式。控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。 [default:SelectedMode.Multiple]
`VisualMap.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
| -| `orient` | | 布局方式是横还是竖。 [default:Orient.Horizonal]
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `location` | | 图例显示的位置。 [default:Location.defaultTop] [Location](Location)| -| `itemWidth` |25.0f | 图例标记的图形宽度。 [default:24f] | -| `itemHeight` |12.0f | 图例标记的图形高度。 [default:12f] | -| `itemGap` |10f | 图例每项之间的间隔。横向布局时为水平间隔,纵向布局时为纵向间隔。 [default:10f] | -| `itemAutoColor` |true | 图例标记的图形是否自动匹配颜色。 [default:true] | -| `itemOpacity` |1 | 图例标记的图形的颜色透明度。 | -| `formatter` | | 图例内容字符串模版格式器。支持用 \n 换行。 模板变量为图例名称 {value}。其他模板变量参考Toolip的itemFormatter。 | -| `numericFormatter` | | 标准数字格式字符串。用于将数值格式化显示为字符串。 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings | -| `labelStyle` | | 文本样式。 [LabelStyle](LabelStyle)| -| `data` | | If data is not specified, it will be auto collected from series. | -| `icons` | | 自定义的图例标记图形。 | -| `colors` | | the colors of legend item. 图例标记的颜色列表。 | - -## `LegendTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `unableColor` | | 文本颜色。 | - -## `Level` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `label` | | 文本标签样式。 [LabelStyle](LabelStyle)| -| `upperLabel` | | 上方的文本标签样式。 [LabelStyle](LabelStyle)| -| `itemStyle` | | 数据项样式。 [ItemStyle](ItemStyle)| - -## `LevelStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `show` |false | 是否启用LevelStyle | -| `levels` | | 各层节点对应的配置。当enableLevels为true时生效,levels[0]对应的第一层的配置,levels[1]对应第二层,依次类推。当levels中没有对应层时用默认的设置。 | - -## `Line` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `LineArrow` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieExtraComponent](#ISerieExtraComponent) - -|field|default|comment| -|--|--|--| -| `show` | | 是否显示箭头。 | -| `position` | | 箭头位置。
`LabelStyle.Position`:
- `Default`: 标签的位置。
- `Outside`: 饼图扇区外侧,通过视觉引导线连到相应的扇区。
- `Inside`: 饼图扇区内部。
- `Center`: 在饼图中心位置。
- `Top`: 图形标志的顶部。
- `Bottom`: 图形标志的底部。
- `Left`: 图形标志的左边。
- `Right`: 图形标志的右边。
- `Start`: 线的起始点。
- `Middle`: 线的中点。
- `End`: 线的结束点。
| -| `arrow` | | 箭头。 [ArrowStyle](ArrowStyle)| - -## `LineStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[ISerieDataComponent](#ISerieDataComponent) - -线条样式。 注: 修改 lineStyle 中的颜色不会影响图例颜色,如果需要图例颜色和折线图颜色一致,需修改 itemStyle.color,线条颜色默认也会取该颜色。 toColor,toColor2可设置水平方向的渐变,如需要设置垂直方向的渐变,可使用VisualMap。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示线条。当作为子组件,它的父组件有参数控制是否显示时,改参数无效。 | -| `type` | | 线的类型。
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `color` | | 线的颜色。 | -| `toColor` | | 线的渐变颜色(需要水平方向渐变时)。 | -| `toColor2` | | 线的渐变颜色2(需要水平方向三个渐变色的渐变时)。 | -| `width` |0 | 线宽。 | -| `length` |0 | 线长。 | -| `opacity` |1 | 线的透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 | - -## `Location` - -Inherits or Implemented: [ChildComponent](#ChildComponent),[IPropertyChanged](#IPropertyChanged) - -位置类型。通过Align快速设置大体位置,再通过left,right,top,bottom微调具体位置。 - -|field|default|comment| -|--|--|--| -| `align` | | 对齐方式。
`Align`:
- `Center`: 对齐方式
- `Left`: 对齐方式
- `Right`: 对齐方式
| -| `left` | | 离容器左侧的距离。 | -| `right` | | 离容器右侧的距离。 | -| `top` | | 离容器上侧的距离。 | -| `bottom` | | 离容器下侧的距离。 | - -## `MainComponent` - -Inherits or Implemented: [IComparable](#IComparable) - - -## `MarkArea` - -Inherits or Implemented: [MainComponent](#MainComponent) - -图表标域,常用于标记图表中某个范围的数据。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示标域。 | -| `text` | | The text of markArea. 标域显示的文本。 | -| `serieIndex` |0 | Serie index of markArea. 标域影响的Serie索引。 | -| `start` | | 标域范围的起始数据。 [MarkAreaData](MarkAreaData)| -| `end` | | 标域范围的结束数据。 [MarkAreaData](MarkAreaData)| -| `itemStyle` | | 标域样式。 [ItemStyle](ItemStyle)| -| `label` | | 标域文本样式。 [LabelStyle](LabelStyle)| - -## `MarkAreaData` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -标域的数据。 - -|field|default|comment| -|--|--|--| -| `type` | | 特殊的标域类型,用于标注最大值最小值等。
`MarkAreaType`:
- `None`: 标域类型
- `Min`: 最小值。
- `Max`: 最大值。
- `Average`: 平均值。
- `Median`: 中位数。
| -| `name` | | 标注名称。会作为文字显示。 | -| `dimension` |1 | 从哪个维度的数据计算最大最小值等。 | -| `xPosition` | | 相对原点的 x 坐标,单位像素。当type为None时有效。 | -| `yPosition` | | 相对原点的 y 坐标,单位像素。当type为None时有效。 | -| `xValue` | | X轴上的指定值。当X轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 | -| `yValue` | | Y轴上的指定值。当Y轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 | - -## `MarkLine` - -Inherits or Implemented: [MainComponent](#MainComponent) - -图表标线。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示标线。 | -| `serieIndex` |0 | 标线影响的Serie索引。 | -| `animation` | | 标线的动画样式。 [AnimationStyle](AnimationStyle)| -| `data` | | 标线的数据列表。当数据项的group为0时,每个数据项表示一条标线;当group不为0时,相同group的两个数据项分别表 示标线的起始点和终止点来组成一条标线,此时标线的相关样式参数取起始点的参数。 | - -## `MarkLineData` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -图表标线的数据。 - -|field|default|comment| -|--|--|--| -| `type` | | 特殊的标线类型,用于标注最大值最小值等。
`MarkLineType`:
- `None`: 标线类型
- `Min`: 最小值。
- `Max`: 最大值。
- `Average`: 平均值。
- `Median`: 中位数。
| -| `name` | | 标线名称,将会作为文字显示。label的formatter可通过{b}显示名称,通过{c}显示数值。 | -| `dimension` |1 | 从哪个维度的数据计算最大最小值等。 | -| `xPosition` | | 相对原点的 x 坐标,单位像素。当type为None时有效。 | -| `yPosition` | | 相对原点的 y 坐标,单位像素。当type为None时有效。 | -| `xValue` | | X轴上的指定值。当X轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 | -| `yValue` | | Y轴上的指定值。当Y轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 | -| `group` |0 | 分组。当group不为0时,表示这个data是标线的起点或终点,group一致的data组成一条标线。 | -| `zeroPosition` |false | 是否为坐标系原点。 | -| `startSymbol` | | 起始点的图形标记。 [SymbolStyle](SymbolStyle)| -| `endSymbol` | | 结束点的图形标记。 [SymbolStyle](SymbolStyle)| -| `lineStyle` | | 标线样式。 [LineStyle](LineStyle)| -| `label` | | 文本样式。可设置position为Start、Middle和End在不同的位置显示文本。 [LabelStyle](LabelStyle)| - -## `Parallel` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `ParallelAxis` - -Inherits or Implemented: [Axis](#Axis) - - -## `ParallelCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[IUpdateRuntimeData](#IUpdateRuntimeData),[ISerieContainer](#ISerieContainer) - -Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart can be drawn in grid. - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示直角坐标系网格。 | -| `orient` | | 坐标轴朝向。默认为垂直朝向。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `left` |0.1f | grid 组件离容器左侧的距离。 | -| `right` |0.08f | grid 组件离容器右侧的距离。 | -| `top` |0.22f | grid 组件离容器上侧的距离。 | -| `bottom` |0.12f | grid 组件离容器下侧的距离。 | -| `backgroundColor` | | 网格背景色,默认透明。 | - -## `Pie` - -Inherits or Implemented: [Serie](#Serie) - - -## `PolarAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `PolarCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[ISerieContainer](#ISerieContainer) - -极坐标系组件。 极坐标系,可以用于散点图和折线图。每个极坐标系拥有一个角度轴和一个半径轴。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示极坐标。 | -| `center` | | 极坐标的中心点。数组的第一项是横坐标,第二项是纵坐标。 当值为0-1之间时表示百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。 | -| `radius` |0.35f | 极坐标的半径。 | -| `backgroundColor` | | 极坐标的背景色,默认透明。 | - -## `Radar` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer) - - -## `RadarAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `RadarCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem),[ISerieContainer](#ISerieContainer) - -Radar coordinate conponnet for radar charts. 雷达图坐标系组件,只适用于雷达图。 - - -## `RadiusAxis` - -Inherits or Implemented: [Axis](#Axis) - -极坐标系的径向轴。 - - -## `RadiusAxisTheme` - -Inherits or Implemented: [BaseAxisTheme](#BaseAxisTheme) - - -## `Ring` - -Inherits or Implemented: [Serie](#Serie) - - -## `Scatter` - -Inherits or Implemented: [BaseScatter](#BaseScatter) - - -## `Serie` - -Inherits or Implemented: [BaseSerie](#BaseSerie),[IComparable](#IComparable) - -系列。 - -|field|default|comment| -|--|--|--| -| `index` | | 系列索引。 | -| `show` |true | 系列是否显示在图表上。 | -| `coordSystem` | | 使用的坐标系。 | -| `serieType` | | 系列类型。 | -| `serieName` | | 系列名称,用于 tooltip 的显示,legend 的图例筛选。 | -| `stack` | | 数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加。 | -| `xAxisIndex` |0 | 使用X轴的index。 | -| `yAxisIndex` |0 | 使用Y轴的index。 | -| `radarIndex` |0 | 雷达图所使用的 radar 组件的 index。 | -| `vesselIndex` |0 | 水位图所使用的 vessel 组件的 index。 | -| `polarIndex` |0 | 所使用的 polar 组件的 index。 | -| `singleAxisIndex` |0 | 所使用的 singleAxis 组件的 index。 | -| `parallelIndex` |0 | 所使用的 parallel coord 组件的 index。 | -| `minShow` | | 系列所显示数据的最小索引 | -| `maxShow` | | 系列所显示数据的最大索引 | -| `maxCache` | | 系列中可缓存的最大数据量。默认为0没有限制,大于0时超过指定值会移除旧数据再插入新数据。 | -| `sampleDist` |0 | 采样的最小像素距离,默认为0时不采样。当两个数据点间的水平距离小于改值时,开启采样,保证两点间的水平距离不小于改值。 | -| `sampleType` | | 采样类型。当sampleDist大于0时有效。
`SampleType`:
- `Peak`: 取峰值。
- `Average`: 取过滤点的平均值。
- `Max`: 取过滤点的最大值。
- `Min`: 取过滤点的最小值。
- `Sum`: 取过滤点的和。
| -| `sampleAverage` |0 | 设定的采样平均值。当sampleType 为 Peak 时,用于和过滤数据的平均值做对比是取最大值还是最小值。默认为0时会实时计算所有数据的平均值。 | -| `lineType` | | 折线图样式类型。
`LineType`:
- `Normal`: 普通折线图。
- `Smooth`: 平滑曲线。
- `StepStart`: 阶梯线图:当前点。
- `StepMiddle`: 阶梯线图:当前点和下一个点的中间。
- `StepEnd`: 阶梯线图:下一个拐点。
| -| `barType` | | 柱形图类型。
`BarType`:
- `Normal`: 普通柱形图。
- `Zebra`: 斑马柱形图。
- `Capsule`: 胶囊柱形图。
| -| `barPercentStack` |false | 柱形图是否为百分比堆积。相同stack的serie只要有一个barPercentStack为true,则就显示成百分比堆叠柱状图。 | -| `barWidth` |0 | 柱条的宽度,不设时自适应。支持设置成相对于类目宽度的百分比。 | -| `barGap` |0.1f | 不同系列的柱间距离。为百分比(如 '0.3f',表示柱子宽度的 30%) 如果想要两个系列的柱子重叠,可以设置 barGap 为 '-1f'。这在用柱子做背景的时候有用。 在同一坐标系上,此属性会被多个 'bar' 系列共享。此属性应设置于此坐标系中最后一个 'bar' 系列上才会生效,并且是对此坐标系中所有 'bar' 系列生效。 | -| `barZebraWidth` |4f | 斑马线的粗细。 | -| `barZebraGap` |2f | 斑马线的间距。 | -| `min` | | 最小值。 | -| `max` | | 最大值。 | -| `minSize` |0f | 数据最小值 min 映射的宽度。 | -| `maxSize` |1f | 数据最大值 max 映射的宽度。 | -| `startAngle` | | 起始角度。和时钟一样,12点钟位置是0度,顺时针到360度。 | -| `endAngle` | | 结束角度。和时钟一样,12点钟位置是0度,顺时针到360度。 | -| `minAngle` | | 最小的扇区角度(0-360)。用于防止某个值过小导致扇区太小影响交互。 | -| `clockwise` |true | 是否顺时针。 | -| `roundCap` | | 是否开启圆弧效果。 | -| `splitNumber` | | 刻度分割段数。最大可设置36。 | -| `clickOffset` |true | 鼠标点击时是否开启偏移,一般用在PieChart图表中。 | -| `roseType` | | 是否展示成南丁格尔图,通过半径区分数据大小。
`RoseType`:
- `None`: 不展示成南丁格尔玫瑰图。
- `Radius`: 扇区圆心角展现数据的百分比,半径展现数据的大小。
- `Area`: 所有扇区圆心角相同,仅通过半径展现数据大小。
| -| `gap` | | 间距。 | -| `center` | | 中心点。 | -| `radius` | | 半径。radius[0]表示内径,radius[1]表示外径。 | -| `showDataDimension` | | 数据项里的数据维数。 | -| `showDataName` | | 在Editor的inpsector上是否显示name参数 | -| `clip` |false | 是否裁剪超出坐标系部分的图形。 | -| `ignore` |false | 是否开启忽略数据。当为 true 时,数据值为 ignoreValue 时不进行绘制。 | -| `ignoreValue` |0 | 忽略数据的默认值。当ignore为true才有效。 | -| `ignoreLineBreak` |false | 忽略数据时折线是断开还是连接。默认false为连接。 | -| `showAsPositiveNumber` |false | 将负数数值显示为正数。一般和`AxisLabel`的`showAsPositiveNumber`配合使用。仅在折线图和柱状图中有效。 | -| `large` |true | 是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。 开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。 缺点:优化后不能自定义设置单个数据项的样式,不能显示Label。 | -| `largeThreshold` |200 | 开启大数量优化的阈值。只有当开启了large并且数据量大于该阀值时才进入性能模式。 | -| `avoidLabelOverlap` |false | 在饼图且标签外部显示的情况下,是否启用防止标签重叠策略,默认关闭,在标签拥挤重叠的情况下会挪动各个标签的位置,防止标签间的重叠。 | -| `radarType` | | 雷达图类型。
`RadarType`:
- `Multiple`: 多圈雷达图。此时可一个雷达里绘制多个圈,一个serieData就可组成一个圈(多维数据)。
- `Single`: 单圈雷达图。此时一个雷达只能绘制一个圈,多个serieData组成一个圈,数据取自`data[1]`。
| -| `placeHolder` |false | 占位模式。占位模式时,数据有效但不参与渲染和显示。 | -| `dataSortType` | | 组件的数据排序。
`SerieDataSortType`:
- `None`: 按 data 的顺序
- `Ascending`: 升序
- `Descending`: 降序
| -| `orient` | | 组件的朝向。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `align` | | 组件水平方向对齐方式。
`Align`:
- `Center`: 对齐方式
- `Left`: 对齐方式
- `Right`: 对齐方式
| -| `left` | | 组件离容器左侧的距离。 | -| `right` | | 组件离容器右侧的距离。 | -| `top` | | 组件离容器上侧的距离。 | -| `bottom` | | 组件离容器下侧的距离。 | -| `insertDataToHead` | | 添加新数据时是在列表的头部还是尾部加入。 | -| `lineStyle` | | 线条样式。 [LineStyle](LineStyle)| -| `symbol` | | 标记的图形。 [SerieSymbol](SerieSymbol)| -| `animation` | | 起始动画。 [AnimationStyle](AnimationStyle)| -| `itemStyle` | | 图形样式。 [ItemStyle](ItemStyle)| -| `data` | | 系列中的数据内容数组。SerieData可以设置1到n维数据。 | - -## `SerieData` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -系列中的一个数据项。可存储数据名和1-n维个数据。 - -|field|default|comment| -|--|--|--| -| `index` | | 数据项索引。 | -| `name` | | 数据项名称。 | -| `id` | | 数据项的唯一id。唯一id不是必须设置的。 | -| `parentId` | | 父节点id。父节点id不是必须设置的。 | -| `ignore` | | 是否忽略数据。当为 true 时,数据不进行绘制。 | -| `selected` | | 该数据项是否被选中。 | -| `radius` | | 自定义半径。可用在饼图中自定义某个数据项的半径。 | -| `data` | | 可指定任意维数的数值列表。 | - -## `SerieSymbol` - -Inherits or Implemented: [SymbolStyle](#SymbolStyle),[ISerieDataComponent](#ISerieDataComponent) - -系列数据项的标记的图形 - -|field|default|comment| -|--|--|--| -| `sizeType` | | 标记图形的大小获取方式。
`SymbolSizeType`:
- `Custom`: 自定义大小。
- `FromData`: 通过 dataIndex 从数据中获取,再乘以一个比例系数 dataScale 。
- `Function`: 通过委托函数获取。
| -| `selectedSize` |0f | 被选中的标记的大小。 | -| `dataIndex` |1 | 当sizeType指定为FromData时,指定的数据源索引。 | -| `dataScale` |1 | 当sizeType指定为FromData时,指定的倍数系数。 | -| `selectedDataScale` |1.5f | 当sizeType指定为FromData时,指定的高亮倍数系数。 | -| `sizeFunction` | | 当sizeType指定为Function时,指定的委托函数。 | -| `selectedSizeFunction` | | 当sizeType指定为Function时,指定的高亮委托函数。 | -| `startIndex` | | 开始显示图形标记的索引。 | -| `interval` | | 显示图形标记的间隔。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 | -| `forceShowLast` |false | 是否强制显示最后一个图形标记。 | -| `repeat` |false | 图形是否重复。 | - -## `SerieTheme` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `lineWidth` | | 文本颜色。 | -| `lineSymbolSize` | | | -| `scatterSymbolSize` | | | -| `pieTooltipExtraRadius` | | 饼图鼠标移到高亮时的额外半径 | -| `selectedRate` |1.3f | | -| `pieSelectedOffset` | | 饼图选中时的中心点偏移 | -| `candlestickColor` |Color32(235, 84, 84, 255) | K线图阳线(涨)填充色 | -| `candlestickColor0` |Color32(71, 178, 98, 255) | K线图阴线(跌)填充色 | -| `candlestickBorderWidth` |1 | K线图边框宽度 | -| `candlestickBorderColor` |Color32(235, 84, 84, 255) | K线图阳线(跌)边框色 | -| `candlestickBorderColor0` |Color32(71, 178, 98, 255) | K线图阴线(跌)边框色 | - -## `Settings` - -Inherits or Implemented: [MainComponent](#MainComponent) - -全局参数设置组件。一般情况下可使用默认值,当有需要时可进行调整。 - -|field|default|comment| -|--|--|--| -| `show` |true | | -| `maxPainter` |10 | 设定的painter数量。 | -| `reversePainter` |false | Painter是否逆序。逆序时index大的serie最先绘制。 | -| `basePainterMaterial` | | Base Pointer 材质球,设置后会影响Axis等。 | -| `seriePainterMaterial` | | Serie Pointer 材质球,设置后会影响所有Serie。 | -| `topPainterMaterial` | | Top Pointer 材质球,设置后会影响Tooltip等。 | -| `lineSmoothStyle` |3f | 曲线平滑系数。通过调整平滑系数可以改变曲线的曲率,得到外观稍微有变化的不同曲线。 | -| `lineSmoothness` |2f | When the area with gradient is filled, the larger the value, the worse the transition effect. | -| `lineSegmentDistance` |3f | 线段的分割距离。普通折线图的线是由很多线段组成,段数由该数值决定。值越小段数越多,但顶点数也会随之增加。当开启有渐变的区域填充时,数值越大渐变过渡效果越差。 | -| `cicleSmoothness` |2f | 圆形的平滑度。数越小圆越平滑,但顶点数也会随之增加。 | -| `legendIconLineWidth` |2 | Line类型图例图标的线条宽度。 | -| `legendIconCornerRadius` | | 图例圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 | - -## `SimplifiedBar` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer),[ISimplifiedSerie](#ISimplifiedSerie) - - -## `SimplifiedCandlestick` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer),[ISimplifiedSerie](#ISimplifiedSerie) - - -## `SimplifiedLine` - -Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer),[ISimplifiedSerie](#ISimplifiedSerie) - - -## `SingleAxis` - -Inherits or Implemented: [Axis](#Axis),[IUpdateRuntimeData](#IUpdateRuntimeData) - -单轴。 - -|field|default|comment| -|--|--|--| -| `orient` | | 坐标轴朝向。默认为水平朝向。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `left` |0.1f | 组件离容器左侧的距离。 | -| `right` |0.1f | 组件离容器右侧的距离。 | -| `top` |0f | 组件离容器上侧的距离。 | -| `bottom` |0.2f | 组件离容器下侧的距离。 | -| `width` |0 | 坐标轴宽。 | -| `height` |50 | 坐标轴高。 | - -## `SingleAxisCoord` - -Inherits or Implemented: [CoordSystem](#CoordSystem) - - -## `StageColor` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `percent` | | 结束位置百分比。 | -| `color` | | 颜色。 | - -## `SubTitleTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - - -## `SymbolStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -系列数据项的标记的图形 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示标记。 | -| `type` | | 标记类型。
`SymbolType`:
- `None`: 不显示标记。
- `Custom`: 自定义标记。
- `Circle`: 圆形。
- `EmptyCircle`: 空心圆。
- `Rect`: 正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。
- `EmptyRect`: 空心正方形。
- `Triangle`: 三角形。
- `EmptyTriangle`: 空心三角形。
- `Diamond`: 菱形。
- `EmptyDiamond`: 空心菱形。
- `Arrow`: 箭头。
- `EmptyArrow`: 空心箭头。
| -| `size` |0f | 标记的大小。 | -| `gap` |0 | 图形标记和线条的间隙距离。 | -| `width` |0f | 图形的宽。 | -| `height` |0f | 图形的高。 | -| `offset` |Vector2.zero | 图形的偏移。 | -| `image` | | 自定义的标记图形。 | -| `imageType` | | 图形填充类型。 | -| `color` | | 图形的颜色。 | - -## `TextLimit` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -文本字符限制和自适应。当文本长度超过设定的长度时进行裁剪,并将后缀附加在最后。 只在类目轴中有效。 - -|field|default|comment| -|--|--|--| -| `enable` |false | 是否启用文本自适应。 [default:true] | -| `maxWidth` |0 | Clipping occurs when the width of the text is greater than this value. | -| `gap` |1 | 两边留白像素距离。 [default:10f] | -| `suffix` | | 长度超出时的后缀。 [default: "..."] | - -## `TextPadding` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -文本的内边距设置。 - -|field|default|comment| -|--|--|--| -| `show` |true | show padding. 是否显示。 | -| `top` |2 | 顶部间距。 | -| `right` |4 | 右部间距。 | -| `left` |4 | 左边间距。 | -| `bottom` |2 | 底部间距。 | - -## `TextStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -文本的相关设置。 - -|field|default|comment| -|--|--|--| -| `show` |true | 文本的相关设置。 | -| `font` | | 文本字体。 [default: null] | -| `autoWrap` |false | 是否自动换行。 | -| `autoAlign` |true | 文本是否让系统自动选对齐方式。为false时才会用alignment。 | -| `rotate` |0 | 文本的旋转。 [default: `0f`] | -| `autoColor` |false | 是否开启自动颜色。当开启时,会自动设置颜色。 | -| `color` | | 文本的颜色。 [default: `Color.clear`] | -| `fontSize` |0 | 文本字体大小。 [default: 18] | -| `fontStyle` | | 文本字体的风格。 [default: FontStyle.Normal] | -| `lineSpacing` |1f | 行间距。 [default: 1f] | -| `alignment` | | 对齐方式。 | -| `tMPFont` | | TextMeshPro字体。 | -| `tMPFontStyle` | | | -| `tMPAlignment` | | | - -## `Theme` - -Inherits or Implemented: [ScriptableObject](#ScriptableObject) - -主题相关配置。 - -|field|default|comment| -|--|--|--| -| `themeType` | | 主题类型。
`ThemeType`:
- `Default`: 默认主题。
- `Light`: 亮主题。
- `Dark`: 暗主题。
- `Custom`: 自定义主题。
| -| `themeName` | | 主题名称。 | -| `font` | | 主题字体。 | -| `tMPFont` | | 主题字体。 | -| `contrastColor` | | 对比色。 | -| `backgroundColor` | | 背景颜色。 | -| `colorPalette` | | 调色盘颜色列表。如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色。 | -| `common` | | [ComponentTheme](ComponentTheme)| -| `title` | | [TitleTheme](TitleTheme)| -| `subTitle` | | [SubTitleTheme](SubTitleTheme)| -| `legend` | | [LegendTheme](LegendTheme)| -| `axis` | | [AxisTheme](AxisTheme)| -| `tooltip` | | [TooltipTheme](TooltipTheme)| -| `dataZoom` | | [DataZoomTheme](DataZoomTheme)| -| `visualMap` | | [VisualMapTheme](VisualMapTheme)| -| `serie` | | [SerieTheme](SerieTheme)| - -## `ThemeStyle` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -主题相关配置。 - -|field|default|comment| -|--|--|--| -| `show` |true | | -| `sharedTheme` | | [Theme](Theme)| -| `transparentBackground` |false | Whether the background color is transparent. When true, the background color is not drawn. |是否透明背景颜色。当设置为true时,不绘制背景颜色。 | -| `enableCustomTheme` |false | 是否自定义主题颜色。当设置为true时,可以用‘sync color to custom’同步主题的颜色到自定义颜色。也可以手动设置。 | -| `customFont` | | | -| `customBackgroundColor` | | 自定义的背景颜色。 | -| `customColorPalette` | | | - -## `Title` - -Inherits or Implemented: [MainComponent](#MainComponent),[IPropertyChanged](#IPropertyChanged) - -标题组件,包含主标题和副标题。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示标题组件。 | -| `text` | | 主标题文本,支持使用 \n 换行。 | -| `subText` | | 副标题文本,支持使用 \n 换行。 | -| `labelStyle` | | 主标题文本样式。 [LabelStyle](LabelStyle)| -| `subLabelStyle` | | 副标题文本样式。 [LabelStyle](LabelStyle)| -| `itemGap` |0 | 主副标题之间的间距。 | -| `location` | | 标题显示位置。 [Location](Location)| - -## `TitleStyle` - -Inherits or Implemented: [LabelStyle](#LabelStyle),[ISerieDataComponent](#ISerieDataComponent),[ISerieExtraComponent](#ISerieExtraComponent) - -标题相关设置。 - - -## `TitleTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - - -## `Tooltip` - -Inherits or Implemented: [MainComponent](#MainComponent) - -提示框组件。 - -|field|default|comment| -|--|--|--| -| `show` |true | 是否显示提示框组件。 | -| `type` | | 提示框指示器类型。
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `trigger` | | 触发类型。
`Tooltip.Trigger`:
- `Item`: 数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。
- `Axis`: 坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。
- `None`: 什么都不触发。
| -| `itemFormatter` | | 提示框单个serie或数据项内容的字符串模版格式器。支持用 \n 换行。 模板变量有{.}、{a}、{b}、{c}、{d}、{e}。
{.}为当前所指示或index为0的serie的对应颜色的圆点。
{a}为当前所指示或index为0的serie的系列名name。
{b}为当前所指示或index为0的serie的数据项serieData的name,或者类目值(如折线图的X轴)。
{c}为当前所指示或index为0的serie的y维(dimesion为1)的数值。
{d}为当前所指示或index为0的serie的y维(dimesion为1)百分比值,注意不带%号。
{e}为当前所指示或index为0的serie的数据项serieData的name。
{f}为数据总和。
{.1}表示指定index为1的serie对应颜色的圆点。
{a1}、{b1}、{c1}中的1表示指定index为1的serie。
{c1:2}表示索引为1的serie的当前指示数据项的第3个数据(一个数据项有多个数据,index为2表示第3个数据)。
{c1:2-2}表示索引为1的serie的第3个数据项的第3个数据(也就是要指定第几个数据项时必须要指定第几个数据)。
{d1:2:f2}表示单独指定了数值的格式化字符串为f2(不指定时用numericFormatter)。
{d:0.##} 表示单独指定了数值的格式化字符串为 0.## (用于百分比,保留2位有效数同时又能避免使用 f2 而出现的类似于"100.00%"的情况 )。
示例:"{a}:{c}"、"{a1}:{c1:f1}"、"{a1}:{c1:0:f1}"、"{a1}:{c1:1-1:f1}" | -| `titleFormatter` | | 提示框标题内容的字符串模版格式器。支持用 \n 换行。可以单独设置占位符{i}表示忽略不显示title。 模板变量参考Toolip的itemFormatter。 | -| `marker` | | serie的符号标志。 | -| `fixedWidth` |0 | 固定宽度。比 minWidth 优先。 | -| `fixedHeight` |0 | 固定高度。比 minHeight 优先。 | -| `minWidth` |0 | 最小宽度。如若 fixedWidth 设有值,优先取 fixedWidth。 | -| `minHeight` |0 | 最小高度。如若 fixedHeight 设有值,优先取 fixedHeight。 | -| `numericFormatter` | | 标准数字格式字符串。用于将数值格式化显示为字符串。 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings | -| `paddingLeftRight` |10 | 左右边距。 | -| `paddingTopBottom` |10 | 上下边距。 | -| `ignoreDataShow` |false | 是否显示忽略数据在tooltip上。 | -| `ignoreDataDefaultContent` | | 被忽略数据的默认显示字符信息。 | -| `showContent` |true | 是否显示提示框浮层,默认显示。只需tooltip触发事件或显示axisPointer而不需要显示内容时可配置该项为false。 | -| `alwayShowContent` |false | 是否触发后一直显示提示框浮层。 | -| `offset` |Vector2(18f, -25f) | 提示框相对于鼠标位置的偏移。 | -| `backgroundImage` | | 提示框的背景图片。 | -| `backgroundType` | | 提示框的背景图片显示类型。 | -| `backgroundColor` | | 提示框的背景颜色。 | -| `borderWidth` |2f | 边框线宽。 | -| `fixedXEnable` |false | 是否固定X位置。 | -| `fixedX` |0f | 固定X位置的坐标。 | -| `fixedYEnable` |false | 是否固定Y位置。 | -| `fixedY` |0f | 固定Y位置的坐标。 | -| `titleHeight` |25f | 标题文本的高。 | -| `itemHeight` |25f | 数据项文本的高。 | -| `borderColor` |Color32(230, 230, 230, 255) | 边框颜色。 | -| `lineStyle` | | 指示线样式。 [LineStyle](LineStyle)| -| `indicatorLabelStyle` | | 提示框的坐标轴指示器文本的样式。 [LabelStyle](LabelStyle)| -| `titleLabelStyle` | | 标题的文本样式。 [LabelStyle](LabelStyle)| -| `contentLabelStyles` | | 内容部分的文本样式列表。和列一一对应。 | - -## `TooltipTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `lineType` | | 坐标轴线类型。 | -| `lineWidth` |1f | 指示线线宽。 | -| `lineColor` | | 指示线颜色。 | -| `areaColor` | | 区域指示的颜色。 | -| `labelTextColor` | | 十字指示器坐标轴标签的文本颜色。 | -| `labelBackgroundColor` | | 十字指示器坐标轴标签的背景颜色。 | - -## `VisualMap` - -Inherits or Implemented: [MainComponent](#MainComponent) - -视觉映射组件。用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。 - -|field|default|comment| -|--|--|--| -| `show` |true | 组件是否生效。 | -| `showUI` |false | 是否显示组件。如果设置为 false,不会显示,但是数据映射的功能还存在。 | -| `type` | | 组件类型。
`Painter.Type`:
- `Base`:
- `Serie`:
- `Top`:
| -| `selectedMode` | | 选择模式。
`VisualMap.SelectedMode`:
- `Multiple`: 多选。
- `Single`: 单选。
| -| `serieIndex` |0 | 影响的serie索引。 | -| `min` |0 | 范围最小值 | -| `max` |100 | 范围最大值 | -| `range` | | 指定手柄对应数值的位置。range 应在[min,max]范围内。 | -| `text` | | 两端的文本,如 ['High', 'Low']。 | -| `textGap` | | 两端文字主体之间的距离,单位为px。 | -| `splitNumber` |5 | 对于连续型数据,自动平均切分成几段,默认为0时自动匹配inRange颜色列表大小。 | -| `calculable` |false | 是否显示拖拽用的手柄(手柄能拖拽调整选中范围)。 | -| `realtime` |true | 拖拽时,是否实时更新。 | -| `itemWidth` |20f | 图形的宽度,即颜色条的宽度。 | -| `itemHeight` |140f | 图形的高度,即颜色条的高度。 | -| `itemGap` |10f | 每个图元之间的间隔距离。 | -| `borderWidth` |0 | 边框线宽,单位px。 | -| `dimension` |-1 | Starting at 1, the default is 0 to take the last dimension in data. | -| `hoverLink` |true | Conversely, when the mouse hovers over a graphic element in a diagram, the corresponding value of the visualMap component is triangulated in the corresponding position. | -| `autoMinMax` |true | Automatically set min, Max value 自动设置min,max的值 | -| `orient` | | 布局方式是横还是竖。
`Orient`:
- `Horizonal`: 水平
- `Vertical`: 垂直
| -| `location` | | 组件显示的位置。 [Location](Location)| -| `workOnLine` |true | 组件是否对LineChart的LineStyle有效。 | -| `workOnArea` |false | 组件是否对LineChart的AreaStyle有效。 | -| `outOfRange` | | 定义 在选中范围外 的视觉颜色。 | -| `inRange` | | 分段式每一段的相关配置。 | - -## `VisualMapRange` - -Inherits or Implemented: [ChildComponent](#ChildComponent) - -|field|default|comment| -|--|--|--| -| `min` | | 范围最小值 | -| `max` | | 范围最大值 | -| `label` | | 文字描述 | -| `color` | | 颜色 | - -## `VisualMapTheme` - -Inherits or Implemented: [ComponentTheme](#ComponentTheme) - -|field|default|comment| -|--|--|--| -| `borderWidth` | | 边框线宽。 | -| `borderColor` | | 边框颜色。 | -| `backgroundColor` | | 背景颜色。 | -| `triangeLen` |20f | 可视化组件的调节三角形边长。 | - -## `XAxis` - -Inherits or Implemented: [Axis](#Axis) - -直角坐标系 grid 中的 x 轴。 - - -## `XCResourcesImporter` - - -## `XCSettings` - -Inherits or Implemented: [ScriptableObject](#ScriptableObject) - -|field|default|comment| -|--|--|--| -| `lang` | | [Lang](Lang)| -| `font` | | | -| `tMPFont` | | | -| `fontSizeLv1` |28 | 一级字体大小。 | -| `fontSizeLv2` |24 | | -| `fontSizeLv3` |20 | | -| `fontSizeLv4` |18 | | -| `axisLineType` | | | -| `axisLineWidth` |0.8f | | -| `axisSplitLineType` | | | -| `axisSplitLineWidth` |0.8f | | -| `axisTickWidth` |0.8f | | -| `axisTickLength` |5f | | -| `gaugeAxisLineWidth` |15f | | -| `gaugeAxisSplitLineWidth` |0.8f | | -| `gaugeAxisSplitLineLength` |15f | | -| `gaugeAxisTickWidth` |0.8f | | -| `gaugeAxisTickLength` |5f | | -| `tootipLineWidth` |0.8f | | -| `dataZoomBorderWidth` |0.5f | | -| `dataZoomDataLineWidth` |0.5f | | -| `visualMapBorderWidth` |0f | | -| `serieLineWidth` |1.8f | | -| `serieLineSymbolSize` |5f | | -| `serieScatterSymbolSize` |20f | | -| `serieSelectedRate` |1.3f | | -| `serieCandlestickBorderWidth` |1f | | -| `editorShowAllListData` |false | | -| `maxPainter` |10 | | -| `lineSmoothStyle` |3f | | -| `lineSmoothness` |2f | | -| `lineSegmentDistance` |3f | | -| `cicleSmoothness` |2f | | -| `visualMapTriangeLen` |20f | | -| `pieTooltipExtraRadius` |8f | | -| `pieSelectedOffset` |8f | | -| `customThemes` | | | - -## `YAxis` - -Inherits or Implemented: [Axis](#Axis) - -直角坐标系 grid 中的 y 轴。 - - -[XCharts主页](https://github.com/XCharts-Team/XCharts)
-[XChartsAPI接口](XChartsAPI-ZH.md)
-[XCharts问答](XChartsFAQ-ZH.md) diff --git a/Assets/XCharts/Documentation/XChartsConfiguration-ZH.md.meta b/Assets/XCharts/Documentation/XChartsConfiguration-ZH.md.meta deleted file mode 100644 index 597b60c..0000000 --- a/Assets/XCharts/Documentation/XChartsConfiguration-ZH.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 1d5cdb90dc99540768bfb21ea8243d04 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsFAQ-EN.md b/Assets/XCharts/Documentation/XChartsFAQ-EN.md deleted file mode 100644 index d3b00d5..0000000 --- a/Assets/XCharts/Documentation/XChartsFAQ-EN.md +++ /dev/null @@ -1,150 +0,0 @@ -# XCharts FAQ - -[XCharts Homepage](https://github.com/XCharts-Team/XCharts)
-[XCharts API](XChartsAPI-EN.md)
-[XCharts Configuration](XChartsConfiguration-EN.md) - -[QA 1: How to adjust the margin between the axis and the background?](#How-to-adjust-the-margin-between-the-axis-and-the=-background) -[QA 2: How to play agian the fadeIn animation?](#How-to-play-agian-the-fadeIn-animation) -[QA 3: How to customize the color of data item in line chart and pie chart?](#How-to-customize-the-color-of-data-item-in-line-chart-and-pie-chart) -[QA 4: How to formatter the text of axis label, such as add a units text?](#How-to-formatter-the-text-of-axis-label-such-as-add-a-units-text) -[QA 5: How to stack the bar of bar chart](#How-to-stack-the-bar-of-bar-chart) -[QA 6: How to make the bar serie in the same bar but not stack?](#How-to-make-the-bar-serie-in-the-same-bar-but-not-stack) -[QA 7: How to adjust the bar width and gap of barchart?](#How-to-adjust-the-bar-width-and-gap-of-barchart) -[QA 8: How to adjust the color of bar?](#How-to-adjust-the-color-of-bar) -[QA 9: Can I adjust the anchor of chart?](#Can-I-adjust-the-anchor-of-chart) -[QA 10: Can display more than 1000 data?](#Can-display-more-than-1000-data) -[QA 11: Can line chart drawing be dash, dot and dash-dot?](#Can-line-chart-drawing-be-dash-dot-and-dash-dot) -[QA 12: How to limit the value range of the Y-axis?](#How-to-limit-the-value-range-of-the-Y-axis) -[QA 13: How to customize the tick value range of value axis?](#How-to-customize-the-tick-value-range-of-value-axis) -[QA 14: How to display text at the top of data items?](#How-to-display-text-at-the-top-of-data-items) -[QA 15: How do I customize icons for data items?](#How-do-I-customize-icons-for-data-items) -[QA 16: How to anti-aliasing and make the chart smoother?](#How-to-anti-aliasing-and-make-the-chart-smoother) -[QA 17: Why does mouse over chart Tooltip not show?](#Why-does-mouse-over-chart-Tooltip-not-show) -[QA 18: How not to display the bar line of Tooltip?](#How-not-to-display-the-bar-line-of-Tooltip) -[QA 19: How do I customize the display of Tooltip?](#How-do-I-customize-the-display-of-Tooltip) -[QA 20: How do I get the Y-axis to display multiple decimal places?](#How-do-I-get-the-Y-axis-to-display-multiple-decimal-places) -[QA 21: How do I dynamically update data with code?](#How-do-I-dynamically-update-data-with-code) -[QA 22: How to display legend? Why are legends sometimes not displayed?](#How-to-display-legend?Why-are-legends-sometimes-not-displayed) -[QA 23: How to make chart as prefab?](#How-to-make-chart-as-prefab) -[QA 24: How do I draw custom graphic in chart,such as line or dot?](#How-do-I-draw-custom-content-in-chart-such-as-line-or-dot) -[QA 25: How to achieve similar data movement effect of ELECTRO cardiogram?](#How-to-achieve-similar-data-movement-effect-of-ELECTRO-cardiogram) -[QA 26: How do I use the background component? What are the conditions?](#How-do-I-use-the-background-component-What-are-the-conditions) -[QA 27: Mesh can not have more than 65000 vertices?](#Mesh-cannot-have-more-than-65000-vertices) -[QA 28: Why are the parameters set in Serie reset after they run?](#Why-are-the-parameters-set-in-Serie-reset-after-they-run) - -## How-to-adjust-the-margin-between-the-axis-and-the=-background - -A: `Grid` conponent,which can adjust the left, right, up, down margins of chart. - -## How-to-play-agian-the-fadeIn-animation - -A: call the `chart.AnimationReset()` API. - -## How-to-customize-the-color-of-data-item-in-line chart-and-pie-chart - -A: `Theme`->`colorPalette`, or the sub component `LineStyle` and `ItemStyle` of `Serie`. - -## How-to-formatter-the-text-of-axis-label-such-as-add-a-units-text - -A: Adjust `formatter` and `numericFormatter` parameter of `Legend`, `AxisLabel`, `Tooltop`, `SerieLabel`. - -## How-to-stack-the-bar-of-bar-chart - -A: Set the `stack` parameter of `Serie`, the series will stack in a bar with the same `stack`. - -## How-to-make-the-bar-serie-in-the-same-bar-but-not-stack - -A: Set the `barGap` of `Serie` to `-1`,`stack` to null. - -## How-to-adjust-the-bar-width-and-gap-of-barchart - -A: Adjust the `barWidth` and `barGap` parameter of `Serie`, the last `serie`'s `barWidth` and `barGap` are valid when multiple `serie`. - -## How-to-adjust-the-color-of-bar - -A: Adjust the `ItemStyle` of `Data` in `inspector`. - -## Can-I-adjust-the-anchor-of-chart - -A: Yes, you can set any one of 16 anchors but the value use default. - -## Can-display-more-than-1000-data - -A: Yes. But `UGUI` limits `65000` vertices to a single `Graphic`, so too much data may not be displayed completely. The sampling simplification curve can be turned on by setting the sampling distance `sampleDist`. You can also set some parameters to reduce the number of vertices in the chart to help show more data. Such as reducing the size of the chart, close or reduce the axis of the client drawing, close `Symbol` and `Label` display. A `Normal` line chart occupies fewer vertices than a `Smooth` line chart. The `1.5.0` and above versions can set `large` and `largeThreshold` parameters to enable performance mode. - -## Can-line-chart-drawing-be-dash-dot-and-dash-dot - -A: Yes. Adjust the `lineType` of `Serie`. - -## How-to-limit-the-value-range-of-the-Y-axis - -A: Select the `minMaxType` of `Axis` as `Custom`, then set `min` and `max` to the values you want. - -## How-to-customize-the-tick-value-range-of-value-axis - -A: By default, it is automatically split by the `splitNumber` of `Axis`. Also, you can customize the `interval` to the range you want. - -## How-to-display-text-at-the-top-of-data-items - -A: Adjust the `Label` of `Serie`. - -## How-do-I-customize-icons-for-data-items - -A: Set the `Icon` of `Data` in `Serie`. - -## How-to-anti-aliasing-and-make-the-chart-smoother - -A: Open the `Anti-Aliasing` setting in `Unity`. Selected the UI Canvas `Render Mode` as `Screen Space-Camera`, selected `MSAA`, set `4` times or higher anti-aliasing. The sawtooth can only be reduced and unavoidable. The higher the pixel, the less obvious the sawtooth is. - -## Why-does-mouse-over-chart-Tooltip-not-show - -A: Verify `Toolip` is opened. Verify that the parent node of chart has turned off mouse events. - -## How-not-to-display-the-bar-line-of-Tooltip - -A: Set the `type` of `Tooltup` as `None`. Or adjust the parameters of `lineStyle`. - -## How-do-I-customize-the-display-of-Tooltip - -A: See the `formatter`, `itemFormatter`, `titleFormatter` parameters of `Tooltip`. - -## How-do-I-get-the-Y-axis-to-display-multiple-decimal-places - -A: Set the `numericFormatter` parameter of `AxisLabel`. - -## How-do-I-dynamically-update-data-with-code - -A: See example: `Example01_UpdateData.cs` - -## How-to-display-legend?Why-are-legends-sometimes-not-displayed - -A: First, the `name` in `Serie` must have a value that is not null. Then set `Legend` is `show`, where `data` can be empty by default, indicating that all legends are displayed. If you only want to display part of the `Serie` legend, fill in `data` with the `name` of the legend you want to display. If none of the values in `data` are `name` of the series, the legend will not be displayed. - -## How-to-make-chart-as-prefab - -A: Before make prefab, please delete all sub gameObject under chart which auto-created by `XCharts`. - -## How-do-I-draw-custom-content-in-chart-such-as-line-or-dot - -A: Implement `onCustomDraw` of chart, see `Example12_CustomDrawing.cs`. - -## How-to-achieve-similar-data-movement-effect-of-ELECTRO-cardiogram - -A: See `Example_Dynamic.cs`. - -## How-do-I-use-the-background-component-What-are-the-conditions - -A: Setting `show` to `true` for the `background` component. - -## Mesh-cannot-have-more-than-65000-vertices - -A: This is the limit of `UGUI` on the number of vertices for a single `Graphic`. `XCharts` is draw chart on a single `Graphic`, so there is also this limitation. The solution can be referred to: [QA 10: Can display more than 1000 data](#Can-display-more-than-1000-data) - -## Why-are-the-parameters-set-in-Serie-reset-after-they-run - -A: Check whether `RemoveData()` and add new `Serie` in the code. If you want to keep the configuration of `Serie`, you can only `ClearData()` which just clear data and then readd the data to the old serie. - -[XCharts Homepage](https://github.com/XCharts-Team/XCharts)
-[XCharts API](XChartsAPI-EN.md)
-[XCharts Configuration](XChartsConfiguration-EN.md) \ No newline at end of file diff --git a/Assets/XCharts/Documentation/XChartsFAQ-EN.md.meta b/Assets/XCharts/Documentation/XChartsFAQ-EN.md.meta deleted file mode 100644 index 6474319..0000000 --- a/Assets/XCharts/Documentation/XChartsFAQ-EN.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: e803ae0ae73794ec6891fed7551fe01d -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsFAQ-ZH.md b/Assets/XCharts/Documentation/XChartsFAQ-ZH.md deleted file mode 100644 index f9d051c..0000000 --- a/Assets/XCharts/Documentation/XChartsFAQ-ZH.md +++ /dev/null @@ -1,154 +0,0 @@ -# XCharts问答 - -[XCharts主页](https://github.com/XCharts-Team/XCharts) -[XChartsAPI](XChartsAPI-ZH.md) -[XCharts配置项手册](XChartsConfiguration-ZH.md) - -[QA 1:如何调整坐标轴与背景的边距?](#如何调整坐标轴与背景的边距) -[QA 2:如何让初始动画重新播放?](#如何让初始动画重新播放) -[QA 3:如何自定义折线图、饼图等数据项的颜色?](#如何自定义折线图_饼图等数据项的颜色) -[QA 4:如何格式化文字,如我想给坐标轴标签加上单位?](#如何格式化文字_如我想给坐标轴标签加上单位) -[QA 5:如何让柱形图的柱子堆叠显示?](#如何让柱形图的柱子堆叠显示) -[QA 6:如何让柱形图的柱子同柱但不重叠?](#如何让柱形图的柱子同柱但不重叠) -[QA 7:如何调整柱形图的柱子宽度和间距?](#如何调整柱形图的柱子宽度和间距) -[QA 8:如何调整柱形图单个柱子的颜色?](#如何调整柱形图单个柱子的颜色) -[QA 9:如何调整图表的对齐方式?](#如何调整图表的对齐方式) -[QA 10:可以显示超过1000以上的大数据吗?](#可以显示超过1000以上的大数据吗) -[QA 11:折线图可以画虚线、点线、点划线吗?](#折线图可以画虚线_点线_点划线吗) -[QA 12:如何限定Y轴(Value轴)的值范围?](#如何限定Y轴的值范围) -[QA 13:如何自定义数值轴刻度大小?](#如何自定义数值轴刻度大小) -[QA 14:如何在数据项顶上显示文本?](#如何在数据项顶上显示文本) -[QA 15:如何给数据项自定义图标?](#如何给数据项自定义图标) -[QA 16:锯齿太严重,如何让图表更顺滑?](#锯齿太严重_如何让图表更顺滑) -[QA 17:为什么鼠标移上图表 Tooltip 不显示?](#为什么鼠标移上图表Tooltip不显示) -[QA 18:如何取消 Tooltip 的竖线?](#如何取消Tooltip的竖线) -[QA 19:如何自定义 Tooltip 的显示内容?](#如何自定义Tooltip的显示内容) -[QA 20:如何让Y轴(数值轴)显示多位小数?](#如何让Y轴显示多位小数) -[QA 21:如何用代码动态更新数据?](#如何用代码动态更新数据) -[QA 22:如何显示图例?为什么有时候图例无法显示?](#如何显示图例_为什么有时候图例无法显示) -[QA 23:如何做成预设?](#如何做成预设) -[QA 24:如何在图表上画点画线等自定义内容?](#如何在图表上画点画线等自定义内容) -[QA 25:如何实现心电图类似的数据移动效果?](#如何实现心电图类似的数据移动效果) -[QA 26:如何使用背景组件?有什么条件限制?](#如何使用背景组件_有什么条件限制) -[QA 27:Mesh can not have more than 65000 vertices?](#Mesh_cannot_have_more_than_65000_vertices) -[QA 28:为什么serie里设置的参数运行后又被重置了?](#为什么serie里设置的参数运行后又被重置了) - -## 如何调整坐标轴与背景的边距 - -答:`Grid`组件,可调整上下左右边距。 - -## 如何让初始动画重新播放 - -答:调用`AnimationReset()`接口。 - -## 如何自定义折线图_饼图等数据项的颜色 - -答:通过`Theme`的`colorPalette`调整,或者部分`Serie`下的`LineStyle`和`ItemStyle`。 - -## 如何格式化文字_如我想给坐标轴标签加上单位 - -答:通过`formatter`和`numericFormatter`参数,在`Legend`、`Axis`的`AxisLabel`、`Tooltop`、`Serie`的`Label`都提供该参数的配置。 - -## 如何让柱形图的柱子堆叠显示 - -答:设置`Serie`下的`stack`,`stack`相同的`serie`会堆叠显示在一个柱子上。 - -## 如何让柱形图的柱子同柱但不重叠 - -答:设置`Serie`下的`barGap`为`-1`,`stack`为空。 - -## 如何调整柱形图的柱子宽度和间距 - -答:调整`Serie`下的`barWidth`和`barGap`,多个`serie`时最后一个`serie`的`barWidth`和`barGap`有效。 - -## 如何调整柱形图单个柱子的颜色 - -答:可通过调整单个`Data`下的`ItemStyle`调整,也可以通过两个`serie`同柱不堆叠来实现,通过设置数据项为`0`来达到类似效果。 - -## 如何调整图表的对齐方式 - -答:默认为左下角对齐,暂不支持调整。可以通过包一层parent来辅助控制。(最新版本`1.5.0`及以上已支持任意锚点,可和做UI一样任意调整对其方式)。 - -## 可以显示超过1000以上的大数据吗 - -答:可以。但`UGUI`对单个`Graphic`限制`65000`个顶点,所以太多的数据不一定能显示完全。可通过设置采样距离`sampleDist`开启采样简化过密曲线。也可以通过设置一些参数来减少图表的顶点数有助于显示更多数据。如缩小图表的尺寸,关闭或减少坐标轴的客户端绘制,关闭`Serie`的`symbol`和`label`显示等。折线图的普通线图`Normal`比平滑线图`Smooth`占用顶点数更少。`1.5.0`以上版本可以设置`large`和`largeThreshold`参数来开启性能模式。 - -## 折线图可以画虚线_点线_点划线吗 - -答:可以。通过`Serie`下的`lineType`选择线条样式。当要显示的数据过多(成千以上)数据间过密时建议使用`Normal`或者`Step`样式。 - -## 如何限定Y轴的值范围 - -答:设置`Axis`下的`minMaxType`为`Custom`,自定义`min`和`max`。 - -## 如何自定义数值轴刻度大小 - -答:默认时通过`Axis`下的`splitNumer`进行自动划分。也可以设置`interval`自定义刻度大小。 - -## 如何在数据项顶上显示文本 - -答:通过设置`Serie`下的`Label`。 - -## 如何给数据项自定义图标 - -答:通过设置`Serie`的`data`下的数据项可单独设置`icon`相关参数。 - -## 锯齿太严重_如何让图表更顺滑 - -答:开启抗锯齿设置(在`Unity`里设置)。调整UI渲染模式为`Camera`模式,开启`MSAA`,设置`4`倍或更高抗锯齿。 - -## 为什么鼠标移上图表Tooltip不显示 - -答:确认`Tooltip`是否开启;确认父节点是否关闭了鼠标事件。 - -## 如何取消Tooltip的竖线 - -答:设置`Tooltip`的`type`为`None`。或者调整`lineStyle`的参数。 - -## 如何自定义Tooltip的显示内容 - -答:自定义总的内容可以通过`Tooltip`的`formatter`。如果只是想调整所有的`serie`的显示格式可以用`itemFormatter`和`titleFormatter`结合。如果想每个`serie`的显示格式不一样,可以定制`serie`的`itemStyle`里的`tooltipFormatter`。具体的用法请查阅[XCharts配置项手册](XChartsConfiguration-ZH.md)。 - -## 如何让Y轴显示多位小数 - -答:设置`Axis`下的`AxisLabel`中的`formatter`为`{value:f1}`或`{value:f2}`。`1.5.0`及以上版本通过`numericFormatter`设置。 - -## 如何用代码动态更新数据 - -答:请查阅`Example`下的代码,`Example13_LineSimple.cs`就是一个简单添加数据构建折线图的例子,其他`Demo`也都是通过代码控制不同的组件实现不同的功能,相关API请查看文档:[XChartsAPI接口](XChartsAPI-ZH.md) 。 - -## 如何显示图例_为什么有时候图例无法显示 - -答:首先,你的`serie`里的`name`需有值不为空。然后开启`Legend`显示,里面的`data`可以默认为空,表示显示所有的图例。如果你只想显示部分`serie`的图例,在`data`中填入要显示的图例的`name`即可。如果`data`中的值都不是系列的`name`,那图例就不会显示。 - -## 如何做成预设 - -答:请删除chart下所有的子组件再拖成预设。 - -## 如何在图表上画点画线等自定义内容 - -答:`XCharts`有自定义绘制回调`onCustomDraw`,具体可参考`Example12_CustomDrawing.cs` - -## 如何实现心电图类似的数据移动效果 - -答:参考`Example`目录下的`Example_Dynamic.cs`。主要通过设置`maxCache`参数实现。`axis`和`serie`都设置相同的`maxCache`。`maxCache`可固定数据个数,当数据超过设定时会先删除第一个在添加新数据,实现数据移动效果。 - -## 如何使用背景组件_有什么条件限制 - -答:设置`background`组件的`show`为`true`。 - -## 区域折线图在用半透明颜色时有时候会一条叠加的线 - -答:这是区域折线图绘制的bug。可以用浅的不透的颜色替代半透明颜色。 - -## Mesh_cannot_have_more_than_65000_vertices - -答:这是`UGUI`对单个`Graphic`的顶点数限制。`XCharts`是将图形绘制在单个`Graphic`上,所以也会有这个限制。解决的办法可以参考:[QA 10:可以显示超过1000以上的大数据吗?](#可以显示超过1000以上的大数据吗) - -## 为什么serie里设置的参数运行后又被重置了 - -答:检测下代码里是否调用了`RemoveData()`并重新添加`Serie`了。如果想保留`Serie`的配置可以只`ClearData()`,然后重新添加数据。 - -[XCharts主页](https://github.com/XCharts-Team/XCharts) -[XChartsAPI](XChartsAPI-ZH.md) -[XCharts配置项手册](XChartsConfiguration-ZH.md) diff --git a/Assets/XCharts/Documentation/XChartsFAQ-ZH.md.meta b/Assets/XCharts/Documentation/XChartsFAQ-ZH.md.meta deleted file mode 100644 index 57f6035..0000000 --- a/Assets/XCharts/Documentation/XChartsFAQ-ZH.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 4df833a2a1e6c4a7da37a08379dd2e18 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsTutorial01-EN.md b/Assets/XCharts/Documentation/XChartsTutorial01-EN.md deleted file mode 100644 index 216e3e8..0000000 --- a/Assets/XCharts/Documentation/XChartsTutorial01-EN.md +++ /dev/null @@ -1,262 +0,0 @@ -# 教程:5分钟上手 XCharts 3.0 - -[XCharts主页](https://github.com/XCharts-Team/XCharts)
-[XCharts问答](XChartsFAQ-ZH.md)
-[XChartsAPI接口](XChartsAPI-ZH.md)
-[XCharts配置项手册](XChartsConfiguration-ZH.md) - -## 获取和导入 XCharts - -XCharts可通过以下任意一种方式导入到项目: - -- 直接将XCharts源码到项目 - - 下载好XCharts源码后,直接将XCharts目录拷贝到Unity项目工程的Assets目录下。 - -- 通过`Assets/Import Package`导入XCharts - - 下载好XCharts的.unitypackage文件后,打开Unity,菜单栏 Assets-->Import Package-->选中.unitypackage导入即可开始使用XCharts。 - -- 通过`Package Manager`导入XCharts - - 对于Unity 2018.3以上版本,可通过 Package Manager来导入XCharts,打开Package Manager后,通过 `Add package form git URL...`,输入XCharts3.0的GitHub URL: `https://github.com/XCharts-Team/XCharts.git#3.0` 稍等片刻后即可使用XCharts。 - - 也可以直接将package加入到`manifest.json`文件:打开`Packages`目录下的`manifest.json`文件,在`dependencies`下加入: - - ``` json - "com.monitor1394.xcharts": "https://github.com/XCharts-Team/XCharts.git#3.0", - ``` - - 如需更新`XCharts`,删除`manifest.json`文件(部分Unity版本可能是packages-lock.json文件)的`lock`下的`com.monitor1394.xcharts`相关内容即会重新下载编译。 - -## 添加一个简单图表 - -在`Hierarchy`视图下右键或菜单栏`GameObject`下拉选择`XCharts->LineChart`,即可快速创建一个默认的折线图出来: - -![linechart1](res/linechart1.png) - -## 添加多个Seire - -在`Inspector`视图,找到`LineChart`的面板,通过`Add Serie`按钮,可以添加第二条`Line`折线: - -![op_addserie](res/op_addserie.png) -![linechart2](res/linechart2.png) - -## 添加其他组件 - -默认图表没有`Legend`,需要`Legend`组件可通过`Add Component`按钮添加: - -![op_addcomponent](res/op_addcomponent.png) - -## 添加Serie组件 - -Serie只自带了几个常见的组件,其他组件按需额外添加。比如,需要给折线图区域填充颜色,可单独给`Serie`添加`AreaStyle`组件: - -![op_addseriecomponent](res/op_addseriecomponent.png) -![linechart3](res/linechart3.png) - -## 添加SerieData组件 - -如果需要个性化定制每个数据项的配置,可以单独给每个`SerieData`添加`Component`。比如我们给折线图的第二个数据单独显示`Label`: - -![op_addseriedatacomponent](res/op_addseriedatacomponent.png) -![linechart4](res/linechart4.png) - -## 更多组件和配置参数 - -功能越丰富就越需要更多的组件和参数支持。XCharts有多达几十种的主组件和子组件,每个组件有几个至几十个不等的可配置参数,以支持各种灵活而复杂的功能。 - -首次接触XCharts者可在 `Inspector` 视图下可以添加和调整各个组件,`Game` 视图会实时反馈调整的效果,以熟悉各种组件实现的效果。各个组件的详细参数说明可查阅[XCharts配置项手册](XChartsConfiguration-ZH.md)。 - -## 如何快速调整参数 - -`XCharts`是配置参数驱动。想要什么效果,你只需要去调整对应组件下的配置参数就可以,不需要去改`Hierarchy`视图下的节点,因为那些节点是由`XCharts`内部根据配置参数生成的,即使改了也会在刷新时被还原回来。 - -快速定位你想要改的效果对应的组件。这就需要对组件有一定的了解。比如我们想要让X轴的轴线末端显示箭头,如何定位?第一步,X轴定位到`XAxis0`;第二步,轴线定位到`AxisLine`;最后,再去看`AxisLine`组件下有没有这样的参数可以实现这个效果。 - -`XCharts`提供从全局`Theme`、系列`Serie`、单个数据项`SerieData`全方位的参数配置。优先级从大到小为:`SerieData`->`Serie`->`Theme`。以`ItemStyle`的颜色为例: - -1. 如果`SerieData`的`ItemStyle`配置有非`0000`颜色值,则优先用这个颜色值。 -2. 如果`Serie`的`ItemStyle`配置有非`0000`颜色值,则优先用这个颜色值。 -3. 否则颜色值取自主题`Theme`的`Color Palette`。 - -通常颜色值为0000时表示用主题默认颜色,配置为0或null时表示用主题默认配置。 - -## 用代码添加折线图 - -给`gameObject`挂上`LineChart`脚本: - -```C# -var chart = gameObject.GetComponent(); -if (chart == null) -{ - chart = gameObject.AddComponent(); - chart.Init(); -} -``` - -调整大小: - -```C# -chart.SetSize(580, 300);//代码动态设置尺寸,或直接操作chart.rectTransform,或直接在Inspector上改 -``` - -设置标题: - -```C# -var title = chart.GetOrAddChartComponent(); -title.text = "Simple Line"; -``` - -设置提示框和图例是否显示: - -```C# -var tooltip = chart.GetOrAddChartComponent<Tooltip>(); -tooltip.show = true; - -var legend = chart.GetOrAddChartComponent<Legend>(); -legend.show = false; -``` - -设置坐标轴: - -```C# -var xAxis = chart.GetOrAddChartComponent<XAxis>(); -xAxis.splitNumber = 10; -xAxis.boundaryGap = true; -xAxis.type = Axis.AxisType.Category; - -var yAxis = chart.GetOrAddChartComponent<YAxis>(); -yAxis.type = Axis.AxisType.Value; -``` - -清空默认数据,添加`Line`类型的`Serie`用于接收数据: - -```C# -chart.RemoveData(); -chart.AddSerie<Line>("line"); -``` - -添加10个数据: - -```C# -for (int i = 0; i < 10; i++) -{ - chart.AddXAxisData("x" + i); - chart.AddData(0, Random.Range(10, 20)); -} -``` - -这样一个简单的折线图就出来了: - -![linechart-simple](res/linechart-simple.png) - -如果一个Chart里面有多个系列时,则Axis的data只需要加一次,不要多个循环加重复了。记住:Axis的数据个数要和Serie的数据个数一致。 - -完整代码请查阅`Examples`:`Example13_LineSimple.cs` - -你还可以用代码控制更多的参数,`Examples`下还有更多的其他例子,凡是`Inspector`上看到的可配置的参数,都可以通过代码来设置。[XCharts配置项手册](XChartsConfiguration-ZH.md)里面的所有参数都是可以通过代码控制的。 - -另外,除非定制,建议调用`Chart`下提供的`public`接口,特别是数据相关操作部分。这些接口内部会做一些关联处理,比如刷新图表等。常见的接口有: - -1. `chart.ClearData()`:清空图表数据(不移除Series) -2. `chart.RemoveData()`:清除图表数据(会移除所有Serie) -3. `chart.AddSerie()`:添加Serie -4. `chart.AddXAxisData()`:添加X轴数据 -5. `chart.AddData()`:添加Serie数据 -6. `chart.UpdateData()`:更新Serie数据 -7. `chart.UpdateXAxisData()`:更新X轴数据 -8. `chart.UpdateDataName()`:更新Serie数据的名字 - -XCharts内部有自动刷新机制,但也是在一定条件下。如果自己调用了内部组件的接口,碰到组件没有刷新,确实找不到原因的话,可以用以下两个接口强制刷新: - -1. `chart.RefreshAllComponent()`:刷新图表组件,会重新初始化所有组件,不建议频繁待用。 -2. `chart.RefreshChart()`:刷新图表绘制,只刷新绘制部分,不会刷新组件文本,位置等部分。 - -## 使用TextMeshPro - -XCharts支持TextMeshPro,但默认是不开启的,需要自己手动切换。可通过以下方式开启和关闭: - -![textmeshpro1](res/op_textmeshpro.png) - -开启后需要设置好TextMeshPro要用的全局字体,也可以在主题Theme里单独设置: - -![textmeshpro-font](res/op_textmeshpro3.png) - -建议在项目初就规划好是否使用TextMeshPro,并设置好字体。在已有很多图表的情况下切换TMP时,可能某些图表无法自动刷新,可以手动点击`Rebuild Chart Object`按钮来重建图表,即可正常初始化。 - -开启了TMP项目在更新XCharts时,可能会碰到丢失了TMP引用而无法编译通过的问题,可通过以下两种方式解决: - -1. 找到`XCharts.Runtime.asmdef`和`XCharts.Editor.asmdef`,手动加上 `TextMeshPro`的引用 -2. 移除`PlayerSetting`中`Scripting Define Symbols`的`dUI_TextMeshPro`宏 - -## 用代码改图表参数 - -`Inspector`上看到的所有参数都可以用代码来修改,关键是要定位好你要改的参数是在组件上、还是serie上、还是在具体的数据项上改。 - -### 改主组件上的参数 - -需要先获取组件,再修改里面的参数: - -```C# -var title = chart.GetOrAddChartComponent<Title>(); -title.text = "Simple LineChart"; -title.subText = "normal line"; - -var xAxis = chart.GetOrAddChartComponent<XAxis>(); -xAxis.splitNumber = 10; -xAxis.boundaryGap = true; -xAxis.type = Axis.AxisType.Category; -``` - -### 改Serie的参数 - -新添加的Serie: - -```C# -var serie = chart.AddSerie<Pie>(); -serie.center[0] = 0.5f; -serie.center[1] = 0.5f; -serie.radius[0] = 80; -serie.radius[1] = 90; -serie.animation.dataChangeEnable = true; -serie.roundCap = true; -``` - -已存在的Serie: - -```C# -var serie = chart.GetSerie<Pie>(); -serie.center[0] = 0.5f; -serie.center[1] = 0.5f; -serie.radius[0] = 80; -serie.radius[1] = 90; -serie.animation.dataChangeEnable = true; -serie.roundCap = true; -``` - -给Serie添加额外组件: - -```C# -serie.AddExtraComponent<AreaStyle>(); - -var label = serie1.AddExtraComponent<LabelStyle>(); -label.offset = new Vector3(0,20,0); -``` - -### 改数据项SerieData上的参数 - -```C# -var serieData = chart.AddData(0, 20); -//var serieData = serie.GetSerieData(0); //从已有数据中获取 -serieData.radius = 10; - -var itemStyle = serieData.GetOrAddComponent<ItemStyle>(); //给数据项添加ItemStyle组件 -itemStyle.color = Color.blue; - -``` - -[XCharts主页](https://github.com/XCharts-Team/XCharts)</br> -[XCharts问答](XChartsFAQ-ZH.md)</br> -[XChartsAPI接口](XChartsAPI-ZH.md)</br> -[XCharts配置项手册](XChartsConfiguration-ZH.md) diff --git a/Assets/XCharts/Documentation/XChartsTutorial01-EN.md.meta b/Assets/XCharts/Documentation/XChartsTutorial01-EN.md.meta deleted file mode 100644 index 2b2b77a..0000000 --- a/Assets/XCharts/Documentation/XChartsTutorial01-EN.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: a772f2d2a3f994d439db4a07365b9554 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/XChartsTutorial01-ZH.md b/Assets/XCharts/Documentation/XChartsTutorial01-ZH.md deleted file mode 100644 index 216e3e8..0000000 --- a/Assets/XCharts/Documentation/XChartsTutorial01-ZH.md +++ /dev/null @@ -1,262 +0,0 @@ -# 教程:5分钟上手 XCharts 3.0 - -[XCharts主页](https://github.com/XCharts-Team/XCharts)</br> -[XCharts问答](XChartsFAQ-ZH.md)</br> -[XChartsAPI接口](XChartsAPI-ZH.md)</br> -[XCharts配置项手册](XChartsConfiguration-ZH.md) - -## 获取和导入 XCharts - -XCharts可通过以下任意一种方式导入到项目: - -- 直接将XCharts源码到项目 - - 下载好XCharts源码后,直接将XCharts目录拷贝到Unity项目工程的Assets目录下。 - -- 通过`Assets/Import Package`导入XCharts - - 下载好XCharts的.unitypackage文件后,打开Unity,菜单栏 Assets-->Import Package-->选中.unitypackage导入即可开始使用XCharts。 - -- 通过`Package Manager`导入XCharts - - 对于Unity 2018.3以上版本,可通过 Package Manager来导入XCharts,打开Package Manager后,通过 `Add package form git URL...`,输入XCharts3.0的GitHub URL: `https://github.com/XCharts-Team/XCharts.git#3.0` 稍等片刻后即可使用XCharts。 - - 也可以直接将package加入到`manifest.json`文件:打开`Packages`目录下的`manifest.json`文件,在`dependencies`下加入: - - ``` json - "com.monitor1394.xcharts": "https://github.com/XCharts-Team/XCharts.git#3.0", - ``` - - 如需更新`XCharts`,删除`manifest.json`文件(部分Unity版本可能是packages-lock.json文件)的`lock`下的`com.monitor1394.xcharts`相关内容即会重新下载编译。 - -## 添加一个简单图表 - -在`Hierarchy`视图下右键或菜单栏`GameObject`下拉选择`XCharts->LineChart`,即可快速创建一个默认的折线图出来: - -![linechart1](res/linechart1.png) - -## 添加多个Seire - -在`Inspector`视图,找到`LineChart`的面板,通过`Add Serie`按钮,可以添加第二条`Line`折线: - -![op_addserie](res/op_addserie.png) -![linechart2](res/linechart2.png) - -## 添加其他组件 - -默认图表没有`Legend`,需要`Legend`组件可通过`Add Component`按钮添加: - -![op_addcomponent](res/op_addcomponent.png) - -## 添加Serie组件 - -Serie只自带了几个常见的组件,其他组件按需额外添加。比如,需要给折线图区域填充颜色,可单独给`Serie`添加`AreaStyle`组件: - -![op_addseriecomponent](res/op_addseriecomponent.png) -![linechart3](res/linechart3.png) - -## 添加SerieData组件 - -如果需要个性化定制每个数据项的配置,可以单独给每个`SerieData`添加`Component`。比如我们给折线图的第二个数据单独显示`Label`: - -![op_addseriedatacomponent](res/op_addseriedatacomponent.png) -![linechart4](res/linechart4.png) - -## 更多组件和配置参数 - -功能越丰富就越需要更多的组件和参数支持。XCharts有多达几十种的主组件和子组件,每个组件有几个至几十个不等的可配置参数,以支持各种灵活而复杂的功能。 - -首次接触XCharts者可在 `Inspector` 视图下可以添加和调整各个组件,`Game` 视图会实时反馈调整的效果,以熟悉各种组件实现的效果。各个组件的详细参数说明可查阅[XCharts配置项手册](XChartsConfiguration-ZH.md)。 - -## 如何快速调整参数 - -`XCharts`是配置参数驱动。想要什么效果,你只需要去调整对应组件下的配置参数就可以,不需要去改`Hierarchy`视图下的节点,因为那些节点是由`XCharts`内部根据配置参数生成的,即使改了也会在刷新时被还原回来。 - -快速定位你想要改的效果对应的组件。这就需要对组件有一定的了解。比如我们想要让X轴的轴线末端显示箭头,如何定位?第一步,X轴定位到`XAxis0`;第二步,轴线定位到`AxisLine`;最后,再去看`AxisLine`组件下有没有这样的参数可以实现这个效果。 - -`XCharts`提供从全局`Theme`、系列`Serie`、单个数据项`SerieData`全方位的参数配置。优先级从大到小为:`SerieData`->`Serie`->`Theme`。以`ItemStyle`的颜色为例: - -1. 如果`SerieData`的`ItemStyle`配置有非`0000`颜色值,则优先用这个颜色值。 -2. 如果`Serie`的`ItemStyle`配置有非`0000`颜色值,则优先用这个颜色值。 -3. 否则颜色值取自主题`Theme`的`Color Palette`。 - -通常颜色值为0000时表示用主题默认颜色,配置为0或null时表示用主题默认配置。 - -## 用代码添加折线图 - -给`gameObject`挂上`LineChart`脚本: - -```C# -var chart = gameObject.GetComponent<LineChart>(); -if (chart == null) -{ - chart = gameObject.AddComponent<LineChart>(); - chart.Init(); -} -``` - -调整大小: - -```C# -chart.SetSize(580, 300);//代码动态设置尺寸,或直接操作chart.rectTransform,或直接在Inspector上改 -``` - -设置标题: - -```C# -var title = chart.GetOrAddChartComponent<Title>(); -title.text = "Simple Line"; -``` - -设置提示框和图例是否显示: - -```C# -var tooltip = chart.GetOrAddChartComponent<Tooltip>(); -tooltip.show = true; - -var legend = chart.GetOrAddChartComponent<Legend>(); -legend.show = false; -``` - -设置坐标轴: - -```C# -var xAxis = chart.GetOrAddChartComponent<XAxis>(); -xAxis.splitNumber = 10; -xAxis.boundaryGap = true; -xAxis.type = Axis.AxisType.Category; - -var yAxis = chart.GetOrAddChartComponent<YAxis>(); -yAxis.type = Axis.AxisType.Value; -``` - -清空默认数据,添加`Line`类型的`Serie`用于接收数据: - -```C# -chart.RemoveData(); -chart.AddSerie<Line>("line"); -``` - -添加10个数据: - -```C# -for (int i = 0; i < 10; i++) -{ - chart.AddXAxisData("x" + i); - chart.AddData(0, Random.Range(10, 20)); -} -``` - -这样一个简单的折线图就出来了: - -![linechart-simple](res/linechart-simple.png) - -如果一个Chart里面有多个系列时,则Axis的data只需要加一次,不要多个循环加重复了。记住:Axis的数据个数要和Serie的数据个数一致。 - -完整代码请查阅`Examples`:`Example13_LineSimple.cs` - -你还可以用代码控制更多的参数,`Examples`下还有更多的其他例子,凡是`Inspector`上看到的可配置的参数,都可以通过代码来设置。[XCharts配置项手册](XChartsConfiguration-ZH.md)里面的所有参数都是可以通过代码控制的。 - -另外,除非定制,建议调用`Chart`下提供的`public`接口,特别是数据相关操作部分。这些接口内部会做一些关联处理,比如刷新图表等。常见的接口有: - -1. `chart.ClearData()`:清空图表数据(不移除Series) -2. `chart.RemoveData()`:清除图表数据(会移除所有Serie) -3. `chart.AddSerie()`:添加Serie -4. `chart.AddXAxisData()`:添加X轴数据 -5. `chart.AddData()`:添加Serie数据 -6. `chart.UpdateData()`:更新Serie数据 -7. `chart.UpdateXAxisData()`:更新X轴数据 -8. `chart.UpdateDataName()`:更新Serie数据的名字 - -XCharts内部有自动刷新机制,但也是在一定条件下。如果自己调用了内部组件的接口,碰到组件没有刷新,确实找不到原因的话,可以用以下两个接口强制刷新: - -1. `chart.RefreshAllComponent()`:刷新图表组件,会重新初始化所有组件,不建议频繁待用。 -2. `chart.RefreshChart()`:刷新图表绘制,只刷新绘制部分,不会刷新组件文本,位置等部分。 - -## 使用TextMeshPro - -XCharts支持TextMeshPro,但默认是不开启的,需要自己手动切换。可通过以下方式开启和关闭: - -![textmeshpro1](res/op_textmeshpro.png) - -开启后需要设置好TextMeshPro要用的全局字体,也可以在主题Theme里单独设置: - -![textmeshpro-font](res/op_textmeshpro3.png) - -建议在项目初就规划好是否使用TextMeshPro,并设置好字体。在已有很多图表的情况下切换TMP时,可能某些图表无法自动刷新,可以手动点击`Rebuild Chart Object`按钮来重建图表,即可正常初始化。 - -开启了TMP项目在更新XCharts时,可能会碰到丢失了TMP引用而无法编译通过的问题,可通过以下两种方式解决: - -1. 找到`XCharts.Runtime.asmdef`和`XCharts.Editor.asmdef`,手动加上 `TextMeshPro`的引用 -2. 移除`PlayerSetting`中`Scripting Define Symbols`的`dUI_TextMeshPro`宏 - -## 用代码改图表参数 - -`Inspector`上看到的所有参数都可以用代码来修改,关键是要定位好你要改的参数是在组件上、还是serie上、还是在具体的数据项上改。 - -### 改主组件上的参数 - -需要先获取组件,再修改里面的参数: - -```C# -var title = chart.GetOrAddChartComponent<Title>(); -title.text = "Simple LineChart"; -title.subText = "normal line"; - -var xAxis = chart.GetOrAddChartComponent<XAxis>(); -xAxis.splitNumber = 10; -xAxis.boundaryGap = true; -xAxis.type = Axis.AxisType.Category; -``` - -### 改Serie的参数 - -新添加的Serie: - -```C# -var serie = chart.AddSerie<Pie>(); -serie.center[0] = 0.5f; -serie.center[1] = 0.5f; -serie.radius[0] = 80; -serie.radius[1] = 90; -serie.animation.dataChangeEnable = true; -serie.roundCap = true; -``` - -已存在的Serie: - -```C# -var serie = chart.GetSerie<Pie>(); -serie.center[0] = 0.5f; -serie.center[1] = 0.5f; -serie.radius[0] = 80; -serie.radius[1] = 90; -serie.animation.dataChangeEnable = true; -serie.roundCap = true; -``` - -给Serie添加额外组件: - -```C# -serie.AddExtraComponent<AreaStyle>(); - -var label = serie1.AddExtraComponent<LabelStyle>(); -label.offset = new Vector3(0,20,0); -``` - -### 改数据项SerieData上的参数 - -```C# -var serieData = chart.AddData(0, 20); -//var serieData = serie.GetSerieData(0); //从已有数据中获取 -serieData.radius = 10; - -var itemStyle = serieData.GetOrAddComponent<ItemStyle>(); //给数据项添加ItemStyle组件 -itemStyle.color = Color.blue; - -``` - -[XCharts主页](https://github.com/XCharts-Team/XCharts)</br> -[XCharts问答](XChartsFAQ-ZH.md)</br> -[XChartsAPI接口](XChartsAPI-ZH.md)</br> -[XCharts配置项手册](XChartsConfiguration-ZH.md) diff --git a/Assets/XCharts/Documentation/XChartsTutorial01-ZH.md.meta b/Assets/XCharts/Documentation/XChartsTutorial01-ZH.md.meta deleted file mode 100644 index a0596c7..0000000 --- a/Assets/XCharts/Documentation/XChartsTutorial01-ZH.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 2ab7eabdc796a45aea5bc457dc9e27f8 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/alipay.png b/Assets/XCharts/Documentation/res/alipay.png deleted file mode 100644 index 209d49d2e4c5605934a327dfdfd32fd7ca099462..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31382 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ೢ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 diff --git a/Assets/XCharts/Documentation/res/alipay.png.meta b/Assets/XCharts/Documentation/res/alipay.png.meta deleted file mode 100644 index 04fcfd5..0000000 --- a/Assets/XCharts/Documentation/res/alipay.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 9619faeb62a184c94b83e389fd22f692 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/linechart-simple.png b/Assets/XCharts/Documentation/res/linechart-simple.png deleted file mode 100644 index 39e521fdd34dde94b01d78ac88fa6f9f4f935ae0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7058 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 diff --git a/Assets/XCharts/Documentation/res/linechart-simple.png.meta b/Assets/XCharts/Documentation/res/linechart-simple.png.meta deleted file mode 100644 index 5f03582..0000000 --- a/Assets/XCharts/Documentation/res/linechart-simple.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 1e91cbf448b1c44769054375b1686439 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/linechart.png b/Assets/XCharts/Documentation/res/linechart.png deleted file mode 100644 index 6bb2eea8433188fb0a0e3af8ab95e58075c3573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5843 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 G5B)C`4}ru0 diff --git a/Assets/XCharts/Documentation/res/linechart.png.meta b/Assets/XCharts/Documentation/res/linechart.png.meta deleted file mode 100644 index 9417852..0000000 --- a/Assets/XCharts/Documentation/res/linechart.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 172962e9e20c74c8a8428f507843b6d3 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/linechart1.png b/Assets/XCharts/Documentation/res/linechart1.png deleted file mode 100644 index 703c6902401a6c198b936ebbd765dba9c4403d96..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6903 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 diff --git a/Assets/XCharts/Documentation/res/linechart1.png.meta b/Assets/XCharts/Documentation/res/linechart1.png.meta deleted file mode 100644 index 2d41701..0000000 --- a/Assets/XCharts/Documentation/res/linechart1.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: e610f9feea0064345909b632bba12e2e -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/linechart2.png b/Assets/XCharts/Documentation/res/linechart2.png deleted file mode 100644 index 308870d8de136f37aa12845b3370c2173de1c548..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10668 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 Y-cRi^kx?T3w}lBOE2#vi6gLX|A8EfJlK=n! diff --git a/Assets/XCharts/Documentation/res/linechart2.png.meta b/Assets/XCharts/Documentation/res/linechart2.png.meta deleted file mode 100644 index 09d9eba..0000000 --- a/Assets/XCharts/Documentation/res/linechart2.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: ba7e7b5180b354b26baf5314d5da59f6 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/linechart3.png b/Assets/XCharts/Documentation/res/linechart3.png deleted file mode 100644 index a91064e4e6aa3973b78f3a0aaf2b805b1b977da4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11889 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 diff --git a/Assets/XCharts/Documentation/res/linechart3.png.meta b/Assets/XCharts/Documentation/res/linechart3.png.meta deleted file mode 100644 index e3665c6..0000000 --- a/Assets/XCharts/Documentation/res/linechart3.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 42bd080b0812b4bdcb8685adad22cd1e -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/linechart4.png b/Assets/XCharts/Documentation/res/linechart4.png deleted file mode 100644 index 929591e717de1c2aabec2cf7d98c3de7f01159c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11978 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 R|4##wl~j_b`u;26e*xQRfoA{! diff --git a/Assets/XCharts/Documentation/res/linechart4.png.meta b/Assets/XCharts/Documentation/res/linechart4.png.meta deleted file mode 100644 index 20e6da9..0000000 --- a/Assets/XCharts/Documentation/res/linechart4.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 52450d00759b44e678862b5ca8895072 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/op_addcomponent.png b/Assets/XCharts/Documentation/res/op_addcomponent.png deleted file mode 100644 index 420e39abb9ba73f4ca1fce868928ec8d8885b19b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61620 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≤32kt9$hz?37a{~ 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�+giQmB3z`g5JIG7i)l`T2R%~9qcTU7`H*{rSJa> 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 diff --git a/Assets/XCharts/Documentation/res/op_addcomponent.png.meta b/Assets/XCharts/Documentation/res/op_addcomponent.png.meta deleted file mode 100644 index 649700d..0000000 --- a/Assets/XCharts/Documentation/res/op_addcomponent.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: c7e8baa3a53ba41e9bb63d02176b87ff -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/op_addserie.png b/Assets/XCharts/Documentation/res/op_addserie.png deleted file mode 100644 index 294b5fe73c9326af56ab86185bec16c82450419f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51413 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 T8>@7s00000NkvXXu0mjfb8ER- diff --git a/Assets/XCharts/Documentation/res/op_addserie.png.meta b/Assets/XCharts/Documentation/res/op_addserie.png.meta deleted file mode 100644 index d610927..0000000 --- a/Assets/XCharts/Documentation/res/op_addserie.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 4fa12bb2901d144b88abb5f304979291 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/op_addseriecomponent.png b/Assets/XCharts/Documentation/res/op_addseriecomponent.png deleted file mode 100644 index ecc517fb1e4a5cdbf0096e2f02f925cd7e897aae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64321 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 diff --git a/Assets/XCharts/Documentation/res/op_addseriecomponent.png.meta b/Assets/XCharts/Documentation/res/op_addseriecomponent.png.meta deleted file mode 100644 index 7b2c01f..0000000 --- a/Assets/XCharts/Documentation/res/op_addseriecomponent.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: b1eb790b2091e4df380350030c6d8d8d -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/op_addseriedatacomponent.png b/Assets/XCharts/Documentation/res/op_addseriedatacomponent.png deleted file mode 100644 index 6f74e895499946d5d04d5079f7120e49e1b161f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56038 zcmaHS1yEc;)8OJ72w`yx7IuRM4X%s3dw>LYg1gJ&?zT7qf(CaMcbDMq8XyGu`M#^V zx~sanSM{piOn1*r_w-D6PtS``R+M^!Ns0*o0N%(*OQ-?>h|t$}2_5OR2Ce#H9{@lC zD9fuudU|?hW@gsbH-4|Kudc2wuB<Jutc{OP2qir!Dk`?MwN+JBb$54fZf^C%;qC41 z_xJZO80_)!sk5`QuD*VJY;0<3s;jH({OtVt`g(M9w7R<5$jIo0OQfl(>Gt;a^5SxR zeSLCba%gaHWqIY-uU`ub3vO<1-CbS1-QC+;+rNMR9vL3i*47>#8a_Eb9vm2$o1JZF zXjocY+}qpZkAM7g^Ji*m`r+Z>=<qN-J^l3b6yDc2KQ}i$J=4<C;_mLQudhEkI%aQg z9~2aHuz#?){99L7x2&uj5fO2BXSbrF!pqBRX=y1xKi}8ax2C41q@*M@B}GF+!^_hX z6%{o)I{MwacMcAYMMXs|t!)ep419ciwY9b8=H{H7oKR@w#>S?rt1BiZCN(v+v$HcD z9bNg4A2>KTMa3mdOiYQ1Nu{NwgoK1PHa7nL{yaQ91qFqytgLc!a(Q|ASy|Z>6qGqR zIkB;^U@-X8Cw5X&(y*{_K|w)jX=zhaQ!z2I<m6;YNy&x9<@opnRaLd@oIGJ+;mpje zkdROb35bb_Np5bgrKM$WAH2VRP+3`deqm{5b}l0$V|H$#qpkhr<>f(9YkXp=qqBQr za{AWFZhn5@QCelcs^%mqy}f!QA666>7iXJ)It45IQTbCf=lNDj`Sj1rxxu%bnjy2Y zXUVjurNfu|e=njbPv2{v2g=LCT3^QOovS*g9)+aMi*I6M<F0&z{u+GSYih|TZb;~P z_HKCAD|l|`o4LAw**<^yHUCmOv|BRvBA5AO60$m`?xr8M)1wnKu<?@oYc;L1|L4q0 zZs(>`#(4eEUI~1sq-ks;AmsV8xMj&7vy}a?9}DUIFV=adPC@CDyDvV4vjNdrjeS!# z`KOh`d#y_^u!`pSgrw$yxyTe)^~nC_*o0f|6uhS1I-+W;7w(zS6Oi&#Kvw@eDvpI; z&eb<u-8$?j8@A`@TGKfr8Fw2}d%huOG(5Z2J-p`c-gQ`9UTzXP<{Xe}^Ml3vZ3h6b zkS`-4s_wpgvihRL=R)3fsimifU&RsxOECCCxMXD$P4yu5C9ZIYUm96J@ox^=07}*s zL~&CjZWEY1HueYiUg_riPe(7S_fTO^pr`QD=nN70m1FE?G^_o_pYx3f6VG>t%_e!d zUXF;+e)`vM(qd_vr(-;5AxVTX-I#PR&0+3Xop6#lAMmi{$I9uvI6@<ibYa953-)d{ z4g_mJt`;^pSF5Fj5OJe@=B-${^-H9SC&@<^sPp{Ih08A5DM1HU{BJuCcAWH6ix-yF z*xBv6faZ;QC?nq)NS2~4pJ?n|>imuh5Jgw$??-V_KM6awmpcMhuQ3$s2@TF3QJ>Ng zVX3K8J<5***s6VpKkt`mx+E=rSSk`B^xU$4IjYn@HrlQhrg`ctXkA13ez##y#W<av zEE-XT%_W9+1QxOcSQqLh6y0(YXOh3$RiC(Jqj~ztVS3xBPeKd0j}5ze;f1~>YtzxM z2{TTDwfbw4Xs=*WxZ#`NI{#zvHYsV94!X9Jc*r$BTrP3!q%oyx(y2Hu`vjH8GFa>i ziawgQA;Z;dazb^uqn&;c=nX}g#nB3D`I`s~SZYl@5X>`<f+4BZTUZ>jSYa#AO1c11 z-dXb9F%q7GL!;Of9SicG1B%BpP6Pd6NWd~E9}Q6E&f-Q~=a~}{bgT)p&wikQ-ZIH% zSTL3#doct7?WKZgEIngIz3jl0>=*n%t>!_5Lin=e;uJ-pJO3;7Oo23o)w?_2(Di(6 znY<<x(o!r3FQcZR<W;~^d;mFPLa{WSO{VsiY#3!R@${i{igKVJGh!ADD`Tx1hNuuA zr?~j$gGE_E8Uek<RUDS3E>Pi!g0Bi2Tjkr25DA&h<|}T%iG$5Q**JP|JMzCbza|B6 zgrjamXcWR|*s6BN{4FhL2AkA-JhuVlt4Z`rhvzaybjtaGbd|af1p<_F0TLPSAiY~= zf~bCJmtEnIy;W3z!+j%#IPE)2SzrKf1t4Pf{7aDqTSCeE1Yd@$Wx{E{k7DthwEu@v zT1vh$%JD8=IwKw(G94uWN-(4Qf1)I`O25Kr{ueB1oN$HsqZxMM0)r4m{^wng9K0cm z(#nI?h>kGVCI>X#p9V+%Eal{?C64pOOFZ=$iMi_B%{x22z2jvyC)VVi@3h|VWC!qm zLL>5m0rTF$YxNr(HF0lA?#SM4EwVe;V#wwCl>ZC%%`(wXU#Go)B+^P;tiVINz{n(3 zlOR>FB%$$DDN0VFDI^|i&mZH%50+s)9A&+?NEZyl6+7#mE`<}$BdH>u<sSL&B)b*) zB8>~d!b&yKq^*aQ_Yqwm#Mow~s+>`MS&77o$WfYTx$jDR5iIY_zot*`nEq1YVFmIO zl@7<Uuc;N5qS*ld3;;6;+Ztx^ZJfO<(8Og9mA6y#Rd#}M_@Ub+*6UIFVS3QNZUYY? z%2}m<^V0T6A(PXfGxN5+dq?6~@;^=2J*f!(x$V5D_8&)FFjod`G($mw)N~PofIXYK zLz_@?zyosxZn1%<(Z{DL00ff4-RlNa@X(sDytU-Ub$g6?2w56XCKLM3(Fcer`%>}e zqYw1?Xa6)FG?9}5n26|B<E*4|@yk?&iQW>R%_lRoBz^RVny2<zwLJ%<L5ihde%uS} z{^d`KO@|*}(S^Z6v1l4xsJ{JRd?Rw{9j%nLs=}Frxl~SLZEsVbcV7`mGd%XF0mY{k zB7MIH3@%s4vII7El8=aj6sNP4qfk7~+6r2WKq>F^s<=Dj5ZJOVrsCSa5|SM&3nV83 zJ|X10$a9ho#VQy2fLh=1jCpP>ew5_tN>jgg2N?z7P@>FEA;FD`x~iC0RqJ(pnniS_ z=@ClR)Ze*^|EO>_T#+@rl(J*vYIYjz==s12g;Vv{zWpz!Wsjr-!<x87D&GoR!-kT} zH2^X6j`4`Y>x7wa4Zk*8l*-}NW6pLse<RMfILZsBAkM_t;G;Jl=tTcby-`1<BkP2# zT&M*chuncPQY-)yh`IBiVHs2t_HqjTQqPZ$Z<5Qs%@C#3r$H<o0<%i@y^{ZB7<qV+ zxyJiew*a*8DO>TE71~jtF#Jo<c%))<HI0Es*RaQ5(4?guiX?bXd8b17yOjH#ApD<- zuRjg3(!GRAfx8#V{Gvv*$ppg2Ak>nnU5y##Ju`$Tx?ekP26WbWzZUs)L3G|;;!8ve zWUx{MAx`E{hJ7oLRar#y&yu_hcTxSAL>9b?EUUw>_VK{<lTAc1djar}W%wC;V@W?; z)5A4x>(nBg#zoU)?3WNk%A!&wVbLHO7OM$%GMEHW1|{y(ldqS!|LxW$3*Mp|!-W70 zq$S3lvw81;dKKx2`Z3I>L6_m@t~&-&Brd;AB1ww|IaQLl=YHrHkffr5G7^@hNs7^n z>*-v_HJ}fn+Ag=4vC8#VbNGyBVg>FOn><ujo2NWa(K*Ulg&r{USv+Wra+`?~NJ9;s zpt`bYQGfd+3AeHcPC#5#8XHce3?3B9rl#`93zvdwQA8^v7mv-qOM|ft=CYw~FVh0I zx0=`Tid8DwE=~<tz5n%K-On^qia93i1=BzRbl+y<s0Et}!QNHhD3jP9i>X(cc7+EA z?vNB69OO&m>FblxI<Kn&#Q|;wpP<TkZzG+$1`{Z{Zi(S>qXcFDr1Yx3c)nDnuKCF@ zivM?d1)6?^SZ3=<j?e<5!S(xj6ah(XX!nJn$Wg+)+Hm0zG^iQw*P7-9Z8+9svK4O_ z{73ci2R4bn?rFtG%Y!A=|B8*F)g#o&ur6i}`S;Ka&OiLXLvF7#jN_gt$*JdCZ4WU= z*j|u{+NiG97+6R)Rynw(kM%^?bi7P$2}K9U4$yz^Yw8bEm7Aq$BX&gS+69w=8G?bW z4wC890_Ll;=j+kK=CjO@UrO=3rk^0$>HEu-(y~m=Or7F*P!vP$V;wzGcvs0+TYM-! z7ZuPTB#8zbID-zz(H)8ANiMh*+HiWK6OYf2qr4)Q^>EqGk|f}e%0aUsE5%>)EXY?< z>rIKCyi<&j){yjD`#d&AoXe%qMJ+l=^F6hZWPcvhg62mpCy)4A$%HhMd(aeuf8Fg= zfM;|To{r+G>LY0f<pIH?3LTKa!VrX*&5I*=Yhy8CniD#N)hfv8-%+Y&YzIs&?VdU} zpSI@!5WW;B4VV!U@c{PMhDflf-k2}1Qv(?+6+z=No?o0~?nadPzK-i5Pvhf3)yAE+ z1%H1bw-Vf!vjZGPpu@rD(_wA=hxx8;E}a<CN)jMN{zS*iWuf2C@8a*BU!5#r(*K_= zJ1lc*ozV4Hrc=-!e5`PJHF?1vC&I_fo908X^<Q4E<v!rG9QG5_Cpq8NoL4mYsrx@G ztb%g(ezuQNpo|{l3`FwmyGfCZ1$F4p&UM^l4?pM=2hdW<oc9!~3E@4fX{6uLi?4sH z{`!2F@ibHFG7B7gW}wq>7QxaJ_{9_9uD^uu3HBTUzMU2poiY;MrwiHE^D~{(!8<P> zj4x2&K}k&Bk!Xudu)6uUY-M`2bN?pF@ijEqd(YS{44LYjQ<OPuE=aSFs7yZ7^w?xo zwkep7_*0l2w|M;&pLoL4FQu8SF+6X?n_*H%jqhJGHQp<c&a^_YuvgpYb@D;3TUhjy zHuK=`N0l3J1kzj#+K0l=9Y;1y*(MWz*wUz}-6-=*nVm-HuxzX-x;Any4wA-$+p2!= zn(X%PkHP(Kq=2lEn;Yb+^4}|S(KNFSVps3=BYh}u8mzzn#76@7m>ZPjP}Ztx8=Wk~ z{~<UOjF&??cntH(^dcbb($>0nzgi5H>MW;SMTh)O_pbstXOkms@aj9;EcnRKn)0n& zQ{J+EZ#`~bt(iesKEE>P@v?8f-a~8Ya>{Ol?K(nrbH`~RTCy@LXJAYN^W;Qb1SG(s zCVp9XoC~E9c61(<(rA1j!u2J6%d5d#6su%I9xk$x1v^`Oj;xlB$<m^f{0iI*+$9cA zCKcW`o;$HFX-Zn!lLMK2OGZTxTgDTOaqR^t|40|8YA;G%KfLQUX;FNZd_e=ZjMxl& zh^(vbkS=XN0vlNn(zZ-oT<rJ58Cy5mGx(6Jzu{$~g*OC0;XzwWlU&4|^7mH-_E#h? zZazO-EgVlt8oF>QPO-o+51MC%x^Sq<8n(=2II(sO7+LiZU9!UU-M5`I4Q!LP$@2;B zaL?EN7#cAG3SY<}!@hJ^A(hc98s>5=1>HaBSP)oDpW_f`OaoRB<>J=!^J#}HP)cFb z)6vSD6tF?AK6Y(qDNO;~V@9ijtcq{_;Qr6E?InXKtd_+ANjYc&Izwom7{XYW@qjaY z$uKY8n{F*!pJV5FT$!fdp7*aiiu_6|VnPg*6k-XPOB!27aQz#MFhOqVY?nW+?|?D- zn`H%YInp*pb<`O8q~mKdr(^rd7`yZ*-F$ytqgWfjFT&K&Iti-@lNuXGDMERb6Q<Tq zDx3Y;7TF$KTgsznOXy#7Z)>L!N9Au=gvl@mht3X@^aj<Bg>Pl=YsPiyvp|0dV$5`} zwm^`UnA*iFNp?yBq9sviW5MHRcvQI49gyfIuj*j20D);g%|v?dM~IlH5x!(HY~tUa zfgs!ZKt{UCu@S$lt=(%CWZBN%f}4UL<MX%1hx+o%yI92`CnRN}v8vxZOS{sXnDdPr zoRD5af$4J<`KyY{oUJ)@cwrx8#mW&?ZD(eUXpQV7dOjj@mi0zS?Iu@{3PL_3Qi%t} zvbi|Z{DfPK<$EV~l$N40!%)=&f)|l?N;2n+Ty9MVu!+<xp2hmcZV~9gD2v?FpiKf+ zl8Lg8*1IcI!UuN+%VhiWbY)-8a*MUG1sEaduzohk;+EV8g2Rti$86Ni8e@Ci(Y4H$ zUP(0Vy~QV!$%>JH^g(9$Tfl7c%G76gR-pa`2>u7PQ9K~U^+($CLuPl6)ZX}|NON~g ziH2SEfMVK-{KO6ItWvsP#@53ahsxtpWndj-@(djw)w5=V1~0D<GKV8i=tdj8i_>O% zqgn`pF75UiAT<?=p_CT(JRo3W_+kNCp5jNJ1*GxLVc#Lj=^j}yyJS}VyHxY}7y`G| zT)*djvhyG9m(OJO<SZ4MsQkn>MnX&JID2LJj4>~je*gG^ojxdPkGCuPuOXBWKD-II z>QYoEZ6pa&&8#@Mfuk7GBZZ;_AE5#mx3o3`U=GWCl@Uy-{h=pZ+?zHaa;H788acRi zDEhc>bx>(lWe2lzCa|YglvY3y@AvB#W&6EB|5qvSJJFv;G|yFX`R5ZVrkBY{Zy3jJ z$$WhkzFlCh{|FnEFNdO|Ju|4fp}}ld2W04$8?hA==wRc8^y*ylLz@btl;Sh6OKoM! zT-usNVSXF7Z)W>czhgKQ7y2u6)idNXBB6#T@3aWZmeZ2fw=nfw_6!9eJOCFEQqDnV z<-nDXki~GhBU3#R`S_7OuV*Eya!!NwwmbGip4+o$21kCJjr)?3cVAZw#5bxU;y!#o zT*M#QOJSnU?4pauVSs84CrUFJK_UgD2@ujz3-06eO>S3wTRNTVyHqZWTl3IXJAQtN z`8V52HOikHc3W^XL*%CR7&L=^XfE@q>CR?>Q8K}cni1n}=?%;F#rdaVTXLfxC#t<S zU+#x)ODD<Nd9*fvwO-#wHpiKFzwAy>e5v^0#F*>%fOj<|MfGxp7^*t!l>$^sd7j__ zD(lHbM(E9lyhL!EG6`1la=fRY5`bqfyzB!z9SDBsz(XdlZbg|lt35C<4TK|A$#FUA zR%PAEt*xzblvpJ47@Jj~U%#4#J6Ut2>NzkdXcFmi|5Ju8;^qnmQSGTfeK>`rP9$mY za+8acUt^y8%h)eIS34aKm)1!z9LxT6ZX(5k+;QBZ1M|+zzqcf#ZAOjCP`*Ockb4K{ zLb3UGe^rTRu6cU{4{puZ-X%U@$>OEI1wp=vJx-|ABgZ+eNP)}I$=K}_l3>s`rzb?- zgH07@{Nk-32*LJm2By#KEZ8;CYg#8oO>frQCHi;uw57lua+muP#c_`5f7x<HGb7AO zM<<sD+V(J>v=tOC^(t&#%aOz>zYa$BNw25(HBux3I%ZXnKd7?8(-ZPk*mgdJ%1`OO ztBY1p;;t%6TMvzxmAlORt~gY0`su&0AKx0tVzdzaKiViAB;5K!F$1Vy2IIh?A<x`4 zRx45n5MawJlR^B-%IPKRyac#|O1zj@nca}c`R!!_?xU7exe2!(pxVX`B>UWevPL9( zDZCq0Xu-E%cgxHna-Q;->|AzQKa7EwXIJ=U#RP(pW}I~c9u7d-;=uOEqE;(R^iWBw zs%Zzd&h)0mb>&ysvE<+G%rFzv`atQalgq*y*>+Sy<?%+l8$PDCT;UeFXQq;W2XH?} zkL+Snnr5;IJpfBGGB@FGI?e{-28cNz0P78XU<ru<G(@dzhc;mJJ0z^vu>xdBOy&d4 zNblj*dcY8;G@b<p=>LjnYs`iDDU?!8o_d6g*p$XF>{cwQY|xRvA}j(C=6Ra7-N3q} zJt~Q+_^TTfMCH4@#3h@+FHYVFuNWJ^&8Q!Ds?J5pQ9PI*aou=H8ar`|E%w}RdUjuj zJf#!|=mIwXu!AP?s3~yd@y6|>c)Fhu$zT_LrrHDE_>LD~r<>d#*c?uJef+4m3LJ4{ z`Q=`qx~>IOqqMi~{)Mz%pfshyzogp{{}&J{&>sgbHdTp3`E*9t3Jzr_XSHmj(>_VR zHRcrpv+8*}>XgZr5%PhB#^b>39pYZ&KCNO%{!2>AZ|S`aSO8s5qV`vwC}EdVCHJ=7 znT9QJKX{xJ2|EOk0Rvsd_a-_B+Ok4U=4MCAbg=)Tp(;$F^MPqz-pSVB7TvE0s*+1z zW`60A>fcV)NrDN%|5Ew=L;g!NIlr{u_Ze%}ywmR)iyg=B=^09+3~dLFeAp4ptE`(q ziLH2ucf5iyy{>`UJYYOV!0V#u8w6*N(9((xrU|b4LZEE5wP+-by(O~ot|TOzw(YBq zG}}&B+=pDE14A$WnrW8#_zjomb&^aN;OHppG}~8!uU%LipU@F6@*VsB0uD9Tas&!H zWqBuj`8Q~I(kj_1ZPRheP`55II!a45KZ_>g*dCuimw)7srcb5tPjuqTP~WTh_hugI z>6GLuPf*r@Nwpc)IDoMN<8&ue#I?sw47Apb2fur60V90K&rIg~j&!!Q#}gbn^OC-x zv>W6o!A&&cx3AH5zA`Aca|mTBf}A}2fZ~^R3jtj5N?&cC-&7snn`2L9UH}_cnW^6N z>XymB1sv?6F@lIL@_}kcokm|unxGh{OmG`Uhujq60)PFg{wgWC%U!1Vls#4Lm6Hjx zXsO?isNy#t1R<@fK20W}qQ+(QDCd(Z{UO%vswx?M20%c>_Oij>q)11VC*VrPr*UJ1 zycMamQWF114(iIk`g_l%VWZz=8rDL;(Mn0z3``7Zf1%ctB6ALv_l3H8b@B2L7wC=W z+<c%@i_}V1Rc1c>xaORrg%1c37C;7^TC49YMniIGIO&#<tG7WP=iDO$|L8-1*!3Z) z*wXE<6jX&X)h^FVve<hB0<(Yf-i}8e9wD@#IfUb>*00>%>X1IzUF$zH%LPI)<jO{x zlz&qPM19Y(;z~h6mnHiFC~m2C)Zd%{`9R09Q#r-u%ar!vv((x@zbS^Bu1-Cdjxd@! zSTJHOtxTzA<!1bi;Z41($ypNIMHN&dH;V$E-Y&C<i{YM*UtG;`RS7v`E+IM4(@kV$ z!1R|<$}?%U<Eog9DlbfZpvMpv@{o1{|70E*8o()`7Zb2-VL;)+EKLTiKP_P&no@mS zI&2^64_xGz=m@{{T{BJso}P(!VtI}ZHT7vA5&}}C^b0{BNg}`e0MF|vTY^y|%RWFh zxu0coVb(z-&3v)ke-C}38Kv2*qFQ26*5C~GvUv-zZtPd+MzbcBb%(V&(m~ZMKXxK) zwF6kcHMwp5&Er!*@9$9e-$HvTCJJ0|!SBLw5iXZGA?IO(Beg94t!WkiKS5?=-N_H& zTgib*ml*{|-sJM=lr5g)kVY-=(m%|ZQSPs)jKu7tBH-m!F2*+T^Q<dxd?u2r43%vD zIbeGWa3-+uo4WY}P=SC&W@-%X-cC7FvPkhqtzHho3=guh*~ds(ruRti<{Yg*@rj`B z#ZKBf-eE`L>%ioBlLFn5E_Y?>1-I<l@RhYpmNcm+E4&?57i`!|7J`_|Q*b?ixlwpA z0Xq@y^?aVtMVn+Llk!xAztd1^H{uTvw@RA;QTryoYWgYhK(o*AZ%lPaqz2GFuy8vL z{n;?~y($l!i&4aWR%t3>lLqkCXDk&)TU@GgFDP&NB<?g}G)N&SGj&X7aiCLE`los8 zH;uC4C$Aqa?hKHZ8VkLJBI$%eUXw%)1x%<uz~9zkfKEjB^DRP`ikq{n*aD3`EyCme z96d1@{@0^|x#xOed8y_D@b1$N%hy8U#U)rCD_b^}0jF((K5BJJVUte@N%c>h66pmK z4Jl?~*-lM0AmPkrRtbwaQk19AD!RL%&Sfci$T!KM)3^1$vv_5LXVOcwsTBo9?qm*C z_(K9(3srvaZGV$SQ@fE+!;5+~LXopkbOwQ6#XgB3rD5Sfs?^#2^s!6O<r!H@YHMa; z88i%owG}`?1yle|%xC)VIgxUyirS4BbFzT*=)T+1AZ*hgWRSl%07<z|*=0M|;LF*t zvPYLs(Lxr@6FVgbRRr3ks5bPyzqnSWQBZ6-9n(56yjZmX=Ftaq{HfS2fcI8cdv?=9 z=>Cj4)^Z)pKWB7JP45(pa$Q)E(E)zUjmm6^Xv+th6fWtk(>QuYndF}!+`wNRggDIC zX-6U8L8C#z4?+<8C9!U{Y15k90lM*)QQXyz;VlO$Xc55TgRIq;zR941oC9bGsZZzD ztQ*}EVm8K0cVWo^Zk6)(7t<(BAJQrO5({pda1i{C^AJo*B751M2Yhw6UYJ3Uq^)2P zFwEdLzUV6aDHxnkA73-Zj@4=OGtM#X#WZx)_F=8){$-7BPo$su<{MZysv@pwh&edk zQD<<KPI2-(q+Z76k=TT+-R7{!!lb}IDl+{~K5*(ojm$*=cZ6uth2H4Ji8Pdi8Lm~n zG;wjzSof39jNg!Y;$#<1CLUu+cEH|-*&Tp)TbnnqXXn)XyT@z<7~&UwMPbLSThIxA z8ao|Z%9M1#wD#Ina#JQ|AB?ki+?La6CZ3RWe0R2=wB4GwpV(IpQ{Pn=*k>?)i-D{C zP(Ty;D_$+@l8~{aWNvY-?cwPX3M<rw$BDkW1I^StS^xM0*aVDzZ2rQweV2&OZ2#Vy z2^|L!6`70+^(+}gf29<+WqS*1?#M|>4u5#U2&exE?TZt|&!+jlLau&LY0sxc6@PL8 zm8ku<C@?VHF8;v(3|fz7DoP&@ILohYv!KrxKDz#^A2X$vr3*}5_8a}sWXTNaj;6j# zKL8dq-Xb6%a#~W`1yX*`SIJPc7tQ2Rd2d(T4tUl#QjE^u`)q)f?gcJqnlYJ2t0vH9 zqTs2TV;#DND18k(iop?y^$i3X>`w<g6r}H#bIM-gy$(#K{)F$0f|N5q?chQjZEjSP z5&TyH*}o0Qy&d=ssYzqp2SAvaFgy&+o-IP>3bB9TapZL^l-?f^`Anyn^ut)oP5q1S z5ip|7sAt&>awsA<B@|12mv#UQXmLGOf-*T*Q>y%y-pac&O)i>?v^1v1{FWtW+Wt?k zJyWUo>Tu{Rp9%i~=%X_p9mD{<%<c;zSN08a|E+IW(mhYID)3jQW*lwKmX{+dO<is0 z>kQV)LC$0A2YyI3-Kmf1yOw!;c7|kcIsheMiQ{{{vXSr%lVTBsC50*VpC2sQeqLJo zK%;)iL~$XpVLg(qJ`}GVl&NJI><H3@j@dhH8UC}+mzR8Nsst2ARq%v58xO73N&VTs zSIpT@!Uz0fp|8-iX3rE<QFB&%`j^*UwzYDbkNkyH){z?1_S<abdU`?hEQDSun}%=* z`o`pk3IROh;f?1dqCMQ5%o9cM+q4?;ZDqSTfwQ!?+Fl_+bzf7=?B=S1iN2J6F06A9 z1@wMBhk(HNJ*2iQI_K3XJEoa%EYlFhG@-a=Ao&!S^9d*Y258K0bZ*fdrx$STPfu%T zST^0!3O1Xs7x#Jq;;MP4JJ0dLQ+x}QRLE?r1U;bT_RnVLXP$|u1%MbTe0(HMOL=SQ zZ<}J38Taqttp@1*^aWr{B)J;@yunDL_*7-&KG$HB5|c-4UsX$<ED$LX*F@dzW7RxE z>&8~DO^B1CAEU=!aVfGAMT;F&@BVxXw^T{RR^sFxEyBHu)~IM{(Kn+fx*9Fd{JR;t zPp+-%r9Eg<-@3{EvA}ny{A8wnF}j}lW;)y%M(GQLXe#H@s5hPf$$alaO-~gCwvcC= z1qkO$7VYP@POP9&x)n(#AD#PXM4D_$+`lYcBaoAqO+4#C7ZiA(PsJ=E4mnCDF(1^v z@lfg5?*wm1*WQ1|8@4~XVl*;T2htAj7g<~k0GFECnI7)@M#__69e<qm9fj4(bf_Mq z;kGi%+2M6@R9g=Y!#|>Yk_0~U^~p_DWhKyUo~yPUn6emt`)YFB(k?dG*<@j*vktC@ zJ_Eb&J~+`&Z*L6Z(;qKM9}epg`uikmV3y4;%0H*kNb_*|)Si-fRseTp+jA(uI=!AQ zpCFW(e*%Rvv^F;@)SEt;eqElL%Kx|hTYC2UUP0$0_QSO+@77f4Up1_^a>*mBQ`bI^ z{~qxl)Nby!v~E%E6<hR()ln;peFi_=h5i}8mjR~XZWmH9o!*hnM{dxXl?Y|EA)=2u zVR0zcP4pnTbt+FJ7o;n?;is|M^Jg=k-${jK@Me<yZ3VjB@&$<+)4C5|foq$HJxR5< zloUmvZ$I`glY7Tr|8f0?Sl1@o7N@Q)7k#!vqD^}v2Dp&LU^HmZHPwoFzSO#6y*ed2 z*<>DB)eCUt4?cdH|BM0dSz3LcCGeSIOIuMAYTS*>fLrXSyA#849;l)pqTK440t zDVD~Ncch17DJjvi=d5)D9ZM<R5Q?9&!3%)@RKW4*?`ht3Sdgjd7ccThN*{fNq7f6u z?+pO)4A>wN81i^3h-wl^4jxeQSZS=UP{MUo8e1q>_uU=Gt~s8>aI(|h^M~SaGR(o= zHz<r`m~H;jo53IdQ(@siNfoBOs_g$fiLt7D!GGf2f$__2j1FrcBzBw+<*$_aobHgk ze~~~2mIHYjEHO^$6H{cv2P7;Kco%Rr5(?ZsIb(-&WuoD*bnxpv2ZQ-A-+)t`uJm3t zQ1!9DudNXS>pY4kx8u`NIJ-^7KVQ2}MXqdi!JmOf-N5YNP@t40WQ1)5sKBh}Zg|vI zch`PmE4*OUpxIMkNnb>U`ZlA*kjnCVD@1-u#zI<!2)icnRRrD?$>SMCUI1kl%VY*B zvKD<}xZB!nj#4)jRdmVpo`}aj8sL?nR63q_B|$L17pQ^bA01g21f&%W^<uRaBt+z8 zMxAP0rp0-b9J@dS6d%y37oz_rgS0w1qm4O0KAD#s!~@c*9)poK#^68Y>z1BG-p8q! ziM|H6*}*ZufKCQNPc*Qh?P4aHt}E0F0nks&^ArX?v)&2_Bw&7RE~yZ`J+RGI8;r_O z+kw}7Hv;@4*lVJ6+W$(Q0&H$#Khg$|%Y7wi+G16GOrU5BwP%Ac<kLgY3%{vwBBw<- zqApf`DQw~ZkM&l+3KfG3+;cXmSi|V$T0T^@DC1zQx?@sc!<2C$=o@9f_xX(=xYks` zo2Kjed$Z~McLLMx%M2j3@PbrbQpqHo-=c&%mxg}{Df8Rtt;Pmrbl7$jtET&k{|y}t zfNl2<g8F{(#v1`({6mlU*V>kC<aV6WB|}dPpzFcgS9^l7UEZPE|8-_Vz|Ua$DIGS5 zeEhrrt+5;>N?*h!vO1!`TTFJO8%$@(Kw((~>fph*?il8d+e~({uXW<j)khGzGGjtD z3FmGg9{qomHnk*N&3vf0td2X^m{{p8Z>TXR8zhTQj#4rEi3J|!JsB%~c{ODZR$R@Y zQOu?v$l;SygZ>3KTjsh#iQa<u!%GhQ)OL))l?(U|<o9uDU$dxlVC4rg+8<+3(_nJ( zubRsE=5=Kx)ASlaStJ#pHl2_8&8;Ee7D8rl`9J3N1d0qU`Kd~fOuUS14%wIK>y{{R z3jzJ><rQ5h+FN$a;sed3!o~4u6L+*zyQIRjif=P%uvV3XEoaU&6X=<w47AnrS2(zZ zj2`SuZe^++ZjlDlQ%NxK)yryV@0MzL1--T=M$35I485gXA9ZBD0(&yf3kl!4$jzX} zzb2N#gkR?t>n|{MHq|yDV7m)Q5t0Lp=mo~2s0jqVLW;w|s)%a(*?eAy(?}9MMRJXw z{v)9v_^ginB?un&_dT1h1R|2nGkx)^EDt9KfVd6<tnU-VyovuWL8mpvO0V<*9RchV z#UsGnW<I!4t=1c4Jg|2|b`l$W7qAmY6mNnn(huyc{mvsCk%d4$;Ma)io)8gWmLS{A zIeXZRC53}hOUK@QkBCDXC`P^}frfAl3JjOn_WD|D>3LxLb^4^nGUFNJ3F*XdqwFpx z^GcvCreS5d1@qL~tzcZ>T7W;(`_@sO`)ixa?XGpZ%WbFBlvSNOHnd=VM2&7rm6J5P z(H;F+p}VxMu}fF&n(Rf!X7*tN4rVFi)zD~oa=!SYBQV75Z~(Mb=XvvAsvGIyA;)$m zMj<jvf+b$(d@V6~GN4q8aULj4q}CYR86#!NY-NuPeaQ|Driq&^H@`@7o#3{<w%FBQ zcO7SVO^u9}nAZ(4=`PKi3v}~5e~UxYkGHD2C|D^gkk*&-?Od@{ChranHK8k-+Yn~e zsz2gwaM!7_pKrLg?&6IfEL1Hf@eJD?()~<pJ%A861EsS{zP6=+M7G1=&;iq+tphG5 zpx{p@3?9tlA0an62S{&+H6kO1BAD(m8k(BkYW@-sVNL~q=usm9w+EkuRM=2dn4y7n zePkV{j^zeX;ZxQiP!<0GA!9QZ5qG~w7poaDq=-a!3j=2QCw#!kP_Ph~oEV<iI>=?) zrA6X#w^p~MsOa_PGxyj3&=P}WFU?evd+DnOi%Qv{>2#uuKXrdQ@YycN2B=2OeKyi$ z9v76p6tkJ;rQg<ZL?%Op!ctg6&5?jA^L}hgKvT(2HK-X%D%=15{mbB#0q58NF0@{P zP4sm?`36$Xg$9_6w+fnV0<?LyYxZ_rQnv&wjOksbEi}I50m%Z~R4Sw+QQ<1K#Gqm7 zdcAcy1u5n*Pw1`wHv8m9>wnfz(=sDv^0`pxmaLr>4)KiI%@5tT6~d}fzY7+DjgwZb z7Ru!9uh0-DL7Xju?~ee8mRQCW;QbCI#9B;dy`TwP&MyI)qyLYT)qy-*MII^@!zP|p zN_b&la7~lPoPM)ZyztuwF(;2W7z3--pHRY)SMB&oomYATa(d13M}A>~4$lD~?DKIF zD$|-IaGO{f{Wq_d93)$5io$JFfXSij?waJ?hB+{n1=kcb*%fl<rQc`opNXlQ(FWVq zblg&iSsTdUp;24H!|t71el$TaQAcTZ5GgQ>E(jL0C6!CsuAWN<jBXsq5wC0<Ck6fk z%HeolY)VP8PK8l<Z=sX^7beATw+*3ZVj&~v@f>F2aqIMXDfMk_Z^grgN-F(!Yqalt z+T0%a)4T9`-xfItHiiG;cl+sQ?~49Lw?NUU0}OiKr|W^2YI}RPbw)_o$bla)`9AjF zX33qb<C4kE%i$h#^8Ey}=Q;yq{NQC~+V&ss<?%}9z?@Il<B+>1r)NTk*NBME^@tX7 ztnB@+mf0oRYbR<qyQ>Q)1F>H&?tLx&ta(7Bf--LFs)~(>&!Ua%9dwXxmxm8PHvBe; zFc}UJbc>V7P939p)PgW;;g4%Rp>8}rmDYsynXhRQ7(;qopJuZY`UGW!1s1t<gC|5J zGunXnvXPXPii~hw=5kLI+LrwF61i@m#V`vt!m|4g?MFyul7278PS*D1d8GGuoc9T( z?Wne54Xqb<d}=>O**uxxbqe^W8%)rDg7}cS-m(#6lt?dn&35d8X=|)Cza4!=Sn5F1 z@`osx^OiRq#EGeKk5n+hgpLF!v#K{_6+r&Ig?vK7(cDu^YZ_Ja^<hh!Q*Fr_@)Y@Q z+f*@9H1Y<g&D89}V1trlO3g?q66Y4isJ<lsKYfR_Q517Crc>JE`$f~C{(3Z~ELt|T z+Dm`lxA-&H2)N60s%qS9&~p8a2cU;1e)f+ngv>d@CzDDa339Sj4pEMOjAaTqy;PPc zV%r$uBHAawE~HhJ6cP8gZ*QvJzeVR0XX0LdQSdCVU}p8N<^!T!94MGkP4bxvWpXb~ zxQYzc%PeqG@9=_H=-Y$dmB?vU8%C5luDZ1TiAq_%)14g7)Hc91-)SdxbFM05kP@hl zlV)h-Y*x(+zBl5_k=2NaB~H9<pBeOMSQgkR>-^6FySFG{>b{0QTUqTE(7o6}V|J_f z+sJWKKfxTBj07e;QqkvIwpx|&P9E>K`9x7WurrK2@Z1L%WS*1eJE#bL*B2)_IWwct zbxbjhWUy-N+hsPPVqYslsoV0WOt@L8#w)_^@Fz}UN6&-zF`Mcnf${fsVMxUoj`YnL z-&7TK&e!)_T0iuNHrq}LW=~XU<L&$D8weSBMy7q=_OYCv@7_h0yBnkQm+W{iu2u9W zB*|#hmkj?S*rmgYEASrvwx0THw9A#HAz7x6t7xMu1I%!iO=TZM04i4O1`T(^)Tz#u z>CES>o=j@9GG7nBXikZ~Ub-v7d{cd#9ES^c*DnB<GKSa&K!PWuxpQBiK!A9+_a*WP z@#~RnwJ-beY9b1^yvi*&@ZzCp$%l91_X)sR(T`nE*Buo)KiKuFiC3wMhGZxvpq9ik zFpNvROpycX^u*Pe^{(MUfNGi@Pqv1ydCbF5rkTs(S^sZbm&f~adp79YP=bqKVj04B z1&_I)-L#!zV9_uvq%}c_8<0R`eLxsNAV&e!m(U<;=7t*?%3N<KU6-e-jKW{Ddg57# zO@-vSVdh0otZ+tK<5C(<S!6^{cfKlj^k7IpJ$~2Bl&=kY?;Jy5z))UdYr)gd<HomT z0OYA^rGs_ikhJyZ8@C^E{6MD}F|v~*^E`ApKfN1DzR4JiX-rgE#!oo@1@GrlLGUel zge{X^j0yrS;UaBZ0GqW5>GuzCDVfyUBy=UP9k2giRE?}rbwxqSi9&Y~aQV*^f8AmM z*VwI!`Nad};8QVh*fOx)X%wTY4#X{xWU?Dg0FvJKKjw3r(!FKE&qZ)3J~0kAk!?Yc z_$lxIEQ9Cm$6*pcfss9w-NJ^(fD}c|*L$jRA#tE6nM#9xy!p@bUguH=l%O076UMr6 zg=1kmGaFn3?!(j2m7%U={yvTbUEXa9mpyaO{X!8UIps*BZ$6#o1KkjiGv-i?ROYLE zguaOVh5@g?R5Mo#e2;}SE@L}`6Ka~AZ1RCag(mDXb;l+iL8@8gXmKf|{zVmidL#35 z(9EjRJ~r|<CmO4(6{)_#b1P%WlsmpY9}$1*iTkD4KOuU!TT;NoQudaJN_-7gMjyW` z2iLVSvowvp`jAJ&2l`i+7A~OVP9vZ})K(uAD5LM|Xh}UsJ&lVaTm~HK3Dk13@{R3x zg*)9CLuckBV`)a8tz1mvRevWGFTSypOQw*WGCx+uE-u8@o0o80ND>Im=f*_v^bw41 z0~l_g^jyp5b~XB5w@rTP9>2P&>yp%)u8@aL{`%-oF~z7Gbc%7JI;~UNUN2G+d@fJe z0<1)C%gg<(m$6Dj()ROq$vi)N1P7jh(tcuMhV%5RP)0Vs4G(|HO;v#CbTM4Rd}`Q} zrNij}+>wB9Znyl{3i`ltX%S1a=WBkh@4MUtWAi=4GWCXoNEv8DtO%7GnE)C#ac@nq zB`{OUsARgj1N==uaYkJz@}<=I;o)(B%8&UhEk8a&bX?;*>HgxjnB+oul0C<H?#zfO zZSliW6IeO!9LJyR?BGgnl&&&fb{FIY_tpE<uJDw_Y_YfS$?Q>ldH!RzAt0Zl%;q}a zsCbOacaceNE3c#fjki+@|L+TrK-_Svy2{bg_&;Nq3+-khF#BIzozE@Rt>tCR+&^3> zaH0J)((>avz9%XZ+9fxwjZQOBCfuZYk>r6iVpl7RN$AYx+)KdRn9591AW>M@K5{)3 z+$BHx{&}x07Us>FJ+g1{FjOO&`e4RBPlW*^&got)n-0oRaNP3rdD3W*L}`t6L*%|G zT07x{3`&b2fZ09~8>~mwL%RyBxM`6%bTJ{eRcd=(Elole1_ME`1L)SNYvM(+AQ71& zsl_TqQ8b6}Z8+MkIrlC#h=mALmoZWj?3KBGj{eWn(pVE&rNVF=;XU{c)&$H1>YmA) zX?z6AES;$`N&0QuIG&&#g{Ji948Di%dD?AOxsL4Sym9QgGSpwu$LhHKm~kI?;%K7d zlA@5z%p56eqeM7T99}4$9Wug&7GJ5hZNc8uq^g4qmP1f{-)A;NO<7i=`6Vn5i!=6O zEQR~4!EM0t!?k-y`q$g5Vs}H#FSV0YjAOqkTLhW~1SDuFZ<wNPKBNxJxAaki%pUA- zVwi5C;@rG#ZRmNOkIl^bmV#g>?di?yf=M>#zk^_lQ9di}eD4JeSQYq$ps<$wFcnUo z?>v@xu>%hb5&#IPBeUE7{MN%xP~h9ktvqT)b=7wLeA3s%sdmC405NY`EHMqBO)fUS z!;DEmiEiZqx<;-0W}l70(bY@59#zKt&4&Z`#^J%Gb^LZTO_;5LIp|mntx{_u76qcS zs$k!^Dl*DapX$k8^r-#($=-Hz{GH2{aCT$BR^k(=N`NJW-Q)eY@!XMpx%80uYGf$$ zPZePQ(Xw_&602t{^R^JQtVsJAhXd<&UZiX^c~<=SeE}%L4rqy&{=JU7E^{RWw)!XU zv!vhtc5qzg*GSc@!ZgwM2c1HFDEOn&5bF2hwg}jH-4t<OX#gUh&96k?tcKZG!dfS= z%T}k<zX!Ce=WhO3^h4z2rj4<gZ1Xd?pFjPS2O3TJS=@5l_pOl4d3!z@9(<=#%Q3am zo`b&f8|N-RhKS}QTIq9>)`@kxu2!z7-saywJ4eA-bRRHvC<$eykQe4+S(H}E7@$#? zDmhE1V)SBeiFbo<hVnNjJe<GiR<atRuMo>crco$Iico-qXRW*vBfnFtjrw`TR4{;s zdX9<D$2-Si8CbADzouzbBaafxazfL?`l(X2`^yL>FNH<6P`zSy@j*|s(6<fk3vEwF z^xEDvUo$W6b<%KkiKh8keFLr!r(Q+H@>BO;;52(}D7{N+3LWnCHb#c#Iog4+0`g5R zc;zP5$dxb*5$oX`B0aLxAen+XqnedPM{Dr|SF1E+fzwkwaj|f8fk*^k0;55AkMc$& z(3vnZ3Htsx^Qj`ACIu(6|Ez3o?e_7oj%Q|OpVj#BAF(p0)Q^!XB)D5k9@#>jy{SA8 zu<)~}F+VUtE;LqmIut0PnH^EwKf?Y*sR&KyUPiaBR>vAJHq%R&(MK8m{Od60C-#%e z2VefaL~>>Cu-dh0SJ->mGDQSzdf~1key*~vYQfLSq-&OWSo!SO<?+~NE~Id~IucGQ zPOf^j@fY+bx${9C5yzXOQhFiu1#_1GLc;Til;{PPBbsuZOH=ASvo~}HgDpmbT*{(4 zXWFBbrg$^G&4KBCW($9?4GEn#C-<@&*NDCdt^7Te&$}0;`!h|<yh7+MO5>=3W23Nv z{F#JO_%{c757VSrX457iEQ{W_ZTOwdFgAAln+&}ES<$+Gh&;ab!<!=|tgfSVHH^M* z<*r0&5R24V<1YL13Q1AZ*plR}nsxjKw`{Qy&_PapNLr?~%cIq%$xG^H$Tzb#sAC5` zjpChiX9|B#=FV3_9nX=V<`NGpINU;=@ckzFT;B}1X)0@pjwBj!O%zjZFs>qz6X+C{ zt)Y|p5H7-ph0~y8P7!l&#$(~Sc=CK{w!8^3i>`HpSmv1W9&!|13jI7ID}k{Yf^G=% zuIWDFM@Sf_K(F`l^=)lNYq`xd6bO>iR;6v|oRj*f=OE}Iisu{?&#k;^tJY>H^T{G? z$VcnlRTiP+wR_7G8C7jnKjTR6Ek3W1I_29ewZaH^M>2?;SF^MD{>Xkf%oF2s`;i%A z&~lcn-1tSZz(Q&YTJF!9yj!n@I<2DN(o4nZhE}{+@UN>Z$jr~6QHt-JuWI`(^!)GF z$QgDrOtKQgCfgYv+sB~qNi@o8bniZJO;K4G`D0b7A(c6NB%qWoQbj^i-zvn>$||ZQ zT>_%g1~cg%#D7Wm$jcGmMKZ(uu9w-2O-shMJ$Z~-w6FD#TuJ<#ABr+i!S~0?c6E8V zeA$X15J%|JDopVyqPn@=*5>-V1EEq^)!lp1K~;Q|WgQ`kvxB%?cmVfD(p1RANKfh5 zauMUY%fYNpwuV`DggTKX7G4~&$GHl*ePyKpQp?8EVczz;XL!Nuzn=XM56k`i%Rf8K zbUW=T%imQx*Rz)?|4@Guq2{Bxos1X;l{5B2$Sy9Jo0o|IjO}GkiFDwI5-g}G6YG>Q ziPjksp)oN$=~4G&^5?s6A1FId`#4@-)c+>Bpj(q*Cu8k9tyQ*Z8?=fJ&cad`Z?G#r z9LR_)k>KLu(pNRmQPYvxMNu`C8Ysd+tepyq2i$zQ)jm27_$jRYD==3)liP|=^8H>I z6Y`X1|Ed|q;+lQ`EIN%XrOjG93y=Q6>c%m*W&3rhaunS;F3#=GDDsqZs{?X$<er5C zw=BW7+rQG0jL$#!xKm3y&+VIZ&pN#`GV~8~4IeB^D+B3RCYTiN)?;-EO2lk!ZN~^~ ziOOKG&~Q5AT=mwkv;h{MH`T*|xNx87n3#U4GKolj1CZl`7#dPM4#;ASRrpv6(NeIS z(f4BZFnaE6E&8vA?;m_0Rc`1e%e8+gzs@M@n7ldaF7>aJ(Hn`lG5xB~0{X){_S}Vc z8913cx{eRa4d+floyiefM>osKw+;F=je)@D!+&9?9Pr1&($54msOkNCkz8YA>gt|! z@1TF`Io?G~%Y;;x%Y`qfyRsD(k|xczi{M2`rT$VQm6%qUE$@2+7^Senwi$#?GyAbL zvEjS1b``_uFjdBc-Zd&ew9Gb{+HuX#&p&IgSV#^_I+`5WHMFy~JQ#e+h`BRp_fD(i zYazxMpHYL33tEv_P3&v7NQkuW!xXmO)1Ut-D&If5tN6T|ZxI#B+<GW$Qyr*IhD-7b zpBX3YqhbKdyAXmgWLmC_8rndDmalD-(t0Mg$s{qH&yQn7RDRCR584_n1Sdz+RADBa zLIv9#d_sZ}rUjp$=l+Z^<25tzC3s}*Ei3zgUBnw~7vetB5<q*kcqwBDy|`%y57f<z z^GTU0rk!kDf1m0sf^gy7`sot`SL)@8?rf=5pHZxSSXdV)ve{Vgtw2tEoa@}n3Oa($ zfIp&=?ynMKV^pa+8GZH+X9~pQ{iGH>x2SH%pBRQfQQKiopEoMq#(5S8YY0>-YttK= zo5f@Z+l&L=IT0O&XtB`nz$M<(WV@H0{L(m1ePDRF<C{R(3b8N%g=}Gc+~+0xe!YDs zu+K|WI0pKVqM~p!Y&PFW_Th3YImCD!DL4uh4GFyK{HcMU#2OT+-%B3*2}dc}yG((c zG&^ST{-)y#)a-qItavo(#=X{Qp0-+o!ki%@lq9hfpKief2lCB7W&2w^c5a$Pnix{V z+P--V_vbCYn62g^FWv%}vA<zmQM7t;pZ+N2W^<+BXVhVZOKv-KC&*`AHz(mFnWg5E zBmm@wt;?5ELSX;a)TWF*!Pbe%ypgpmu9eVgGA~zQ=otXL@^P)g>2f|%Vc3DXe?v9z zlYtTLG0l<Gt9l?>sQ*A~KTyZ#ec^}hjPn@_NeN@t1l%Jd@-86dTKo*i%oRxrYbY6J zArPyhUdL7yz_cZ`G!NB#3j@j3h!W{$#83BUPqM%c{>IILLROM`R6P;I-k1nv#aQ7( ziu%*87ymfn9o*!Bt;Vor8elkYjlw(G!s#?l22^ji<uBO}TKY9)MxWQV?^J+1LO9rv z$#$KL^16GYY*RsptXZxJogv=IM?hXv|NFP1j$H9e@7)MlFjSoXE|w64GX!#D^q_}s zuoqeFBcWsLESusR&VGPKS~HC(e5vYUpfJ<POy*_g^X^`(fWMG`Es>!p=|rW?;oZLU zkT}wK_cr9HnI_(2LxG}yH~TGCNvM=yzCl|exZ@Wg3UE8f1-P9)%Y8;#OArhy_pay- zG44MW!{KI@z!MYwHL1+C+~6T!Y5<%YKPU_v`HT_C&{pRu!(^rz$tR-gZlp$zq*Vbl z%KKH>2a3_xYK|d4Y=!|K0Uy3IpvYvcjX4?jT~tIPLAU{sb^tstdp8^^1|*`j$tq^r z6Pu^NhiPMBsLX0NQ=m3P(?}m1aSTAXY%gx-#P1-?DHbQ3&ondU4iJ5%;Fep3lL#x6 z>l5h-0=<IIB(dBMHErWKwEYya{34EO98lboGwSJGB3Rl;@GU4YR!$xs76Q@~L#2jB z_5BhKSeA+}UAJ4gU;fNo!z@TdQJa?$j*?9NKLAKTx4!_9xFVP$fH(pr#kW0IY>lFM z&O|kKN>~rlY=xdyo6RV02U68Ci~vQ|CYP5X11q7Cbh?V76;P~&3U!opwvrUJjbcr_ z&0KHjIK!b&p|K}|FUrTp@T{ehDc(GxtSvoXpJ1*Y?YUwL6wUtRVEvCg0Z`H<R)VBK zTf)>D#biF@P&J}R;S#r9FGVT1hfXy`xO3Pg@CMmxsDx@VbL;hlpzRX3i?c=HCuyJ} zyEGy?WN9lb%0(4d1mOiXf};BP$Z?goujh*2qBxyfRSBYVj!#KbSRV`d5oOHUt+O-X z@~pQR#lhgZdvbX(`FNZx`~@FJKW*zW>yH??)-zpRiRW#e1sdryYx)@tB@7X%B5WcD zifY>24sq9_pp916P2mRGTaYSFI@V+5e$nAd3xYZhrm?yS0_!H8J*zQ_$C1i=zl(B3 z@xh>YZ+qOU5Js2mfxM&`%jht8^oA$4wzK0ajyI!-EKm7$Phl&v2`Jh!JRexkc!CT` z7;UM9ui%d9l4vF!ij@4cFhsN%W4RD0yV@R#!PJh<kg!Eai96}@4D0Z(?&y^984^aQ zZsS~$RJO6yurmx$>>^h@5ELi%v&}mb$9L2DM1IpuoRVICnl2WGr)3D88(yv;YaAlP zX>x|rPI_n#A%>h6GR&Ku<gEtdlA?86W-jQK5mg>4l|IoVq?g4ZM8xb4SF~hm55?7? zLOx#_DwCmEH6<zLi^I7?C$Vaaay&qf)l3mmMIaIO%OVY+c(hAgQG5_6;v42%s96fe zxffPZwbrP~BK_W(LDMMJk`vPe?zNCk=}8OS7!s=eY0ISvnMqX}kNXu~)96SithE4% zu*@PKBRglYD*I)tD2`e>*cBTLQApz7L(w>w)O717Fji3PSi#^70u;#xZWy0|#LIAs z;5wzTbd4*D4+6yrMuECj9giYNPF7mvI8lTFTB!t6B!{mQqbFOtVso&f*1bPA)%INx zH+}}i|NfX&2crl}&|r#W{!A*|Fg(NADmVprUBSpsb%iU6#XS_e8bvLLEVaN^#Y#z$ zWQyR5Bi9i+&$M>Mnwp!9*f#h5VOJE|VGqSFN0A6TaSYQ)wkhJLvQo(bQ^Y7juJ}`W zp_);DZQNQ|)c&q3o_YCw`d*qAUpGd2DE<<P@(agKb*TFKPW6$Wr_P)?bMfMtJ6G?V zy>SIL_TmCh{|U8p^n3U$8iLP-?aRT^z}Lo0Nm^BVZ4A!7{%I0#jnAix)=B0&D8926 zp7&5}14Zq%+s8Up_mADLKzaXE-^ISZi<rnecdnj2d*y}*+oW<3h-xM66z?_)hu`P( zzH+@c?_p}M{fVXbM~<ki^Wq<)_+cvL=6QZ?XZ!_jtql2_JkV82JZmPghvHA8xRP|v zbgaT*{0uvt&gva@0|Rhh-RjC}xx6y|YW(rs<L}^Okpu$qv7bRPmwk#+q<PP+AEW4Z zNA%Rq1syMu;g&wTr0t>jCs7>eT-_bGi=TV=I|lIX9%gW5<<+ZK@QL17(db4ldaN}* zbCIoV`dytS0g4w}q8LcjQ0!|sUwV;{D6ViNamQgILhIK2fMV+VDBkL!_-~1#$TdxH z?>0qOB!z2_G#a=v%px--ldY#Mm**pMIzB8W6P9s9D)ngZ5kawkZr|;5ylY0W;0f^g z{Z%}nIXRWjS|7dz3O6ODsYJved;59E?QuX7=yrc3oT)Z6VwoY!NAg=Q7q$#fAoi)a zeR`sT;@j>0$X1XMA2^DNZq^s}&b23zD~#jAN+n#nWCN>-8j`BiCKhAu3lr0ds6hyJ z@rIy-43S~bQEr3a4uT*`S#()Z_r<pHO*iRh=-2CW&Ws}L*xEvi+wNbhbI!2aWb@1O zoabErM`!p5gl+5KKj06!#`X3hM-uQAv29=NOQX1$uNr5$83n4AR~a%*v9S_D@iIs9 z=`>rS8c@trG!rYldeZqiOTv3*2w3c-$OKDq%;8)*P4RR^(a}+5EYsIwgme^Hnx|ry z3XXC>lQ?6Kh6NNaml-zAkp+hpNc>AEesZ1t7-VYHGN`DGNTPULCWn6BIQ9MnxmHhd z^8=U30*z2CbLpe;@d=K;Cqe6#?9ln-ex6*i0*XvNbi7cd+0B7#Kb0mrI*wQ-AN}?G z9fZN#1byM-r=YQ2s_NweiZk@-!dq2@ocl>SDE@OOZhXv&`zn#h%%fKXeTk}oe7>A7 zmpePNY)Xz5f3g5~*L}>=@slT;Oy32>#-lWJU6>gEHN?BjJtz(zk+}iX$MszTitH*1 zs<g@6(J`H%Hy|8lvK+(2d_RtK-lEvKNG2vbF8t(XzkuR3%P*jDV>O$UM)A{F@#Axy zy}eTa{luAiOc*2zreUFw?bU0ksMxs|Q`!`YdCmkGy2#@yd#nm5b|-ihYCL76Q5<(N z6*b6DW#0jcTra$TMOLN(sUjUh`Bvk%6udkiA!=odBJbUW{2ZH*3uTLeW`9-x`s<Gt zF7pY+zl7qmv325+3VS8uJCwy6F#u0MQW!RFz@X9bOtNelpQrOPQ&T3EG;}<n*bwUL z?gJFn`7D7ykd{XAyh4*4h-K0}fMVJV#mg%)q5$A9ib&Qs`@S?^KE6fqZIqoFwq@s3 zVg-Fg(;O1dM>{(|q4-~NorSeNwDR231E&Z;PqC}#R~j9FX>{16P&8C&E(;>*+2bc! zHjetVbAY1$G=?X56s$CgBQs2K7UYaXF9j4k?xJ`xFpX(EkI<EoTNDTNT=Cq`Ixj>N z_h@z&6b%MLj|W9nuUfAo{$Uwm<860yD2m>$qw8j(ze{Y4XwBWz&}ygpLA4X7K;zd4 z#!&<#SQbN&G^nLev|h2L*&jhZw(#!B8R<m3Uu}6nak|Rvc0xlfHCBY>zv~RSa*h55 zg+eZY;+x0{US2uQFurqyqHj_T>M>>gXZiTeyy6=sjsAdja{994k)UWe@l}<}KL5S` zikoF)JygLNI1nA2_phmlhbkVNQzlHFq^9ZZ5V}?0a<Olv7dHl8d*+H3&x;;e8&%t` zhzyXCeb_YKtSI^&Yr3_nUWWvVBOZSK7_YG8Nk_*CQ_y$Hp9XnAv9m(<X*!-fwS0i$ z8#+A(jP9iqi^oqc;z9p4LebE17sbI5jy!pXrWO0h=(Sv4=9B|+(Deyh@b;bGplB^I z(RUrzpUNv6|9Vt3sC7~y(aD9`7`f%W*L61RZE&643LK<T2Vth<Q9smmHb|#SS!OGr zY!*f18O<G@QmJ{=_->XWO9e08N66YLeA;iaU)F`)a*!kZG)58UXhNr3S4*JSq0g6I z2v0sT(s^Dai_uKZ%c9AgP=P-ymvbE7h~gzjT7J_$c@yE3^Zxl$cJ@L7MfoO7b^A|d z=eWWyAefA?GyZR3Vcg)Qx$@xcYReVH&1A}b>7xE$N70r^>OVx~RV;kAlYBokLr4oB zvubdi4d<fHmB^_(JlEh+cUAFA+sZCQm*Vj<6|gjk;%LrYoX{`C{cF&8{+>yf)%xA{ zSMaKh!YInR(7xGmAQ5}n!DdCAqS3wmI<pjt7dxcoTzK5$sPT>s6GgIKUlE~bohY(A zUy6DgQItEgjCbit=lV>RW%=yXc?V9=0*dcC<nm>N;<+<MvJ}r3_s0Rn^9aSTlPE(+ z=)>OH!k_i!A;+?uCI0qbM-h%$`Ja72%2YTTN8!wPpX;nnZxqLP^{%tp#awu6(_HhT z1$n}AHP_h>ZWv$p*z--Ictlb*Y-opEa>fo*(H_BMQ`Sz2hpZ;W%L(wg7UaDxpa@q1 znAM>VQM9U-HadmJcRx;C170sySGS3cePplm)|kw^5B>aXPw_;QHo0L%m5gm?q8sLc z&TTuH6WcTzUjCT;8Sr{Dq5l?e3oVVn&Y<zN6KAk|WxSRnX`Y?DNALPq7$07Z{(0@k zOH@<$CjI{8`b9?@P#l_azTDL|y3Tr^)rg5#s>LA(dMsDgdS{Adf>3*+2vf7)qMUoF zyK7XkpbT&}f^bCps>;e9@Z$HnxW3Agw$@cA?Yt||9E$yxfM@j9<a5bg(#sx&fJD4= z76(Pqw@EnG0{^DnfTH8`hirX4KJKVBt_P(*1uoeF%GcJq9Xawk4fgk34%b?P@B`NS zyb}%kao*zf!3UApde_<LiMp<k^^;o`^$jaK=>w8JC~iYkE4YWU?yWvZx~V+yrq9td zAEsC8TxZKE*G@N)Js`Q1J0B<1CNRf4NO{ae>87hr8~KBBb11IoT}S<2n+Y5R2R7{{ z#dDqRxvbq1%^|wrKmj)X2VV&B2sB>%*P^jv!$E-7NdiPE4QnF_zHeIcNI`p0M91<c z?q=z+xxkipRj7q+Tx#gqQo`+7NA3^|@4VW*ah(l@Pv6J=;RE$u6m6`1N<~;Qd-3-% zcZAT|z_@PpmAbpubt{$aMKsTB8k$3KE$v>KqDVgBK(+K-pl_)_lBM_U9x8UB`Wd1k zOzGg$_~P867!_eQNA0-hE`dMA^3U0Q2#27-MK*nA?tD}zf@{v~zOGjDs&j6aTWQk( zF2O)zo#-ypr`s6CeJ!E6wQoAe=m>4mwb@|x88H)j9Xv%`#hR&|&^6<#61Un(9k>rR zjYM-OPVjDyvUu_?G6d!j$^c0vBE^G)%-6DZ3Rr~kE3i0;k3b`d2TxG}-Tjr;ED;s! zj+8dS_W`l@e;z=5m}Kk3v^0rrL=j*t1A3w~=HDn6rVC8%e6YF6&$3Gh#Z7IUsoi^c z<#Q<;P@EC!mi4K6*IDSQGqoes&R{X+K6EsP;t^?&t(|}Uv}pHE$_xd2D*9$*bSO+4 zWo?ys;tzeHS#I&T-zbiX-Dr**mo4{4MaiSl4X>m>4<J5V@ae~gBG@?j7iv2h4W6*w zy+G(m>^keR(=R`?`V?Pz@1p47>`sWBC(9J$u0s)b)w#~11u(~HK&fpqD%$<Xr9^9Y z>t%+7T{((o7b*J*bhc09C_&4xn;ouN5Q^fBerVP~r8NjBwmvEXi61|T*Z{evi7k5{ zp=Sc8eMp|&4-Jr+B7Wt(i{g9QmDH$8_5(|>dKX3L3R{9jK(S7m{Qxu3<XCa*wG1h| zm6U1cTxYnEaILgAL*wK;js}YgsG-rFr_<sL_fuR!8~&N72q3nC#P*^%6>YqoF9Gpx zEavvy<2oBnQTrdb&URY@=@4;dFA1)*H5A3JMihy~R4UUHiop00uAWm{Yp8-=#?i3q znr&+pjSWa~e(oPfZg!YNVTzl;3EBW<OUt7oPR?xzimgNuKup&1q)vy)tJ+VAb)Tzb zkVY{X+lp!%TxV6Qq-$!O;Ou^MGX_R+#$ALGTkIP8AS%8J&?ilyIN2A7AVc^!t^@dW z<<9m(W5DZ*cgfnQN#SaOE`{i5C(h-dun2c51B&a8)<;DEu{9*N5ydIzk@0S7UbX2B zW66}uNodw+w@*Db)~hx*q6n7*Q7<=)dIz4&NtNNqMtq3eLg0DrmfnS{Lwg<;Wt<1p z(U?kuyIvjIOVB0A;V`ZnwjuOxG`HH4Wa+EX5#r2cfrg<Pj%Y@nMpGrNti3{GMeJ1a z9GiS17O|ThBxntck`0a)j}<Y9A3KUu&ei%UZr>JJ&6!f}QwVyhGVP}3Or`u%BZ`D$ zIh;yZiWIJ(T@1&O2X49#g}^DdD|^awsnm>vc%2Qz=619<T?e<$o`;kr=!?1da+3>x z{lOGjnXd+7I%st5r&GnLKAPNbuL1I;NTT3V^1KHp=-Z7sIw3)~Fe)Mr+dyJ#Q3MdT z8){hpDa+6d<-?Iud!%GZHkPvyn!ebMfb6p@-t@2$^ztNIg0e;Jr9j?9MM(3y3P)0& z-3VI%fLBj>epaQ6h+U^kgrG{Aq-nmes%hHlGwLN7)?^l}K3^+&hEMFbeZ2)Z6wMXI zJ&QLcpWkU9Dz>zO#vp$DD9-y|8;C~f99KK9#xysrg|(2GkktC_+JYoXV{5>%Dugea zHrs64hAu4q>yw=|T`TOHh}~zkX~covXX>`wIteimzF-?IfCvH<YirP2t=SQ3Ra68J zTS{VkP_&h=K3cQSN9`nr6Ew=t;>2Q)cuR)31`P??(W2EB3}V}ZV)G~(!4dvr)uTpH zpm7{WMPapN`fJf~7Dz;!!~n(SqoM%fBM6G0j#)ik6mfd)LKSouUT&Gj6|@i)H8?7U znx0q0AhsCA&QB=**HFYkQM{f&+&YWv7I70dlr2q;6-5vqM^LnWLh<pUIC;B`yI%n) zVk2%mR1~A4`Qh`5(j6GY#}X7jq4=HR3;E;JFgVS^7w8A@_x$$D>+9=pWcaEAMGttx z1CV3ApZ^hUlIGkk0})94t0;a-&>yes?2YZL{0ks+7?}L>%P+tG9?EKr<EVK<Ix0Ry zz~Q4J@wj>WCjG~(xGxf%a?U?qt-$vRe6LJl4NYwZ1$jK+>Xe%Y6#te0#7Bmr_5W^a zXZpCbj8w#`R+Y-b%I6Qgp}@FSvx&FvuJ!*t`i8H+yq`qv3)L}@_&^j}pP)6mk6B|c zkDe{6AE_KzA^am`1MMy@uB{<YZtz3i13&JomrM6W#qH&p^SkW<Pk!$<B2Fd>2Dzy1 znUl+hf;hUloGs0*_S}P_KRf&L-$c<03HpCOR(!;!cB*y3(Qe&f0MlcG5hNPVVoSTw zE^?i{|AvBH=^F|lHIIV<vRss(sysA8Ze&RY#P+R2<L6DKs^LgWl$(DCB;JqWr?Tab z%NF9%I*C08!B62t3p(rf6iM(X(Wz7h!&qqd9u#{MH0}IZ0!09^9>q-B_dpZ}z4W2_ z-N=rY@q90rf4xjEv<OA36;&<&EQ%V<W4{sgv76eVX>IsYz@FKj5j3YLdfI8bRbUW5 zX1fnXKbxm+ZYTgc20Pzi6gyyo=y-5Y0!4TM8pd71hlYixVQ5$f(Q_|J{*1cf9C#fM z4;1NME52_0rdGiy!f&h9dTg~mltkcA)WtuBqQ<=FFYl<$_r2E{4c+zr^2RZc(O}j- z7~tC9)Z`TRBt#r68PapH(JyPKYFl#@{o^pf-2+&{W(e4tBOb|Dt-~g<4k?}I*xxK< z+=`wrk4zkQmdsIC5D`Z*N|Kr}e~98pw8~PJ{c9Bc49*0Zjf8-|{&J%H@{mtgRM2=y zW-*eAwY_usY?h>BCFk*3eg{`9mExL+qSX=cvdjK+2^9bF1l=u(jwY_$3Ty>jh5NX= zN|kJN9k%dRI2=A;O2IYlUn22knB8j<#h!#4D}{Y?%5FisvbJhcbP}6{NyM(_{XpV0 zc;*0!qYxQkHw50rEtk@EzGws|&gby>WrpEnUe24Pu3&(dBe__N%TkRfKCd$A7{yZM zOZlKNL8iSFNv;jbp9gtwEEZ!KQ@32M=b2>xmtx?=C}y2twOB>Q$S=~%285!b)4E9V zl$Yau(+?)mDikfp&7<g8+K@m;eHchr=Fh0oeJCc$!%%~hSb#ds$H=gY%%~c6E-o(U zi2Jn2*y(0X?Y=I#7#0+hffP>r0cvn+S-aIGp7<MA2&2Xx*bO0Whd@qZA;%Lb5-(=S zss4@Am}(fMRnB=X+dpIwinAOwG1)(nrW;YrF{hz#-Z;6#kbKlaS{8nI;~^<6ph#1* zijmbU^I}kbz08o76XVmaK~z0|UBqL>0X_{E5sW*@skZ`(KgGzQfw#Y$a#8DF3yR0q zR&1S}eLeO8DbW=73I)eq;vTK9+3E?#$E*aiCi<lQ@0+463&cG#9tPYkKrtn9hf#D- z$sU0wL87T$zoNDsVickH9ihchQ4&S1g-XidhJquQ1Pn5L@bh>n4Jcll7(Y}TgPBGY zFG+SAp3j|gFXZujNe>8LE6EI?$mGDb?%N9Ezl0<{mt|?PFt47hq1Z9UgZsN`Is0RW zfMSMRKJM(ictu(i4@VI&v_e#D$$<j@nz3QH=5ZHl6l#pglO4hMZg=0fzP|&h*}S)i zP}GH%PL>>+TNFXbnEkL9Fj<^9Ioa0}gf?Uf6jqbH-9lFqx@yvTT#3?u6GZ{Wu5rOh ztp8@~>{D?&1lpNnlR|NDKc?L6=~>}SkfE#m5$YSO0*bl>yN()9nFbU$Xm978*_{FW zf;j^e*?IK5!bZE~0CZ?*xj-@5lgS#2ugT&?=UUqGMno~k_!dEaPHB`zQMzma5L*%z zLG!=u8Z`A$k&YU~=Wd&iqiL^m44zGFW{3;t2x2c*bU<u;pCD7T@^zh)m?!K8OXFak zWe(Vgo><5o*uy-xvMzM-&{fmREpI&kA4L&cePSmu?B9gS7917D2_3CjIx6<B(4|T+ zxXhErVL8QyP@k?3P;}(88vKED1By$u^7c=!@be1v`vrXnD5f*$*~vP^8K1X?)gqHn z*HC=tjTwH9veC~(6c1@S4Pwb^=;8U<ioRMB6|tO0b-TIac^B_l6!NUz<j(snB$Lsh z6Mu(vsW>a1_|u$l%yLB;C>idexKG+=wS@QdEMhuH%@Siy&P67cS8uzbcmC&W>Pp`V z6y2Lkw$U3D1J#|lwqMp}0f>00i2aX2J;E+-(EwRE2Q9UhY*f<eJcy*DU&>2t9QCQ@ z07ZQvrbCTswgJUBeR^w}7-cu7(eDYSSdZfL`CA-wLs{yihT?IMo&Bj;2z7`k0;m~~ zGkBzVaMc3e))tKwMa^E_Ie*%{nhk6fq9_pR{O*_y{KUe`y$HpFiki@gC@v`79s@Dv zb-lccqCSo6n|6%wG#4<{+#zt+8152fRBkzmR-l*&L)i9h3n-S|DLQT10W#Yv!MF($ zG$!%+-2(-};Zy0T`0WInFFymp$w-C#jGPC`hIjLTVo#M>9E3)wajZDNaBtxGdt;oC zPk5Jqg6H7~IaH70Z<QbAnCj*9Zx}@fw)5;|i$A8%-rb-WWP*sii;?N$2j%D5@76^{ zY?!mJud(=QE@e+yU{q)*ZdnWlgC9)t5sF1a?Hu%bo_r6l&RlbMQ8Z&yJEZj?m$HT; z7B&|XrJLEZXj_3||B`bm=XJ$wxNPlp&PNWzq<=uxUIB@appij@n4m>hcpwpv70r^9 zIRi8NJl?c$o@Z>sC(LQDb&&AzfZ||<wCINAgsBn5;ZxGnBmdT6s%}F}<^1o4f3U^a zcs+_`=5PZ>l#?gk!Y(A{WqK7~ouN>2MatiCgW?{W4Ou(iu0=A6hoNW{e!_Qa?VDCs z@3?Yr%$^2ZhXz8=xj3a#nGG{12*s$bhT=*%oQGGOJ%1O)4bDEKA~f5xGiRlGCo$Yr zGb&k4u}8bRNpC9SP&K`a`?>AZUKke}im_anTadL?Kq68XuAo6RCoya#ro9KnjZ*0a zei*KhmBDipsho=Td08}><2WQO&S)RUH%{ifh_Sxel_H-b<T8IO8!2xVn24etMdFZA z&ae7CdDb%miTR8vOfABk;<cZq69yC?F^bdR5kHjKEO7IaQY1=eXaU9Jf6z%xvz80k zA%QY3-iuV+|IkS+oW`%t?xOhWclORLCdn|2<5U!t-}=UYv8A!qvfMhX!CD(D>EMcQ z7#aj5XkuuPqymCOWm?kAMQ69#?6lgtYU`?HUUbtst*v!oU3b@77hbf^$LD!@IfP~s z%#Z5(J00KqVLA8ndEV!JpYQ)VxGPFoQ*GeDNnbjObSQ;lyQKrZ*Vp0-n2kB2h}yz= zbjgcSA9sascL*|B#KVLnBt^qn8OxKKf5g6Nj0D{ug%b+mFO7kE$rAY{JfWb~j3{bC z=H`f_x1u&3MQn%Ic(8qMBvRj12l;z_Uwd=2qqh}OwqgfGF#r|x5<^ME0jKNwn(UaF zrBD`a!=^CRUPtTsB#JXc$2uK>NM|K8;rvYEB9_p3MX}OU^iz0}`?y086+K6Ts9mZI z6d@`G`p7N!PZhMSu|`zU;;4xEThmaaLmN^kc6IlHYCW#{WzsyLsNgLA<i&z+t`ctX zDL|1riID^iJAc?0L82mE%rT697-F+5q+Uo%X@9t1ypXMlM)k+le&lnFPU<{Zv|vlk zIWd(|s@C8Qwf~lP3q!t9ArFGx^a`AI>ZD2>VU6r&e6P{EwaTkMLAIUyRUwlcw-!Y{ zpO$Px&kov80d>a>XPhSY@+=m(Y1NX?sJPZT$^qgq*C|q&U5A;moy4Ne`}Q!Irgr{X zu0$>B<#s4jrgmmTkq)I$EZT)K?cCSrw&wvwma`a=7jrtf3Vu(sDo5c&kvfSXi3uk$ z5p@!qKaqY{jVA44&E{Xct4EX8Av<I2H=UB4>k%j0wKpP@{mzJaJzk}>@pR9O42^>! zUCYU9RNTKMZD~<&z}KY#u1h3~dK#UC!%--zPr7Eg@eV~1tzfi=T=ik4XfL+|qUt&h zH?eoLbc5AXd`L}((pBA@W7z^K$In)-BgN&OMvswCPdf@DX6U4o*xZDZ*lOw|1_^r7 zmC-M|slMJzO6hSmPWg->5kSmiRBVg=wBfQL(!SVQ)oW=i0wB9wjhouqx|W49QDn6B zp4x4FYt8ErMNhZ+aJ#R=RcnG3%5_{v*Y?^DSH!9kMI)YNZ8frW+`g`3bSS?lsw%GN z!$)nFJ`xYT6@LHXW>*O_g-4~F#L7oIiOoqkiSdr&GDokod|K8hX2Li<e{;nuQ^p~u zO)V~u&Ex8fVJNI?YIJ!#w(e17i---+vcavE5=4=+SS+57-b#avoW{brZ0*(qmVgz` ztAc;6$(|VEU?{&R>V38ro2$`DGP111W3zeo9n<k06lqk11TDc79Y1U`-VVVisgsy^ z(v{JVCR*M<?T=BU!l;<9J!osOjLA4|vf5PDR3$AX!wg#&avs#H05O%Eg@M$;YD%3x zY7NQl@Jdcps-jJ2Dx<YVC#&{`;2!IadesaJIbo;{htkB9mdbKOalPJISs`65i5D!Y zXjPk5H@AEW?;?FU_(g$|P$w}E{7P7vE^QC`<(HAc0bVpXGNj1`MeMW%5c6Yd*QaO4 zKIEMlr=xoUx0v`{`lgH_RQ}u{aQQBU9$XXzhwwp<Ra+HrSENp2tCLP*v~1B_x-dLE zk0%WepM9g5_D54i+6)nA@l?(z7R6?Z{#F&XQAr{$Vun^MAhz(hnuB!<KHkFG>0-{3 zp#k1Fq%;n^&Lt>fh87;PDr6L~WFdQh3(6G|%+F9k)6EtT=~tYOBwoBdk9Q%9*;g$n z5)?5i_6R6WDOAOm6-n6=cM_wWIoLYOut^kO56mk7jmzSg9Hwx@sJKyxiUo`!t)S6g zQGqBXoWy9qBHj4YjNBwF+`Mp>7hRzL{UuGdb48-~Tv3RMh~iw$qQcbqH6U;gTXULl z2}EMk;#}N^1{(3?mSS92jHl<}vx7sg=UnDNufBa4CSmdN(_iZD1oZUNe~)6}I*Bzj zkT3Haz)6gH+~J>1!bxoT99`X1@xl=T!tJ4+k58W6xi@ptwesEP4<sype)qd~j;nij z{&N)lDn_DMTCjpA2*|U~WMw<vs909Uva{_fFfNhru4xdz93&ik>3Q+&`b>WG?mNlR zUmxaxBI-X!F(fTq8I4l-00o2La4Z%MhrqH)tJRuJrh{H@^on)=o(A#I011k(pFX=W zlP}#TVeyfGVh&;rhU$V<F;P(wd{SF6H?b4jwaX6zJdZ@RQ^iAMsyMjxJzpduijVMT zcyM1p@n01~q-4sJc+M%NWxEQ5hGKQqfTufVoS#7P?X{Ww>7jt)KQ0C&0uW^&R>l&W zJ0!6bw(5(E5k+Y-Dn8C)qR119D+Lt)S}~|HMp?$Nh$674qbSx96!k%462+@o<Yxgz zL0O|ndP<bg5QZSK7!+xOmXib>OeN^&0*Zn%mH)XSWau(X(Dr0hq;th!DnUQbf*b)w zL0L-)30f(FszsJwwy3EKvO6rGC}=W-`59?cvOm~6m)9nOIF2uPv34Oe5pswK9)e!H z2wuEIQLrJU^_5nu@zvJGYHHQCK2lo+i`G^U#Q77Jh288fdo{c4mdzy^K`#b^U=Df^ z74hiF-)}Z)j81%1O%u&GJ<RNM6KFsDUh~V24}Orv{{9d}vE-mT7dlSVKv5QiDvvGX z7q!abVooZL)eJk|af%xAdPXnm%R+H$3&kcDu!w;oyfAHn1Uf_=G$`iAirw8ctfK6Q zViihKR!LWIQp6>k@^+C~1`?G#lPDplEViuT|0kYWMZgi#7E~!#+!9>7=lfPsDiD&- zRH5ko0!30mF{h;1C=!Q_;v!ilid$PKHm}@b4(In^h1=&Tl@;M+0w590VkENAv4M@E zE)r5OTPU{lXT*a+<ouibAlE3;3>rv;U@-<HVu^bd3q|C`OB7ATu_~LoAt8!%BBc#e zsD+}Mk#t?ks4j{bO*e4t-lt2l+CuSv6*S@CNd!FS^H2|s(PAlsMh{)vL2D_pm;#n? zETz1Jh}jgPsOl*~h~?BkQ8sXyq>y2e6mcRtxSGk^IL^zzf#TMmLb2)3NBgJcc|Z-K z8z+L+VpTEFj?EDh<4hFQv|?+Hk}}bXrHEqN79ohDW)ll1Y!ub<GTtZ>yifF6z@MBK z714$(X|)b0u4!+n;S>QOa`?hi{?5W7fAEZ;L+3lX7Z%1RCbnJP$IPJ3A}N}NO?0qg z4pDNZpxcOICQGceAmlAJin4B}blG$)uciWu-mH`{3Sc9_$a=F{228DG{%sVS{w&>p zR58>Zcm)E`G3KHPNFtDj4s~>lPn@~WOj|TtNy|ck6v0EMNI^gks{o3U>$KIy8V*{} zBtZ~#%CJa86X~?9^y<82>9{}?{Wnl-#fr@<zT6JM`!H{z8MM0z4U`7ljXws8z@1mj zW1=FOs;nrEODCWRhEh{;QY%(8jl7e~S|p7qX5Ffg*O7CC6dlLO5wFui@xK)95aVG7 z8frPEe#J^>&Yl2n{4q=1QkD=gm9hvRB@nk%tzp`ti$ubSS;IkVMT;n+MO+kf^jEVa z2lNpOMZ^}0|EYLan*c>>6+KJs5L>XvyGA>NYFI!bNFjwx<`=A@kb_LyN#{ft#bVhi zW^!K9$%Arftyxj@1^ryZiw~Y&n5fdF^Lsp8BZ#N+gD{bHOWYyXK?90V%weJ^IK<9t zprWEk<ybLoRboY%S<FG~NY+#lSc;;Jv7#Z;Skcy0oM=KLqZk?O2{L<10{afkAN+Qy zYvxj!&qH_TV10$f2QK$)9IDdE?V}spxrPvR&?pa8|56wCo*3=oW;kdBE|;MLn>cEY zSdJv=DK~@mifL0yi`6J<63SE&Macw$T@<~Gl4)cygEms$qGn3@RH{B!F&J5vDY%ii z#yrMv-|U6S=(TVEqhrzS<<FVxn~rcRt@USmUOoIu+Xs`IyI0<z^Hi9%peTx=B^1}X zvEsLBi>xbR+8t%Rb_T$-3R&BWD5|<m>}*z4s!)Vw)S>_m8phz)T@;Ce6RdFyj-{ls zSu8l#1;w*-_t!4t&p&*$YYXf8<^A(*eMi1U@j`g0jN<vDyH?&Rw)gZtd-=LbkK3Z* z__{sZii^kBCYnH(+PFjICb1YzTUdM008~M8hiQvQs#Xx`Zi|veKV48@;wYlA)C{H& zS2mc%qJ_Uoi#awa7Q95U9TSrm2LV-z8ovGCNAb|cuBnCfKYIS*(vZh->0EHuQxdlf z2fLC>DDo^6J;9Kl{SkH4@X1#%tMzO&9u6nBhq#p&PX&8_o7}vmzl>sxR&zR8D9Vx{ z$>lnsA;4VIb#Si+GL?}Gm<Sm3xl&EdaHYvm%z;${u0XG&X231FA;AzNNOVQT8w~01 zqquQ<Pw(lky|jN~X8QW<F3OB=eBGVtgTpxNnLpn?GkuO)#kJ_?cHO&v@3^n()}Ato z>(7l|s%aIc=5Mc`yLWw^>#NtC*?s*Yykp(eIrQpjm7csvhQra#F>d9>(@>Fjvlc|r zwTiS~F~GEnY{{}($**zD7G3>vS*>wj9Z;k&wpV-UxeJMrk>oVu<LNz|xH6b%I|SqF z@sr2m@p*^|lX%#DY)5i%B#}JHMlm*h>Kp^bsl-L#Z-3v;d&zh-J{Cl1Hx5pYOeWUV z1q3#Vk4M7c@Rj2{*8t*q#1T;3<Ti<wySQ;DhPKXjY-pM<6#OcR2;+?)S5dHS;9zIu z?0NLZr{O5g$aq`)U_WFZ;mMKXr-8IH@v*&}f3)x7?Z}x#BEYtaT{9C56n72W8Rq!5 z=w$M4_qN194}3)L<gwn!{jt7YA6FkCich}O<M%*fa`SDj0faeA*({=mu5@u@HK#oS zY0HU!7)5~b+(gAoM{W(Efj}D(8XcJRaQxihozsZo;Z7f3rYMe&C42pxe}8z0i6Xxy z<ogba@u~GZKO5ZvImG_HQ6J|&nAltg7tKWR(Z^^woR}S&;2J<YkL4U>(Zkacx2Iwi z5yj5#j^_Cu^m0%{826U_)0)}nm8pI@TzjPNZXght8X4J#D0U%TB^1w1UcCuRN23>+ zC{oo%aURX^OmsiTUAi#X1@Chpd8AHN9z^lQqc8Mk00PDL?-~R}1d;CidFUo|DQhXA zh_PbDDn4)Yr$a0YMTGHq+0}NBg~Nw;t$|VCRM^$2n~36^zk=eyzS7c><)AneDx-K~ zGVE%kldFd+D87A8NqnA!55M}hQBb7vqlflTtJn{lEg(d(9n{%fLGe-M=gDa*6uWwt z%4)IE!DzUxA5n}?&!9FAe~aSb&2(wk@1mG!n?ZHet>8#eeEu={{w<RD0Z1Ht^Qd7^ zq%=~C=&Ra;F2#ypp!muBc@N!0D1K(|>|z?JqBuT=S}dK|m{v(_ZK8sjASB|0Nt1<A zNGU1HH<V=xL!_O;KubShv4uiusRarYSP~IY;~HaPeDJ|<AAC|DOf(_tM&n0fG;7rO z88v=I&%HBkX(_huVmoI0XPCJIWgj-boO92;=bqELVjvHPE)G-69O`0f>L)m*p$HC| zUL&wB55;NL(nRD}fFh6x*7%#RFI@NmNHqQMrf^WiMiIeCrc@GBfKn@oJ#_J{0-D9w z-}rA(Y;9Ug#;@=n0ry~U6vCGE-iRVIiZjm9cG*9mD3_Btp(qWHG^>fc3Q)Z8^*6mO zh{X@!G4joY3l{`}B4&|58-L~TN@CoyVl7_F!PO!7{sa%a{Od2T70fRF{v=oG^JG!% zY0?~qL7|y34t6?wTjBr3McJcgl*)-S>U0$4>n8V{u|w+WOz!R4CLDIUYr=?PA5EVz ziDI<P1?p61K(T!Iti?K^l#ZRrS85DK@xqtiVHUZGqHs{edr(~10w|(vh!h7c#St_V zKt}rZ;;(N#|Ju`qppo~_@BH=iWubV@)2U0`lS|5!C2m)Mny+@6=s`r(oY&+FZ<+&| zbQB3`^X%+ux5u|h#I@vcGQFd;6Lo^_h}c^RUcQ!DFAFmFWk8Xrv@&*cx5PQ0x6Bxf zB4!cm?3Wh=g(6;7yo0MG1{aXXZ~Q6a4!Y{chjB6PZ@;?u+grapev<kmUGHbodvE`V zOL0H>%Db8Le6D)tmz0ga^Xc9C6xyJZHmkVB9hs)v>7!R0jX+M|9LcfjS?EBY>j~06 zr)PzTYkV_;)r=>bo8ttpXdr?m87DOJjo|RDt9>%$tyi_!m<~&vK4(yy&#>h~5YOW1 z4<8~421QIGfCzRGlvdQvXhZcCMPKn<)n0n>(Sqp3m$=?)FJ8>CWsClhl0Ss6B#P~Q zt_(Q<GNqxCjK9bSJEa3eMh(~|6eMx^l1V3&`Et(~#SbujypR4uSSaFUMWP%~#10y> z$Zxj9tImR1eBdSl=%q)*mw+M<WC-6ANn*n@wSw4q&94B(FR&1c-+j%Gg@Gcrix5Dg z!!3LS9nZ`eOrj{d`0c|t6<iNLdiSNF7(x(oS0Z&*DJQN#*>3;fZBAc)XZbQdynTic zfRdFy!6eEP$E-kHQ9JCQ1;OGw4?KEN{O?iZ$04|`)`za_9)AR(oc#XlIDkL!gRehm zA0vby5`?RL%J`x=iArLF2^2AlKRyJJL*ew?Lw^8?mxJQfMHGp8jrRKw()7LdzQU)M zCn||09CR6uph30V*%qS_IcThkuYP>-r3W4^h#q+9#UH<_5ML^a&}x!r@k&RLtkq1W zAG2y7?-0VQ8BquooWMb+RuW4bv%;0ccvW0{`H=$Y<%<B~rJ#sLAv{7h@rt*K1Ub-Q zw57<XR11Mb%p!p|{t}hM5=mk>Y%w6K_@AjH7h%}Y?Gmlx)f|V|HeT6Hc!ezz1T4ax zKa+nr9RihiLPhO(6^2AW5$n>eBA7!QKZ8-!7f}?dNFGHwC?2)&Nn)r)ff1}?oA6N- z|Fcz0cFDiOTayc0@vsFgabx!kaSP|4;o|ZYb9K<$gKO6&UQS;(ReC8bcAl%r#-eQ{ zmOF|t0tORZ@~`;0qJYI6C?NPsVtl?L2rnz*V^*%4MVZy+8QM7f9&`9-5-)YDf!g@^ zx`k#=j+(42hTWZ6P%K@gtonaz6%mN=U9^hA6;Mc`m<85ykX4j}gN{egs46^P9U`Ol z)-B9fl_;r=A^Ke6<sQFT5g*U_ES&uEtai~uxw5$EP?$Nd|F>2VyXT@+6t+mN%O9>J z#uv>&4jNo^2S{o=Hf%9^ESA>N+)(W997IxwazZg1i@QK#?ks}v9cU~r<_K6gYDu2S zFN1pAYIQvhTcAS$o-4XC&lM}?*dQG&<6iE*s<d>Q;83i(txk8#sasM|9J(d(XQ%3J z+utp{=d|eVdvv#4RUs-7@7HaG?kU~fso+q2Y=2L;w=c#BZr!t6y0?Q-gpcTUw-JPO zyIXMAZ|&)Hdpr6pD8eXd6!k@`C}i<L3!n%}rbAS6J^qf5pf?uWODbmVG#cO1*Uh?B zi&2c?#-xYxt#_C+qgc};S<#x=;PQ>*tBku^Q6bVzdgg{#DgU~33!}Ky6Y%=2WqNoi z9hR_Ez!4Ldh_^eNonCWeEl}u)*nq^E;dz#wU%6GE-70bq#A0!-C}5HNCN!#<gT*C@ z)uON^akeFsT#;_|oNrwR!&6O+JF@CDn-PjPswg@Tp#5|TiltRZFur!3HTzd1USHH1 z@tB!FOjOgznw|btGZj$k0YzpW{@h0`#7auG9bS5M)oIz>E7`h^c6-8pucTHlu4dZ6 zG+G(wriAudb^o}sh#w*R3M>{k{sgSUHD}9lsn6s=Xvh-dYvyFosY$B!hT5RB9{4g+ zzLlE0u9Gkb#df!Oy6&DCrzK^sIEA;EWC%se>h!4%6~#2hsuVQ43@BRM{p7ZynQGPn ziWX;AUCo@?e}73yWkYbeZri|8oh7<{wtrWz9tyODI22<(=d^z3eo3@8>moM{IS`8* ze*zbY+6dve1uI$9jw|0Zl^Ml>X6KA(KT0j_i$qo?3h_utLj#K2-Ao_+sG=_gMGJ%E zjUp7O*4sp)MJK%h)5;<5Bto(ILGZ@L2rCnVRdm2O=5P;#e^$%3O2naVrl};Ra`)7P z#4*LKoK@66$e0a#`ke>WyV)j-aUUJh7p<b8#bt=WJ*}u+WxS}}OhyzdrfJDoET(mb z!9z>DT_R9r7*LdX*a7qsqYk6!UvPjLmk^3RxQnhcOKJec9&ZnzNcEr~Wj|~g)5BbG z5ypG%)FeE%WrnHcaSzi|vbVyT`@5dl*azycRowMZo~9{<PM<Y|<|%|LR7?^RvQPxg z2hg|)?_m@>q{mvt(%UWmsKc@8r6BO2S(^wXR{@H~fS<&Xj4xx@0w_AWFp6P>Vk<_` zy@J<tRLuD;ele$R5}{bS*zEMtP79zYe$YDa_C|)5OL-KxCK~)+R-#qz<d6}8Z}3&z zgBG&l1(5locHp1+vn}AD6ScUHs#ap5gCMV^{Wej6ZNomh8c?hZ(sJ~2Bbz&l;H7~@ zeKoTjN<nejPpc;T7K4CdiFnsG*C=7l_wR5hiuD^a?a_$0S)J2KE6y+$_n?I=GO-EG z_iZT~;H@H8s3bFrcXzSD`wSo}8@OJyK;2#iK6@+zDC#yD*J*%k!je0RmZ4H)RD(>V z_%Mp%ero7J2&$_AMZK<6FWyr&P}Uj_#qF9su|BpGba!R<&`IN1w2A^2iG`z<JK`jQ zl9j}!GNBlAc-!wrgPK*?{99xKw$l}I2L&irIH>Nj3XwegZ&37)UnRO;>t2nOq@dVH zIciGuQ*J=<R%_z~tl;!hS{)a*D5F|PicoCQ=W;q~6@u%KgO*hmB{bE76mZ2G{wZ;e zA_y$r#F;Z^Tx(tDGAwa-_yaCHsB%yX6*UdayyM<#vztB#zw%JsR%^G9O%Gc@tv6;w zk#Yyttx?*yw3C8j$qP<;VX`se0~Bi(sQI3`em{Nx7KdUz&8j9>RK99;b`<eMkw4o~ z?0hO@88Le{B!j_b=<Gy|PoeW^+uF>`^ttnkM^QZW0;8(ohG*Qq(yDqDO?mzO)d<DY zu4Xqy1^UdH(jmx0DBcMuwqq213sE2CU7fpLlt8fwp;*)Iq*(X*0-zYGUH7p*_k5p@ z4_o#%9<SR+s|?#&QG^lq2qhMC%FBuprt0hATaD{BffSr?27zfDTb?=Uper^E;DoX2 zq=wtzT{%6ixV21*_}njlqH9WB*P*;8;gqEYPRdiFeVGz{=z66ZIe5ZG0*dtThC$;} z-%<rA*4jz|Mg4|t10K4;=`KTzG?4I<*c10_#?*TNo!X#-`%ZnQX88$nD>WhF_+{>p zzL*XnY$YP-M7|;r$?vu(<4I!KRdxFGp|{(B)0_n;-Y2TKyCP$vPH0P<80)uEGjjA> zTWQHTnPH4SfW+bwH(6<LU6&%)ghDVq{?H8<g@>=QBbCIaPT*`yb`%r(cP9(7qL^^b zczydatm29E`cbrX4iE(ushFBxPLpP3MF735lGPzd0;8DR_)~C|#0+RL=RcLMeO`0u z^@LHxFv7*3CrF?uZ7Vz8No1ssnVr5oaFr_i$cTH5D5UCLYl9!B>9O_by`2I$f6ApR z5;#i?I80U&tK=(*wSj~FPgQl>_95q<GmE*Sh+*W<wrnLTiD~C-8G8Jw>?XV2Zt*qD z5b3gyXo#G(V)qz`RLQNq-i38lVQYd^&OGt)XQ}#Bt5T^1(3BOOg9gb-Sl=dP<v?Qc z@F@;m3@D2`5Bg70#2|8~tq#{$JU@5@#&C<Bb+fa*Exlp&<)GN!5=m#y<}qoBLaTE5 ziC0tf@xdIBXq_O0AY3qq;4^a&i`)`7pE_$p=@9wViF#-~Zx)YO#oIycn#%HY6dM%C zeK(Bsddf}~#q0cMn}|FsJBrVK9#yG^G==ZMOOPN$BjhW>g&ViP*%m%`wjfp!bkcDP zwu<OG#VTS=wyDcAph%F`UQ;`Is*Rlng`7tb>T((eWjFwlVo)okYJ&UJgsrk(sVGlD z5q@1?UTf==%HSjQ_t9r>mnvXbUJL)Gv@r1tM)9YgUVRo(2-i=qI8>@=tBnwXxCRAx z0E{>@C)rqy&&)yRp!2PhM3Glo>MWqhYuKPB(@_Meoh=bLA)gp>pS6UiWf;Z2CZ~ON z{yacLHu$h188Rb7Cm&m2&$6nXK)5m$MTc``x|%W3&?8kg%#MyQbi)K8TkfXLTFhD{ zk$(Y-pFSJctIt0B)2H_WiT5rEqDwxuia1|UE>EV;q8-89=Zb<xQGfWvpFSN$koE=X zz)=)sx3@4xVnPCC+ao6b7zrr$Hd|Pl8DW=5qTJsyhfJks#DN-9dPdoB*hlrUgQ+M= zdc$spcK6y{&_~s08u9w02C|Q_`y0aSXt#pMzc7kPaTCSQmxY2NN#aUkiNu`5Tyd}i z7qz=tly{xHRRkI{TSZW-Mp>4QVtH4~SxtSvNn#`_JtM8~dwUDpuar;wd%J5>QB*gM zIH791O)_#6#Zmu~OzlRWBHGNB6?iC}BSQlO*~XfzME=F2c)*j0CW?;FKNSRuKq2mu z4=~1y+Qm=&DUt<{vq}(VF(ZM=C%*Jqdi*6&B&S-=F1jMKT9`Xq?GgpDiv0-D_ECB{ z6~!}=Q3rY%o;`}9yAAAVLvM8w#Ywxx$XQ);{yWq2C_eT1D+h?jSB6xog^vz|fnuVP z7@(L|)NW9LQOwan3&1QMXAgO!$eG1VDE17usgIzjX|YUqF(%aKFE~m|6A|<hL-nPi z*u?;2$Drs?b4^+jD3Yqt`C0;=Gc8p9mly%XR}K!I`e?ls9tWRVVWRl`rvgC{IK(L4 z5ibwHlZdTi!B7O9<iesp`N%X^oSRl0oh!;)Td0onvm*?Pv^khSv5RGfQ&C)+rTUIT z(ORF5V)qCa+;sL@^4|~~qxjV4>nfENp5MbnvHz6=!JvqA2aw1c#esojsZV^&YAUw~ zS^#G8I1YKch`utQ*rbt`XNaH&g1y1=af_vK9BECKw2GAXzEl(!EzDf*C^nBsFp91g zCjWbYJc<q#V(}xGD6W5gAQTi4i+I8quOyaIbrvt?<QBFFmc{rQH#{?-*gkHMWn5QW zGMSoy9=n!ITjE|ZnWqqnEAV%N6hd(ddZd;EysFV0P$c@fwr%p^7Iy(cXx>317Og|z zp68wt42p^K1b1+YImyGPig;tS|2c|(vv+n)Nkm})uGo=5H>t2MVW?58Cdy{8$v#oQ z(898;Ox;xsVb!GqSJ9T?!yp17MX-x%ys4RP`U73`7yJv|G}900AM~EHD~LgwPPr9N zjeCxZUO3O3@AJN5!&tO~?tF4vORn8*86ZhgImF#tFzjd;9G=-L+!e>u78TfM8aBcB zFL}+<LRKlRAr)&<_w2JB2@QLXtyy2iNoKSM#5F{Q+qdBe0;u@m!-r*X5%X>N10W3* zMHh2JMchT_$BOD-m_cv<Bw94Dw2{%mJ?Novyzf`2qTduwwa1;qG1!(RU%;B8t0(aI zu>mdSP^V{yOjDd2t!<Ao;jo>-%QOcU>0zgz=N0$44XCJmJj%MB1r(zkNdBk6Dq<Js zG{9r10G}kGA_?FxpdyYWrbOE<SVe;{Z9$R5HpaF$i$9;VSl4vWZPP`LjNZ9+Z*+9@ zku%a}LsexW_UO^n)YO8on8Qs?J+cp>1@W=S@cmJ{JA_vZD-#+!rwH7AMCVn!7r$Lh zMWCkF`N%nSf2Mmo_I<I6*hSPmfBhgK6?3`Cv5I&tM_l8^IsWj`S!t;#+e8PAY+Q3* zaisf}vRLA=MTBp>N_?qOU-Y!LT^xa~xo1ebceZutb|qc`xAj2rV24kQYlaTkXm;J7 z$Zh=9B+%zN68P*-Rbm89gvKTf_#ONjS7*0vJ50nX=3M-|EG-pb(o!mt*nkj8?5|gG zh1JI)R7!G#e;#GO@KF`$sI1KStEz<hYP9id$3ef102>M0bX2v$_f}MK`SZ7B;KMSg z=##=JZW1G`<p`0)asiN01mq3hZ2=_i;%^KKKdo{2#@<DS8EK@-`}ryE=bx6>@a64I z!w!i6Dw0@47%Ub<68p8qoUGb6pR3%MoR$~7h5LLP!0hfTu3|=eQM)-6#gwO*-=kvB z)IH!D|5W<PR1XgL623y<8#W0XSHw50@IEvg6ccw_v@L>(1JEv(iX?`4kxcDaU9X;_ zeYuJ;9yF}_Xo}|Tr`_w@_@0_5-YmZH_}f;>n?5G?n^Yuk4fPJXF81&E3m^^SzC;1O zy|*M`q8I?gKs&$x7&nRs@p(ltSq3_<SS740md;S%?AuU=f@l}(bW-qt&Pc3-%^51* zMZfA|J)2X}x~iP{?=PQ98R70J3>Hb~pv4(9z6K5aw1c*V7-#E-G89bH)bV+}d6wmd zwyYv%GgD|xIV`+{A;H6y3<ao%&P`hy#7JV(CBnk%0&K{e?8jyOlDx6LjubN#WcQ~V zn^$KjaPf0>@MxOlG&<eR+N>~ktUX37nVXN9)3rPGH|px^_aD<^6?JuuY55YA0jtrR zHaADNs-j4=tfG_=vRNS)l_cJSR_6Agv5F-x6wIeMw}zQ+LS=a%#&V`-8l<BBU>9U4 z2v^a06*Ww!5jiSfd}yr;1ZOi)F}4TQ`WL~+?hxyBRgRcAHtDWIDkiI-yfBm|fToe& zBoz!#FNrE{-bJgm+$u^P5=0b(+TrsM;@y^fP`gseG9W`i3q-4{g<`gg@kb_TAwxmE ziSmX*H0{r;=;3C@>aU26=_1#zgy)!-HWO~AmyS$$`3VI*k!0DuQBctyq(c!q>oCJC zykmxqE8s;Ux)l}k9+qR~NST#|#S<VRfEq<{w?zyKf3vuXFCjxgGlZDcLQmR3*#nK) zz8C{4>btn$3!@Qsx$-Iw#Gsk{XsdjMD%u!54K1XDbzA`z`A)g<iJe&(IW}*i9L=Dj zGtyx+_jtWe^#pl`pVL~?oxE3DpdzrT9@<)N6{U>01q~(&8-L1G`Je~X&_S0tuh?=L zG8AM|)RQHG=w-r9(1tB~g$xDnP=<n!SVfVM)C}+B6&`gIR%JS=u9py;mbd9Z#W?ib zm3P<x2>rxvGJ}c~S`gab%D9#YUog_Ihb6@rAK0>r*78_U>WGaZa`D8<!JJ&)meMJN zbP2nnue!RGTUeW+AXJc{Kt$emSEH~q$+uw9ByCa><2XZsn`wuaJ5uyTc=+hkwV<Nk zNT3RvswUdFUNf3S2dJ>1;<_%DXV8B$BmlQhRe(~3kIv>U6sSvIv)b=)(wf0R1y2pE zm!V)~joQ!?VPefP*=r4bQ|Dj<S)^iEP%#0IX+gyxff)1NX(3#cry2dck692@+-kE} z&f6koNQ96<NLb8S)j_LEUnr=VaN0uv@9fMFGwdYpv&9SrN+^pN3S@{(dOnJt)<q`X z0M%L6qq^fY=!>gp&k(>(zv(s6#o~2K**nHmR`K75TuJdqibF*RKU=T|Jz1=SKK7Ik zxotoz7dI1O$^l;K`huY1{ur|tWhfYfv7$_%@vf%70@>5T#9QF`Fw*V`rW&DCOhtYG z%Gm&8X(qbqJM&PfNby|-Dq?<3#c~HNeezLfVXUaiMH0hfMI6+w=y}ET9P4SqjbD-( z*LO4V+fkiz5N9Z`@UfN(nNpEg(U_v<log<)i-~2SUOQ+HvfUX$McG;v8B;Y8eHh|~ zbVS1hH!IgieSUw(7F8^~P*4JL!0l;0US_*+2po5~1bSV)7>mX77%`~1TSP@QJ=2E^ zdJC1()oPgJpe5$zKt<@fsRfHA=4U}gk>_zX*4yT2=j_k0L_L1zjFu2ogs+7vvi8%K zxe%{Wq3H8ougMV(Qk}*^6*0foDz2}hYTRXtDauHMi5wvWq^nBC!w+O@$v%M$1w!$* zpOX{Hl$YV-E*LAqh;YorQB?9BombH~7UL<7XOfGraJ@$1beUy273WhyA3D7ws2Kkk zrzrc}Egd>>(W78_D%oj<qGufyx7tCI59dsQ7WsiP+en=pvmgGQI@Ji&*H>3pUnbG$ zv0rQJ*!2Sy^=eWt6kpb;t-C7H4ddf2X3`+vwM&+nuStycXB!OJd_ect>h88@w*Dod zs*SOeR#Y&nU!!Tw>jpVI<c7){M6+7EQ#<~`kZvLn%_?=Gs$UKzYkD9pE94hfbF4pC zv7yc6yME;SzB1dz`8|8ipFh6`II`!+IpFZoqlXS%I&<d2)vISup4_dM@7TR-ePp@{ zS*|RL>SSxR$rzU^#BwG8(_>jN2m##<B2SaP)S>RpY`2tFu_NU&?kV$~z4L8KB8cNS z788>Q<sfFrm>kDthY_bvjCr1^SshBI1gC-Gbx4GPRFh>28d(-r+P|4<deocf?e*K` z!fZqYq<U~49d3WSck<*j-`y2B{wb$&7M?nVJv<2_Hl6F~=^pCp>Y{ZPyXk~@s8kN` z0XKg1er)_%fzeVvU~sS#bp4k9<Z*?62PlZac?h&Nfr=1`-4Kdy+M)&(4dB)R%BZ=u zxW2|g<L|my^qo1^jy^u6@Gk)YK|&meAR<i8Xm$n>yWBKnqQy=*4B~;hsDAhH8Jeog zk+G6kEUu#eyh0&bds?@PlRZuNC|AJw1K^|#60r$H>_Hyl$r+nSlAW8!M6A}nfATVx zOVw1oTtvl_3YaEZ?B3a<n_ZgUu3k&&e7ki>Gd$KpxmyeUEuFjR<i2PH<Sax#J-I}b zmx*diC&_HyEHM>jC9C0L1zYI-q++WAmO-CdnmxCp%Q7g8Y*!!nZ2nx+N<1n=B`=)6 zD{SOJW9$9^0WnxZ@DS*N$yp~_M75nHsT$|aGE)(#s*1n?PtZ*Yh^}#-UsvtuvV)4- z)dfELt4Z}oQ}Y)_vPZj{c1Qoj+t{=(dN4Q*v4=yjNJOhdv`i#BJE>ldy;<@yvEpE? z${zZ1F%@Te6p#rV+(LZG-<_`kG9lcM3t*gI?UAVuBwNt`TQukLqqrX(ano(p3~dh; zMmF$V&O-1I?^bA0gxC5=SSM0UO=DY2`Kbu}KPm!6RP0s&hNgtr7Jr42OS(?0J?2OV z7g6ChHE3<j9KYHv<BxASx345?wOW-LHQQ@R(V%s7cZ&um4Rx2XW4J*xRP3qY7fXoq z5GNu`&32E6qIzpMBT}&xc8Xc1j8#(c^4=;ADFEbzF#Ax5P39{5+&a9bJK+^hLtz;{ z8-o{R2l@3OnTL_U9NCp?cMXgt1CiA=3fhU#Ykx3)YiLNdZZ^V&@Y%UY;7T8yS&*(@ zxB;|j7DbC%ZHLJjL}WNZV=~wdRg#KO|3513or=qD1wg;JXftG_TXtN17h;2#rh^N@ zX(+V8aR2B;c9CCq%dlQwY+j|q?Qe<r(UFNKfe%nV;GYK`m@l~9HX*2j3sZ|Lqy0jr z*S#mSj7}6`vw}n<<wWEfH5zMeLxrgbRLjL9yHUQ1v;s}5=OnMab41GCM3prrJ<`$Y z$)qq#)7(aMP(#xvw)k~gM!cJj3P<NS9Zg&A2q~7f&n)$uXgbX=+%VA=n(h#Sbu?j) zkM`0`+E-5(MyI27fT%kp$06*RJ+NEp1rr-xMw7|f*HF<~5qip!vGiE1Tt!hq6l=2a zr=mC+Tl%4f${!8c;Xq6av!bX?hQ~zUF`vqxuC^s2e0aLfB6e;>-+(vwLcwNHO!NIU zc)USKo)B+`V)tO^mb4-k#$pjI=n*u;9(p_=BAED|a}k7Qz~RuhRGx~t!+)>hE46~! zem#0$#W2Ubyx9unhGZt;U|bPq)#|ly?v`ABKBeBqbm4ha+9K3k(ib{=_H247P_I^} zd4DG!y)Gn=slPA8(=e3uWr{pGau97)IzdD1A%i?5j7C$t)v2;gi4}yR+$Hx{=wh{1 zBo#<%nvbJ5t_JwnB$P*e2@f3FSA+?Yd=<~MkN~Ji{!Z;|)Hg$F7Jc_u5&g|1ndW~` zc&u4S-Xxdf@gN==B=^JvQAmP>SVQoz1_z?X*xqj4)U$OB&4&&m70cL8|7{g7c@#X> z1u2L~#-$O$<Jt0UP^cGF^mtyyR~tOQ44?Asz_H3d@Mx0JL<gcz<MCwp#|$3Q3dugt z<Au;19x{0L0xO8=WqLUPiHH-?>SS5g(4akZP^nm{jFtY6yO@fU0_FFmrx4f8zKo5c zR-|<XdReb9NKtFy#YqY{&8MiH^!rvRVng!wQZgCd&*8?fkZhqQLkl0MqVyst<{JZP z$T5vB^p<Yet-#y4^?H^))Ap%(SXWLe0=uLlrhFGG+(H*qkx^ih(i(#q4+u|dm~lax zWNJ1C<IzEe(WZQ}PR8Yr@IgkVww8lON0Lu4++;NTl#$8sGX!qj7D642(=0u2VTw_c zgR9{Pjv%mz;2|s$!9*2n_|&JpU1+U{*;zteEEVyw6#klu^Dc#9U%-)Top``+oN&R^ z8@^(G5)MWaF4w@U5Ko&^3u!*+k{OL{&5ti<q;Q|hwK*Y$%`-Cz^BtEf%g-2Hh`Z5H zgUfX_6%C$#e5rrMwKqhgtC7$UMl>%Y5AkPPSXKo$MgDXQKHE~p4m#i7y&J01C}D=K zKt)2KpHIjw&BgfQ7(v*wyibZP_eW9xi8pbdv@|-x2ML+^B?-MTXZ5NEu4tPNNYSW} zh0C)1vWY;9MMF~rF)(~qfT8#bQ5c+q$U*ou0Voe0utwCYRCVxO<$blb+jn<Q#XPty zEM~!hlBu?eqecb2!D*DS*44Fx6s&fxzRsa<)1y9T$IFL(R;z){pHy4FJo0K-Wx|!? z*x1w89V}eN8mvZ4dmD?!OnTePr(*`au`uAD(KLV@bYS#Oryfnsb#=L$me}CSarV1b z{Mh{RZN9kt;^F7rPI9ch{<yb|N4^%eksJFkP(2k*3cJz1qrlb9p7sJK|9M`q=fNvO z2TaS(cBdX-k%w&td?zP#L$R^3LKF0hb+hXCdh<>4Wxn82!G`>a=H>Tt^VwV^b9Jw1 z{O-LUNt){msQAU3oT{FR4uyY-)d^UgusU?=Sv?CPo@r}qLy?&KroZd=CJU%YOozkw z4*#y=bZB=Km!G`(`pdn$$t$&m=jrz=;Yc7Bh&-8p5BDCMSe-iZr;4FsDgx!I=v4TJ z=mB{A$==y_rLkRMoB)Nzi&87bR#~(lm;?h2npGOE0a1$*OfVv%3<?n#%_xYVB%r*A za*d+kTh@v$|7q6hXUNy<K4(z0L9dA>-lRMb=Ik?bhP3y0_n9+u+0Ua+S`QddRIL6z z&WN<7mEiS7C{CqFvWxp=C<1!B$Cq3*dI`$gZ9WW8$u}%kx5+<yIf|egL~)?Ds@qkG z!rBK99xxgi0OI@iw9g;5`LoW?S4NSuK}Ew^K26g>ccIWNq*3G;G>pQBqYF@6)o?jX zb9eVHx5y|O=riqUVDvGf&Q97`AkAcWj-!*>{X>NhoZVsz26C^+HJ4E2=rqCt_xMIp zoX_2R-&xfyiot;Q1I7d4{rlh}^d1C@6<4VkH&~xq>*^|_SjZ=4^28f6YIkq!P?5g3 z5`-d4G>{?^=_z+*6bGX{MW)fDo=Jy^a90x|v9OU#giU%bERWaypK$rR!mmoR*B$qJ z++BOp<R)6ktm>1)+!Bh1!_jy+zi+rn6sOV?^Y<TAb!)<PK4Fz21PbrJuYX@IYIkD7 zyHy!QR$Wr<@_N$U(B2y$J<*+{+l^2xnusKimvkp8quB2;6`0~^BD|T)M*JZTlT{pz z!vK%xEs!-qrp8;2Sy)54gg<LvK3H`Vix3vKBVG=TV$n`!c2b`3%E1kyDBVyG^c(M2 zb&GlrWw`6{wEP}>S>feMJ0=mK_@*+7d$zdEAWem(uyC0rJR{x5FYP3t$Qq#5>-P4> zlKx9k^xMbHj5#v$ka_Tl;?3_hEQga~4y!-o4{xva^K~3n`C4&+%)@4IJ=$ElR_q~p z?Yo-ZNJ@NzC<>=W)gkZ7P*u056?m_#%wVk{eSG_N1myL4mzS4&2fP(gG^*VT%+)k8 zvdd(Sk`t?NC-GevPy~m98R%lqT#h0!&tWoKBk^%&i^MYmI2+QWeidrQ_pKBDh`qPn zTt-n84{KPvGx5+7jpCl06r(f=120%Ye^u4l#@PW$wZ7u-LecZp6=`j5X7ZI#<m@MS zV}(Ljga<QpG_FT|Qahk1N<~B{Xdx~|(Je(mCO*qN%y@b}f$YS<5v-=07KZcD1YvJJ zvx3f1dRB2FyjEI4D-+}h3|Lmj1DqQ~5llfBy&Jt%{Vp^IvSAGj40m<GdomE3tMs&` zJK%Sl(&;Ec404zr%8L4gXxSpjBpE2sU4E^&=|VvYP&7vT@h~VJ32>QsP0Sta%@Ct| zWfX^ChHg*h_$3q<BK|N^1ff`w#cD0?A5dt~f)>w>*qR*V!e!x0cXHrb(OP-g0#|$C zD2Vb8??Q6hLVYeZpeW5I4l%3oE21cJdjk8Qk(u$`V_|_d*61bGjb#*DJW0_C71%AI zD2Nbxq&4p#+FeEQ=MZ*n0e=F3QA9hd@lWk0$I%LUsv?T3Gx4Z?5Ck@A-OLFhz=k<{ zED0#ebL0y%EU@SOS46R(cH`;&sG#E%@+SNM+N>u{1%zUq8HKB%$Xq(P#VVoL9VQU5 ze>f^|F}PI}e-4#cL^pIWizRDvCBChAVOB&A1@s-oELq0_KbA2wN0cT2MNUtAN6KM} zqE|&xHy1a-0LHNT<*H$m?9u><QWF6=&>->8=`d^kgxh1+oS?{2lVG(0&t&pIXJr<v zDE@d7o}@)&W(A_1PeEt0;^)_jtY-J-OS&~m<T>0tnaPKE;Rv9}l=6t^_BJm;okcO+ zCqW9ZKSz-xRa4RJ9y{Ec;V{=C5qr--C`x5t0+FMHJFnkG_8M7##MXBD;7^<(a-q>& zWJk%ORYmb<P|3|oSYnayDoxO0F&MYdZdRXX#e)%2(p}1O;84IiOuNZ=rmGL3$eEHv z2qHCf?rDpkR;KMdicvt3X&y|w;{;{uhkHPVg-w#6h`72R)s!F1Q)I{hje|M=x}f|F znlq*L5OFFmSgoS?6A359`|zUIEqqaVf(8<i32%jG(3~b^fkQWsjY>0<t#Qrvi?{_B znupCrX`NMg%y%7}F1L+JS|S#6&sA7u9vq5x(T+o@0S(Z&`p3jYGZVEB$MxRDcG`(; zwWt&@%+NUAAWa7>Y-V6YjG7C^*Z)=)@j+Ns6n}itR#s>M4e#;<jZhpH4<Z!N)0QiU z!zs5}W(dAW97WmRV0UkoQ$`Gb7S=s_)_IxDc-KW~@vH7DT6@!`zN&6t>OOTzcB~xI z4lf!)C{`|Ue5D`%UAu}m!yYE=d#p=!11O60k{w=EzY|5vqMx;ZGU@Zso&QnumDsun z(<`DVCL^$7{?;f8UzjBC+Wz>bs%}mH1eGj=K(u29wkd#$cmGnU+PIB1pJ&C==efjp zJ~(@Lg+A5=11hqJ7SZ1vMRAuz@Yg?8bz1@uv7Z&Z07DS%X7x*{7_zEH)z(n|>Nm6E z#X#b?(o}sR!SJr2Yp{4l6knPK6o0Jh7WG&30{sJ-31JRTeAQ5Oc(BW85Wf1ZS@E_| z1UIXH{IROr)L&^~4;LV@?C^(u3fPK<#_yXIug_v-6svAl6@~xNpAT+H2tfP?a|kMN z2syC^3W2iQT3bZlIV-Zh9g0;8q0jXTSK3;R+QcpAcRx|7{skUD-%Xf7JTrq%EHhrI zWKjF_X^ZH0niV-`Ul3m#MX(V1%TNCLn@TE>|LvR<+e_YZq<7@b?0fQP);m1BtQQm^ z`0QLr=ey3w=fjJ3owQE`7}6#}kP=ICa}5(&w*ZR#njax60*>cZwGgVHUk2k)R2#Am zyh`dw2baqS%vgBk;Q3HCNG3dlb4iVcoD+0Z>bf|pysLZ~Y-WYufFYWiOE%Cz;ww}i zzT@egT4T-k&Wc~fVim<Jh&=#CRs3^Z$LZikIa)h|Vw-KrpWYuAznGJxA^g_*rD0M0 z>hD<p!WhE38M_t8pe*upMXT1(Y5eZ@6>oNizPg3b-+y{B!qdUv$iL2ZY4gF2a`ef< zJ83@A`<Is6a8suF`*+Yjndd&i0(%!^-+~e%%+1&_<Ed6FXGnjHtoXk(bk)u3bJggb zS(Bx&p%k_)+HCKP`Cu;!UNvtFjMToh@J<fCyJJb;IXn7U?T~HYtxJX4s>OwlyYFmX zqv~<v$iPU;W8BsHaK+XuP|)AiygY1MY{KnMy-`;G*7laRvwGaUGGLq6qNa6-s}l6u z7N5iSOHI@6-WlU7j3MF>tT=E+#FiOgn86h)zk62vIu@^w;^UuPTzhOpA0x)-=&pny zJ)USX*b6~NZ<tI(Hr1Bs$-%Rc={nV!!R)$doQe=hZyP#1;odUEmx5XASd?@w@$No; z{5%mJ%K4qn#PU-(;ORXN>7j_+6dL-G2zawG=TZ*sQ7LnAil8RDp{@2WbR~jLBEWvE z9bR%wlkvIZXK;Z?`<==#h_q#f0sJ!Rm0y(=Wo5C^AN&GcDJ$N{3|)1z`d_KWmy(Yf zqmIcA6xF01(XIZOTrfBXyVgjLw|{HGZ;759?OlpU&knYR$<g`QWy1gN)w5@JoYU*; z8y{1?<hp(26X6(AJ<~dU>)GCqk|4RDdR7w%x>u&=N1YiyjGgmQk(_sgaI8U~NyR2# z>r=6hvS-gSmJB(uVsnz#XKbTn+P$H7wW&}(WWK`Q843&{w#?u*X<Xu~-B&EPWtWQi zTe_(ky6R^2zdF9>3^5hMzKj$_?LnsqjH<@7!8w)cQFMCbd5x+eZHcN%8lGMksmkJR zPp7#xs^@dg@Kcpa=X7Mp6|!ZgbAr#7<$WQU>W<SV0h7sMpJSpyrHnggnW`F%eL4hV z=X}!>{5IKyqfez$j7;YYD)4|&7gef^B{;&Z;bxt4aMVap{Rr7v(TVGfn-y3UaJfxQ zwXXIrEDQe~Sge>7LDxfZL-v!aND)&q*;vH6#)jygBZWFOrl3tG+loh&DDqmMlh)+) z=6hLLVz++=Z9DxAI8yFhdIP~q%q_r&n%ZP{olCPa&~h*%mCZSmI%u~oT9RCu%;w9Y zvv2sKGMR428GvHPTZ!<XOqQ{Pp2}p}{B!_)cTinG6tZOs1+1B|y&v*!LDjjNnlukP zrPxB~CTYAjiWh@<R#i8v|51nDmuca0>vI-UEzEv9mJsTF1SqoEy}^_SMaz~HyQBf9 zTgfhK-k%slTSdg8SFjtLF);))v8WMF6__?XXLFq~>~%FnCai3U&tyPTY`cSklh}ON z8f)1HC)Y$QL4qJ+zW8f4d)+bvW?6>x^eF5G6d7#_xHv>kMjfp*hX#WjGGYT1MXqHi zn*qg}V6oiwJ+dO`i_J0=Kerlq7GDfBZ6RMmn6U&<Z>K3Zpip!<dG#pTu%r|vd1JAD zMOj-h4~zmOEF;eqO@Jb_XJRQSYy#7Lt%`2c1=16VDTUgX*P%e_iwhKr0bjlao!kc} ze?<5)CZvE-p;))9bSM;e0Y%uo9JC9;g#0-`sCe4(6q#pebx<cB=H`dUsGw1dQM|Y+ ze1-TX^5R!zMb`CD?D(nGD)j|-kfJe*P2K@6KNF}Mq1e$e;M_E#2v9sZe%52@m6wOt z5!4&BH4v7?){YiuY#f5MSV{?-QD2|7LxZ|NZ)59&9ciDv0ez>y5|P5$efe65dVO&6 z7I)Al$7=2902JYqo1Y$q-GE{}Bty77Yy}L_%zRhgfK7yOefZA$W&uL+h7;qrS-AWb zivQnkR)$eu-hd>Z@U1IbpQasQ)NM>TyTHWCPfVd`+mbyw{;t{)A1n_SZw5Ee)*5p( zwzd|Xv1SN9#j@=%k&gP*hSo=P7x<g@30u8E>JbF;4a+*XS`GUooe=f<Hd|YpwjDd# z){<a?)<Rc)Is^kZf;oPx7M9C*wCHaszl+VRAR}s^DzdOq$RD&`*`Yw7KjToaxX=Ci zyx4ZUdLeGy{YCSYP^`LHozp{q@HO4i$9;N(_KnZ-PA-@79L_GScHC|0>6CZ(_$=Ae z0d<tcBj5rR-0=aew)>tVDm54y)V|z9t+vw{6M+BJNGv-J8$eO6t#wZKG#PZ(b*J}^ zwv)0f%kLPB@t_UP)a8>rfX$q56Al(Qmp1MiU@-zdSV_y;UHF?xrbDp%qu)I%m*am~ zz)J|bXJGS|N01SbhmZ@oSyk3z(!^k1T8mp&R(pngctsY?&3$1%#rwp?aG5!*^Ad;M zdsj+}RX3}18nPryt=g1D(x}r#9lm5TNM@Xq(ATx(h-@x7O_pqV1l$Om&i34sBrFk# z#5|uT6i7}J<8qyj;fz_K4^SM0O%F`Rx`NXZ^z?)h(<Tvgt;Bq}fe<;pqk&-3hrUk- zD8i?v*Xi60jP9iBbh@PF6Blf-07ckg%{Y>ybsFp?L>swikf|CCqDaJ-TBm9*aVX$i ziei~Xc8DasSIdjLZz+O`L<nMn0c<UAZhS3@RX3}1GLajl7I%(Hg2hy=J?LDDE>2MB ze|Sq55e!Bamt%H$SyT3y6SNeaL6LHT3_4@E@dju!D31V6G?TE4AsQyrO>&`gX)Y6V z`qNT8c56N83=*TYs69u98e!ul@yT0O+_1~9ZkEe;VncAYVh_;;{S7POU@*XFXhQk0 z8`jJ%$Tb5%MCBroV@7}fMGgg7lDv1hLqVBEd6*zmimR~5V#KMQMsxQ_lJr6;<Vhm% zwJ28ItbR-Um+eibfpALD^4SsfFV@yxG@e9_Q?vCjpt9<nvDudPe*WnJ%6V%`<wIMP zvxA-g+X)szoy}IpLztCm4;R|qkI{%tgrrJod;e@@WE2||&%NoQ@i7z+4>gA+hk~O5 z|F9c76qH#Uis#&v7&q^9HppxF4;7IAx*7c95l*ZeZb5Wd++#s&$j>`QJtN7{;$C5! zm=H2J2BC(&P85FNlu+dC6%R#4gZYw+#j2at_ms%F^!hsEX(y`|_`n#J+^oPusAS#J zKK^>P@&sLwB!=?D;woxu=6DpP_R<ao#;z<Gk-T;Til;0pOr(C82(VFmD>FKfB}Tcj zW4$CCj}A*Y0OfcnNkmf1O)RDvYAYV#lTHm9#-fy;a%Xg7$-DviWppK14rmlP8m~Q( zurC)l=UKcCiY--LLq_M)*foYj9)ve+Xb5YOaRyY0M<zlp7qV3okB^PjT<B0RLOT=~ zy2$X3J>w1|6bpUCy4}8Bb|{d6_~A%{lvtOe_6n6qW^->19Yb-?j(U^ogVLbl9F<k? zc!*vzlQT<%XM_f@E&w%eyGeJSWcM(<J_TX>PI#)66_4f!cg~)S+|yi)V%5#+dy2oF zwO-TB3ajMdf)nC<<Ysl^m?4<2jN$<}6zmyO9^_E)nh1a79#5%D4h5O9r+c&O<@$<% zUoVwbC{mF{8pX({QrpIsh9h3?^Km;h$zd(nd)m$2y;KtNVYi8h^!5HK*5J99zE<Rh zA~v{(J>$tU=xasJJeAo$(!I-i^yZsEv99W7bv-fqt&P_^LuZ-8`{)u8p~x>4o*frA zTQBhVGuquRn5z>dhk|VdTs*#U(+&kItB^ETFp9Kfh8=RgjqN4!3XEb-i65KCO&l0C z8@G3}x{ci|Cg(6rb~9lUiblwIc699M6vfqrxSGq-jmAd~XcSj_;$0k6?T#4GvCiph zQ5>@eq>QS*UO>?G1y(}$As;rruSXc-jEE~NBI6cog`#$#HgG7IM-By1>`<_O>QKNh zITUCJj3TZ6Fxd>&W&WfHqqyB71Eoo|7c@zw#7vgPIyACui}-8N+`rfC?NPhQjDGKQ z1uaZvW?AB$O+je|y&H|^(P&9LUAP$(1)=<6{e!A*O+q0cD5On<fI|$T5oN^F`igH} zyt=@lKrNA^2%`D79ST@Iad7>YnEa7tjN)jM48$X`(SV1@O|guDY{KJCk{CryBVV5* z)uK}rk8G5Uv*PK|lu$hO_zCP%Kuw5P=k=8+y59DUzH6_)U)61?9t%^5F+42_KPUzg zt=8GfD2h{lHxESl@9i=-f5V}mnDS?NAUCPLQ%2E5ntlcCf9ls94Ny_r%CCzaK#{`` zVsBK=kUK0mMNt9OYWac0jQIq`Ogw}}&&&vpu8$(txUEkT7_RDfpnF}QNl;)i5D1JS z_4I^7>4BPx4h6h7?V!0xvVpmM#-ZRSM=qGr0^46kaVWew4{(d$d6L!>6q(F9VjJx= z7h6_c>c|M(Q*?y^#npgm0goEXB%2Y6Aq*I!FJs%;X=jyCTuoEGsM}EJ20G8{D^V1V zzYW=WRs9|mJ);y>HjCV>Dxg@Lpn4Uk!OfB{Sc_z`?$n`RG|q!Ng|1W?MOfU}_Fya1 zrKv8AVmIoxMm+mw=CR&B+0E~Z!}6yo6bBT|HZnI3>zTqRB@u$bUp%#kEqF($aO9ru z1V!@@k?J?IG`+bs!_A-watX#>RCQZgSitYCtvBek2-*kf^~m=REdM@!9O?b|`2;O% z4rgcSRv<3nd`Oc?(?pbZC~)l%seC$h#-Tu&iZ^p`0{oTSX*oslU=D5>_DI}`-c?-} zkxYl|_*#+0&l1^mpl2r%UI7UADZ)Ow3w#N{!15jE1Vy$cL}Vl(yJ!8^)eBLq*5dx* z1j`n>DtvvpEPOl6sCe13P@xw0@d%mc(#@#^)xaujBZq<k6Lu&N<Rb)`+IPF#nY6r~ zToE@|he`JvCPoqI!(57p6PXb%><C2&A~O^A7Xesto+2oMi0Y5fdS%k%Pu#&Ky#7AC zLTRU;wlGH52_l~R)xfHv_>)N3h`cfwjg3OuLI_-VF^TQtVBB(n2`~GDNW&`4zK0?+ zlf^w02nssQAvPT7u74>m?lOeCOj_K-qM2@)3x_(U?oh*_LqkD2CNAvZN6@Z*0pnQ6 zH>052HNUnfE*>+1D>$`SijrYVC~m_E@c8f$#T+g}JgY1ous&B6#UE0%X$$rcY6K8L zC5Hm#IGq)@zSyAv0@hVaz$-W>t@9QKyJmcfvQ2?`-jn(d>%7{`u;=Db6k6x<YI{|` z1Lfd-q8%i>mPu^`ieIUV?F?97=2o!UAEn~=D%9k@K@>$pCSFy)6GhRBR;pxCK(C;$ zp$qK{SYLwT?g|mM=~&+qMd6ky|At+4D7ZaAMfgAA%J5K=8_IE?Eewww3ToJLVL2;) zfltfDr6kJzzg77OTBmfGzv9<cRfmEfN!XzP%rXGPfBccIhm5On1B$o^at*to@hVxd z0#Co46+Z*_JjGx4duaTk^`#C4ZGWulHiaz;uuw&ATnHIzeqs_;HL_RFx%D--locVo z-fvK=4h27wXb92Fd|H(or$nfN_gIA;3c9a|;%#Kb%1QB*#i~QWk0g9;h#d+*xGFLR z5pp6bJ`45jI-o54?PbO5)fB5b6kMz)H8qd_{FmREpg=sT5Dy&EAmRlJDhw}!k~+wt zpysL|-gs67T_-DYstyH}{Q;g7=Qkz;bDv&|usr}4Zk#`^q;m6o&)-|>q$(UM`o({) zt!w^;wiwX7<o>yQY|Z$X=5LkMGS-a;oEKe|`-DTfFg#TKM3u#~fa0yKps(vzP%R5z zQ3`!(iS&f2U~m&w2JptO&jo#SKR)EM!yXU$J+FU(#uMAp<lo;o2_x<{NT|9e<znyc zac8IoPVm`lIJg1*SmhIA3IRjfp@1%gEQ6egDlLLT!IdZIZ;=(hip465mx;aX_ov^9 zl`p*$eP25E7vsmqCnxPDwZr}pwgNKT{Y%ZdL;VVRACHh}LwSJAX0f=Hl}@!~dj0I& zsj<K);|WTL_y!Jk%8+4)f>!KMaGTePtZU8CRfmEKdQu04Y+7-%rsa!Aj|P`(PTK!^ zNd<dle{YD!w!q$EYI<oOI;HC#0l;*kN8#xuXYao%oJn>^_T)^6`GXIX4bM7d$dG9Z zB2g>9e|uT++G(-sP*6d4B#yqOvmK9HR=NVqVi`1>-*)1zh9R*EOarWQqjOT^D)4-0 z{waTBq)G8Q>DckUtu2l0xHs()$R>lK=Mb<Zj!eT7ZBNYBRzA0CaXOQ><R0Qcx%LKs z-=i5NoYc5huYy3j5t#JWL-)Tx5Yrewqd{b{QAR`+7x#3AhI%l|xVmosTJbt4Rvii| zXfQmzraBYLW}^g^Ai_57<Hv7f6S!-Q>Qy~%o%6&av2Y!9bW)qknWbcNi`t25#x9<W z6{UQVjksI%4B;d7I|p8E5mCnDvJC1a?~52o50H8YbTY0a`4ToZa#`{C@tWK3iBP?# z1D-)Pd{(2X0iz7ah%)3*fD8)mpt|rPWzGLdR{ZH53TWy5ME{vkrF8p4vw}6xl2`GJ z;af65U+oT6_pHY2kM0XboRs$2Gm+C7=8g2rpAT+2`t}zzCxc}(;FJ*?V&gzDZ1K$S zh#}dTlS_l)N1ZuG&oPSFa}J{MnPMZB)<P6=bhSRaL-|&kt#wL#@TtIF5|!kJnYjca zste!H!dKpIR=f_2RfmEK@;bxgXF|i|w7Q`Nj00kkS`{<n_y{D7E#>5@#%$~jTcy~s z45?~d&S`aHTMc9@iO<%dDodXCS<)~Z10?eJ$YB1is;rLT>1}3P?{rd3f0x~oH4GB& zdK82l_x4ovPNxE9Vj09RAHRZR2=@?WuSyOD9nU+SBC8BkW~||1i&1>NtXNrB&x+SU zvFcDzLCa3}_?fUiv$Tx1Egr{wn{39i4rSkZmU^M$78$m3x!h4pUM4d-<Fhg>K(SR; z7F2|{<eN%C$6JRb+$=kzhm^lxCY$n1d)shajQG@>v3)jbha8gz*<HUw!jRE|UM3qh z*d_z~2|BQ4i&h7Pkh!?_ta6-r)B3U%^!G!t?f*jFV50v_C?<$^XbWZHmyg?YL8r1! z83{|<+H65z%<uO*Ez!0%r88lq5104`v}Z<7xqTMro9Cs-m4r&hXZ9)<ee2+fAndc) zg>=uL)90LciksVx0JjZXTzr0$^6VH`r*wct0SH+XV26V4CJk~ZXdisV{1#&URwgZn zUyWkbp`e2F#FG9@DDcPM;KruKc1NKwIeN4orzNcl#jumG=aH5b3WTBp%j6r-l?S&- zoIP1bvauB2k2(X2Gcxcjjv&Zq@h{Ll3|RIo(oI0IL7~uEqYj7PTORWqUbIt&R%<{m zR;VJk1{GTrikoYg-%{tN=?c0=TC6%0RM6nMWwfarj#K0s+8W%Jkvkn7Rtv@Fk$ULZ zSXv)9AZa@~#Lk2gAKhy54VP^Tp!)j`{{>;`Ds|NZiXCV4-sj9A@%)xR10JyM@L1fn zc;|!z|210gwx=wF7|q7;#_m;Gzz{nW$mO^&yauc?YK5Ke$F0{x@%q=7Uyowdp`e29 zY&-lfo}Pvxo-=^9&6J}VdgYWeG@WUJj<JMu;pDJ!XQUlBo|=4<4X0!K-SPd_r=e*l zj6~w6;9O;abAjZf;T}YdfW=<x_NjHK4Jc~p<7yK@FWPDmhFUZ$Lq3!Ph;rnVK^LHX z@SxE(XuawLeej>5GY$ps^xVoNLcLoD<>1rnN(F6otP4^6@T=Z%WfZFp1(h_Fv`~vJ z@DKW-xCfqLcztdwwDZ%^`>^xwq{ZjFrv=F+zRf`{>}k?!1=A5R9(yM=&ASiY0$81C z-zZnBWw<SywYb9wC~C{%`kgQ7)>g##@vipH3kUhoV2uR_bkLV}^gPls-anMfUGb$A zI5h|mykoedgX=?V9fWHkYfwRMp|Bnt3NAvCwV3P^Ugl8HUTTg>cqcNwUL7H$0w5Lt zq>oic_A&oQd%aPL3`@q$=qpx_S^tBgD;q9c8O5qYK}G33;7u?wD)Bh{5V=g#RC;vX zNsP%MlDGRT)F3{rJ>?@!fwbGM(*cUmhqO;Pb^-$2Y#0fq+EHUIX4&APhBW0IJ?Dww zF0~%zENZ^aNI1dPplM{9*oUtI6brg{vGtxn*thver@JfHfme%8-XP~<hXT4VJP7K- zLuGhA-*{nJ_z&Pv@Pcy%6!n`CFdXm`@R`xG<}=$2D5Db{FjPeGgW6Ad!U@8&Y=9uY zUbqg5RfmGgYR(f&u$qWv-=c^gpq7^WJN?~wU#Fdr$Z5Gk@uj6$1pa>+jHKG>z6Ki{ zyn>s`KKB~kCn4Oms9`ikZ1Pia^TftUd)c!tkcSAo_kIs)0>gp;G0-U==lPeGNQn_2 zkJNxD)HI-Uh%H-cQDJx?`h~t!+24P`wPJskAOn>h3S{R{)YTh}#ypvaPtjc_Yj+j; zmJ{0_DxzrfyY)wA{wTHi5{fiN{e0FnP^>x>TqNPx%FK)UlZYYce_zpgfMM;IHhtDN z_^{#T#1L48xN%w@o}QH-(M}nNL{un3DwT=>#fuyYcH9{k3(wWMg3(wkITW;kvA(P2 z2%}h5fV@|lfQ1_KL18jt8WeF(P*i+iNclxP8E+C^jP>aH3|nK(_!sz1Oaq_6VS%`O zjk$y(r~6RKZ#lSG6dzV~yV4-F;A9A*9STqZ9TzUgJ^u1#WfU0_&rq7!Uq$T}Ta=>g z%O>nlAPsDi5!1Z;0u=jG0nMN~LdL`H4<!`M%C0CCHVx^Z9U*2AksQX@A!j&D_&shL zQ|!)t0Jsh|+{=a%itRm{lv}cIxE#f*L&1+Ea40}(K@b9kXsv=c<by*2E}b(t_PXM= zBI`x6PxRK4#|{Mn(rq_w(hda-HL=;(x9N^tfZ~fpy6Ec45N?yiK%>ZUNvN#J?(wWZ zjZX>5n<~H-Y0VVz+a)VZT{7_k;Ntgr-f?IYMJa-3+VLdy2bZE)btw3ORIUz>^+1T~ z(7s0`8fmW#!F**D_iXXGJw7-TK#|XRu(y!!TKlj=!7!D5d3-RH@n3@C`D?`wHp<kz z+r8mQGFZ&1b<#cIt&_t2oYQN?)h;5$VR07RYGdhIQ9?>YtHrrQPI_Y~f<r-PZB@6b zPK+T`n1|BvK;mg-cqJ;wJ!q|)uZW`5o~&b<CkQXp3+o|5$f01X<WMk#918STM^U6s zE&^~mHTe=2<O`BaoJ{2Al;%?uIpgt^hGm!odkz}Kqc|l3+7A2N`b$x)Iu!g+dLV@2 z@C=*|!NaN^j52^j3?eEFe^Di|HhqFuClt~S1*te*IUCPA6kHj_=43e33(ArkyU?eZ z?+xuF2(`Gpg8r}*e!~*=t=E-S(9Qlh8UR<A8#jicAS8KLFMLpa-P#N3KAx59MK~Y2 zXb_>k;`rc2r9QDkLD+6GWeHNiuINx;NL(4k*@!>l1`(b)`XZ6T75A<aa|fp=?vBJm zoUw4eP(o4f_q&lIkqypGp~(N(*P|C#9SUww^;ja>!s@;21Vl)Q&8WPhwg1gRr4{se z*6+@NDF5UtGaG+%>QG=z(GCSo@hhYFA9u2M9<;LH;_SHqWDs|foG6~6$Z>h1#@@(= zxrAcBKY|9-z0-?s2t|;1u20f4d9SKl(qu`{2+$hE>H%{C(DwFrzN?Z$!5XnsCk1Up z++1de7=^_P8#@#ja^$bbp<v;+t`#NR6BJ#!%skGtLLKXnXF9@PutA2J5Q<`ai<_Hv z52#aCRtd#!B2o)&bGPt_bz>+B#cNfEg5QUt@GdKLX??|Fy5vwG&yriLH>7(@!RF@) zw1N)Aqe?c@xOq8>pFEjERtd%K$#~w#VHziR%^X9R=+eNQM(Yl-VP@)he(x?qarI3+ z9GUoVf+B}UrZp_HIBj})V<>|7&9h@w-Ja%8R99Dr91FG<X`=$YUXM%)J}$3)j-pHu z&i0=;6qwp{+oW5a&xR9#B2$zjHcgVv1a&Ejvq>VAzC)wP5!<OOm>R@$1s3xY72%~v zCF^lJ4ChG5aGxGfWQ#Wao)OOJgFmG^9?j=B!A|2+6sxtke<TTo@TPBTi{MYmp+Jcj z(1U{l>(q<7&ry5|4h0|RrWG6tn8lErBsS;p(-!u4Izf=pt)yFdcE}{zMK|g&iU-R{ zl4xSh(@$Fj=`cY=CXh4q-oH0VA`XFa74{5D;^Zh3z~XlKdD8MTXwHAs9)d`Wy3AD+ ze;Q#F8ygXf_kl+20}TQcLAWgZi_cMH8w%VLhk|0E4W2>QirZWExWxnLY5P!XH8wqe zR0NjFIw~B|jpJfB2R3^}k&DATC}7_V^M}ItAQ<4|c8hCaW{Ob?xQE7WgyM%Tq6hmE z!1tN)Wny8lxp2f`RZ;wDBt%0084eh?(7r7$Od>3z2L;$}@@ftRZ1$O;jdi6u+ZQ+- zu*_!8xubxq@$mZCXRN_T6~&)N03!OpH+0|yN%7nSE$DwSU&Fj*wTV-4V*B&CxQgOW zB_T3yX@nO8qX;v!@zj@G0P5cY=hJU0)^G0Mj1l30j#WkR=N2SI3}by`BVM)Or!A$l zI4D5NmYYYBb@qijD*i6N)Pry409)T4#d`2#uj;?-UHebdP!wi5U8Z(wWN5}R?OtL_ zdB~#j7!LuV%sFw+PKu0jH>|_!aB~GI3Qh?E8kYF0Klzt>Zd*Iw1|Q5YzJ+|}+<SW0 zu#eMrB=@T_z(lRFvA*#hxZ;Bcbmac%=;-+PUHF3M#=_jY-RO!H4Sr9cfPXK=W1eD$ zE8F++AK-f?yrs?c6}VTdYFFGPDF&to+=H2!eN+*d3X&!U2lfB^O>N!&R*HMED}t|D z=Hl4Cn^hHY1z;GsXodx*VFuX>S#z_hjjq_3oa#G!Wgpc8$dLSi40RzIZdSTY0mDeF zv#vI};sY+noPb}({;N7KU4o_zL5I2!TlMYXDT!uXr~ZQ{=v|QFN&B6%XW`1Qk7@xV zNPa3pG+H9LI+MLWqs^yk;|UrZ3NG!VsxX|aK!*UsLugo6BJ@Ny=sR8;_lh;*X63v6 zWb9}2XJR?OnRtip41eJ^#k4m>L+4017F)LN^u4?N-j3E!N#Oj=&ab?zbT=!_NTy<D zWw=?<QGamzcx~J(5;v>8gVqdu0Wx^K*!%UwV}T3);FuSK+h@*os!ESJ0){MXWj++> z=L#h|H+Toks=_$mva?g7i!1h0!M*riPjm8l$(&=lVom2hb8s<)sNE%!jghTZ@F{5D zo~W6w2!D=y<aLG-P+C-lbQ~O}^brFm<#;>L_YSh7$E|0Ev07&qN7AXNnRINV@X{Jr z5CsKHge*AQM%MYsi=YzvR%Vsbh&`>Ab<?XD%2>^{+vDOpkRU{w3N@Qa!{1MHvto5O zs|o2Z3vs7iakn-=zSF&TAR)XMh{QznHu&Yl6FJ`dgJbS)xLUi%uzK1Yxt~s%hg*l# z+1P~3>+8Fb>Fn<A#aT!9&oLA~UP&wi^5)&PhUS}GqSQkMK#Ht6OO3zUZUqGb3>6aV z-7($GYK|+u?;yLwU+Amu6ZCItvBur3Xru;OJK5`KeL~AS0b1}zj(g1nhCd_93Z_#G zR*&mLfQRW+xYekP%&IxRRyQ04^5Um;=BfZQB&>y<&l2O6=^W1A3z5K4LT(aVN6BdA zAVvyx>KY^%Gu*5wts`#9F)wTvYVkICsJ|-19d^Y(x<2nvio<&cEK)B5y;CO%4R;I` zo(&u&QBhv&c`~v(@=$_=n(C*4S~ixOffnDM3JptGJp!?G-@O`t-IZSIH5Lpfc{>!D zaN?(@95aP@k=3$S1EuvX?F|Bh3$734^I=y~<)2T@^yuXd*mT~iMPuWMY(4O8lx%qw zUv&q_V05m(56JqOd$#tD1|2etFIQe)<!*HNa!>jB0rz-=*VW{ya#!5BJGm*v+I6$? zBefnH%QVuwrJ6V8?4*$Hg7CFm+EV01Lihlmcoc~i7;BtduLml~3rxt0)jl|UL&2%M znv$0qj0Kxk<^Hiy1<iuEyd=v=U6deuE@an5l)VSxBIY=Z%1)1nctOpN>g7cd&PRtY zk8?o%$X&*8BKRRB&bas@6tX<Rv-7GDqZx)inw5oo9zU`iDIs3Qc-m|8ft%G|72z)2 zE1K8m+O-f0BDImB0_!sQTo0^)tw1n>vb_w`CCmAk!?z-<4u%QyiWiC_OY=v8Hu)}z zVX^9An7irxLO47=pIEXnI_}M;=YUN31eD&4xH7OGGGxnv_MnqPTM$koA-mzTNK*R} z|H2Zc_41eizCk*?apVR%kA&1Km!r%pEW@-Eln;zFgt;T{kBD*;MYoBGb&t(f=LlO` z)=+Yy&gXRcChB*sD+0dlin}O9YVRP7<f-d%6-{{|8Bb@O6y+}qFDUAk{PfKMm{0LT zEM?&p8_eGaDFT5MX)21<0Og!QNgAFQ-YEI2#)6|*TmUk$EhL`XB<gNH)d<-E32y6N z^P3PZBX!QIm8AG5W_eOB)fwUC6}}8KgC^_YM0y3j3sx&Ai&9@nc_K;lBh+v8=lJx| zsOB>n4s+<d@3OO{+2Oe;{bddQqAPxFy!HoDtX(%N3*rIrph1!uq2TH1Ipvm<;87)) zw{=%4E=c$CiVNb0`S}RYCVz{igBV|=J(IJyNYM=?-%Oa)V6g~f!XeBa1&YjPBP0dy z@NkiT2GKI&+VqkXzhIVw6q}6DyT#jqGU$<w*536ktX5F&(67Z*@fhsGgzSFHYNF6V zlo$r{77op{k$pfNp6_<WgI0or2kAfQiYClU@lKpF4*OqTJAC*@lP#xh*ACULo0S&{ zxm$%q+((iDlt2W+6wA)Z_Bt|_l%HGJ23{cr5Avx|pjCdZgKfw79y>alKS_!flswF9 zxSvih0-2~2!~oFfd=?J%H!N_IBIcjL$Oal|(@Ro((Ja3$OnQvax0V<I0x7ykI>K|X zT0xm+r!lXe=ceDAMJvQ+lGyv%;waPOY6j<)@48u8KeBhmPidQB91o;RPGE8zsooJU zKM3jEsktuxz+F$n#9j!;mV!<Zl+lek41?8ZWSw2DYi8VR3kBmHa{fZ^_#5``?Rf*z z*|F8_y0z>4f<Ev2<bA>~pL^c-4f;M@8;N%K#J|j8Uk~~b`L+&*5Qz(*DEesC&?I-A zK;Y^6%P8{3iTK|Cx0)51yPyBGSSWogKxa0$`oS&G-Bcg|D7w&qx%B}da5Y-K4sDoa zi(ml7YXPBDiU$(qO%EEhUEZt)I^tK?m#+n0Xe_zHg8>vFlp9#zT)Vd%T?G%IIM^AI zjUM%e|9GdI|FqK_-b{V~W-a%WL*2>fY#`v;E#D5@F0Fk23DOVO5Q?aLh7jzah@qnw zhbg)bisP8!Q4~d$jkNySo_g0L!vqqUw*S>65}0PFiqbOTP3W0UrFQ;u2gUzyH7j54 zesOB_X0mVuwWz*K?s8`req0|I26HWv`&^jvMa$DuQ>RBOSp|H1(H}pW8ZDKaQ_{-H z4`}dwc@wT%ntmKTWUfv1<V~(nU=rCvVrpt_eT$re33?SgH*=A0Og4I>H=JLM-W;`B zGfx&*JYbh|PyJSXtLSHNH$ZXf#>!6OnzcH-c6Aq4qEJ4AMAfVoa?4(HF849ze7`S> zyigaaY|6l{*k6ZwD2~Tl*sD>jJ<(W!&?}PRfP`3A4D&UhIP>mkB6nYznQ=_!wy2pI z^{b@vQTM|0^+O8GV0LldHp4C6r)F$SWHFlp-(K{&FhiC~u^E0ZxlGQ?On;LsVBNTn z=I<xJnYQjC9K)~U<VpriDqDci-No;1Gs04I6+Aa{ldew4M)dZ~nQU|GJ4FHAhuK}+ zC!w*NoArXhN{e~8+oSULGyLxQXFjW<T9CXOEvu+{3tA&i<{mnxr^k*R&U}9q(-wjb zPkbCqzzjC)pW=uoLDz*wP`8iQo6UNlGrA^_K~sc`SFel6A=c{z^iG4MP{YroSZl;u z>7WT-qE>GN&42}7)6|1x^OO+lBpDRJQ#B-Hh>FD4@w#6%xQ0mtn^tZVg`j?hVyzht zH%;+kDB9i~UC)(NnBSm^)Kknx&gLF`%Q&b6WwYH|FV9IKYPqz5*=)YA*4Oe!v*p~5 z2V(Z3_eO2LWGQc}uH~{z(vydU#lo<yEAP`}>7j=YvBjl<QJXE4T%p0MW(yEHxi}zY zjs_MBY0`E#H|gy}M551ludf@<Zsm4wFy4?F$!#deF_&Ap<#fa!F763%w@2ll1@dmW zaFY%J-54V0@rfci6xzw{{p5^or!emNTypg&7V;i5e~#jWk^<ax7oAeuZUF#t7rl(6 zsUfox^T;vmQ#6=kB}0j0qP<3SCSQM>H|>EzO40HRiJwCeQ#8YqU<f-AX7aL<sfY+T zg>@G-l?hkcvL?A84-OkK(Snq0=s49fjF#%wGg1ZlxHjGBqG-Bfnjxhd7b_t&^zLXd zSMq@Ie^M%c&keB)_sd%ghuP(!p{4aZ8>`Ru?r$E2hlZ}MC6hZV8<E0}27?cxOIL@u zWJwwtitVnK3U@YVO9glDmi*&8>t8+E-z_A+gHR^9;smEBTabr_=D%Ca9_(ywu8+iq zZsjJsG27+b;bZzNTp1|c*@`?{Ngm8w{cm!Gor8r3$qjTH=27|P=%{!3tMbAA?#@D( z<c_lI<%0(+BmCgtx7o#wfq936iAjHkVl|}%?1Wb?QhZ)zVSWwCi5O2Q2Bpv}trq=g zizBH{KCWmkLUhXvN{1oMEshVWN}P9koWXM_a(qh5vlxMswA!ZPEwxJE#EGFwnM^{? zOKpmlH4d(7@=3Es;FeC}nh~d};)#&~K1H{|);lQH(uP9Eiy9?d2u1SUk$>_rg)F<a z|2;;Mj#~o<dt0B&B&qJ-x-oKi7}@rdAn)9xz1gGK+;RpwpDiT9<iyAbLz2GY!$*6Q z^XkL7X|gBpQe<x<ySn@NjjJR%Hu5wCK5F@!3=F?LaIkgPy>z&skxwE&W2B|4KX2_V z#CzfF#{;X`)vaY`r~Avm^QFnX!;zwO?Xdha1YqDfcoezko0zz+K0Z7+oV@48rd_uO z9vsYvLTtX+A4LXgNS~4!nH{%>J(6D>4?EQgj!^Uy1ZHR%6R%UU1Gm>{Puhl0VJ(%! z$(FNjx7%nnjE@%8ijE7E#t{A1iZ!Oi28o(mmUM(-t0Ian)u5W=CT*k%T;w&aov!%M z2KsERNHpbQ6FM2KB6d*Z45d=jt8ES17buqDdxtem@h)Wj-a+3W!wh!a6Aozh)AbNL z{X6F%pGd{L{f1){+?@-BCSLNof7>04srg>?p!d3Onq@evlUcp9)bX+z2gmt2DC2_h zPIef>T*G5-HjzgMmJ}2HQH;T%CTw1oNQ7S+d{-(mBSM?eVeP1SeBh}Xz?r|;7T_{L zX<qwjJW+*InxN`-tVIEXI4QSJ`=Quq=fhz1ywN}?Iw9RP+MX)PfieaBnQ13X%SEbE z>!FC(GA$R(&q|x@Zd+J`0s0_YvgTzqtG8C3Sm<7PGcmydgCNciWrTXgtk4PF?r!Cl zl+yoUj;yL4&B$;tPsg;l8$`*OI-ux6S<a(=1iv|h740q+-~?5SjGe&b&^VFyV1%93 z+9)U_OW}Sfa*D#DN=AxNK`637T98g~U@EP60F2nEq%#Raan*V#itrI4fETKDQOq0d zG>A6n#$`3Dw^oq{yF1B;V}7XWht#d$f`Jf-h!Msjkxr%hXGMCjTFDy@5qc>@D}qug zF93>_aSO%z8Hx_g4TDf82FWf#3qo8X;S^89NEC~TqB(v2P^`9$mI5-A6F^a8UZ6OQ zP_!i0xwz48^iaf`iqxo6u)OS|=-D<>Alb-V1jSDVFZCw0w7)m-f%7+Ygb;?)F05Na z2&F{EI!#PX{o%IdiYrw_yXKh8gh3oP6zGGZtJTYjXbG68Ruu;3WLBemD5y%-`e(&F z76w(hdOs9}pooJAf1<^`KoJ(0C!9hz&rmEHJO`@6XIxgZdTTXC7h~>jVL$Z3x>baZ zyC5<Q4<yEEr>cJOhdXGK*3tpAYjz-KpkBMu2Su*fMr}N!dC~IG!=zgkh;_Ai!VV78 z{N1)?7&>G-PuhX5Q$g&9BGazmNMT8_P}~+QGPzbf4M~{z%~}zp3-woTTa?Ih2D{Xo z698x(vG^e*L)Y<ehr{mNoXOC=5<>k^#HUkg1Gi7e5-b^~ys_baS<&W{9W^^%@pwpZ zHQP#}-GIiZ(t-^)QHinVvm!xhJWS}PtjyGLoTT%?ekh(85=Q`oj7A56*Tgo4BMC9B zmEedo6sy}xRfmU*lKa(JF}^nYwN=gP^8GKrT|Ifnpyn<dJBz9a9Xnu^&vZ$Q$K$;N zko%)(7vmZ=ZV#lj1PxPp(U12*k?<GQJk?GaCj^Rc7)BaULpvC?P0@<#J)aeUvR3<q zz{z$?%48%XuJ=RH%o~c6rzBa$M085L(Q=|Rsk^tgDYJ)SjWJsJcwS3YUY!-aN0E`+ z&SUST-kgrn+nshChoH)2_sChaN~8hASgiQ1=g%H-bBYWbVBIarvd75*ggq2ZbX8+T zfUX+%XmZR2O(2a+rK+fb5~8eW#R_uwP(+4TjSTv>#rhH@RL5UJv7(}FOP$pWkW|&J zdD>}gqaj4NC7%!-6kULynJ&Vhc2&Q?p?2x#k%h^~rQQNfqE}Z79qsQwd$#qo4~q72 zJz&`@x_-s#noUzgt$;p`{JM@K+G?U@#9G7DyUCBxtr3>{l&pjMOt@adkriw8Q`8k} z&ETnsgG9>^dX2C;y5%#&6~6!<fJD@Urrtp@PZCHq)51?TgW=#szJmt2Qy)YwkNSK| zbpE7IB&cR}!J|I$3tqi=&;|Zd`(>BO8zGUf)Pqm_3uke=F7@UFC0k&v=o)sz!$eSb zsmL%C6}Qeqj-evF|G4meP~v}8HLA6pC-E03ULFhoAChYrRc#p?1_6qobf-cAkE-xO zF)LIL`ZfJC3;y!!Jccj%@xOuM>96da>u=If7{<Zr2xvDI@q&vHtYBKF!8M!iW^pVA z1g{{ln>2-aoCDo(=q8M5Ty|9!jo<dw|I_!J0tIIZqbOV8Ii&6T9vVLE$pd8J{r!4( zQP<Y8;vp4eqDBMJs4+^p2t?>2EQ4@cw&kxastl>vm-kgo$~krn4(&BtvGeNW#g-bZ z<FE*v;3dEbX7T^yFoyEs_V)XQFa4AX3#v%Ps(;)^mMkSFDiaF&LoGtVK~R#cJ%|E; z@E+(?Y%f2<MXgr6ns#o*{N9!tF2C1r_w#n10LzQCf{{elE2s>`8d9-(Bg(1RE_G_P zV&^BP{StTkbW07=?c4CkkL5nui{~Lrb3f1Dgt=mbP@vNY4M@f6-=0fNsp!PYgaSj0 zP|!$$2Mc_HA}V8mpfX_S6Co5Bh1&erh*WH^-HPFEm#0N2Xy5`D7C;#ndVA%0+<4HP z2hX>oP3I1DD$4qc6I+CWL#5u{LLP#^hY~77;s*(qqdjILRiph>e1lfyMA?chLc!tE z1&G5uD5DUGqht!QAQ1`-|NR>@6!mdpi%_7T%d}2MOOSxOq3~!$v_Y(&x$sYQ8847D z8XlA%$BhXE0_&rPat5IW^QlZlRYsJp*t~>-iaPpZE4i|={45lP;sg51R=Qy}_-yF1 zI;E$~m7Y>?Ar3?-5;=yUq`B~pT&J*aBdY$asLF}56`Ph&P-&glIHU0ur*ktJT!laW zb2LSl;08c@?+Bw+?Rj-Cx+Xp@;u7|5%b<*#19+S_F(QNMK^B%}X`8LD<L-Y?Mb%EM z&5DtMrjc1MX2Msr+8cM*Uqcx|Q$3Y#nL|5g2h{0QM60ly=M%t#h?4>lPlmVnSRYJU zv}*Qi#Wt0x2vX-n*^13eC{Wg&5SqElkt>e{juDjIy;)8hfa~(&6xz{AWuaeo`a7in zALTY>8U3S$OBrcUWE9--kUYfjAOYT-*&d(G;c(~%FA4i}q54#;lM|bmP@pU$4EeH@ z)M=E}J#ntxH*mP}bY?Rve2(l``nxA4l6JruJVZMtARnZ&ogTbFdwDaQPI&naTqPo- zgRa#~CSkyv>r)ra{F)2M10#OxU}#g{Pvf>L3(uuTcxy+Dw6Glf%0%|oTp~;=4qlxj zoD7K_gndZUK8(ufJ8LplJr=&LKB=hIiLw=&m{6dsPf?5^khLK?vneD7Qdgj$=73JH zh>`}lHYbCD`M1$&2ghwA{dG==#k(YC!ESf-HJl=GwBUiw;2UZj&1a&4&qnBGQEWmK zw>VDsaWOq3ih*E6fObX%UV*i&rCAbFYm4z0@fbFs2M(|p3Ty}xEG*5^JvNBMVXe+| zqe?<STOCtTofBm%HZh?<S$r@vSXyt0!Bi+`%D7`te2Y#$VXX;~rvYsch(BOipBXp< z3rK&3+4#75jUi&wm@}}Ob-V4m4AUL>M!o4^*|E*I3pTp~!KJXx#xUk!AhkI;%%f!^ zwBNd4G0Z)w<wwgu8RqDkd&kBOJrAM~gGCW+5G;xWBH^jQr$lXEpOp{_s49$D$5gDJ z6PuV&pscTAGFMu=M6}_fs7Ipy2t|9vE@*{kmdB`Y)D5%&N$W_TdpbRTCSMAd#ED_* zOlCZlJV6ajFVUp?-5wZ$Q&(VoOu+RG;24|*M8eY2ae^!e7hAKWwGc;U*w7{rzD>Zg zSipuXh-Q5~G#)`atnIU!O)!nyFiBN3Vx3Zv9P4PsCMFd8Ztwhm(m3Nd4pNT@PC`6c z;x!}{uXCZ2RevBc3iG<0XXq5B%!*RYQ193fMUG{<*;=ueRxK1p6EOaAOZY$cejYg| ztupr|TN8c9_VYZ?J-{#Te2zzR?^kQVilZ0jNQ&)3SyuM%+zTAeJ+j$sFP63>pbb_$ z#-3l5?DEdavDcW7E-qy59jracu7vK5%zfs)*XA8Fdsd@waBV#L*i1KlF}D&zu_HX5 zA`3G2?s*zZi)1OCcs7iQA67&gyn`WSOG4;}IIQ5_9PlF=z6VbHqRSn=%!(E-)g8-q zo|&>-v#m1B^}8Y?<}0V7c!d)yg&H2hzrlop)>@t0bX=ToB<^}pV8woK@AhOuA==7# z?<RJA#-0&ndn-EY_ZsR+&wXcpwB>xG{BVClK}3Ala>wTOdh{tlB1ESHbkpeE8jm6) zJRSug7q7SLYzdT&h}Sz4y?cs@^^KCI`}+;SgcOt!2>8#8=tGjurLpjLJRu@3=F9&b zrr+gT@~oV{t`jMsKuZPvBHWj+l-{#qRnkw|+ix(TptY8NTn~MHVGb)6QGQYOhx;FV zugq)^{bcGtO6+=!J>Muhdx<^!{d2R7L_4_sx1WBy^3=V(B=mQ0Dtpu44o08i8m!ny zH^GVxjzNSX3pBdKVhndC`}<+VhnNUYl{9IDMCgUkLmX8Q%IyN6pvU^a2P0BK!R3$S zXCkQxGP;7Lwtq1ezI<IPnp8CziRfBgfcrY7VE!^I-e5vOYjI1HtGyTI(~0pel-J7P z{o&qc%Bn#kn4Md(8RHj9HrJ8J#>b2oh1Zr=x1T(WFYT_bKj|ADj2@YXdp?Uk$EAtr zw3Y7Zgzr#No8Ql)fGIRQY`VCVPVDx9QZPEGq=)Y}L_*}vW;Db;h!6@Mc#yX^`nk!` zicsL;lNzED|G6xG(TXKa;{#&8C~IysM2E_jnw;3M;teJgv{v9K@#8mEGJ4ocFafZl z3FWo2XCCX@NbEWq`yvaI8+~LK$OJzqSx0C;G02-67rS5nytVyetfymrYcBP0Y$5Rq z;Dhw!5iU(cANQW^nOh5^L^iiGC}0YWjSZYHImgC+U0063=yh-Wtfa}uK<0<khAuzx zA<f10c@Vis!o_S{=*r9-$l>G|6haON&_IaFN&fUisFvFL16UI2Zl;2jvWS7-Pgg{L zfFUoc3jR~e2VF5AunOP}SRg<Q1i??oO!?%rVil}qGVy3hk*pP^A%Celq}qK}5ef0s zie(`n8de0L0O$hodRE*p-x%5Vq6-@l-fho)_Xg9)iSYrHuarHPIS|~O8=vQSX&z{U zBV}dT9#4*pn#~8wv!L0ztBeQzW~v9%laqTxX7iJ|$t5recBA8x{CY9^*3k!I!K{z& zaR9%DGQYGvg|ajGtJ(anv9w8+d>zrX^lHb#j*<pXA%GuxO6l|W^z{%M;?|4+&@Kes zAzmzKms?rUmz;;W^4(m<S-1HKp&-)Dr?iYaP>`Lf+)43NMK*<a_8K7+$VD0^FSC_4 z(G;FnC0?*JThVgrK(uj$^%1Z6gY~InnYUti8k2&+#5g$tUNmV^=?qX{EeUot2S7o| znvqKk+~?38rG^zNHUJ7zZb7_pgn~cQadthilkM1DSs%n~HZjqS0xMcwE+M!3^Y_{8 z=6(j`fWdWTac^e}oPpnzXKt5kWJ!76-RC0e%dJO`dR?v;Ym@1s%eDM-VhMkkS^F`~ zy9T3QVg(AqcPN>q?PHXk$q|>!Hn$ccOPh4b{&Hdc$HmpVb5C4-XR`JI*J2gONySGS z;wX$r9@4kD<(5|L%0$FAfCnT>D1ejPYBIzRMYMP_%yW9Ah`k;u!|?!P)cQq-+8`9v zM6b!2WO>e6uQppT52`?%4LM~28BMGzvus_f`$-0gia;_%9@oo=msM4pwZc%H*dz__ zl+P#CBCJ@oI}42)G<mBq!pOLj_M1j1_)`r%p4nSm+#8&gF*&~b?I=p-Xrl+^f&8dr zKRdAz#5nl)<zaSacED<tkG|>zMBw1)sT-S!+^f%XWXtM=)QeYbyxku^;HR^1IP3Cw z&PTVHo<EAA41M{8Mfq-=BTMPv*;1Th4-TeZryOtBr!j^H@za9@SR`~4AEF<UKyJj` zIgqu;OVSmD0+H#j2%O3@ZM{y(Co+OvH(6lCh{wwmG>rwJU`Pd_Ai(LdvSqm7%=B1< z42g&j5JJI8Br{401w3=niWZLws(@%^)mYwQo00{QIjL(bjl+>WVyPI>&=wiDs>yt< zNDk1(cSSL%vG7_^w^tih^l2Hqm9LHzz4n_<DELsLTqF{|98ciu9*P-P2G}5m*U<oB z8gvD_d;hXR3o9eWN1t^=kFOC7|2fIyw!K4q4$n$gz%pdS>#&k4TZ#Q*G^9>-ix|7} z7^_nPVHN<X0YZVD5(?s~qpcE7cH#b<jF*u*%X)D;u1?h}O;+SJo;<l%t@%We(+U_{ ztXd>btQaE~;&iQ4<1#tIB`Tj=k*TVw3PH8R@(nAxwIP^~gvD3dZwUn-rCxk11^L`e z;?RaZ=%FTr{)pu69H6=Ilu!_kL_WEaP@sWOfSwl8xEK^x;{jOlj8LGL@xO;eeb&wi z1!35A%I)osO;JKYC<eJfC}^^xG*z@T<d=0nsUnasup*i+#A}@lSvx7%*p#L_D(6-# z)%61I&&i^3f|hf#8^R5~+I~wY_$W2Auz9$*r7V7fF(DM-AN3&wA9m9qCz=b7<ecz) z@^UMNi@rk0AQWhnP@oSHD;AoqcupuNQbGY*WPnTcw6$@RP>^aS6u^qQE?63}O347V zqNICZMG%T0w^|d=0R^lk3FlT6O&Ti}^>Ep+qK@MXq-vbdFk=3eQ1EeSB>i&#aOS&X zQ)6z}kdiV;Fua4tiJir9XXe|kI<{CkGbukI6sSQfB>4Q|B~~;D1#mBk*iJSG1w$$; z&=*zn7p!Qp)c@#;0eR}ID>^gPW-Iy;?8!jBlwN395jxQ&D@lbntSEf|C=hQ61s|72 zgPbIB?-~}QCZq?IPD08ctPCR<o<*#kbN=cR^eLwX(eZ+6gHUkFTw+CED%2npILI${ zoP01-fPX*L<CIVU2x^lR-M|GwRYx%|a$2$RT~TbdA}@DRD++S5NURvARz$v{yDs_K z4J+cUXe&GkTq6KEGVv(<`K|tU4Uo`JgmPaX6!0t?Cu!Vji!5$SVLpRnORp9|AbiOo z*DmXdW&2d{6e;j$gaUtkK54IFP@N}CE2bb1oi<sKaQPU<&t@DVPS7bFmje<`(9Krt z)bNdvVE`zoR~e?}Oa>T8ENUtm<hd1nIlTZtK`a@pG;YtW2?Ym^&RhLoLLa2Lv+y9~ zaFB)=GzbNpJshI>imeC*G{N1WCF}8!4nn~tRs{J}m%_5H(eq6HoKR4h(j{OGng|7D z3NF>_Ttt-x*e|Xo>s(Tk%kNpS1SCNy9*(GbEzd9>9iLD7;)#^gYweKnd&O6}RF?>= z^3S_s_p6D!zuXcE{y)Kk_<_(4-_gWbdTu5iF>Z%IC^&9OD416TII<?I+7u-eoLjNd zfMvjRzBnNin3(qo1@<XTm6`|zWeU8IG))Z)491lp2m?trV7X{T6N8!iIH%#XRLGNV zSW9XeJwpd`a@DXRO35a@dX)pk;5wmpwu6b6GlRGKC^Tc}CC~&^$X$H)=Ca4E?ucGm zEuzSr!3GFSfR3o+#ETQK1^oBvkgokP8n#x934N~yZa}P5Peq1~MIi67Ojq-C$ta~N z1r#tuU>XESEydt{dORtW8nrA0=&<z-n(EWk>@A_-BT@DPM!_Kn1xK*re<sWI#k4c; gNfgwir@gg)2ew*1j1OL7wg3PC07*qoM6N<$f(e@7(EtDd diff --git a/Assets/XCharts/Documentation/res/op_addseriedatacomponent.png.meta b/Assets/XCharts/Documentation/res/op_addseriedatacomponent.png.meta deleted file mode 100644 index 3eca7ba..0000000 --- a/Assets/XCharts/Documentation/res/op_addseriedatacomponent.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 1ca6fe245906a453284b526f09c44eff -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/op_textmeshpro.png b/Assets/XCharts/Documentation/res/op_textmeshpro.png deleted file mode 100644 index 8ea4172e7b7ce4b1065488095e319ed0d87dd3dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65659 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 HB=Y|Nu1k7! diff --git a/Assets/XCharts/Documentation/res/op_textmeshpro.png.meta b/Assets/XCharts/Documentation/res/op_textmeshpro.png.meta deleted file mode 100644 index 6c13d6f..0000000 --- a/Assets/XCharts/Documentation/res/op_textmeshpro.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 9031f7bed8c7f4350affc32cc7016b5e -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/op_textmeshpro3.png b/Assets/XCharts/Documentation/res/op_textmeshpro3.png deleted file mode 100644 index 52f71b77da1a4c12e8f439976223f5b5d308a1c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30997 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 ULI{v5tpET307*qoM6N<$f|msya{vGU diff --git a/Assets/XCharts/Documentation/res/op_textmeshpro3.png.meta b/Assets/XCharts/Documentation/res/op_textmeshpro3.png.meta deleted file mode 100644 index c74cfa5..0000000 --- a/Assets/XCharts/Documentation/res/op_textmeshpro3.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: 1777b9bc4f1df446eaf01931cb0b07ed -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Documentation/res/wechat.png b/Assets/XCharts/Documentation/res/wechat.png deleted file mode 100644 index c2f8b6777729c2754a31048ed73e17a8a6845000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11704 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 O0000<MNUMnLSTZ|je&0f diff --git a/Assets/XCharts/Documentation/res/wechat.png.meta b/Assets/XCharts/Documentation/res/wechat.png.meta deleted file mode 100644 index a66a7c3..0000000 --- a/Assets/XCharts/Documentation/res/wechat.png.meta +++ /dev/null @@ -1,76 +0,0 @@ -fileFormatVersion: 2 -guid: c62c735b2989c4367b8c97b8ca75c216 -TextureImporter: - fileIDToRecycleName: {} - externalObjects: {} - serializedVersion: 4 - mipmaps: - mipMapMode: 0 - enableMipMap: 1 - sRGBTexture: 1 - linearTexture: 0 - fadeOut: 0 - borderMipMap: 0 - mipMapsPreserveCoverage: 0 - alphaTestReferenceValue: 0.5 - mipMapFadeDistanceStart: 1 - mipMapFadeDistanceEnd: 3 - bumpmap: - convertToNormalMap: 0 - externalNormalMap: 0 - heightScale: 0.25 - normalMapFilter: 0 - isReadable: 0 - grayScaleToAlpha: 0 - generateCubemap: 6 - cubemapConvolution: 0 - seamlessCubemap: 0 - textureFormat: 1 - maxTextureSize: 2048 - textureSettings: - serializedVersion: 2 - filterMode: -1 - aniso: -1 - mipBias: -1 - wrapU: -1 - wrapV: -1 - wrapW: -1 - nPOTScale: 1 - lightmap: 0 - compressionQuality: 50 - spriteMode: 0 - spriteExtrude: 1 - spriteMeshType: 1 - alignment: 0 - spritePivot: {x: 0.5, y: 0.5} - spritePixelsToUnits: 100 - spriteBorder: {x: 0, y: 0, z: 0, w: 0} - spriteGenerateFallbackPhysicsShape: 1 - alphaUsage: 1 - alphaIsTransparency: 0 - spriteTessellationDetail: -1 - textureType: 0 - textureShape: 1 - maxTextureSizeSet: 0 - compressionQualitySet: 0 - textureFormatSet: 0 - platformSettings: - - buildTarget: DefaultTexturePlatform - maxTextureSize: 2048 - resizeAlgorithm: 0 - textureFormat: -1 - textureCompression: 1 - compressionQuality: 50 - crunchedCompression: 0 - allowsAlphaSplitting: 0 - overridden: 0 - androidETC2FallbackOverride: 0 - spriteSheet: - serializedVersion: 2 - sprites: [] - outline: [] - physicsShape: [] - spritePackingTag: - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Attributes/ComponentEditorAttribute.cs b/Assets/XCharts/Editor/Attributes/ComponentEditorAttribute.cs deleted file mode 100644 index 3e5d460..0000000 --- a/Assets/XCharts/Editor/Attributes/ComponentEditorAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace XCharts.Editor -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public sealed class ComponentEditorAttribute : Attribute - { - public readonly Type componentType; - - public ComponentEditorAttribute(Type componentType) - { - this.componentType = componentType; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs b/Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs deleted file mode 100644 index c747be6..0000000 --- a/Assets/XCharts/Editor/Attributes/SerieEditorAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace XCharts.Editor -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] - public sealed class SerieEditorAttribute : Attribute - { - public readonly Type serieType; - - public SerieEditorAttribute(Type serieType) - { - this.serieType = serieType; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Charts.meta b/Assets/XCharts/Editor/Charts.meta deleted file mode 100644 index 412c017..0000000 --- a/Assets/XCharts/Editor/Charts.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9e4407eed14ec4e518a373f4d8ae9b3c -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Charts/BaseChartEditor.cs b/Assets/XCharts/Editor/Charts/BaseChartEditor.cs deleted file mode 100644 index 617d12e..0000000 --- a/Assets/XCharts/Editor/Charts/BaseChartEditor.cs +++ /dev/null @@ -1,320 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomEditor(typeof(BaseChart), true)] - public class BaseChartEditor : UnityEditor.Editor - { - class Styles - { - public static readonly GUIContent btnAddSerie = new GUIContent("Add Serie", ""); - public static readonly GUIContent btnAddComponent = new GUIContent("Add Main Component", ""); - public static readonly GUIContent btnCovertXYAxis = new GUIContent("Covert XY Axis", ""); - public static readonly GUIContent btnRebuildChartObject = new GUIContent("Rebuild Chart Object", ""); - public static readonly GUIContent btnCheckWarning = new GUIContent("Check Warning", ""); - public static readonly GUIContent btnHideWarning = new GUIContent("Hide Warning", ""); - } - protected BaseChart m_Chart; - protected SerializedProperty m_Script; - protected SerializedProperty m_EnableTextMeshPro; - protected SerializedProperty m_Settings; - protected SerializedProperty m_Theme; - protected SerializedProperty m_ChartName; - protected SerializedProperty m_DebugInfo; - protected SerializedProperty m_RaycastTarget; - - protected List<SerializedProperty> m_Components = new List<SerializedProperty>(); - protected List<SerializedProperty> m_Series = new List<SerializedProperty>(); - - private bool m_BaseFoldout; - - private bool m_CheckWarning = false; - private int m_LastComponentCount = 0; - private int m_LastSerieCount = 0; - private string m_VersionString = ""; - private StringBuilder sb = new StringBuilder(); - MainComponentListEditor m_ComponentList; - SerieListEditor m_SerieList; - - protected virtual void OnEnable() - { - if (target == null) return; - m_Chart = (BaseChart) target; - m_Script = serializedObject.FindProperty("m_Script"); - m_EnableTextMeshPro = serializedObject.FindProperty("m_EnableTextMeshPro"); - m_ChartName = serializedObject.FindProperty("m_ChartName"); - m_Theme = serializedObject.FindProperty("m_Theme"); - m_Settings = serializedObject.FindProperty("m_Settings"); - m_DebugInfo = serializedObject.FindProperty("m_DebugInfo"); - m_RaycastTarget = serializedObject.FindProperty("m_RaycastTarget"); - - RefreshComponent(); - m_ComponentList = new MainComponentListEditor(this); - m_ComponentList.Init(m_Chart, serializedObject, m_Components); - - RefreshSeries(); - m_SerieList = new SerieListEditor(this); - m_SerieList.Init(m_Chart, serializedObject, m_Series); - - m_VersionString = "v" + XChartsMgr.fullVersion; - if (m_EnableTextMeshPro.boolValue) - m_VersionString += "-tmp"; - } - - public List<SerializedProperty> RefreshComponent() - { - m_Components.Clear(); - serializedObject.UpdateIfRequiredOrScript(); - foreach (var kv in m_Chart.typeListForComponent) - { - InitComponent(kv.Value.Name); - } - return m_Components; - } - - public List<SerializedProperty> RefreshSeries() - { - m_Series.Clear(); - serializedObject.UpdateIfRequiredOrScript(); - foreach (var kv in m_Chart.typeListForSerie) - { - InitSerie(kv.Value.Name); - } - return m_Series; - } - - public override void OnInspectorGUI() - { - if (m_Chart == null && target == null) - { - base.OnInspectorGUI(); - return; - } - serializedObject.UpdateIfRequiredOrScript(); - if (m_LastComponentCount != m_Chart.components.Count) - { - m_LastComponentCount = m_Chart.components.Count; - RefreshComponent(); - m_ComponentList.UpdateComponentsProperty(m_Components); - - } - if (m_LastSerieCount != m_Chart.series.Count) - { - m_LastSerieCount = m_Chart.series.Count; - RefreshSeries(); - m_SerieList.UpdateSeriesProperty(m_Series); - } - OnStartInspectorGUI(); - OnDebugInspectorGUI(); - EditorGUILayout.Space(); - serializedObject.ApplyModifiedProperties(); - } - - protected virtual void OnStartInspectorGUI() - { - ShowVersion(); - m_BaseFoldout = ChartEditorHelper.DrawHeader("Base", m_BaseFoldout, false, null, null); - if (m_BaseFoldout) - { - EditorGUILayout.PropertyField(m_Script); - EditorGUILayout.PropertyField(m_ChartName); - EditorGUILayout.PropertyField(m_RaycastTarget); - if (XChartsMgr.IsRepeatChartName(m_Chart, m_ChartName.stringValue)) - { - EditorGUILayout.BeginHorizontal(); - EditorGUILayout.HelpBox("chart name is repeated: " + m_ChartName.stringValue, MessageType.Error); - EditorGUILayout.EndHorizontal(); - } - } - EditorGUILayout.PropertyField(m_Theme); - EditorGUILayout.PropertyField(m_Settings); - m_ComponentList.OnGUI(); - m_SerieList.OnGUI(); - } - - protected virtual void OnDebugInspectorGUI() - { - EditorGUILayout.PropertyField(m_DebugInfo, true); - EditorGUILayout.Space(); - AddSerie(); - AddComponent(); - CheckWarning(); - } - - protected void PropertyComponnetList(SerializedProperty prop) - { - for (int i = 0; i < prop.arraySize; i++) - { - EditorGUILayout.PropertyField(prop.GetArrayElementAtIndex(i), true); - } - } - - private void InitComponent(string propName) - { - var prop = serializedObject.FindProperty(propName); - for (int i = 0; i < prop.arraySize; i++) - { - m_Components.Add(prop.GetArrayElementAtIndex(i)); - } - m_Components.Sort((a, b) => { return a.propertyPath.CompareTo(b.propertyPath); }); - } - - private void InitSerie(string propName) - { - var prop = serializedObject.FindProperty(propName); - for (int i = 0; i < prop.arraySize; i++) - { - m_Series.Add(prop.GetArrayElementAtIndex(i)); - } - m_Series.Sort(delegate(SerializedProperty a, SerializedProperty b) - { - var index1 = a.FindPropertyRelative("m_Index").intValue; - var index2 = b.FindPropertyRelative("m_Index").intValue; - return index1.CompareTo(index2); - }); - } - - private void ShowVersion() - { - EditorGUILayout.HelpBox(m_VersionString, MessageType.None); - } - - private void AddComponent() - { - if (GUILayout.Button(Styles.btnAddComponent)) - { - var menu = new GenericMenu(); - foreach (var type in GetMainComponentTypeNames()) - { - var title = ChartEditorHelper.GetContent(type.Name); - bool exists = !m_Chart.CanAddChartComponent(type); - if (!exists) - menu.AddItem(title, false, () => - { - m_ComponentList.AddChartComponent(type); - }); - else - { - menu.AddDisabledItem(title); - } - } - - menu.ShowAsContext(); - } - } - private void AddSerie() - { - if (GUILayout.Button(Styles.btnAddSerie)) - { - var menu = new GenericMenu(); - foreach (var type in GetSerieTypeNames()) - { - var title = ChartEditorHelper.GetContent(type.Name); - if (m_Chart.CanAddSerie(type)) - { - menu.AddItem(title, false, () => - { - m_SerieList.AddSerie(type); - }); - } - else - { - menu.AddDisabledItem(title); - } - } - menu.ShowAsContext(); - } - } - - private List<Type> GetMainComponentTypeNames() - { - var list = new List<Type>(); - var typeMap = RuntimeUtil.GetAllTypesDerivedFrom<MainComponent>(); - foreach (var kvp in typeMap) - { - var type = kvp; - if (RuntimeUtil.HasSubclass(type)) continue; - - if (type.IsDefined(typeof(ComponentHandlerAttribute), false)) - { - var attribute = type.GetAttribute<ComponentHandlerAttribute>(); - if (attribute != null && attribute.handler != null) - list.Add(type); - } - else - { - list.Add(type); - } - } - list.Sort((a, b) => { return a.Name.CompareTo(b.Name); }); - return list; - } - private List<Type> GetSerieTypeNames() - { - var list = new List<Type>(); - var typeMap = RuntimeUtil.GetAllTypesDerivedFrom<Serie>(); - foreach (var kvp in typeMap) - { - var type = kvp; - if (type.IsDefined(typeof(SerieHandlerAttribute), false)) - list.Add(type); - } - list.Sort((a, b) => { return a.Name.CompareTo(b.Name); }); - return list; - } - - private void CheckWarning() - { - if (m_Chart.HasChartComponent<XAxis>() && m_Chart.HasChartComponent<YAxis>()) - { - if (GUILayout.Button(Styles.btnCovertXYAxis)) - m_Chart.CovertXYAxis(0); - } - if (GUILayout.Button(Styles.btnRebuildChartObject)) - { - m_Chart.RebuildChartObject(); - } - if (m_CheckWarning) - { - EditorGUILayout.BeginHorizontal(); - if (GUILayout.Button(Styles.btnCheckWarning)) - { - m_CheckWarning = true; - m_Chart.CheckWarning(); - } - if (GUILayout.Button(Styles.btnHideWarning)) - { - m_CheckWarning = false; - } - EditorGUILayout.EndHorizontal(); - sb.Length = 0; - sb.AppendFormat("v{0}", XChartsMgr.fullVersion); - if (!string.IsNullOrEmpty(m_Chart.warningInfo)) - { - sb.AppendLine(); - sb.Append(m_Chart.warningInfo); - } - else - { - sb.AppendLine(); - sb.Append("Perfect! No warning!"); - } - EditorGUILayout.HelpBox(sb.ToString(), MessageType.Warning); - } - else - { - if (GUILayout.Button(Styles.btnCheckWarning)) - { - m_CheckWarning = true; - m_Chart.CheckWarning(); - } - - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Charts/BaseChartEditor.cs.meta b/Assets/XCharts/Editor/Charts/BaseChartEditor.cs.meta deleted file mode 100644 index 2916db0..0000000 --- a/Assets/XCharts/Editor/Charts/BaseChartEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d7f1cff1e5bae244a872040086b1cfa8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents.meta b/Assets/XCharts/Editor/ChildComponents.meta deleted file mode 100644 index b2aa5c5..0000000 --- a/Assets/XCharts/Editor/ChildComponents.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7861b681552cf4bc9b2c2f16d25c628c -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs b/Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs deleted file mode 100644 index 8d7a59c..0000000 --- a/Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(AnimationStyle), true)] - public class AnimationDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Animation"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Enable", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Type"); - PropertyField(prop, "m_FadeInDuration"); - PropertyField(prop, "m_FadeInDelay"); - PropertyField(prop, "m_FadeOutDuration"); - PropertyField(prop, "m_FadeOutDelay"); - PropertyField(prop, "m_DataChangeEnable"); - PropertyField(prop, "m_DataChangeDuration"); - PropertyField(prop, "m_ActualDuration"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs.meta deleted file mode 100644 index 5a9ff4d..0000000 --- a/Assets/XCharts/Editor/ChildComponents/AnimationDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 844042f92a581474ba0491427f3fd592 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs deleted file mode 100644 index 25aa9bc..0000000 --- a/Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(AreaStyle), true)] - public class AreaStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "AreaStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Origin"); - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_ToColor"); - PropertyField(prop, "m_HighlightColor"); - PropertyField(prop, "m_HighlightToColor"); - PropertyField(prop, "m_Opacity"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs.meta deleted file mode 100644 index 78e98cf..0000000 --- a/Assets/XCharts/Editor/ChildComponents/AreaStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c51fd822c8be44490832d81652d1aef5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs b/Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs deleted file mode 100644 index 77ae7b0..0000000 --- a/Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs +++ /dev/null @@ -1,211 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; - -namespace XCharts.Editor -{ - public delegate void DelegateMenuAction(Vector2 postion); - public class BasePropertyDrawer : PropertyDrawer - { - protected int m_Index; - protected int m_DataSize; - protected float m_DefaultWidth; - protected string m_DisplayName; - protected string m_KeyName; - protected Rect m_DrawRect; - protected Dictionary<string, float> m_Heights = new Dictionary<string, float>(); - protected Dictionary<string, bool> m_PropToggles = new Dictionary<string, bool>(); - protected Dictionary<string, bool> m_DataToggles = new Dictionary<string, bool>(); - - public virtual string ClassName { get { return ""; } } - public virtual List<string> IngorePropertys { get { return new List<string> { }; } } - - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - m_DrawRect = pos; - m_DrawRect.height = EditorGUIUtility.singleLineHeight; - m_DefaultWidth = pos.width; - var list = prop.displayName.Split(' '); - if (list.Length > 0) - { - if (!int.TryParse(list[list.Length - 1], out m_Index)) - { - m_Index = 0; - m_DisplayName = prop.displayName; - m_KeyName = prop.propertyPath + "_" + m_Index; - } - else - { - m_DisplayName = ClassName + " " + m_Index; - m_KeyName = prop.propertyPath + "_" + m_Index; - } - } - else - { - m_DisplayName = prop.displayName; - } - if (!m_PropToggles.ContainsKey(m_KeyName)) - { - m_PropToggles.Add(m_KeyName, false); - } - if (!m_DataToggles.ContainsKey(m_KeyName)) - { - m_DataToggles.Add(m_KeyName, false); - } - if (!m_Heights.ContainsKey(m_KeyName)) - { - m_Heights.Add(m_KeyName, 0); - } - else - { - m_Heights[m_KeyName] = 0; - } - } - - private string GetKeyName(SerializedProperty prop) - { - var index = 0; - var list = prop.displayName.Split(' '); - if (list.Length > 0) - { - int.TryParse(list[list.Length - 1], out index); - } - return prop.propertyPath + "_" + index; - } - - protected void AddSingleLineHeight() - { - m_Heights[m_KeyName] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - m_DrawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - protected void AddHeight(float height) - { - m_Heights[m_KeyName] += height; - m_DrawRect.y += height; - } - - protected void PropertyListField(SerializedProperty prop, string relativePropName, bool showOrder = true) - { - if (IngorePropertys.Contains(relativePropName)) return; - var height = m_Heights[m_KeyName]; - var toggleKeyName = m_KeyName + relativePropName; - m_DataToggles[toggleKeyName] = ChartEditorHelper.MakeListWithFoldout(ref m_DrawRect, ref height, - prop.FindPropertyRelative(relativePropName), - m_DataToggles.ContainsKey(toggleKeyName) && m_DataToggles[toggleKeyName], showOrder, true); - m_Heights[m_KeyName] = height; - } - - protected void PropertyField(SerializedProperty prop, string relativePropName) - { - if (IngorePropertys.Contains(relativePropName)) return; - if (!ChartEditorHelper.PropertyField(ref m_DrawRect, m_Heights, m_KeyName, prop, relativePropName)) - { - Debug.LogError("PropertyField ERROR:" + prop.displayName + ", " + relativePropName); - } - } - - protected void PropertyFieldLimitMin(SerializedProperty prop, string relativePropName, float minValue) - { - if (IngorePropertys.Contains(relativePropName)) return; - if (!ChartEditorHelper.PropertyFieldWithMinValue(ref m_DrawRect, m_Heights, m_KeyName, prop, - relativePropName, minValue)) - { - Debug.LogError("PropertyField ERROR:" + prop.displayName + ", " + relativePropName); - } - } - protected void PropertyFieldLimitMax(SerializedProperty prop, string relativePropName, float maxValue) - { - if (IngorePropertys.Contains(relativePropName)) return; - if (!ChartEditorHelper.PropertyFieldWithMaxValue(ref m_DrawRect, m_Heights, m_KeyName, prop, - relativePropName, maxValue)) - { - Debug.LogError("PropertyField ERROR:" + prop.displayName + ", " + relativePropName); - } - } - - protected void PropertyField(SerializedProperty prop, SerializedProperty relativeProp) - { - if (!ChartEditorHelper.PropertyField(ref m_DrawRect, m_Heights, m_KeyName, relativeProp)) - { - Debug.LogError("PropertyField ERROR:" + prop.displayName + ", " + relativeProp); - } - } - - protected void PropertyTwoFiled(SerializedProperty prop, string relativeListProp, string labelName = null) - { - PropertyTwoFiled(prop, prop.FindPropertyRelative(relativeListProp), labelName); - } - protected void PropertyTwoFiled(SerializedProperty prop, SerializedProperty relativeListProp, - string labelName = null) - { - if (string.IsNullOrEmpty(labelName)) - { - labelName = relativeListProp.displayName; - } - ChartEditorHelper.MakeTwoField(ref m_DrawRect, m_DefaultWidth, relativeListProp, labelName); - m_Heights[m_KeyName] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - protected bool MakeFoldout(SerializedProperty prop, string relativePropName) - { - if (string.IsNullOrEmpty(relativePropName)) - { - return ChartEditorHelper.MakeFoldout(ref m_DrawRect, m_Heights, m_PropToggles, m_KeyName, - m_DisplayName, null); - } - else - { - var relativeProp = prop.FindPropertyRelative(relativePropName); - return ChartEditorHelper.MakeFoldout(ref m_DrawRect, m_Heights, m_PropToggles, m_KeyName, - m_DisplayName, relativeProp); - } - } - protected bool MakeComponentFoldout(SerializedProperty prop, string relativePropName, bool relativePropEnable, - params HeaderMenuInfo[] menus) - { - if (string.IsNullOrEmpty(relativePropName)) - { - return ChartEditorHelper.MakeComponentFoldout(ref m_DrawRect, m_Heights, m_PropToggles, m_KeyName, - m_DisplayName, null, null, relativePropEnable, menus); - } - else - { - var relativeProp = prop.FindPropertyRelative(relativePropName); - return ChartEditorHelper.MakeComponentFoldout(ref m_DrawRect, m_Heights, m_PropToggles, m_KeyName, - m_DisplayName, relativeProp, null, relativePropEnable, menus); - } - } - - protected bool MakeComponentFoldout(SerializedProperty prop, string relativePropName, string relativePropName2, - bool relativePropEnable, params HeaderMenuInfo[] menus) - { - if (string.IsNullOrEmpty(relativePropName)) - { - return ChartEditorHelper.MakeComponentFoldout(ref m_DrawRect, m_Heights, m_PropToggles, m_KeyName, - m_DisplayName, null, null, relativePropEnable, menus); - } - else - { - var relativeProp = prop.FindPropertyRelative(relativePropName); - var relativeProp2 = prop.FindPropertyRelative(relativePropName2); - return ChartEditorHelper.MakeComponentFoldout(ref m_DrawRect, m_Heights, m_PropToggles, m_KeyName, - m_DisplayName, relativeProp, relativeProp2, relativePropEnable, menus); - } - } - - protected virtual void DrawExtendeds(SerializedProperty prop) { } - - public override float GetPropertyHeight(SerializedProperty prop, GUIContent label) - { - var key = GetKeyName(prop); - if (m_Heights.ContainsKey(key)) return m_Heights[key] + GetExtendedHeight(); - else return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - protected virtual float GetExtendedHeight() - { - return 0; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs.meta deleted file mode 100644 index 51f7228..0000000 --- a/Assets/XCharts/Editor/ChildComponents/BasePropertyDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4e5a04ce1f0a841b9b966a6d74de00e4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs b/Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs deleted file mode 100644 index 962ba61..0000000 --- a/Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs +++ /dev/null @@ -1,26 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(CommentItem), true)] - public class CommentItemDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "CommentItem"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", "m_Content", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Content"); - PropertyField(prop, "m_Position"); - //PropertyField(prop, "m_MarkRect"); - //PropertyField(prop, "m_MarkStyle"); - PropertyField(prop, "m_LabelStyle"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs.meta deleted file mode 100644 index dc4966b..0000000 --- a/Assets/XCharts/Editor/ChildComponents/CommentItemDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d485d6a729a1449cdb5032f380fba70f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs deleted file mode 100644 index 126d7cd..0000000 --- a/Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs +++ /dev/null @@ -1,22 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(CommentMarkStyle), true)] - public class CommentMarkStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "MarkStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_LineStyle"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs.meta deleted file mode 100644 index d54117b..0000000 --- a/Assets/XCharts/Editor/ChildComponents/CommentMarkStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d74ed458b24774b129611ed816b6b6cd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs b/Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs deleted file mode 100644 index 06bec27..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(ComponentTheme), true)] - public class ComponentThemeDrawer : BasePropertyDrawer - { - public override string ClassName { get { return ""; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "", true)) - { - ++EditorGUI.indentLevel; -#if dUI_TextMeshPro - PropertyField(prop, "m_TMPFont"); -#else - PropertyField(prop, "m_Font"); -#endif - PropertyField(prop, "m_FontSize"); - PropertyField(prop, "m_TextColor"); - DrawExtendeds(prop); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(BaseAxisTheme), true)] - public class BaseAxisThemeDrawer : ComponentThemeDrawer - { - public override string ClassName { get { return "Axis"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_LineType"); - PropertyField(prop, "m_LineWidth"); - PropertyField(prop, "m_LineLength"); - PropertyField(prop, "m_LineColor"); - PropertyField(prop, "m_SplitLineType"); - PropertyField(prop, "m_SplitLineWidth"); - PropertyField(prop, "m_SplitLineLength"); - PropertyField(prop, "m_SplitLineColor"); - PropertyField(prop, "m_TickWidth"); - PropertyField(prop, "m_TickLength"); - PropertyField(prop, "m_TickColor"); - PropertyField(prop, "m_SplitAreaColors"); - } - } - - [CustomPropertyDrawer(typeof(AxisTheme), true)] - public class AxisThemeDrawer : BaseAxisThemeDrawer - { - public override string ClassName { get { return "Axis"; } } - } - - [CustomPropertyDrawer(typeof(RadiusAxisTheme), true)] - public class RadiusAxisThemeDrawer : BaseAxisThemeDrawer - { - public override string ClassName { get { return "Radius Axis"; } } - public override List<string> IngorePropertys - { - get - { - return new List<string> - { - "m_TextBackgroundColor", - "m_LineLength", - "m_SplitLineLength", - }; - } - } - } - - [CustomPropertyDrawer(typeof(DataZoomTheme), true)] - public class DataZoomThemeDrawer : ComponentThemeDrawer - { - public override string ClassName { get { return "DataZoom"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_BackgroundColor"); - PropertyField(prop, "m_BorderWidth"); - PropertyField(prop, "m_BorderColor"); - PropertyField(prop, "m_DataLineWidth"); - PropertyField(prop, "m_DataLineColor"); - PropertyField(prop, "m_FillerColor"); - PropertyField(prop, "m_DataAreaColor"); - - } - } - - [CustomPropertyDrawer(typeof(LegendTheme), true)] - public class LegendThemeDrawer : ComponentThemeDrawer - { - public override string ClassName { get { return "Legend"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_UnableColor"); - } - } - - [CustomPropertyDrawer(typeof(TooltipTheme), true)] - public class TooltipThemeDrawer : ComponentThemeDrawer - { - public override string ClassName { get { return "Tooltip"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_LineType"); - PropertyField(prop, "m_LineWidth"); - PropertyField(prop, "m_LineColor"); - PropertyField(prop, "m_AreaColor"); - PropertyField(prop, "m_LabelTextColor"); - PropertyField(prop, "m_LabelBackgroundColor"); - } - } - - [CustomPropertyDrawer(typeof(VisualMapTheme), true)] - public class VisualMapThemeDrawer : ComponentThemeDrawer - { - public override string ClassName { get { return "VisualMap"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - // PropertyField(prop, "m_BorderWidth"); - // PropertyField(prop, "m_BorderColor"); - // PropertyField(prop, "m_BackgroundColor"); - } - } - - [CustomPropertyDrawer(typeof(SerieTheme), true)] - public class SerieThemeDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Serie"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_LineWidth"); - PropertyField(prop, "m_LineSymbolSize"); - PropertyField(prop, "m_ScatterSymbolSize"); - PropertyField(prop, "m_SelectedRate"); - PropertyField(prop, "m_PieTooltipExtraRadius"); - PropertyField(prop, "m_PieSelectedOffset"); - PropertyField(prop, "m_CandlestickColor"); - PropertyField(prop, "m_CandlestickColor0"); - PropertyField(prop, "m_CandlestickBorderColor"); - PropertyField(prop, "m_CandlestickBorderColor0"); - PropertyField(prop, "m_CandlestickBorderWidth"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs.meta deleted file mode 100644 index 5ddef75..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ComponentThemeDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c7937a2a7addd42299e960c5cfb75e34 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs b/Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs deleted file mode 100644 index af03faf..0000000 --- a/Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs +++ /dev/null @@ -1,25 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(DebugInfo), true)] - public class DebugInfoDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Debug"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", false)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_FoldSeries"); - PropertyField(prop, "m_ShowDebugInfo"); - PropertyField(prop, "m_ShowAllChartObject"); - PropertyField(prop, "m_LabelStyle"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs.meta deleted file mode 100644 index 34acfda..0000000 --- a/Assets/XCharts/Editor/ChildComponents/DebugInfoDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 99bd61acea264400fb4747b17a2731e4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs deleted file mode 100644 index 89377f3..0000000 --- a/Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(Emphasis), true)] - public class EmphasisDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Emphasis"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Label"); - PropertyField(prop, "m_LabelLine"); - PropertyField(prop, "m_ItemStyle"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(EmphasisItemStyle), true)] - public class EmphasisItemStyleDrawer : ItemStyleDrawer - { - public override string ClassName { get { return "EmphasisItemStyle"; } } - } - - [CustomPropertyDrawer(typeof(EmphasisLabelStyle), true)] - public class EmphasisLabelStyleDrawer : LabelStyleDrawer - { - public override string ClassName { get { return "EmphasisLabel"; } } - } - - [CustomPropertyDrawer(typeof(EmphasisLabelLine), true)] - public class EmphasisLabelLineDrawer : LabelLineDrawer - { - public override string ClassName { get { return "EmphasisLabelLine"; } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs.meta deleted file mode 100644 index a6cdfc4..0000000 --- a/Assets/XCharts/Editor/ChildComponents/EmphasisStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7de9b5e4c5d474fdd88ebb89f0924305 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs deleted file mode 100644 index 2f2e1a6..0000000 --- a/Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs +++ /dev/null @@ -1,30 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(IconStyle), true)] - public class IconStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "IconStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Layer"); - PropertyField(prop, "m_Align"); - PropertyField(prop, "m_Sprite"); - PropertyField(prop, "m_Type"); - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Height"); - PropertyField(prop, "m_Offset"); - PropertyField(prop, "m_AutoHideWhenLabelEmpty"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs.meta deleted file mode 100644 index fb19ace..0000000 --- a/Assets/XCharts/Editor/ChildComponents/IconStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9cae26ad61d224d8a97d41bdc52ec0b7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs deleted file mode 100644 index 8ad71d4..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(ImageStyle), true)] - public class ImageStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "ImageStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Sprite"); - PropertyField(prop, "m_Type"); - PropertyField(prop, "m_AutoColor"); - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Height"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs.meta deleted file mode 100644 index 6907fec..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ImageStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4649856b17dfd4f628eb975040fb791c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs deleted file mode 100644 index 50978b0..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs +++ /dev/null @@ -1,39 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(ItemStyle), true)] - public class ItemStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "ItemStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", false)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_Color0"); - PropertyField(prop, "m_ToColor"); - PropertyField(prop, "m_ToColor2"); - PropertyField(prop, "m_BackgroundColor"); - PropertyField(prop, "m_BackgroundWidth"); - PropertyField(prop, "m_CenterColor"); - PropertyField(prop, "m_CenterGap"); - PropertyField(prop, "m_BorderWidth"); - PropertyField(prop, "m_BorderGap"); - PropertyField(prop, "m_BorderColor"); - PropertyField(prop, "m_BorderColor0"); - PropertyField(prop, "m_BorderToColor"); - PropertyField(prop, "m_Opacity"); - PropertyField(prop, "m_ItemMarker"); - PropertyField(prop, "m_ItemFormatter"); - PropertyField(prop, "m_NumericFormatter"); - PropertyListField(prop, "m_CornerRadius", true); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs.meta deleted file mode 100644 index 78d018c..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ItemStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f40830a3b05574467ad0d8873c6c8790 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs deleted file mode 100644 index dcd2d6c..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs +++ /dev/null @@ -1,30 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(LabelLine), true)] - public class LabelLineDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "LabelLine"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_LineType"); - PropertyField(prop, "m_LineColor"); - PropertyField(prop, "m_LineAngle"); - PropertyField(prop, "m_LineWidth"); - PropertyField(prop, "m_LineGap"); - PropertyField(prop, "m_LineLength1"); - PropertyField(prop, "m_LineLength2"); - PropertyField(prop, "m_StartSymbol"); - PropertyField(prop, "m_EndSymbol"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs.meta deleted file mode 100644 index 72f2076..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LabelLineDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 29a267a45c6e64454a982032947046c6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs deleted file mode 100644 index 103b345..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs +++ /dev/null @@ -1,40 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(LabelStyle), true)] - public class LabelStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Label"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Position"); - PropertyField(prop, "m_Formatter"); - PropertyField(prop, "m_NumericFormatter"); - PropertyField(prop, "m_AutoOffset"); - PropertyField(prop, "m_Offset"); - PropertyField(prop, "m_Distance"); - PropertyField(prop, "m_Rotate"); - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Height"); - PropertyField(prop, "m_Icon"); - PropertyField(prop, "m_Background"); - PropertyField(prop, "m_TextStyle"); - PropertyField(prop, "m_TextPadding"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(EndLabelStyle), true)] - public class EndLabelStyleDrawer : LabelStyleDrawer - { - public override string ClassName { get { return "End Label"; } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs.meta deleted file mode 100644 index 390d611..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LabelStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: abd47f4015a9840b9acae8efb21db7c3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs deleted file mode 100644 index 8879a5e..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs +++ /dev/null @@ -1,37 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(LevelStyle), true)] - public class LevelStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "LevelStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyListField(prop, "m_Levels"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(Level), true)] - public class LevelDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Level"; } } - 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; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs.meta deleted file mode 100644 index 37b74c7..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LevelStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7a1ff119a53a44e5abe2ef6f57816aa6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs deleted file mode 100644 index 031498f..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(ArrowStyle), true)] - public class ArrowDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Arrow"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Height"); - PropertyField(prop, "m_Offset"); - PropertyField(prop, "m_Dent"); - PropertyField(prop, "m_Color"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(LineArrow), true)] - public class LineArrowStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "LineArrow"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Position"); - PropertyField(prop, "m_Arrow"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs.meta deleted file mode 100644 index 3c9213f..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LineArrowDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 817d27d232da94f6c9dab9e3d0c22631 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LineDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LineDrawer.cs deleted file mode 100644 index b3d4896..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LineDrawer.cs +++ /dev/null @@ -1,66 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(BaseLine), true)] - public class BaseLineDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Line"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - DrawExtendeds(prop); - PropertyField(prop, "m_LineStyle"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(AxisLine), true)] - public class AxisLineDrawer : BaseLineDrawer - { - public override string ClassName { get { return "AxisLine"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_OnZero"); - PropertyField(prop, "m_ShowArrow"); - PropertyField(prop, "m_Arrow"); - } - } - - [CustomPropertyDrawer(typeof(AxisSplitLine), true)] - public class AxisSplitLineDrawer : BaseLineDrawer - { - public override string ClassName { get { return "SplitLine"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_Interval"); - PropertyField(prop, "m_Distance"); - PropertyField(prop, "m_AutoColor"); - } - } - - [CustomPropertyDrawer(typeof(AxisTick), true)] - public class AxisTickDrawer : BaseLineDrawer - { - public override string ClassName { get { return "AxisTick"; } } - protected override void DrawExtendeds(SerializedProperty prop) - { - base.DrawExtendeds(prop); - PropertyField(prop, "m_AlignWithLabel"); - PropertyField(prop, "m_Inside"); - PropertyField(prop, "m_ShowStartTick"); - PropertyField(prop, "m_ShowEndTick"); - PropertyField(prop, "m_SplitNumber"); - PropertyField(prop, "m_Distance"); - PropertyField(prop, "m_AutoColor"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LineDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LineDrawer.cs.meta deleted file mode 100644 index 5830eeb..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LineDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2e69f60c7d200439abcf3407c15f8c4d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs deleted file mode 100644 index 17d6fac..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs +++ /dev/null @@ -1,28 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(LineStyle), true)] - public class LineStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "LineStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Type"); - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_ToColor"); - PropertyField(prop, "m_ToColor2"); - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Length"); - PropertyField(prop, "m_Opacity"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs.meta deleted file mode 100644 index e4bda69..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LineStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4a36d5076e1414d619b53d1ef998806f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs b/Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs deleted file mode 100644 index 2cfe596..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs +++ /dev/null @@ -1,25 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(Location), true)] - public class LocationDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Location"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Align", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Top"); - PropertyField(prop, "m_Bottom"); - PropertyField(prop, "m_Left"); - PropertyField(prop, "m_Right"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs.meta deleted file mode 100644 index 4b0c2f5..0000000 --- a/Assets/XCharts/Editor/ChildComponents/LocationDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 34092595791508d4b94b074a8788c388 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs b/Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs deleted file mode 100644 index 0f3e214..0000000 --- a/Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(SerieSymbol), true)] - public class SerieSymbolDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Symbol"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - var type = (SymbolType) prop.FindPropertyRelative("m_Type").enumValueIndex; - PropertyField(prop, "m_Type"); - if (type == SymbolType.Custom) - { - PropertyField(prop, "m_Image"); - PropertyField(prop, "m_ImageType"); - PropertyField(prop, "m_Width"); - // PropertyField(prop, "m_Height"); - // PropertyField(prop, "m_Offset"); - } - PropertyField(prop, "m_Gap"); - PropertyField(prop, "m_SizeType"); - switch ((SymbolSizeType) prop.FindPropertyRelative("m_SizeType").enumValueIndex) - { - case SymbolSizeType.Custom: - PropertyField(prop, "m_Size"); - PropertyField(prop, "m_SelectedSize"); - break; - case SymbolSizeType.FromData: - PropertyField(prop, "m_DataIndex"); - PropertyField(prop, "m_DataScale"); - PropertyField(prop, "m_SelectedDataScale"); - break; - case SymbolSizeType.Function: - break; - } - PropertyField(prop, "m_StartIndex"); - PropertyField(prop, "m_Interval"); - PropertyField(prop, "m_ForceShowLast"); - PropertyField(prop, "m_Repeat"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs.meta deleted file mode 100644 index f780f98..0000000 --- a/Assets/XCharts/Editor/ChildComponents/SerieSymbolDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8a164822bc0fd4e5291f00c5a4ee86f6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs b/Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs deleted file mode 100644 index ac79899..0000000 --- a/Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs +++ /dev/null @@ -1,36 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(Settings), true)] - public class SettingsDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Settings"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", false, new HeaderMenuInfo("Reset", () => - { - var chart = prop.serializedObject.targetObject as BaseChart; - chart.settings.Reset(); - }))) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_ReversePainter"); - PropertyField(prop, "m_MaxPainter"); - PropertyField(prop, "m_BasePainterMaterial"); - PropertyField(prop, "m_SeriePainterMaterial"); - PropertyField(prop, "m_TopPainterMaterial"); - PropertyField(prop, "m_LineSmoothStyle"); - PropertyField(prop, "m_LineSmoothness"); - PropertyField(prop, "m_LineSegmentDistance"); - PropertyField(prop, "m_CicleSmoothness"); - PropertyField(prop, "m_LegendIconLineWidth"); - PropertyListField(prop, "m_LegendIconCornerRadius", true); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs.meta deleted file mode 100644 index 11a0c6c..0000000 --- a/Assets/XCharts/Editor/ChildComponents/SettingsDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 70536a1ba3af245e7ad3b11e97682d8d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs deleted file mode 100644 index d30ac90..0000000 --- a/Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(SymbolStyle), true)] - public class SymbolStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Symbol"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - var type = (SymbolType) prop.FindPropertyRelative("m_Type").enumValueIndex; - PropertyField(prop, "m_Type"); - if (type == SymbolType.Custom) - { - PropertyField(prop, "m_Image"); - PropertyField(prop, "m_ImageType"); - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Height"); - // PropertyField(prop, "m_Offset"); - } - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_Size"); - PropertyField(prop, "m_Gap"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs.meta deleted file mode 100644 index f8294f2..0000000 --- a/Assets/XCharts/Editor/ChildComponents/SymbolStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 72d557cf0b7134953b457ab973364520 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs b/Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs deleted file mode 100644 index cbc0bbf..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs +++ /dev/null @@ -1,24 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(TextLimit), true)] - public class TextLimitDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "TextLimit"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Enable", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_MaxWidth"); - PropertyField(prop, "m_Gap"); - PropertyField(prop, "m_Suffix"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs.meta deleted file mode 100644 index 708bf5d..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TextLimitDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 842d3986d1c1747d8b0668649e8b1a0e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs b/Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs deleted file mode 100644 index 608605d..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs +++ /dev/null @@ -1,25 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(TextPadding), true)] - public class TextPaddingDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Padding"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Top"); - PropertyField(prop, "m_Right"); - PropertyField(prop, "m_Bottom"); - PropertyField(prop, "m_Left"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs.meta deleted file mode 100644 index dccf74b..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TextPaddingDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 46cc25f4c9fc846938a06cf3b8fc75bd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs deleted file mode 100644 index edaf6d0..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UnityEditor; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(TextStyle), true)] - public class TextStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "TextStyle"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; -#if dUI_TextMeshPro - PropertyField(prop, "m_TMPFont"); -#else - PropertyField(prop, "m_Font"); -#endif - PropertyField(prop, "m_Rotate"); - PropertyField(prop, "m_AutoColor"); - PropertyField(prop, "m_Color"); - PropertyField(prop, "m_FontSize"); - PropertyField(prop, "m_LineSpacing"); -#if dUI_TextMeshPro - PropertyField(prop, "m_TMPFontStyle"); - PropertyField(prop, "m_TMPAlignment"); -#else - PropertyField(prop, "m_FontStyle"); - PropertyField(prop, "m_Alignment"); - PropertyField(prop, "m_AutoAlign"); - PropertyField(prop, "m_AutoWrap"); -#endif - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs.meta deleted file mode 100644 index faa64c5..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TextStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f14c425fb2bff44f2bf9ddb8d6ff1741 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs b/Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs deleted file mode 100644 index 573fb02..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.IO; -using UnityEditor; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(ThemeStyle), true)] - public class ThemeStyleDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Theme"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - var defaultWidth = pos.width; - var defaultX = pos.x; - var chart = prop.serializedObject.targetObject as BaseChart; - if (MakeComponentFoldout(prop, "m_Show", false, new HeaderMenuInfo("Reset|Reset to theme default color", () => - { - chart.theme.sharedTheme.ResetTheme(); - chart.RefreshAllComponent(); - }), new HeaderMenuInfo("Export|Export theme to asset for a new theme", () => - { - ExportThemeWindow.target = chart; - EditorWindow.GetWindow(typeof(ExportThemeWindow)); - }), new HeaderMenuInfo("Sync color to custom|Sync shared theme color to custom color", () => - { - chart.theme.SyncSharedThemeColorToCustom(); - }))) - { - ++EditorGUI.indentLevel; - var chartNameList = XCThemeMgr.GetAllThemeNames(); - var lastIndex = chartNameList.IndexOf(chart.theme.themeName); - var y = pos.y + EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - var selectedIndex = EditorGUI.Popup(new Rect(pos.x, y, pos.width, EditorGUIUtility.singleLineHeight), - "Shared Theme", lastIndex, chartNameList.ToArray()); - AddSingleLineHeight(); - if (lastIndex != selectedIndex) - { - XCThemeMgr.SwitchTheme(chart, chartNameList[selectedIndex]); - } - PropertyField(prop, "m_SharedTheme"); - PropertyField(prop, "m_TransparentBackground"); - PropertyField(prop, "m_EnableCustomTheme"); - using(new EditorGUI.DisabledScope(!prop.FindPropertyRelative("m_EnableCustomTheme").boolValue)) - { - PropertyField(prop, "m_CustomBackgroundColor"); - PropertyField(prop, "m_CustomColorPalette"); - } - --EditorGUI.indentLevel; - } - } - - private void AddPropertyField(Rect pos, SerializedProperty prop, ref float y) - { - float height = EditorGUI.GetPropertyHeight(prop, new GUIContent(prop.displayName), true); - EditorGUI.PropertyField(new Rect(pos.x, y, pos.width, height), prop, true); - y += height + EditorGUIUtility.standardVerticalSpacing; - m_Heights[m_KeyName] += height + EditorGUIUtility.standardVerticalSpacing; - } - } - - public class ExportThemeWindow : UnityEditor.EditorWindow - { - public static BaseChart target; - private static ExportThemeWindow window; - private string m_ChartName; - static void Init() - { - window = (ExportThemeWindow) EditorWindow.GetWindow(typeof(ExportThemeWindow), false, "Export Theme", true); - window.minSize = new Vector2(600, 50); - window.maxSize = new Vector2(600, 50); - window.Show(); - } - - void OnInspectorUpdate() - { - Repaint(); - } - - private void OnGUI() - { - if (target == null) - { - Close(); - return; - } - GUILayout.Space(10); - GUILayout.Label("Input a new name for theme:"); - m_ChartName = GUILayout.TextField(m_ChartName); - - GUILayout.Space(10); - GUILayout.Label("Export path:"); - if (string.IsNullOrEmpty(m_ChartName)) - { - GUILayout.Label("Need input a new name."); - } - else - { - GUILayout.Label(XCThemeMgr.GetThemeAssetPath(m_ChartName)); - } - - GUILayout.Space(20); - if (GUILayout.Button("Export")) - { - if (string.IsNullOrEmpty(m_ChartName)) - { - ShowNotification(new GUIContent("ERROR:Need input a new name!")); - } - else if (XCThemeMgr.ContainsTheme(m_ChartName)) - { - ShowNotification(new GUIContent("ERROR:The name you entered is already in use!")); - } - else if (IsAssetsExist(XCThemeMgr.GetThemeAssetPath(m_ChartName))) - { - ShowNotification(new GUIContent("ERROR:The asset is exist! \npath=" + - XCThemeMgr.GetThemeAssetPath(m_ChartName))); - } - else - { - XCThemeMgr.ExportTheme(target.theme.sharedTheme, m_ChartName); - ShowNotification(new GUIContent("SUCCESS:The theme is exported. \npath=" + - XCThemeMgr.GetThemeAssetPath(m_ChartName))); - } - } - } - - private bool IsAssetsExist(string path) - { - return File.Exists(Application.dataPath + "/../" + path); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs.meta deleted file mode 100644 index 107eab6..0000000 --- a/Assets/XCharts/Editor/ChildComponents/ThemeDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 704e7c2793bca4050821c6e0756c8316 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs b/Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs deleted file mode 100644 index 66ad6d6..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs +++ /dev/null @@ -1,12 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomPropertyDrawer(typeof(TitleStyle), true)] - public class TitleStyleDrawer : LabelStyleDrawer - { - public override string ClassName { get { return "TitleStyle"; } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs.meta b/Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs.meta deleted file mode 100644 index ad95f9b..0000000 --- a/Assets/XCharts/Editor/ChildComponents/TitleStyleDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e451ee4c9f65a414784fd5fd9cad6ec1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents.meta b/Assets/XCharts/Editor/MainComponents.meta deleted file mode 100644 index 6cc4e5e..0000000 --- a/Assets/XCharts/Editor/MainComponents.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f98ff753316eb48d58325ecd996f2a1f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/AxisEditor.cs b/Assets/XCharts/Editor/MainComponents/AxisEditor.cs deleted file mode 100644 index 652d0d3..0000000 --- a/Assets/XCharts/Editor/MainComponents/AxisEditor.cs +++ /dev/null @@ -1,205 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(Axis))] - public class AxisEditor : MainComponentEditor<Axis> - { - public override void OnInspectorGUI() - { - var m_Type = baseProperty.FindPropertyRelative("m_Type"); - var m_LogBase = baseProperty.FindPropertyRelative("m_LogBase"); - var m_MinMaxType = baseProperty.FindPropertyRelative("m_MinMaxType"); - var type = (Axis.AxisType) m_Type.enumValueIndex; - EditorGUI.indentLevel++; - if (component is ParallelAxis) - { - PropertyField("m_ParallelIndex"); - } - else if (!(component is SingleAxis)) - { - PropertyField("m_GridIndex"); - PropertyField("m_PolarIndex"); - } - PropertyField("m_Type"); - PropertyField("m_Position"); - PropertyField("m_Offset"); - if (type == Axis.AxisType.Log) - { - PropertyField("m_LogBaseE"); - EditorGUI.BeginChangeCheck(); - PropertyField("m_LogBase"); - if (m_LogBase.floatValue <= 0 || m_LogBase.floatValue == 1) - { - m_LogBase.floatValue = 10; - } - EditorGUI.EndChangeCheck(); - } - if (type == Axis.AxisType.Value || type == Axis.AxisType.Time) - { - PropertyField("m_MinMaxType"); - Axis.AxisMinMaxType minMaxType = (Axis.AxisMinMaxType) m_MinMaxType.enumValueIndex; - switch (minMaxType) - { - case Axis.AxisMinMaxType.Default: - break; - case Axis.AxisMinMaxType.MinMax: - break; - case Axis.AxisMinMaxType.Custom: - EditorGUI.indentLevel++; - PropertyField("m_Min"); - PropertyField("m_Max"); - EditorGUI.indentLevel--; - break; - } - PropertyField("m_CeilRate"); - if (type == Axis.AxisType.Value) - { - PropertyField("m_Inverse"); - } - } - PropertyField("m_SplitNumber"); - if (type == Axis.AxisType.Category) - { - //PropertyField("m_InsertDataToHead"); - PropertyField("m_MaxCache"); - PropertyField("m_BoundaryGap"); - } - else - { - PropertyField("m_Interval"); - PropertyField("m_BoundaryGap"); - } - DrawExtendeds(); - PropertyField("m_AxisLine"); - PropertyField("m_AxisName"); - PropertyField("m_AxisTick"); - PropertyField("m_AxisLabel"); - PropertyField("m_SplitLine"); - PropertyField("m_SplitArea"); - PropertyListField("m_Icons", true); - if (type == Axis.AxisType.Category) - { - PropertyListField("m_Data", true, new HeaderMenuInfo("Import ECharts Axis Data", () => - { - PraseExternalDataEditor.UpdateData(chart, null, component as Axis); - PraseExternalDataEditor.ShowWindow(); - })); - } - EditorGUI.indentLevel--; - } - } - - [ComponentEditor(typeof(XAxis))] - public class XAxisEditor : AxisEditor - { } - - [ComponentEditor(typeof(YAxis))] - public class YAxisEditor : AxisEditor - { } - - [ComponentEditor(typeof(SingleAxis))] - public class SingleAxisEditor : AxisEditor - { - protected override void DrawExtendeds() - { - base.DrawExtendeds(); - PropertyField("m_Orient"); - PropertyField("m_Left"); - PropertyField("m_Right"); - PropertyField("m_Top"); - PropertyField("m_Bottom"); - PropertyField("m_Width"); - PropertyField("m_Height"); - } - } - - [ComponentEditor(typeof(AngleAxis))] - public class AngleAxisEditor : AxisEditor - { - protected override void DrawExtendeds() - { - base.DrawExtendeds(); - PropertyField("m_StartAngle"); - PropertyField("m_Clockwise"); - } - } - - [ComponentEditor(typeof(RadiusAxis))] - public class RadiusAxisEditor : AxisEditor - { } - - [ComponentEditor(typeof(ParallelAxis))] - public class ParallelAxisEditor : AxisEditor - { } - - [CustomPropertyDrawer(typeof(AxisLabel), true)] - public class AxisLabelDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "AxisLabel"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Inside"); - PropertyField(prop, "m_Interval"); - - PropertyField(prop, "m_ShowAsPositiveNumber"); - PropertyField(prop, "m_OnZero"); - PropertyField(prop, "m_ShowStartLabel"); - PropertyField(prop, "m_ShowEndLabel"); - - PropertyField(prop, "m_Rotate"); - PropertyField(prop, "m_Offset"); - PropertyField(prop, "m_Distance"); - PropertyField(prop, "m_Formatter"); - PropertyField(prop, "m_NumericFormatter"); - PropertyField(prop, "m_Width"); - PropertyField(prop, "m_Height"); - PropertyField(prop, "m_Icon"); - PropertyField(prop, "m_Background"); - PropertyField(prop, "m_TextStyle"); - PropertyField(prop, "m_TextPadding"); - PropertyField(prop, "m_TextLimit"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(AxisName), true)] - public class AxisNameDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "AxisName"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Name"); - PropertyField(prop, "m_LabelStyle"); - --EditorGUI.indentLevel; - } - } - } - - [CustomPropertyDrawer(typeof(AxisSplitArea), true)] - public class AxisSplitAreaDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "SplitArea"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "m_Show", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Color"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/AxisEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/AxisEditor.cs.meta deleted file mode 100644 index 5ffd445..0000000 --- a/Assets/XCharts/Editor/MainComponents/AxisEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2e6d7780afa9b49aa9081bf55d301955 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs b/Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs deleted file mode 100644 index 25c867f..0000000 --- a/Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(Background))] - internal sealed class BackgroundEditor : MainComponentEditor<Background> - { - public override void OnInspectorGUI() - { - - ++EditorGUI.indentLevel; - PropertyField("m_Image"); - PropertyField("m_ImageType"); - PropertyField("m_ImageColor"); - PropertyField("m_AutoColor"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs.meta deleted file mode 100644 index 96466f3..0000000 --- a/Assets/XCharts/Editor/MainComponents/BackgroundEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 89d95a9a994ad4b4692832e9a548e9e4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/CommentEditor.cs b/Assets/XCharts/Editor/MainComponents/CommentEditor.cs deleted file mode 100644 index 922e44a..0000000 --- a/Assets/XCharts/Editor/MainComponents/CommentEditor.cs +++ /dev/null @@ -1,18 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(Comment))] - public class CommentEditor : MainComponentEditor<Comment> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_LabelStyle"); - //PropertyField("m_MarkStyle"); - PropertyListField("m_Items", true); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/CommentEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/CommentEditor.cs.meta deleted file mode 100644 index 8c2401f..0000000 --- a/Assets/XCharts/Editor/MainComponents/CommentEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f2364066bf3174aa39b79020266ce72d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs b/Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs deleted file mode 100644 index f54c001..0000000 --- a/Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs +++ /dev/null @@ -1,60 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(DataZoom))] - public class DataZoomEditor : MainComponentEditor<DataZoom> - { - public override void OnInspectorGUI() - { - var m_SupportInside = baseProperty.FindPropertyRelative("m_SupportInside"); - var m_SupportSlider = baseProperty.FindPropertyRelative("m_SupportSlider"); - var m_Start = baseProperty.FindPropertyRelative("m_Start"); - var m_End = baseProperty.FindPropertyRelative("m_End"); - var m_MinShowNum = baseProperty.FindPropertyRelative("m_MinShowNum"); - ++EditorGUI.indentLevel; - PropertyField("m_Orient"); - PropertyField("m_SupportInside"); - if (m_SupportInside.boolValue) - { - PropertyField("m_SupportInsideScroll"); - PropertyField("m_SupportInsideDrag"); - } - PropertyField(m_SupportSlider); - PropertyField("m_ZoomLock"); - PropertyField("m_ScrollSensitivity"); - PropertyField("m_RangeMode"); - PropertyField(m_Start); - PropertyField(m_End); - PropertyField(m_MinShowNum); - if (m_Start.floatValue < 0) m_Start.floatValue = 0; - if (m_End.floatValue > 100) m_End.floatValue = 100; - if (m_MinShowNum.intValue < 0) m_MinShowNum.intValue = 0; - if (m_SupportSlider.boolValue) - { - PropertyField("m_ShowDataShadow"); - PropertyField("m_ShowDetail"); - PropertyField("m_BackgroundColor"); - PropertyField("m_BorderWidth"); - PropertyField("m_BorderColor"); - PropertyField("m_FillerColor"); - PropertyField("m_Left"); - PropertyField("m_Right"); - PropertyField("m_Top"); - PropertyField("m_Bottom"); - PropertyField("m_LineStyle"); - PropertyField("m_AreaStyle"); - PropertyField("m_LabelStyle"); - PropertyListField("m_XAxisIndexs", true); - PropertyListField("m_YAxisIndexs", true); - } - else - { - PropertyListField("m_XAxisIndexs", true); - PropertyListField("m_YAxisIndexs", true); - } - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs.meta deleted file mode 100644 index 78d0550..0000000 --- a/Assets/XCharts/Editor/MainComponents/DataZoomEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 06bc176df52bf4953b8d46254523d2ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs b/Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs deleted file mode 100644 index 460161c..0000000 --- a/Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs +++ /dev/null @@ -1,23 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(GridCoord))] - public class GridCoordEditor : MainComponentEditor<GridCoord> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_Left"); - PropertyField("m_Right"); - PropertyField("m_Top"); - PropertyField("m_Bottom"); - PropertyField("m_BackgroundColor"); - PropertyField("m_ShowBorder"); - PropertyField("m_BorderWidth"); - PropertyField("m_BorderColor"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs.meta deleted file mode 100644 index 7df3d86..0000000 --- a/Assets/XCharts/Editor/MainComponents/GridCoordEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bb28a0ae5edd34b63ae9cbce0986585b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/LegendEditor.cs b/Assets/XCharts/Editor/MainComponents/LegendEditor.cs deleted file mode 100644 index 34fc324..0000000 --- a/Assets/XCharts/Editor/MainComponents/LegendEditor.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(Legend))] - public class LegendEditor : MainComponentEditor<Legend> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_IconType"); - PropertyField("m_ItemWidth"); - PropertyField("m_ItemHeight"); - PropertyField("m_ItemGap"); - PropertyField("m_ItemAutoColor"); - PropertyField("m_ItemOpacity"); - PropertyField("m_SelectedMode"); - PropertyField("m_Orient"); - PropertyField("m_Formatter"); - PropertyField("m_Location"); - PropertyField("m_LabelStyle"); - PropertyListField("m_Icons"); - PropertyListField("m_Colors"); - PropertyListField("m_Data"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/LegendEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/LegendEditor.cs.meta deleted file mode 100644 index 8429e30..0000000 --- a/Assets/XCharts/Editor/MainComponents/LegendEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5ef040b104aa2452f80d91c7c33775c4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs b/Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs deleted file mode 100644 index eb7b9b0..0000000 --- a/Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs +++ /dev/null @@ -1,116 +0,0 @@ -using UnityEditor; -using UnityEngine; -using UnityEngine.Assertions; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class MainComponentBaseEditor - { - protected const string MORE = "More"; - protected bool m_MoreFoldout = false; - public BaseChart chart { get; private set; } - public MainComponent component { get; private set; } - - public SerializedProperty baseProperty; - public SerializedProperty showProperty; - - internal void Init(BaseChart chart, MainComponent target, SerializedProperty property, UnityEditor.Editor inspector) - { - this.chart = chart; - this.component = target; - this.baseProperty = property; - showProperty = baseProperty.FindPropertyRelative("m_Show"); - if (showProperty == null) - showProperty = baseProperty.FindPropertyRelative("m_Enable"); - OnEnable(); - } - - public virtual void OnEnable() - { } - - public virtual void OnDisable() - { } - - internal void OnInternalInspectorGUI() - { - OnInspectorGUI(); - EditorGUILayout.Space(); - } - - public virtual void OnInspectorGUI() - { } - - protected virtual void DrawExtendeds() - { } - - public virtual string GetDisplayTitle() - { - var num = chart.GetChartComponentNum(component.GetType()); - if (num > 1) - return ObjectNames.NicifyVariableName(component.GetType().Name) + " " + component.index; - else - return ObjectNames.NicifyVariableName(component.GetType().Name); - } - - protected SerializedProperty FindProperty(string path) - { - return baseProperty.FindPropertyRelative(path); - } - - protected void PropertyField(string path) - { - var property = FindProperty(path); - if (property != null) - { - var title = ChartEditorHelper.GetContent(property.displayName); - PropertyField(property, title); - } - else - { - Debug.LogError("Property not exist:" + baseProperty.propertyPath + "," + path); - } - } - - protected void PropertyFiledMore(System.Action action) - { - m_MoreFoldout = ChartEditorHelper.DrawHeader(MORE, m_MoreFoldout, false, null, null); - if (m_MoreFoldout) - { - if (action != null) action(); - } - } - - protected void PropertyField(SerializedProperty property) - { - Assert.IsNotNull(property); - var title = ChartEditorHelper.GetContent(property.displayName); - PropertyField(property, title); - } - - protected void PropertyField(SerializedProperty property, GUIContent title) - { - EditorGUILayout.PropertyField(property, title); - } - - protected void PropertyListField(string relativePropName, bool showOrder = true, params HeaderMenuInfo[] menus) - { - var m_DrawRect = GUILayoutUtility.GetRect(1f, 17f); - var height = 0f; - var prop = FindProperty(relativePropName); - prop.isExpanded = ChartEditorHelper.MakeListWithFoldout(ref m_DrawRect, ref height, - prop, prop.isExpanded, showOrder, true, menus); - if (prop.isExpanded) - { - GUILayoutUtility.GetRect(1f, height - 17); - } - } - - protected void PropertyTwoFiled(string relativePropName) - { - var m_DrawRect = GUILayoutUtility.GetRect(1f, 17f); - var prop = FindProperty(relativePropName); - ChartEditorHelper.MakeTwoField(ref m_DrawRect, m_DrawRect.width, prop, prop.displayName); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs.meta deleted file mode 100644 index c0299b8..0000000 --- a/Assets/XCharts/Editor/MainComponents/MainComponentBaseEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2909950e65ad44c2eb617a8b75845431 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs b/Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs deleted file mode 100644 index 05e2896..0000000 --- a/Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs +++ /dev/null @@ -1,8 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class MainComponentEditor<T> : MainComponentBaseEditor - where T : MainComponent - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs.meta deleted file mode 100644 index 6e9b172..0000000 --- a/Assets/XCharts/Editor/MainComponents/MainComponentEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 276997094e92e4b6590591727cb21349 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs b/Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs deleted file mode 100644 index 211cb31..0000000 --- a/Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using UnityEditor; -using UnityEngine.Assertions; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public sealed class MainComponentListEditor - { - public BaseChart chart { get; private set; } - BaseChartEditor m_BaseEditor; - - //SerializedObject m_SerializedObject; - List<SerializedProperty> m_ComponentsProperty; - SerializedProperty m_EnableProperty; - - Dictionary<Type, Type> m_EditorTypes; - List<MainComponentBaseEditor> m_Editors; - - public MainComponentListEditor(BaseChartEditor editor) - { - Assert.IsNotNull(editor); - m_BaseEditor = editor; - } - - public void Init(BaseChart chart, SerializedObject serializedObject, List<SerializedProperty> componentProps) - { - Assert.IsNotNull(chart); - - this.chart = chart; - m_ComponentsProperty = componentProps; - - Assert.IsNotNull(m_ComponentsProperty); - - m_Editors = new List<MainComponentBaseEditor>(); - m_EditorTypes = new Dictionary<Type, Type>(); - - var editorTypes = RuntimeUtil.GetAllTypesDerivedFrom<MainComponentBaseEditor>() - .Where(t => t.IsDefined(typeof(ComponentEditorAttribute), false) && !t.IsAbstract); - foreach (var editorType in editorTypes) - { - var attribute = editorType.GetAttribute<ComponentEditorAttribute>(); - m_EditorTypes.Add(attribute.componentType, editorType); - } - - RefreshEditors(); - } - - public void UpdateComponentsProperty(List<SerializedProperty> componentProps) - { - m_ComponentsProperty = componentProps; - RefreshEditors(); - } - - public void Clear() - { - if (m_Editors == null) - return; - - foreach (var editor in m_Editors) - editor.OnDisable(); - - m_Editors.Clear(); - m_EditorTypes.Clear(); - } - - public void OnGUI() - { - if (chart == null) - return; - - for (int i = 0; i < m_Editors.Count; i++) - { - var editor = m_Editors[i]; - string title = editor.GetDisplayTitle(); - int id = i; - - bool displayContent = ChartEditorHelper.DrawHeader( - title, - editor.baseProperty, - editor.showProperty, - () => { ResetComponentEditor(id); }, - () => { RemoveComponentEditor(id); } - ); - if (displayContent) - { - editor.OnInternalInspectorGUI(); - } - } - - if (m_Editors.Count == 0) - { - EditorGUILayout.HelpBox("No componnet.", MessageType.Info); - } - } - - void RefreshEditors() - { - foreach (var editor in m_Editors) - editor.OnDisable(); - - m_Editors.Clear(); - for (int i = 0; i < chart.components.Count; i++) - { - if (chart.components[i] != null) - { - CreateEditor(chart.components[i], m_ComponentsProperty[i]); - } - } - } - - void CreateEditor(MainComponent component, SerializedProperty property, int index = -1) - { - - var settingsType = component.GetType(); - Type editorType; - - if (!m_EditorTypes.TryGetValue(settingsType, out editorType)) - editorType = typeof(MainComponentBaseEditor); - var editor = (MainComponentBaseEditor) Activator.CreateInstance(editorType); - editor.Init(chart, component, property, m_BaseEditor); - - if (index < 0) - m_Editors.Add(editor); - else - m_Editors[index] = editor; - } - - public void AddChartComponent(Type type) - { - chart.AddChartComponent(type); - m_ComponentsProperty = m_BaseEditor.RefreshComponent(); - RefreshEditors(); - EditorUtility.SetDirty(chart); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - - private void ResetComponentEditor(int id) - { - m_Editors[id].component.Reset(); - EditorUtility.SetDirty(chart); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - - private void RemoveComponentEditor(int id) - { - m_Editors[id].OnDisable(); - chart.RemoveChartComponent(m_Editors[id].component); - m_Editors.RemoveAt(id); - m_ComponentsProperty = m_BaseEditor.RefreshComponent(); - RefreshEditors(); - EditorUtility.SetDirty(chart); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs.meta deleted file mode 100644 index 5810b63..0000000 --- a/Assets/XCharts/Editor/MainComponents/MainComponentListEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 62cc000ee006f492aadb05138ac6fe87 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs b/Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs deleted file mode 100644 index 43e2894..0000000 --- a/Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(MarkArea))] - public class MarkAreaEditor : MainComponentEditor<MarkArea> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_SerieIndex"); - PropertyField("m_Text"); - PropertyField("m_ItemStyle"); - PropertyField("m_Label"); - PropertyField("m_Start"); - PropertyField("m_End"); - --EditorGUI.indentLevel; - } - } - - [CustomPropertyDrawer(typeof(MarkAreaData), true)] - public class MarkAreaDataDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "MarkAreaData"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "", true)) - { - ++EditorGUI.indentLevel; - var type = (MarkAreaType) (prop.FindPropertyRelative("m_Type")).enumValueIndex; - PropertyField(prop, "m_Type"); - PropertyField(prop, "m_Name"); - switch (type) - { - case MarkAreaType.None: - PropertyField(prop, "m_XPosition"); - PropertyField(prop, "m_YPosition"); - PropertyField(prop, "m_XValue"); - PropertyField(prop, "m_YValue"); - break; - case MarkAreaType.Min: - case MarkAreaType.Max: - case MarkAreaType.Average: - case MarkAreaType.Median: - PropertyField(prop, "m_Dimension"); - break; - } - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs.meta deleted file mode 100644 index fd786ea..0000000 --- a/Assets/XCharts/Editor/MainComponents/MarkAreaEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 83cc6f39a078f4ecfb2c3da09b116355 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs b/Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs deleted file mode 100644 index 6c8530a..0000000 --- a/Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs +++ /dev/null @@ -1,59 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(MarkLine))] - public class MarkLineEditor : MainComponentEditor<MarkLine> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_SerieIndex"); - PropertyField("m_Animation"); - PropertyListField("m_Data", true); - --EditorGUI.indentLevel; - } - } - - [CustomPropertyDrawer(typeof(MarkLineData), true)] - public class MarkLineDataDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "MarkLineData"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "", true)) - { - ++EditorGUI.indentLevel; - var type = (MarkLineType) (prop.FindPropertyRelative("m_Type")).enumValueIndex; - var group = prop.FindPropertyRelative("m_Group").intValue; - PropertyField(prop, "m_Type"); - PropertyField(prop, "m_Name"); - switch (type) - { - case MarkLineType.None: - PropertyField(prop, "m_XPosition"); - PropertyField(prop, "m_YPosition"); - PropertyField(prop, "m_XValue"); - PropertyField(prop, "m_YValue"); - break; - case MarkLineType.Min: - case MarkLineType.Max: - case MarkLineType.Average: - case MarkLineType.Median: - PropertyField(prop, "m_Dimension"); - break; - } - PropertyField(prop, "m_Group"); - if (group > 0 && type == MarkLineType.None) PropertyField(prop, "m_ZeroPosition"); - PropertyField(prop, "m_LineStyle"); - PropertyField(prop, "m_StartSymbol"); - PropertyField(prop, "m_EndSymbol"); - PropertyField(prop, "m_Label"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs.meta deleted file mode 100644 index 0793155..0000000 --- a/Assets/XCharts/Editor/MainComponents/MarkLineEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 341fcecf4884e47519a2aff6defb30de -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs b/Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs deleted file mode 100644 index 3a216f3..0000000 --- a/Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(ParallelCoord))] - public class ParallelCoordEditor : MainComponentEditor<ParallelCoord> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_Orient"); - PropertyField("m_Left"); - PropertyField("m_Right"); - PropertyField("m_Top"); - PropertyField("m_Bottom"); - PropertyField("m_BackgroundColor"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs.meta deleted file mode 100644 index 339b121..0000000 --- a/Assets/XCharts/Editor/MainComponents/ParallelCoordEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f3d4d8d4d5c4b4197b021a25a7125390 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs b/Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs deleted file mode 100644 index 8d359e7..0000000 --- a/Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs +++ /dev/null @@ -1,18 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(PolarCoord))] - public class PolarCoordEditor : MainComponentEditor<PolarCoord> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyTwoFiled("m_Center"); - PropertyField("m_Radius"); - PropertyField("m_BackgroundColor"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs.meta deleted file mode 100644 index aeb2e65..0000000 --- a/Assets/XCharts/Editor/MainComponents/PolarCoordEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5f488cf12ded545de8737a2cde8bfead -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs b/Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs deleted file mode 100644 index 752ec81..0000000 --- a/Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs +++ /dev/null @@ -1,50 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(RadarCoord))] - public class RadarCoordEditor : MainComponentEditor<RadarCoord> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_Shape"); - PropertyField("m_PositionType"); - PropertyTwoFiled("m_Center"); - PropertyField("m_Radius"); - PropertyField("m_SplitNumber"); - PropertyField("m_CeilRate"); - PropertyField("m_IsAxisTooltip"); - PropertyField("m_OutRangeColor"); - PropertyField("m_ConnectCenter"); - PropertyField("m_LineGradient"); - PropertyField("m_AxisLine"); - PropertyField("m_AxisName"); - PropertyField("m_SplitLine"); - PropertyField("m_SplitArea"); - PropertyField("m_IndicatorList"); - --EditorGUI.indentLevel; - } - } - - [CustomPropertyDrawer(typeof(RadarCoord.Indicator), true)] - public class RadarIndicatorDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Indicator"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeComponentFoldout(prop, "", true)) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Name"); - PropertyField(prop, "m_Min"); - PropertyField(prop, "m_Max"); - PropertyTwoFiled(prop, "m_Range"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs.meta deleted file mode 100644 index 484b250..0000000 --- a/Assets/XCharts/Editor/MainComponents/RadarCoordEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f1bfbd3f054624d42b854bcac720a58b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/ThemeEditor.cs b/Assets/XCharts/Editor/MainComponents/ThemeEditor.cs deleted file mode 100644 index 86fcf5f..0000000 --- a/Assets/XCharts/Editor/MainComponents/ThemeEditor.cs +++ /dev/null @@ -1,39 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Editor -{ - [CustomEditor(typeof(Theme))] - public class ThemeEditor : UnityEditor.Editor - { - static class Styles - { - internal static GUIContent btnReset = new GUIContent("Reset", "Reset to default theme"); - internal static GUIContent btnSync = new GUIContent("Sync Font", "Sync main theme font to sub theme font"); - } - - private Theme m_Theme; - - void OnEnable() - { - m_Theme = target as Theme; - } - - public override void OnInspectorGUI() - { - base.OnInspectorGUI(); - if (GUILayout.Button(Styles.btnReset)) - { - m_Theme.ResetTheme(); - } - if (GUILayout.Button(Styles.btnSync)) - { - m_Theme.SyncFontToSubComponent(); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/ThemeEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/ThemeEditor.cs.meta deleted file mode 100644 index b14f798..0000000 --- a/Assets/XCharts/Editor/MainComponents/ThemeEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7856321df80e646c99317e95964991bc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/TitleEditor.cs b/Assets/XCharts/Editor/MainComponents/TitleEditor.cs deleted file mode 100644 index 2a22c05..0000000 --- a/Assets/XCharts/Editor/MainComponents/TitleEditor.cs +++ /dev/null @@ -1,21 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(Title))] - public class TitleEditor : MainComponentEditor<Title> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_Text"); - PropertyField("m_SubText"); - PropertyField("m_ItemGap"); - PropertyField("m_Location"); - PropertyField("m_LabelStyle"); - PropertyField("m_SubLabelStyle"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/TitleEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/TitleEditor.cs.meta deleted file mode 100644 index 7780391..0000000 --- a/Assets/XCharts/Editor/MainComponents/TitleEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c50c4d317d9274b32a5f137db0d66038 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/TooltipEditor.cs b/Assets/XCharts/Editor/MainComponents/TooltipEditor.cs deleted file mode 100644 index af7b434..0000000 --- a/Assets/XCharts/Editor/MainComponents/TooltipEditor.cs +++ /dev/null @@ -1,49 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(Tooltip))] - public class TooltipEditor : MainComponentEditor<Tooltip> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - PropertyField("m_Type"); - PropertyField("m_Trigger"); - PropertyField("m_ShowContent"); - PropertyField("m_AlwayShowContent"); - PropertyField("m_TitleFormatter"); - PropertyField("m_ItemFormatter"); - PropertyField("m_NumericFormatter"); - PropertyFiledMore(() => - { - PropertyField("m_TitleHeight"); - PropertyField("m_ItemHeight"); - PropertyField("m_Marker"); - PropertyField("m_BorderWidth"); - PropertyField("m_BorderColor"); - PropertyField("m_PaddingLeftRight"); - PropertyField("m_PaddingTopBottom"); - PropertyField("m_BackgroundImage"); - PropertyField("m_BackgroundType"); - PropertyField("m_BackgroundColor"); - PropertyField("m_FixedWidth"); - PropertyField("m_FixedHeight"); - PropertyField("m_MinWidth"); - PropertyField("m_MinHeight"); - PropertyField("m_IgnoreDataDefaultContent"); - PropertyField("m_Offset"); - PropertyField("m_FixedXEnable"); - PropertyField("m_FixedX"); - PropertyField("m_FixedYEnable"); - PropertyField("m_FixedY"); - }); - PropertyField("m_LineStyle"); - PropertyField("m_IndicatorLabelStyle"); - PropertyField("m_TitleLabelStyle"); - PropertyListField("m_ContentLabelStyles"); - --EditorGUI.indentLevel; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/TooltipEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/TooltipEditor.cs.meta deleted file mode 100644 index 0952d61..0000000 --- a/Assets/XCharts/Editor/MainComponents/TooltipEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9179fea7bb2354601acce0feb82f8b17 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs b/Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs deleted file mode 100644 index 059f3c4..0000000 --- a/Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs +++ /dev/null @@ -1,64 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [ComponentEditor(typeof(VisualMap))] - public class VisualMapEditor : MainComponentEditor<VisualMap> - { - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - var type = (VisualMap.Type) baseProperty.FindPropertyRelative("m_Type").enumValueIndex; - var isPiece = type == VisualMap.Type.Piecewise; - PropertyField("m_Type"); - PropertyField("m_SerieIndex"); - PropertyField("m_AutoMinMax"); - PropertyField("m_Min"); - PropertyField("m_Max"); - PropertyField("m_SplitNumber"); - PropertyField("m_Dimension"); - PropertyField("m_WorkOnLine"); - PropertyField("m_WorkOnArea"); - PropertyField("m_ShowUI"); - if (baseProperty.FindPropertyRelative("m_ShowUI").boolValue) - { - PropertyField("m_SelectedMode"); - PropertyTwoFiled("m_Range"); - PropertyTwoFiled("m_Text"); - PropertyTwoFiled("m_TextGap"); - PropertyField("m_HoverLink"); - PropertyField("m_Calculable"); - PropertyField("m_ItemWidth"); - PropertyField("m_ItemHeight"); - if (isPiece) PropertyField("m_ItemGap"); - PropertyField("m_BorderWidth"); - PropertyField("m_Orient"); - PropertyField("m_Location"); - } - PropertyListField("m_OutOfRange"); - PropertyListField("m_InRange"); - --EditorGUI.indentLevel; - } - } - - [CustomPropertyDrawer(typeof(VisualMapRange), true)] - public class VisualMapRangeDrawer : BasePropertyDrawer - { - public override string ClassName { get { return "Range"; } } - public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) - { - base.OnGUI(pos, prop, label); - if (MakeFoldout(prop, "m_Color")) - { - ++EditorGUI.indentLevel; - PropertyField(prop, "m_Min"); - PropertyField(prop, "m_Max"); - PropertyField(prop, "m_Label"); - PropertyField(prop, "m_Color"); - --EditorGUI.indentLevel; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs.meta b/Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs.meta deleted file mode 100644 index 288d90a..0000000 --- a/Assets/XCharts/Editor/MainComponents/VisualMapEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 38b6413ab74484d6599bebbca7f5d437 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series.meta b/Assets/XCharts/Editor/Series.meta deleted file mode 100644 index 9afafc7..0000000 --- a/Assets/XCharts/Editor/Series.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 303691ade88f04660abab870b613cc3a -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/BarEditor.cs b/Assets/XCharts/Editor/Series/BarEditor.cs deleted file mode 100644 index c06a04e..0000000 --- a/Assets/XCharts/Editor/Series/BarEditor.cs +++ /dev/null @@ -1,47 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Bar))] - public class BarEditor : SerieEditor<Bar> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_Stack"); - if (serie.IsUseCoord<PolarCoord>()) - { - PropertyField("m_PolarIndex"); - } - else - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - } - PropertyField("m_BarType"); - PropertyField("m_BarPercentStack"); - PropertyField("m_BarWidth"); - PropertyField("m_BarGap"); - if (serie.barType == BarType.Zebra) - { - PropertyField("m_BarZebraWidth"); - PropertyField("m_BarZebraGap"); - } - PropertyField("m_Clip"); - PropertyFiledMore(() => - { - PropertyFieldLimitMin("m_MinShow", 0); - PropertyFieldLimitMin("m_MaxShow", 0); - PropertyFieldLimitMin("m_MaxCache", 0); - PropertyField("m_Ignore"); - PropertyField("m_IgnoreValue"); - PropertyField("m_IgnoreLineBreak"); - PropertyField("m_ShowAsPositiveNumber"); - PropertyField("m_Large"); - PropertyField("m_LargeThreshold"); - PropertyField("m_PlaceHolder"); - }); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/BarEditor.cs.meta b/Assets/XCharts/Editor/Series/BarEditor.cs.meta deleted file mode 100644 index afc8184..0000000 --- a/Assets/XCharts/Editor/Series/BarEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3b924d2e0412243769e4ac6ee8bd5fa6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/CandlestickEditor.cs b/Assets/XCharts/Editor/Series/CandlestickEditor.cs deleted file mode 100644 index ff77a8d..0000000 --- a/Assets/XCharts/Editor/Series/CandlestickEditor.cs +++ /dev/null @@ -1,25 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Candlestick))] - public class CandlestickEditor : SerieEditor<Candlestick> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - PropertyFieldLimitMin("m_MinShow", 0); - PropertyFieldLimitMin("m_MaxShow", 0); - PropertyFieldLimitMin("m_MaxCache", 0); - PropertyField("m_BarWidth"); - PropertyField("m_Clip"); - PropertyField("m_ShowAsPositiveNumber"); - PropertyField("m_Large"); - PropertyField("m_LargeThreshold"); - - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/CandlestickEditor.cs.meta b/Assets/XCharts/Editor/Series/CandlestickEditor.cs.meta deleted file mode 100644 index e10eb32..0000000 --- a/Assets/XCharts/Editor/Series/CandlestickEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 713afd224d3194435b9559720035a5fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/EffectScatterEditor.cs b/Assets/XCharts/Editor/Series/EffectScatterEditor.cs deleted file mode 100644 index b686744..0000000 --- a/Assets/XCharts/Editor/Series/EffectScatterEditor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(EffectScatter))] - public class EffectScatterEditor : SerieEditor<EffectScatter> - { - public override void OnCustomInspectorGUI() - { - if (serie.IsUseCoord<SingleAxisCoord>()) - { - PropertyField("m_SingleAxisIndex"); - } - else - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - } - PropertyField("m_Clip"); - PropertyField("m_Symbol"); - - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/EffectScatterEditor.cs.meta b/Assets/XCharts/Editor/Series/EffectScatterEditor.cs.meta deleted file mode 100644 index a94c3a7..0000000 --- a/Assets/XCharts/Editor/Series/EffectScatterEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fc8fce25209234fa3b6c3cb79d02b47e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/HeatmapEditor.cs b/Assets/XCharts/Editor/Series/HeatmapEditor.cs deleted file mode 100644 index 739952b..0000000 --- a/Assets/XCharts/Editor/Series/HeatmapEditor.cs +++ /dev/null @@ -1,17 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Heatmap))] - public class HeatmapEditor : SerieEditor<Heatmap> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_Ignore"); - PropertyField("m_IgnoreValue"); - - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/HeatmapEditor.cs.meta b/Assets/XCharts/Editor/Series/HeatmapEditor.cs.meta deleted file mode 100644 index f630b51..0000000 --- a/Assets/XCharts/Editor/Series/HeatmapEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3137acf1aff4f4cd29af0d3c3ca78bca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/LineEditor.cs b/Assets/XCharts/Editor/Series/LineEditor.cs deleted file mode 100644 index 5d6c234..0000000 --- a/Assets/XCharts/Editor/Series/LineEditor.cs +++ /dev/null @@ -1,43 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Line))] - public class LineEditor : SerieEditor<Line> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_Stack"); - if (serie.IsUseCoord<PolarCoord>()) - { - PropertyField("m_PolarIndex"); - } - else - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - } - PropertyField("m_LineType"); - //PropertyField("m_Clip"); - PropertyFiledMore(() => - { - PropertyFieldLimitMin("m_MinShow", 0); - PropertyFieldLimitMin("m_MaxShow", 0); - PropertyFieldLimitMin("m_MaxCache", 0); - PropertyField("m_SampleDist"); - PropertyField("m_SampleType"); - PropertyField("m_SampleAverage"); - PropertyField("m_Ignore"); - PropertyField("m_IgnoreValue"); - PropertyField("m_IgnoreLineBreak"); - PropertyField("m_ShowAsPositiveNumber"); - PropertyField("m_Large"); - PropertyField("m_LargeThreshold"); - }); - PropertyField("m_Symbol"); - PropertyField("m_LineStyle"); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/LineEditor.cs.meta b/Assets/XCharts/Editor/Series/LineEditor.cs.meta deleted file mode 100644 index c817b49..0000000 --- a/Assets/XCharts/Editor/Series/LineEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 065fbd043ce6e40609cfb52114aaaa6a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/ParallelEditor.cs b/Assets/XCharts/Editor/Series/ParallelEditor.cs deleted file mode 100644 index c0d7b2c..0000000 --- a/Assets/XCharts/Editor/Series/ParallelEditor.cs +++ /dev/null @@ -1,16 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Parallel))] - public class ParallelEditor : SerieEditor<Parallel> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_ParallelIndex"); - PropertyField("m_LineType"); - PropertyField("m_LineStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/ParallelEditor.cs.meta b/Assets/XCharts/Editor/Series/ParallelEditor.cs.meta deleted file mode 100644 index b368384..0000000 --- a/Assets/XCharts/Editor/Series/ParallelEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 01af34b37a31d4876bd2d9ca7687ccd1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/PieEditor.cs b/Assets/XCharts/Editor/Series/PieEditor.cs deleted file mode 100644 index 7a66372..0000000 --- a/Assets/XCharts/Editor/Series/PieEditor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Pie))] - public class PieEditor : SerieEditor<Pie> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_RoseType"); - PropertyField("m_Gap"); - PropertyTwoFiled("m_Center"); - PropertyTwoFiled("m_Radius"); - PropertyField("m_AvoidLabelOverlap"); - PropertyFiledMore(() => - { - PropertyField("m_MinAngle"); - PropertyField("m_RoundCap"); - PropertyField("m_Ignore"); - PropertyField("m_IgnoreValue"); - }); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/PieEditor.cs.meta b/Assets/XCharts/Editor/Series/PieEditor.cs.meta deleted file mode 100644 index b0486f5..0000000 --- a/Assets/XCharts/Editor/Series/PieEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3e7ae042a30a3433d8ae63a82bf37278 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/RadarEditor.cs b/Assets/XCharts/Editor/Series/RadarEditor.cs deleted file mode 100644 index aedf983..0000000 --- a/Assets/XCharts/Editor/Series/RadarEditor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Radar))] - public class RadarEditor : SerieEditor<Radar> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_RadarType"); - PropertyField("m_RadarIndex"); - - PropertyField("m_Symbol"); - PropertyField("m_LineStyle"); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/RadarEditor.cs.meta b/Assets/XCharts/Editor/Series/RadarEditor.cs.meta deleted file mode 100644 index 179183d..0000000 --- a/Assets/XCharts/Editor/Series/RadarEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7b6a9ab6dd1ea4e3a98bef73e90d42a9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/RingEditor.cs b/Assets/XCharts/Editor/Series/RingEditor.cs deleted file mode 100644 index 71ec6db..0000000 --- a/Assets/XCharts/Editor/Series/RingEditor.cs +++ /dev/null @@ -1,21 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Ring))] - public class RingEditor : SerieEditor<Ring> - { - public override void OnCustomInspectorGUI() - { - PropertyTwoFiled("m_Center"); - PropertyTwoFiled("m_Radius"); - PropertyField("m_StartAngle"); - PropertyField("m_Gap"); - PropertyField("m_RoundCap"); - PropertyField("m_Clockwise"); - - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/RingEditor.cs.meta b/Assets/XCharts/Editor/Series/RingEditor.cs.meta deleted file mode 100644 index 4664e80..0000000 --- a/Assets/XCharts/Editor/Series/RingEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 647f8e564429a4b76833d3b428f5ab13 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/ScatterEditor.cs b/Assets/XCharts/Editor/Series/ScatterEditor.cs deleted file mode 100644 index 77cd8bb..0000000 --- a/Assets/XCharts/Editor/Series/ScatterEditor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(Scatter))] - public class ScatterEditor : SerieEditor<Scatter> - { - public override void OnCustomInspectorGUI() - { - if (serie.IsUseCoord<SingleAxisCoord>()) - { - PropertyField("m_SingleAxisIndex"); - } - else - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - } - PropertyField("m_Clip"); - - PropertyField("m_Symbol"); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/ScatterEditor.cs.meta b/Assets/XCharts/Editor/Series/ScatterEditor.cs.meta deleted file mode 100644 index 7b59778..0000000 --- a/Assets/XCharts/Editor/Series/ScatterEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3dfef7780c8cc412f87d00e437c94715 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/SerieBaseEditor.cs b/Assets/XCharts/Editor/Series/SerieBaseEditor.cs deleted file mode 100644 index 1022c1f..0000000 --- a/Assets/XCharts/Editor/Series/SerieBaseEditor.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using UnityEngine.Assertions; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class SerieBaseEditor - { - internal BaseChart chart { get; private set; } - internal Serie serie { get; private set; } - - //Editor m_Inspector; - internal SerializedProperty baseProperty; - internal SerializedProperty showProperty; - internal List<HeaderMenuInfo> menus = new List<HeaderMenuInfo>(); - internal List<HeaderMenuInfo> serieDataMenus = new List<HeaderMenuInfo>(); - protected Dictionary<string, Type> m_CoordOptionsDic; - protected List<string> m_CoordOptionsNames; - private string m_DisplayName; - - internal void Init(BaseChart chart, Serie target, SerializedProperty property, UnityEditor.Editor inspector) - { - this.chart = chart; - this.serie = target; - this.baseProperty = property; - m_DisplayName = string.Format("Serie {0}: {1}", serie.index, serie.GetType().Name); - //m_Inspector = inspector; - showProperty = baseProperty.FindPropertyRelative("m_Show"); - if (showProperty == null) - showProperty = baseProperty.FindPropertyRelative("m_Enable"); - OnEnable(); - - if (serie.GetType().IsDefined(typeof(CoordOptionsAttribute), false)) - { - var attribute = serie.GetType().GetAttribute<CoordOptionsAttribute>(); - m_CoordOptionsDic = new Dictionary<string, Type>(); - m_CoordOptionsNames = new List<string>(); - if (attribute.type0 != null) - { - m_CoordOptionsDic[attribute.type0.Name] = attribute.type0; - m_CoordOptionsNames.Add(attribute.type0.Name); - } - if (attribute.type1 != null) - { - m_CoordOptionsDic[attribute.type1.Name] = attribute.type1; - m_CoordOptionsNames.Add(attribute.type1.Name); - } - if (attribute.type2 != null) - { - m_CoordOptionsDic[attribute.type2.Name] = attribute.type2; - m_CoordOptionsNames.Add(attribute.type2.Name); - } - if (attribute.type3 != null) - { - m_CoordOptionsDic[attribute.type3.Name] = attribute.type3; - m_CoordOptionsNames.Add(attribute.type3.Name); - } - } - } - - public virtual void OnEnable() - { } - - public virtual void OnDisable() - { } - - internal void OnInternalInspectorGUI() - { - OnInspectorGUI(); - EditorGUILayout.Space(); - } - - public virtual void OnInspectorGUI() - { } - - protected virtual void DrawExtendeds() - { } - - public virtual string GetDisplayTitle() - { - // var title = string.Format("serie {0}: {1}", serie.index, serie.GetType().Name); - // return ObjectNames.NicifyVariableName(title); - return m_DisplayName; - } - - internal SerializedProperty FindProperty(string path) - { - return baseProperty.FindPropertyRelative(path); - } - - protected SerializedProperty PropertyField(string path) - { - Assert.IsNotNull(path); - var property = FindProperty(path); - Assert.IsNotNull(property, "Can't find:" + path); - var title = ChartEditorHelper.GetContent(property.displayName); - PropertyField(property, title); - return property; - } - - protected void PropertyField(SerializedProperty property) - { - Assert.IsNotNull(property); - var title = ChartEditorHelper.GetContent(property.displayName); - PropertyField(property, title); - } - - protected void PropertyField(SerializedProperty property, GUIContent title) - { - EditorGUILayout.PropertyField(property, title); - } - - protected void PropertyListField(string relativePropName, bool showOrder = true) - { - //TODO: - PropertyField(relativePropName); - } - - protected void PropertyTwoFiled(string relativePropName) - { - var m_DrawRect = GUILayoutUtility.GetRect(1f, 17f); - var prop = FindProperty(relativePropName); - ChartEditorHelper.MakeTwoField(ref m_DrawRect, m_DrawRect.width, prop, prop.displayName); - } - protected void PropertyFieldLimitMin(string relativePropName, double min) - { - var prop = PropertyField(relativePropName); - switch (prop.propertyType) - { - case SerializedPropertyType.Float: - if (prop.floatValue < min) - prop.floatValue = (float) min; - break; - case SerializedPropertyType.Integer: - if (prop.intValue < min) - prop.intValue = (int) min; - break; - } - - } - protected void PropertyFieldLimitMax(string relativePropName, int max) - { - var prop = PropertyField(relativePropName); - switch (prop.propertyType) - { - case SerializedPropertyType.Float: - if (prop.floatValue > max) - prop.floatValue = (float) max; - break; - case SerializedPropertyType.Integer: - if (prop.intValue > max) - prop.intValue = (int) max; - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/SerieBaseEditor.cs.meta b/Assets/XCharts/Editor/Series/SerieBaseEditor.cs.meta deleted file mode 100644 index fad64c3..0000000 --- a/Assets/XCharts/Editor/Series/SerieBaseEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 991edc42b5abf429b8062fd202278a4d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/SerieEditor.cs b/Assets/XCharts/Editor/Series/SerieEditor.cs deleted file mode 100644 index 9b410ea..0000000 --- a/Assets/XCharts/Editor/Series/SerieEditor.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class SerieEditor<T> : SerieBaseEditor where T : Serie - { - protected const string MORE = "More"; - protected bool m_MoreFoldout = false; - private bool m_DataFoldout = false; - private bool m_DataComponentFoldout = true; - private Dictionary<int, bool> m_DataElementFoldout = new Dictionary<int, bool>(); - - public override void OnInspectorGUI() - { - ++EditorGUI.indentLevel; - //PropertyField("m_InsertDataToHead"); - PropertyField("m_SerieName"); - if (m_CoordOptionsNames != null && m_CoordOptionsNames.Count > 1) - { - var index = m_CoordOptionsNames.IndexOf(serie.coordSystem); - var selectedIndex = EditorGUILayout.Popup("Coord System", index, m_CoordOptionsNames.ToArray()); - if (selectedIndex != index) - { - var typeName = m_CoordOptionsNames[selectedIndex]; - serie.coordSystem = m_CoordOptionsDic[typeName].Name; - } - } - OnCustomInspectorGUI(); - OnExtraInspectorGUI(); - PropertyFieldData(); - --EditorGUI.indentLevel; - } - - public virtual void OnCustomInspectorGUI() - { } - - private void OnExtraInspectorGUI() - { - foreach (var kv in Serie.extraComponentMap) - { - var prop = FindProperty(kv.Value); - if (prop.arraySize > 0) - PropertyField(prop.GetArrayElementAtIndex(0)); - } - } - - private void PropertyFieldData() - { - m_DataFoldout = ChartEditorHelper.DrawHeader("Data", m_DataFoldout, false, null, null, - new HeaderMenuInfo("Import ECharts Data", () => - { - PraseExternalDataEditor.UpdateData(chart, serie, null); - PraseExternalDataEditor.ShowWindow(); - })); - if (!m_DataFoldout) return; - EditorGUI.indentLevel++; - var m_Datas = FindProperty("m_Data"); - var m_DataDimension = FindProperty("m_ShowDataDimension"); - var m_ShowDataName = FindProperty("m_ShowDataName"); - PropertyField(m_ShowDataName); - PropertyField(m_DataDimension); - var listSize = m_Datas.arraySize; - listSize = EditorGUILayout.IntField("Size", listSize); - if (listSize < 0) listSize = 0; - if (m_DataDimension.intValue < 1) m_DataDimension.intValue = 1; - int dimension = m_DataDimension.intValue; - bool showName = m_ShowDataName.boolValue; - if (listSize != m_Datas.arraySize) - { - while (listSize > m_Datas.arraySize) m_Datas.arraySize++; - while (listSize < m_Datas.arraySize) m_Datas.arraySize--; - } - if (listSize > 30) // && !XCSettings.editorShowAllListData) - { - int num = listSize > 10 ? 10 : listSize; - for (int i = 0; i < num; i++) - { - DrawSerieData(dimension, m_Datas, i, showName); - } - if (num >= 10) - { - ChartEditorHelper.DrawHeader("... ", false, false, null, null); - DrawSerieData(dimension, m_Datas, listSize - 1, showName); - } - } - else - { - for (int i = 0; i < m_Datas.arraySize; i++) - { - DrawSerieData(dimension, m_Datas, i, showName); - } - } - EditorGUI.indentLevel--; - } - - protected void PropertyFiledMore(System.Action action) - { - m_MoreFoldout = ChartEditorHelper.DrawHeader(MORE, m_MoreFoldout, false, null, null); - if (m_MoreFoldout) - { - if (action != null) action(); - } - } - - private void DrawSerieData(int dimension, SerializedProperty m_Datas, int index, bool showName) - { - bool flag; - if (!m_DataElementFoldout.TryGetValue(index, out flag)) - { - flag = false; - m_DataElementFoldout[index] = false; - } - var fieldCount = dimension + (showName ? 1 : 0); - m_DataElementFoldout[index] = ChartEditorHelper.DrawHeader("SerieData " + index, flag, false, null, - delegate(Rect drawRect) - { - //drawRect.width -= 2f; - var maxX = drawRect.xMax; - var currentWidth = drawRect.width; - var lastX = drawRect.x; - var lastWid = drawRect.width; - var lastFieldWid = EditorGUIUtility.fieldWidth; - var lastLabelWid = EditorGUIUtility.labelWidth; - var serieData = m_Datas.GetArrayElementAtIndex(index); - var sereName = serieData.FindPropertyRelative("m_Name"); - var data = serieData.FindPropertyRelative("m_Data"); -#if UNITY_2019_3_OR_NEWER - var gap = 2; - var namegap = 3; -#else - var gap = 0; - var namegap = 0; -#endif - if (fieldCount <= 1) - { - while (2 > data.arraySize) - { - var value = data.arraySize == 0 ? index : 0; - data.arraySize++; - data.GetArrayElementAtIndex(data.arraySize - 1).floatValue = value; - } - SerializedProperty element = data.GetArrayElementAtIndex(1); - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15 + gap; - drawRect.x = startX; - drawRect.xMax = maxX; - EditorGUI.PropertyField(drawRect, element, GUIContent.none); - } - else - { - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15 + gap; - var dataWidTotal = (currentWidth - (startX + 20.5f + 1)); - var dataWid = dataWidTotal / fieldCount; - var xWid = dataWid - 2; - for (int i = 0; i < dimension; i++) - { - var dataCount = i < 1 ? 2 : i + 1; - while (dataCount > data.arraySize) - { - var value = data.arraySize == 0 ? index : 0; - data.arraySize++; - data.GetArrayElementAtIndex(data.arraySize - 1).floatValue = value; - } - drawRect.x = startX + i * xWid; - drawRect.width = dataWid + 25; - SerializedProperty element = data.GetArrayElementAtIndex(dimension <= 1 ? 1 : i); - EditorGUI.PropertyField(drawRect, element, GUIContent.none); - } - if (showName) - { - drawRect.x = startX + (fieldCount - 1) * xWid; - drawRect.width = dataWid + 40 + dimension * namegap - 2.5f; - EditorGUI.PropertyField(drawRect, sereName, GUIContent.none); - } - EditorGUIUtility.fieldWidth = lastFieldWid; - EditorGUIUtility.labelWidth = lastLabelWid; - } - }); - if (m_DataElementFoldout[index]) - { - if (!(serie is ISimplifiedSerie)) - DrawSerieDataDetail(m_Datas, index); - } - } - - private void DrawSerieDataDetail(SerializedProperty m_Datas, int index) - { - EditorGUI.indentLevel++; - var serieData = m_Datas.GetArrayElementAtIndex(index); - var m_Name = serieData.FindPropertyRelative("m_Name"); - - PropertyField(m_Name); - if (serie.GetType().IsDefined(typeof(SerieDataExtraFieldAttribute), false)) - { - var attribute = serie.GetType().GetAttribute<SerieDataExtraFieldAttribute>(); - foreach (var field in attribute.fields) - { - PropertyField(serieData.FindPropertyRelative(field)); - } - } - - serieDataMenus.Clear(); - if (serie.GetType().IsDefined(typeof(SerieDataExtraComponentAttribute), false)) - { - var attribute = serie.GetType().GetAttribute<SerieDataExtraComponentAttribute>(); - foreach (var type in attribute.types) - { - var size = serieData.FindPropertyRelative(SerieData.extraComponentMap[type]).arraySize; - serieDataMenus.Add(new HeaderMenuInfo("Add " + type.Name, () => - { - serie.GetSerieData(index).GetOrAddComponent(type); - EditorUtility.SetDirty(chart); - }, size == 0)); - } - foreach (var type in attribute.types) - { - var size = serieData.FindPropertyRelative(SerieData.extraComponentMap[type]).arraySize; - serieDataMenus.Add(new HeaderMenuInfo("Remove " + type.Name, () => - { - serie.GetSerieData(index).RemoveComponent(type); - EditorUtility.SetDirty(chart); - }, size > 0)); - } - } - serieDataMenus.Add(new HeaderMenuInfo("Remove All", () => - { - serie.GetSerieData(index).RemoveAllComponent(); - }, true)); - m_DataComponentFoldout = ChartEditorHelper.DrawHeader("Component", m_DataComponentFoldout, false, null, null, serieDataMenus); - if (m_DataComponentFoldout) - { - foreach (var kv in SerieData.extraComponentMap) - { - var prop = serieData.FindPropertyRelative(kv.Value); - if (prop.arraySize > 0) - PropertyField(prop.GetArrayElementAtIndex(0)); - } - } - EditorGUI.indentLevel--; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/SerieEditor.cs.meta b/Assets/XCharts/Editor/Series/SerieEditor.cs.meta deleted file mode 100644 index 58ee781..0000000 --- a/Assets/XCharts/Editor/Series/SerieEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6a03d2daaabd8465398b1ff06a9889cb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/SerieListEditor.cs b/Assets/XCharts/Editor/Series/SerieListEditor.cs deleted file mode 100644 index 280ee25..0000000 --- a/Assets/XCharts/Editor/Series/SerieListEditor.cs +++ /dev/null @@ -1,268 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine.Assertions; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public sealed class SerieListEditor - { - public BaseChart chart { get; private set; } - BaseChartEditor m_BaseEditor; - - SerializedObject m_SerializedObject; - List<SerializedProperty> m_SeriesProperty; - SerializedProperty m_EnableProperty; - - Dictionary<Type, Type> m_EditorTypes; - List<SerieBaseEditor> m_Editors; - private bool m_SerieFoldout; - - public SerieListEditor(BaseChartEditor editor) - { - Assert.IsNotNull(editor); - m_BaseEditor = editor; - } - - public void Init(BaseChart chart, SerializedObject serializedObject, List<SerializedProperty> componentProps) - { - Assert.IsNotNull(chart); - Assert.IsNotNull(serializedObject); - - this.chart = chart; - m_SerializedObject = serializedObject; - m_SeriesProperty = componentProps; - - m_Editors = new List<SerieBaseEditor>(); - m_EditorTypes = new Dictionary<Type, Type>(); - - var editorTypes = RuntimeUtil.GetAllTypesDerivedFrom<SerieBaseEditor>() - .Where(t => t.IsDefined(typeof(SerieEditorAttribute), false) && !t.IsAbstract); - foreach (var editorType in editorTypes) - { - var attribute = editorType.GetAttribute<SerieEditorAttribute>(); - m_EditorTypes.Add(attribute.serieType, editorType); - } - - RefreshEditors(); - } - - public void UpdateSeriesProperty(List<SerializedProperty> componentProps) - { - m_SeriesProperty = componentProps; - RefreshEditors(); - } - - public void Clear() - { - if (m_Editors == null) - return; - - foreach (var editor in m_Editors) - editor.OnDisable(); - - m_Editors.Clear(); - m_EditorTypes.Clear(); - } - - public void OnGUI() - { - if (chart == null) - return; - if (chart.debug.foldSeries) - { - m_SerieFoldout = ChartEditorHelper.DrawHeader("Series", m_SerieFoldout, false, null, null); - if (m_SerieFoldout) - { - DrawSeries(); - } - } - else - { - DrawSeries(); - } - } - - void DrawSeries() - { - for (int i = 0; i < m_Editors.Count; i++) - { - var editor = m_Editors[i]; - string title = editor.GetDisplayTitle(); - bool displayContent = ChartEditorHelper.DrawHeader( - title, - editor.baseProperty, - editor.showProperty, - editor.menus); - if (displayContent) - { - editor.OnInternalInspectorGUI(); - } - } - if (m_Editors.Count <= 0) - { - EditorGUILayout.HelpBox("No serie.", MessageType.Info); - } - } - - void RefreshEditors() - { - m_SerializedObject.UpdateIfRequiredOrScript(); - foreach (var editor in m_Editors) - editor.OnDisable(); - - m_Editors.Clear(); - - for (int i = 0; i < chart.series.Count; i++) - { - var serie = chart.series[i]; - if (serie != null) - { - CreateEditor(serie, m_SeriesProperty[i]); - } - } - } - - void CreateEditor(Serie serie, SerializedProperty property, int index = -1) - { - var id = index >= 0 ? index : m_Editors.Count; - var settingsType = serie.GetType(); - Type editorType; - - if (!m_EditorTypes.TryGetValue(settingsType, out editorType)) - editorType = typeof(SerieBaseEditor); - var editor = (SerieBaseEditor) Activator.CreateInstance(editorType); - editor.Init(chart, serie, property, m_BaseEditor); - editor.menus.Clear(); - editor.menus.Add(new HeaderMenuInfo("Clone", () => - { - CloneSerie(editor.serie); - })); - editor.menus.Add(new HeaderMenuInfo("Remove", () => - { - if (EditorUtility.DisplayDialog("", "Sure remove serie?", "Yes", "Cancel")) - RemoveSerieEditor(id); - })); - editor.menus.Add(new HeaderMenuInfo("Move Down", () => - { - if (chart.MoveDownSerie(id)) - { - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - } - })); - editor.menus.Add(new HeaderMenuInfo("Move Up", () => - { - if (chart.MoveUpSerie(id)) - { - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - } - })); - foreach (var type in GetCovertToSerie(editor.serie.GetType())) - { - editor.menus.Add(new HeaderMenuInfo("Covert to " + type.Name, () => - { - CovertSerie(editor.serie, type); - })); - } - if (editor.serie.GetType().IsDefined(typeof(SerieExtraComponentAttribute), false)) - { - var attribute = editor.serie.GetType().GetAttribute<SerieExtraComponentAttribute>(); - foreach (var type in attribute.types) - { - var size = editor.FindProperty(Serie.extraComponentMap[type]).arraySize; - editor.menus.Add(new HeaderMenuInfo("Add " + type.Name, () => - { - editor.serie.AddExtraComponent(type); - RefreshEditors(); - chart.RefreshAllComponent(); - EditorUtility.SetDirty(chart); - }, size == 0)); - } - foreach (var type in attribute.types) - { - var size = editor.FindProperty(Serie.extraComponentMap[type]).arraySize; - editor.menus.Add(new HeaderMenuInfo("Remove " + type.Name, () => - { - editor.serie.RemoveExtraComponent(type); - RefreshEditors(); - chart.RefreshAllComponent(); - EditorUtility.SetDirty(chart); - }, size > 0)); - } - } - if (index < 0) - m_Editors.Add(editor); - else - m_Editors[index] = editor; - } - - public void AddSerie(Type type) - { - m_SerializedObject.Update(); - var serieName = chart.GenerateDefaultSerieName(); - type.InvokeMember("AddDefaultSerie", - BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, - new object[] { chart, serieName }); - m_SerializedObject.Update(); - m_SerializedObject.ApplyModifiedProperties(); - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - EditorUtility.SetDirty(chart); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - - public void CovertSerie(Serie serie, Type type) - { - chart.CovertSerie(serie, type); - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - } - - public void CloneSerie(Serie serie) - { - var newSerie = serie.Clone(); - newSerie.serieName = chart.GenerateDefaultSerieName(); - chart.InsertSerie(newSerie); - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - } - - private void RemoveSerieEditor(int id) - { - m_Editors[id].OnDisable(); - chart.RemoveSerie(m_Editors[id].serie); - m_Editors.RemoveAt(id); - m_SerializedObject.Update(); - m_SerializedObject.ApplyModifiedProperties(); - m_SeriesProperty = m_BaseEditor.RefreshSeries(); - RefreshEditors(); - EditorUtility.SetDirty(chart); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - - private List<Type> GetCovertToSerie(Type serie) - { - var list = new List<Type>(); - var typeMap = RuntimeUtil.GetAllTypesDerivedFrom<Serie>(); - foreach (var kvp in typeMap) - { - var type = kvp; - if (type.IsDefined(typeof(SerieConvertAttribute), false)) - { - var attribute = type.GetAttribute<SerieConvertAttribute>(); - if (attribute != null && attribute.Contains(serie)) - list.Add(type); - } - } - list.Sort((a, b) => { return a.Name.CompareTo(b.Name); }); - return list; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/SerieListEditor.cs.meta b/Assets/XCharts/Editor/Series/SerieListEditor.cs.meta deleted file mode 100644 index f8d7bf2..0000000 --- a/Assets/XCharts/Editor/Series/SerieListEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5fbdf672386ce40bb803a8bb3bb2a3ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs b/Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs deleted file mode 100644 index c09d3ee..0000000 --- a/Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(SimplifiedBar))] - public class SimplifiedBarEditor : SerieEditor<SimplifiedBar> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - PropertyField("m_BarWidth"); - PropertyField("m_BarGap"); - PropertyField("m_Clip"); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs.meta b/Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs.meta deleted file mode 100644 index a1b72e9..0000000 --- a/Assets/XCharts/Editor/Series/SimplifiedBarEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 99f8e53a5ab7c49e6b87aedee03cf856 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs b/Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs deleted file mode 100644 index d180a57..0000000 --- a/Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs +++ /dev/null @@ -1,17 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(SimplifiedCandlestick))] - public class SimplifiedCandlestickEditor : SerieEditor<SimplifiedCandlestick> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - PropertyField("m_BarWidth"); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs.meta b/Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs.meta deleted file mode 100644 index 9562375..0000000 --- a/Assets/XCharts/Editor/Series/SimplifiedCandlestickEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 73d22e02d33e948d6981d537ba1f680e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs b/Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs deleted file mode 100644 index b5be0c2..0000000 --- a/Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs +++ /dev/null @@ -1,19 +0,0 @@ -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [SerieEditor(typeof(SimplifiedLine))] - public class LineHPEditor : SerieEditor<SimplifiedLine> - { - public override void OnCustomInspectorGUI() - { - PropertyField("m_XAxisIndex"); - PropertyField("m_YAxisIndex"); - PropertyField("m_LineType"); - //PropertyField("m_Clip"); - PropertyField("m_LineStyle"); - PropertyField("m_ItemStyle"); - PropertyField("m_Animation"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs.meta b/Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs.meta deleted file mode 100644 index 4e85e3d..0000000 --- a/Assets/XCharts/Editor/Series/SimplifiedLineEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cedf2a45756cd415cb5a74f3188ebd72 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Utilities.meta b/Assets/XCharts/Editor/Utilities.meta deleted file mode 100644 index 51eefcd..0000000 --- a/Assets/XCharts/Editor/Utilities.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b4c4e4069901c4c3089878f483167df8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs b/Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs deleted file mode 100644 index 647e716..0000000 --- a/Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs +++ /dev/null @@ -1,734 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class HeaderMenuInfo - { - public string name; - public Action action; - public bool enable = true; - - public HeaderMenuInfo() { } - public HeaderMenuInfo(string name, Action action) - { - this.name = name; - this.action = action; - } - public HeaderMenuInfo(string name, Action action, bool enable) - { - this.name = name; - this.action = action; - this.enable = enable; - } - } - - public static class ChartEditorHelper - { - public const float HEADER_HEIGHT = 17f; - public const float FOLDOUT_WIDTH = 13f; -#if UNITY_2019_3_OR_NEWER - public const float INDENT_WIDTH = 15; - public const float BOOL_WIDTH = 15; - public const float ARROW_WIDTH = 20; - public const float GAP_WIDTH = 2; - public const float DIFF_WIDTH = 0; -#else - public const float INDENT_WIDTH = 15; - public const float BOOL_WIDTH = 15; - public const float ARROW_WIDTH = 14f; - public const float GAP_WIDTH = 0; - public const float DIFF_WIDTH = 1; -#endif - static Dictionary<string, GUIContent> s_GUIContentCache; - - static ChartEditorHelper() - { - s_GUIContentCache = new Dictionary<string, GUIContent>(); - } - - public static void SecondField(Rect drawRect, SerializedProperty prop) - { - RectOffset offset = new RectOffset(-(int) EditorGUIUtility.labelWidth, 0, 0, 0); - drawRect = offset.Add(drawRect); - EditorGUI.PropertyField(drawRect, prop, GUIContent.none); - drawRect = offset.Remove(drawRect); - } - - public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, - string name) - { - while (arrayProp.arraySize < 2) arrayProp.arraySize++; - var prop1 = arrayProp.GetArrayElementAtIndex(0); - var prop2 = arrayProp.GetArrayElementAtIndex(1); - MakeTwoField(ref drawRect, rectWidth, prop1, prop2, name); - } - - public static void MakeDivideList(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, - string name, int showNum) - { - while (arrayProp.arraySize < showNum) arrayProp.arraySize++; - EditorGUI.LabelField(drawRect, name); -#if UNITY_2019_3_OR_NEWER - var gap = 2; -#else - var gap = 0; -#endif - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + gap; - var dataWidTotal = (rectWidth - (startX + INDENT_WIDTH + 1)); - EditorGUI.DrawRect(new Rect(startX, drawRect.y, dataWidTotal, drawRect.height), Color.grey); - var dataWid = dataWidTotal / showNum; - var xWid = dataWid - gap; - for (int i = 0; i < 1; i++) - { - drawRect.x = startX + i * xWid; - drawRect.width = dataWid + (EditorGUI.indentLevel - 2) * 40.5f; - EditorGUI.PropertyField(drawRect, arrayProp.GetArrayElementAtIndex(i), GUIContent.none); - } - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty prop1, - SerializedProperty prop2, 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) / 2; - 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); - EditorGUI.PropertyField(centerXRect, prop1, GUIContent.none); - EditorGUI.PropertyField(centerYRect, prop2, 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); - var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; - var diff = 14 + EditorGUI.indentLevel * 14; - var offset = diff - INDENT_WIDTH; - var tempWidth = (rectWidth - startX + diff) / 2; - var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height); - var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth, drawRect.height); - var x = EditorGUI.FloatField(centerXRect, prop.vector3Value.x); - var y = EditorGUI.FloatField(centerYRect, prop.vector3Value.y); - prop.vector3Value = new Vector3(x, y); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - } - - public static bool MakeFoldout(ref Rect drawRect, ref bool moduleToggle, string content, - SerializedProperty prop = null, bool bold = false) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - var style = bold ? EditorCustomStyles.foldoutStyle : UnityEditor.EditorStyles.foldout; - drawRect.width = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH; - moduleToggle = EditorGUI.Foldout(drawRect, moduleToggle, content, true, style); - MakeBool(drawRect, prop); - drawRect.width = defaultWidth; - drawRect.x = defaultX; - return moduleToggle; - } - - public static bool MakeFoldout(ref Rect drawRect, Dictionary<string, float> heights, - Dictionary<string, bool> moduleToggle, string key, string content, SerializedProperty prop, bool bold = false) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - var style = bold ? EditorCustomStyles.foldoutStyle : UnityEditor.EditorStyles.foldout; - drawRect.width = EditorGUIUtility.labelWidth; - moduleToggle[key] = EditorGUI.Foldout(drawRect, moduleToggle[key], content, true, style); - if (prop != null) - { - if (prop.propertyType == SerializedPropertyType.Boolean) - { - MakeBool(drawRect, prop); - } - else - { - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; - drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - 2; - EditorGUI.PropertyField(drawRect, prop, GUIContent.none); - } - } - - drawRect.width = defaultWidth; - drawRect.x = defaultX; - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - heights[key] += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - return moduleToggle[key]; - } - public static bool MakeComponentFoldout(ref Rect drawRect, Dictionary<string, float> heights, - Dictionary<string, bool> moduleToggle, string key, string content, SerializedProperty prop, - SerializedProperty prop2, bool propEnable, params HeaderMenuInfo[] menus) - { - var sourRect = drawRect; - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - float headerHeight = DrawSplitterAndBackground(drawRect); - - drawRect.width = EditorGUIUtility.labelWidth; - - moduleToggle[key] = EditorGUI.Foldout(drawRect, moduleToggle[key], content, true, EditorStyles.foldout); - if (prop != null) - { - if (prop.propertyType == SerializedPropertyType.Boolean) - { - if (!propEnable) - using(new EditorGUI.DisabledScope(true)) - MakeBool(drawRect, prop); - else - MakeBool(drawRect, prop); - if (prop2 != null && !moduleToggle[key]) - { - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH + BOOL_WIDTH; - drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH; - EditorGUI.PropertyField(drawRect, prop2, GUIContent.none); - } - } - else - { - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; - drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - 2; - EditorGUI.PropertyField(drawRect, prop, GUIContent.none); - } - } - DrawMenu(sourRect, menus); - drawRect.width = defaultWidth; - drawRect.x = defaultX; - drawRect.y += headerHeight; - heights[key] += headerHeight; - return moduleToggle[key]; - } - - public static void MakeBool(Rect drawRect, SerializedProperty boolProp, int index = 0, string name = null) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - float boolWidth = index * (BOOL_WIDTH + GAP_WIDTH); - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH + boolWidth; - drawRect.width = (EditorGUI.indentLevel + 1) * BOOL_WIDTH + index * 110; - if (boolProp != null) - { - EditorGUI.PropertyField(drawRect, boolProp, GUIContent.none); - if (!string.IsNullOrEmpty(name)) - { - drawRect.x += BOOL_WIDTH; - drawRect.width = 200; - EditorGUI.LabelField(drawRect, name); - } - } - drawRect.width = defaultWidth; - drawRect.x = defaultX; - } - - public static bool MakeFoldout(ref Rect drawRect, ref float height, ref Dictionary<string, bool> moduleToggle, - SerializedProperty prop, string moduleName, string showPropName, bool bold = false) - { - var relativeProp = prop.FindPropertyRelative(showPropName); - var flag = MakeFoldout(ref drawRect, ref moduleToggle, prop, moduleName, relativeProp, bold); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - return flag; - } - - public static bool MakeFoldout(ref Rect drawRect, ref Dictionary<string, bool> moduleToggle, SerializedProperty prop, - string moduleName, SerializedProperty showProp = null, bool bold = false) - { - var key = prop.propertyPath; - if (!moduleToggle.ContainsKey(key)) - { - moduleToggle.Add(key, false); - } - var toggle = moduleToggle[key]; - - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; -#if UNITY_2019_3_OR_NEWER - drawRect.width = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH; -#else - drawRect.width = EditorGUIUtility.labelWidth; -#endif - var displayName = string.IsNullOrEmpty(moduleName) ? prop.displayName : moduleName; - var foldoutStyle = bold ? EditorCustomStyles.foldoutStyle : UnityEditor.EditorStyles.foldout; - toggle = EditorGUI.Foldout(drawRect, toggle, displayName, true, foldoutStyle); - - if (moduleToggle[key] != toggle) - { - moduleToggle[key] = toggle; - } - if (showProp != null) - { - drawRect.x = EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + ARROW_WIDTH; - if (showProp.propertyType == SerializedPropertyType.Boolean) - { - drawRect.width = (EditorGUI.indentLevel + 1) * BOOL_WIDTH; - } - else - { - drawRect.width = defaultWidth - drawRect.x + ARROW_WIDTH - GAP_WIDTH; - } - EditorGUI.PropertyField(drawRect, showProp, GUIContent.none); - } - drawRect.width = defaultWidth; - drawRect.x = defaultX; - return toggle; - } - - public static bool MakeListWithFoldout(ref Rect drawRect, SerializedProperty listProp, bool foldout, - bool showOrder, bool showSize, params HeaderMenuInfo[] menus) - { - var height = 0f; - return MakeListWithFoldout(ref drawRect, ref height, listProp, foldout, showOrder, showSize, menus); - } - - public static bool MakeListWithFoldout(ref Rect drawRect, ref float height, SerializedProperty listProp, - bool foldout, bool showOrder, bool showSize, params HeaderMenuInfo[] menus) - { - var rawWidth = drawRect.width; - var headerHeight = DrawSplitterAndBackground(drawRect); - var foldoutRect = drawRect; - foldoutRect.xMax -= 10; - bool flag = EditorGUI.Foldout(foldoutRect, foldout, listProp.displayName, true); - ChartEditorHelper.DrawMenu(drawRect, menus); - height += headerHeight; - drawRect.y += headerHeight; - drawRect.width = rawWidth; - if (flag) - { - MakeList(ref drawRect, ref height, listProp, showOrder, showSize); - } - return flag; - } - - public static void MakeList(ref Rect drawRect, SerializedProperty listProp, bool showOrder = false, - bool showSize = true) - { - var height = 0f; - MakeList(ref drawRect, ref height, listProp, showOrder, showSize); - } - - public static void MakeList(ref Rect drawRect, ref float height, SerializedProperty listProp, - bool showOrder = false, bool showSize = true) - { - EditorGUI.indentLevel++; - var listSize = listProp.arraySize; - var iconWidth = 14; - var iconGap = 3f; - - if (showSize) - { - var headerHeight = DrawSplitterAndBackground(drawRect); - if (showOrder) - { - var elementRect = new Rect(drawRect.x, drawRect.y, drawRect.width - iconWidth + 2, drawRect.height); - var oldColor = GUI.contentColor; - GUI.contentColor = Color.black; - GUI.contentColor = oldColor; - listSize = listProp.arraySize; - listSize = EditorGUI.IntField(elementRect, "Size", listSize); - } - else - { - listSize = EditorGUI.IntField(drawRect, "Size", listSize); - } - if (listSize < 0) listSize = 0; - drawRect.y += headerHeight; - height += headerHeight; - - if (listSize != listProp.arraySize) - { - while (listSize > listProp.arraySize) listProp.arraySize++; - while (listSize < listProp.arraySize) listProp.arraySize--; - } - } - if (listSize > 30 && !XCSettings.editorShowAllListData) - { - SerializedProperty element; - int num = listSize > 10 ? 10 : listSize; - for (int i = 0; i < num; i++) - { - element = listProp.GetArrayElementAtIndex(i); - DrawSplitterAndBackground(drawRect); - EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i)); - drawRect.y += EditorGUI.GetPropertyHeight(element); - height += EditorGUI.GetPropertyHeight(element); - } - if (num >= 10) - { - EditorGUI.LabelField(drawRect, "..."); - drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; - element = listProp.GetArrayElementAtIndex(listSize - 1); - DrawSplitterAndBackground(drawRect); - EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + (listSize - 1))); - drawRect.y += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; - height += EditorGUI.GetPropertyHeight(element) + EditorGUIUtility.standardVerticalSpacing; - } - } - else - { - for (int i = 0; i < listProp.arraySize; i++) - { - SerializedProperty element = listProp.GetArrayElementAtIndex(i); - DrawSplitterAndBackground(drawRect); - if (showOrder) - { - var temp = INDENT_WIDTH + GAP_WIDTH + iconGap; - var isSerie = "Serie".Equals(element.type); - var elementRect = isSerie ? - new Rect(drawRect.x, drawRect.y, drawRect.width + INDENT_WIDTH - 2 * iconGap, drawRect.height) : - new Rect(drawRect.x, drawRect.y, drawRect.width - 3 * iconWidth, drawRect.height); - EditorGUI.PropertyField(elementRect, element, new GUIContent("Element " + i)); - var iconRect = new Rect(drawRect.width - 3 * iconWidth + temp, drawRect.y, iconWidth, drawRect.height); - var oldColor = GUI.contentColor; - GUI.contentColor = Color.black; - if (GUI.Button(iconRect, EditorCustomStyles.iconUp, EditorCustomStyles.invisibleButton)) - { - if (i > 0) listProp.MoveArrayElement(i, i - 1); - } - iconRect = new Rect(drawRect.width - 2 * iconWidth + temp, drawRect.y, iconWidth, drawRect.height); - if (GUI.Button(iconRect, EditorCustomStyles.iconDown, EditorCustomStyles.invisibleButton)) - { - if (i < listProp.arraySize - 1) listProp.MoveArrayElement(i, i + 1); - } - iconRect = new Rect(drawRect.width - iconWidth + temp, drawRect.y, iconWidth, drawRect.height); - if (GUI.Button(iconRect, EditorCustomStyles.iconRemove, EditorCustomStyles.invisibleButton)) - { - if (i < listProp.arraySize && i >= 0) listProp.DeleteArrayElementAtIndex(i); - } - else - { - drawRect.y += EditorGUI.GetPropertyHeight(element); - height += EditorGUI.GetPropertyHeight(element); - } - GUI.contentColor = oldColor; - } - else - { - EditorGUI.PropertyField(drawRect, element, new GUIContent("Element " + i)); - drawRect.y += EditorGUI.GetPropertyHeight(element); - height += EditorGUI.GetPropertyHeight(element); - } - } - } - EditorGUI.indentLevel--; - } - - public static bool PropertyField(ref Rect drawRect, Dictionary<string, float> heights, string key, - SerializedProperty prop) - { - if (prop == null) return false; - EditorGUI.PropertyField(drawRect, prop, true); - var hig = EditorGUI.GetPropertyHeight(prop); - drawRect.y += hig; - heights[key] += hig; - return true; - } - - public static bool PropertyFieldWithMinValue(ref Rect drawRect, Dictionary<string, float> heights, string key, - SerializedProperty prop, float minValue) - { - if (prop == null) return false; - EditorGUI.PropertyField(drawRect, prop, true); - if (prop.propertyType == SerializedPropertyType.Float && prop.floatValue < minValue) - prop.floatValue = minValue; - if (prop.propertyType == SerializedPropertyType.Integer && prop.intValue < minValue) - prop.intValue = (int) minValue; - var hig = EditorGUI.GetPropertyHeight(prop); - drawRect.y += hig; - heights[key] += hig; - return true; - } - - public static bool PropertyFieldWithMaxValue(ref Rect drawRect, Dictionary<string, float> heights, string key, - SerializedProperty prop, float maxValue) - { - if (prop == null) return false; - EditorGUI.PropertyField(drawRect, prop, true); - if (prop.propertyType == SerializedPropertyType.Float && prop.floatValue > maxValue) - prop.floatValue = maxValue; - if (prop.propertyType == SerializedPropertyType.Integer && prop.intValue > maxValue) - prop.intValue = (int) maxValue; - var hig = EditorGUI.GetPropertyHeight(prop); - drawRect.y += hig; - heights[key] += hig; - return true; - } - - public static bool PropertyField(ref Rect drawRect, Dictionary<string, float> heights, string key, - SerializedProperty parentProp, string relativeName) - { - return PropertyField(ref drawRect, heights, key, parentProp.FindPropertyRelative(relativeName)); - } - public static bool PropertyFieldWithMinValue(ref Rect drawRect, Dictionary<string, float> heights, string key, - SerializedProperty parentProp, string relativeName, float minValue) - { - var relativeProp = parentProp.FindPropertyRelative(relativeName); - return PropertyFieldWithMinValue(ref drawRect, heights, key, relativeProp, minValue); - } - public static bool PropertyFieldWithMaxValue(ref Rect drawRect, Dictionary<string, float> heights, string key, - SerializedProperty parentProp, string relativeName, float maxValue) - { - var relativeProp = parentProp.FindPropertyRelative(relativeName); - return PropertyFieldWithMaxValue(ref drawRect, heights, key, relativeProp, maxValue); - } - - public static GUIContent GetContent(string textAndTooltip) - { - if (string.IsNullOrEmpty(textAndTooltip)) - return GUIContent.none; - - GUIContent content; - - if (!s_GUIContentCache.TryGetValue(textAndTooltip, out content)) - { - var s = textAndTooltip.Split('|'); - content = new GUIContent(s[0]); - - if (s.Length > 1 && !string.IsNullOrEmpty(s[1])) - content.tooltip = s[1]; - - s_GUIContentCache.Add(textAndTooltip, content); - } - - return content; - } - - public static void DrawSplitter() - { - var rect = GUILayoutUtility.GetRect(1f, 1f); - rect.xMin = 0f; - rect.width += 4f; - DrawSplitter(rect); - } - public static void DrawSplitter(Rect rect) - { - if (Event.current.type != EventType.Repaint) - return; - EditorGUI.DrawRect(rect, EditorCustomStyles.splitter); - } - - public static float DrawSplitterAndBackground(Rect drawRect, bool drawBackground = false) - { - float defaultWidth = drawRect.width; - float defaultX = drawRect.x; - - var splitRect = drawRect; - splitRect.y = drawRect.y; - splitRect.x = EditorGUI.indentLevel * INDENT_WIDTH + 4; - splitRect.xMax = drawRect.xMax; - splitRect.height = 1f; - - DrawSplitter(splitRect); - - if (drawBackground) - { - var bgRect = drawRect; - bgRect.y = drawRect.y; - bgRect.x -= 10 - EditorGUI.indentLevel * INDENT_WIDTH; - bgRect.xMax = drawRect.xMax; - bgRect.height = HEADER_HEIGHT + (EditorGUI.indentLevel < 1 ? 2 : 0); - EditorGUI.DrawRect(bgRect, EditorCustomStyles.headerBackground); - } - return HEADER_HEIGHT; - } - - internal static bool DrawHeader(string title, bool state, bool drawBackground, SerializedProperty activeField, - Action<Rect> drawCallback, params HeaderMenuInfo[] menus) - { - var rect = GUILayoutUtility.GetRect(1f, HEADER_HEIGHT); - var labelRect = DrawHeaderInternal(rect, title, ref state, drawBackground, activeField); - DrawMenu(rect, menus); - if (drawCallback != null) - { - drawCallback(rect); - } - var e = Event.current; - if (e.type == EventType.MouseDown) - { - if (labelRect.Contains(e.mousePosition)) - { - if (e.button == 0) - { - state = !state; - e.Use(); - } - } - } - return state; - } - - internal static bool DrawHeader(string title, bool state, bool drawBackground, SerializedProperty activeField, - Action<Rect> drawCallback, List<HeaderMenuInfo> menus) - { - var rect = GUILayoutUtility.GetRect(1f, HEADER_HEIGHT); - var labelRect = DrawHeaderInternal(rect, title, ref state, drawBackground, activeField); - DrawMenu(rect, menus); - if (drawCallback != null) - { - drawCallback(rect); - } - var e = Event.current; - if (e.type == EventType.MouseDown) - { - if (labelRect.Contains(e.mousePosition)) - { - if (e.button == 0) - { - state = !state; - e.Use(); - } - } - } - return state; - } - - private static Rect DrawHeaderInternal(Rect rect, string title, ref bool state, bool drawBackground, SerializedProperty activeField) - { - var splitRect = rect; - splitRect.x = EditorGUI.indentLevel * INDENT_WIDTH + 4; - splitRect.xMax = rect.xMax; - splitRect.height = 1f; - - var backgroundRect = rect; - backgroundRect.x = splitRect.x; - backgroundRect.xMax = rect.xMax; - - var labelRect = rect; - labelRect.xMin += 0f; - labelRect.xMax -= 35f; - - var foldoutRect = rect; - //foldoutRect.x -= 12f - EditorGUI.indentLevel * INDENT_WIDTH ; - foldoutRect.x = rect.x - FOLDOUT_WIDTH + EditorGUI.indentLevel * INDENT_WIDTH + DIFF_WIDTH; - foldoutRect.y += 1f; - foldoutRect.width = FOLDOUT_WIDTH; - foldoutRect.height = FOLDOUT_WIDTH; - - DrawSplitter(splitRect); - if (drawBackground) - EditorGUI.DrawRect(backgroundRect, EditorCustomStyles.headerBackground); - if (!string.IsNullOrEmpty(title)) - EditorGUI.LabelField(labelRect, GetContent(title)); - state = GUI.Toggle(foldoutRect, state, GUIContent.none, EditorStyles.foldout); - if (activeField != null) - { - var toggleRect = backgroundRect; - toggleRect.x = rect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * INDENT_WIDTH + GAP_WIDTH; - toggleRect.y += 1f; - toggleRect.width = 13f; - toggleRect.height = 13f; - activeField.boolValue = GUI.Toggle(toggleRect, activeField.boolValue, GUIContent.none); - } - return labelRect; - } - - internal static bool DrawHeader(string title, SerializedProperty group, SerializedProperty activeField, - Action resetAction, Action removeAction) - { - if (group == null) return false; - group.isExpanded = DrawHeader(title, group.isExpanded, false, activeField, null, - new HeaderMenuInfo("Reset", resetAction), new HeaderMenuInfo("Remove", removeAction)); - return group.isExpanded; - } - - internal static bool DrawHeader(string title, SerializedProperty group, SerializedProperty activeField, - params HeaderMenuInfo[] menus) - { - group.isExpanded = DrawHeader(title, group.isExpanded, false, activeField, null, menus); - return group.isExpanded; - } - - internal static bool DrawHeader(string title, SerializedProperty group, SerializedProperty activeField, - List<HeaderMenuInfo> menus) - { - group.isExpanded = DrawHeader(title, group.isExpanded, false, activeField, null, menus); - return group.isExpanded; - } - - internal static void DrawMenu(Rect parentRect, params HeaderMenuInfo[] menus) - { - if (menus == null || menus.Length <= 0) return; - var menuIcon = EditorCustomStyles.paneOptionsIcon; - var menuRect = new Rect(parentRect.xMax - menuIcon.width, parentRect.y + 2f, - menuIcon.width, menuIcon.height); - GUI.DrawTexture(menuRect, menuIcon); - var e = Event.current; - if (e.type == EventType.MouseDown) - { - if (menuRect.Contains(e.mousePosition)) - { - ShowHeaderContextMenu(new Vector2(menuRect.x, menuRect.yMax), menus); - e.Use(); - } - else if (parentRect.Contains(e.mousePosition)) - { - if (e.button != 0) - { - ShowHeaderContextMenu(e.mousePosition, menus); - e.Use(); - } - } - } - } - - internal static void DrawMenu(Rect parentRect, List<HeaderMenuInfo> menus) - { - if (menus == null || menus.Count <= 0) return; - var menuIcon = EditorCustomStyles.paneOptionsIcon; - var menuRect = new Rect(parentRect.xMax - menuIcon.width, parentRect.y + 2f, - menuIcon.width, menuIcon.height); - GUI.DrawTexture(menuRect, menuIcon); - var e = Event.current; - if (e.type == EventType.MouseDown) - { - if (menuRect.Contains(e.mousePosition)) - { - ShowHeaderContextMenu(new Vector2(menuRect.x, menuRect.yMax), menus); - e.Use(); - } - else if (parentRect.Contains(e.mousePosition)) - { - if (e.button != 0) - { - ShowHeaderContextMenu(e.mousePosition, menus); - e.Use(); - } - } - } - } - - static void ShowHeaderContextMenu(Vector2 position, params HeaderMenuInfo[] menus) - { - if (menus == null || menus.Length <= 0) return; - var menu = new GenericMenu(); - foreach (var info in menus) - { - if (info.enable) - menu.AddItem(GetContent(info.name), false, () => info.action()); - else - menu.AddDisabledItem(GetContent(info.name)); - } - menu.DropDown(new Rect(position, Vector2.zero)); - } - static void ShowHeaderContextMenu(Vector2 position, List<HeaderMenuInfo> menus) - { - if (menus == null || menus.Count <= 0) return; - var menu = new GenericMenu(); - foreach (var info in menus) - { - if (info.enable) - menu.AddItem(GetContent(info.name), false, () => info.action()); - else - menu.AddDisabledItem(GetContent(info.name)); - } - menu.DropDown(new Rect(position, Vector2.zero)); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs.meta b/Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs.meta deleted file mode 100644 index 570f008..0000000 --- a/Assets/XCharts/Editor/Utilities/ChartEditorHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd22466b776d93c4cb0b252ee510cc7a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Utilities/EditorStyles.cs b/Assets/XCharts/Editor/Utilities/EditorStyles.cs deleted file mode 100644 index 602a269..0000000 --- a/Assets/XCharts/Editor/Utilities/EditorStyles.cs +++ /dev/null @@ -1,32 +0,0 @@ -using UnityEditor; -using UnityEngine; - -namespace XCharts.Editor -{ - public class EditorCustomStyles - { - static readonly Color splitterDark = new Color(0.12f, 0.12f, 0.12f, 0.5f); - static readonly Color splitterLight = new Color(0.6f, 0.6f, 0.6f, 0.5f); - static readonly Texture2D paneOptionsIconDark = (Texture2D) EditorGUIUtility.Load("Builtin Skins/DarkSkin/Images/pane options.png"); - static readonly Texture2D paneOptionsIconLight = (Texture2D) EditorGUIUtility.Load("Builtin Skins/LightSkin/Images/pane options.png"); - static readonly Color headerBackgroundDark = new Color(0.1f, 0.1f, 0.1f, 0.2f); - static readonly Color headerBackgroundLight = new Color(1f, 1f, 1f, 0.2f); - - public static readonly GUIStyle headerStyle = UnityEditor.EditorStyles.boldLabel; - public static readonly GUIStyle foldoutStyle = new GUIStyle(UnityEditor.EditorStyles.foldout) - { - font = headerStyle.font, - fontStyle = headerStyle.fontStyle, - }; - public static readonly GUIContent iconAdd = new GUIContent("+", "Add"); - public static readonly GUIContent iconRemove = new GUIContent("-", "Remove"); - public static readonly GUIContent iconUp = new GUIContent("↑", "Up"); - public static readonly GUIContent iconDown = new GUIContent("↓", "Down"); - public static readonly GUIStyle invisibleButton = "InvisibleButton"; - public static readonly GUIStyle smallTickbox = new GUIStyle("ShurikenToggle"); - - public static Color splitter { get { return EditorGUIUtility.isProSkin ? splitterDark : splitterLight; } } - public static Texture2D paneOptionsIcon { get { return EditorGUIUtility.isProSkin ? paneOptionsIconDark : paneOptionsIconLight; } } - public static Color headerBackground { get { return EditorGUIUtility.isProSkin ? headerBackgroundDark : headerBackgroundLight; } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Utilities/EditorStyles.cs.meta b/Assets/XCharts/Editor/Utilities/EditorStyles.cs.meta deleted file mode 100644 index 7e7555c..0000000 --- a/Assets/XCharts/Editor/Utilities/EditorStyles.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f91656ebb897d40d49795e4701f255f9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Utilities/ThemeCheck.cs b/Assets/XCharts/Editor/Utilities/ThemeCheck.cs deleted file mode 100644 index bb31b35..0000000 --- a/Assets/XCharts/Editor/Utilities/ThemeCheck.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.IO; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - internal static class ThemeCheck - { - public class ThemeAssetPostprocessor : AssetPostprocessor - { - static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, - string[] movedFromAssetsPaths) - { - foreach (var assetPath in importedAssets) - { - CheckAddedAsset(assetPath); - } - foreach (var assetPath in deletedAssets) - { - CheckDeletedAsset(assetPath); - } - } - } - - public static void CheckAddedAsset(string assetPath) - { - var fileName = Path.GetFileName(assetPath); - if (fileName.Equals("XCSettings.asset")) - { - XCThemeMgr.ReloadThemeList(); - return; - } - if (!IsThemeAsset(assetPath)) return; - var theme = AssetDatabase.LoadAssetAtPath<Theme>(assetPath); - if (XCSettings.AddCustomTheme(theme)) - { - XCThemeMgr.ReloadThemeList(); - } - } - - public static void CheckDeletedAsset(string assetPath) - { - if (!IsThemeAsset(assetPath)) return; - if (XCSettings.Instance == null) return; - var themes = XCSettings.customThemes; - var changed = false; - - for (int i = themes.Count - 1; i >= 0; i--) - { - if (themes[i] == null) - { - themes.RemoveAt(i); - changed = true; - } - } - if (changed) - { - XCThemeMgr.ReloadThemeList(); - } - } - - private static bool IsThemeAsset(string assetPath) - { - if (!assetPath.EndsWith(".asset")) return false; - var assetName = Path.GetFileNameWithoutExtension(assetPath); - if (!assetName.StartsWith(XCSettings.THEME_ASSET_NAME_PREFIX)) return false; - return true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Utilities/ThemeCheck.cs.meta b/Assets/XCharts/Editor/Utilities/ThemeCheck.cs.meta deleted file mode 100644 index 17375c1..0000000 --- a/Assets/XCharts/Editor/Utilities/ThemeCheck.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4b4ba2a9503ae46b1b7b1ae94ec59127 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Widgets.meta b/Assets/XCharts/Editor/Widgets.meta deleted file mode 100644 index cd48390..0000000 --- a/Assets/XCharts/Editor/Widgets.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b92d575a960f54e9a9417cca092d1e11 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs b/Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs deleted file mode 100644 index 112269b..0000000 --- a/Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs +++ /dev/null @@ -1,51 +0,0 @@ -using UnityEditor; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomEditor(typeof(ProgressBar), false)] - public class ProgressBarEditor : UnityEditor.Editor - { - - [MenuItem("XCharts/ProgressBar", priority = 200)] - [MenuItem("GameObject/XCharts/ProgressBar", priority = 200)] - public static void AddPyramidChart() - { - XChartsEditor.AddChart<ProgressBar>("ProgressBar"); - } - - protected SerializedProperty m_Script; - protected SerializedProperty m_Value; - protected SerializedProperty m_BackgroundColor; - protected SerializedProperty m_StartColor; - protected SerializedProperty m_EndColor; - protected SerializedProperty m_CornerRadius; - - protected virtual void OnEnable() - { - m_Script = serializedObject.FindProperty("m_Script"); - m_Value = serializedObject.FindProperty("m_Value"); - m_BackgroundColor = serializedObject.FindProperty("m_BackgroundColor"); - m_StartColor = serializedObject.FindProperty("m_StartColor"); - m_EndColor = serializedObject.FindProperty("m_EndColor"); - m_CornerRadius = serializedObject.FindProperty("m_CornerRadius"); - } - - public override void OnInspectorGUI() - { - serializedObject.Update(); - OnStartInspectorGUI(); - serializedObject.ApplyModifiedProperties(); - } - - protected virtual void OnStartInspectorGUI() - { - EditorGUILayout.PropertyField(m_Script); - EditorGUILayout.PropertyField(m_BackgroundColor); - EditorGUILayout.PropertyField(m_StartColor); - EditorGUILayout.PropertyField(m_EndColor); - EditorGUILayout.PropertyField(m_Value); - EditorGUILayout.PropertyField(m_CornerRadius); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs.meta b/Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs.meta deleted file mode 100644 index 37bbd28..0000000 --- a/Assets/XCharts/Editor/Widgets/ProgressBarEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 17cd5e3604edc43e5b7b6bfc3c71857b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Windows.meta b/Assets/XCharts/Editor/Windows.meta deleted file mode 100644 index 6e597ab..0000000 --- a/Assets/XCharts/Editor/Windows.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ac8865193d4f548d2aaf66163c4192d9 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs b/Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs deleted file mode 100644 index 2e7667a..0000000 --- a/Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class PraseExternalDataEditor : UnityEditor.EditorWindow - { - private static BaseChart s_Chart; - private static Serie s_Serie; - private static Axis s_Axis; - private static PraseExternalDataEditor window; - private static string inputJsonText = ""; - - public static void ShowWindow() - { - window = GetWindow<PraseExternalDataEditor>(); - window.titleContent = new GUIContent("PraseExternalData"); - window.minSize = new Vector2(450, 550); - window.Focus(); - window.Show(); - } - - public static void UpdateData(BaseChart chart, Serie serie, Axis axis) - { - s_Chart = chart; - s_Serie = serie; - s_Axis = axis; - inputJsonText = UnityEngine.GUIUtility.systemCopyBuffer; - } - - void OnInspectorUpdate() - { - Repaint(); - } - - private void OnGUI() - { - if (s_Chart == null) - { - Close(); - return; - } - EditorGUILayout.LabelField("Input external data (echarts data):"); - inputJsonText = EditorGUILayout.TextArea(inputJsonText, GUILayout.Height(400)); - if (GUILayout.Button("Add")) - { - if (s_Serie != null) - { - if (!ParseArrayData(s_Serie, inputJsonText)) - { - if (ParseJsonData(s_Serie, inputJsonText)) - inputJsonText = ""; - } - else - { - inputJsonText = ""; - } - } - else if (s_Axis != null) - { - if (!ParseArrayData(s_Axis, inputJsonText)) - { - if (ParseJsonData(s_Axis, inputJsonText)) - inputJsonText = ""; - } - else - { - inputJsonText = ""; - } - } - } - } - - private static bool ParseArrayData(Axis axis, string arrayData) - { - arrayData = arrayData.Trim(); - if (!arrayData.StartsWith("data: Array")) return false; - axis.data.Clear(); - var list = arrayData.Split('\n'); - for (int i = 1; i < list.Length; i++) - { - var temp = list[i].Split(':'); - if (temp.Length == 2) - { - var category = temp[1].Replace("\"", "").Trim(); - axis.data.Add(category); - } - } - axis.SetAllDirty(); - return true; - } - - private static bool ParseArrayData(Serie serie, string arrayData) - { - arrayData = arrayData.Trim(); - if (!arrayData.StartsWith("data: Array")) return false; - serie.ClearData(); - var list = arrayData.Split('\n'); - for (int i = 1; i < list.Length; i++) - { - var temp = list[i].Split(':'); - if (temp.Length == 2) - { - var strvalue = temp[1].Replace("\"", "").Trim(); - var value = 0d; - var flag = double.TryParse(strvalue, out value); - if (flag) - { - serie.AddYData(value); - } - } - } - serie.SetAllDirty(); - return true; - } - - private static bool ParseJsonData(Axis axis, string jsonData) - { - if (!CheckJsonData(ref jsonData)) return false; - axis.data.Clear(); - string[] datas = jsonData.Split(','); - for (int i = 0; i < datas.Length; i++) - { - var txt = datas[i].Trim().Replace("[", "").Replace("]", ""); - var value = 0d; - if (!double.TryParse(txt, out value)) - axis.data.Add(txt.Replace("\'", "").Replace("\"", "")); - } - axis.SetAllDirty(); - return true; - } - - /// <summary> - /// 从json中导入数据 - /// </summary> - /// <param name="jsonData"></param> - private static bool ParseJsonData(Serie serie, string jsonData) - { - if (!CheckJsonData(ref jsonData)) return false; - serie.ClearData(); - if (jsonData.IndexOf("],") > -1 || jsonData.IndexOf("] ,") > -1) - { - string[] datas = jsonData.Split(new string[] { "],", "] ," }, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < datas.Length; i++) - { - var data = datas[i].Replace("[", "").Replace("]", "").Split(new char[] { '[', ',' }, StringSplitOptions.RemoveEmptyEntries); - var serieData = new SerieData(); - double value = 0; - if (data.Length == 2 && !double.TryParse(data[0], out value)) - { - double.TryParse(data[1], out value); - serieData.data = new List<double>() { i, value }; - serieData.name = data[0].Replace("\"", "").Trim(); - } - else - { - for (int j = 0; j < data.Length; j++) - { - var txt = data[j].Trim().Replace("]", ""); - var flag = double.TryParse(txt, out value); - if (flag) - { - serieData.data.Add(value); - } - else serieData.name = txt.Replace("\"", "").Trim(); - } - } - serie.AddSerieData(serieData); - } - } - else if (jsonData.IndexOf("value") > -1 && jsonData.IndexOf("name") > -1) - { - string[] datas = jsonData.Split(new string[] { "},", "} ,", "}" }, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < datas.Length; i++) - { - var arr = datas[i].Replace("{", "").Split(','); - var serieData = new SerieData(); - foreach (var a in arr) - { - if (a.StartsWith("value:")) - { - double value = double.Parse(a.Substring(6, a.Length - 6)); - serieData.data = new List<double>() { i, value }; - } - else if (a.StartsWith("name:")) - { - string name = a.Substring(6, a.Length - 6 - 1); - serieData.name = name; - } - else if (a.StartsWith("selected:")) - { - string selected = a.Substring(9, a.Length - 9); - serieData.selected = bool.Parse(selected); - } - } - serie.AddSerieData(serieData); - } - } - else - { - string[] datas = jsonData.Split(','); - for (int i = 0; i < datas.Length; i++) - { - double value; - var flag = double.TryParse(datas[i].Trim(), out value); - if (flag) - { - var serieData = new SerieData(); - serieData.data = new List<double>() { i, value }; - serie.AddSerieData(serieData); - } - } - } - serie.SetAllDirty(); - return true; - } - - private static bool CheckJsonData(ref string jsonData) - { - if (string.IsNullOrEmpty(jsonData)) return false; - jsonData = jsonData.Replace("\r\n", ""); - jsonData = jsonData.Replace(" ", ""); - jsonData = jsonData.Replace("\n", ""); - int startIndex = jsonData.IndexOf("["); - int endIndex = jsonData.LastIndexOf("]"); - if (startIndex == -1 || endIndex == -1) - { - Debug.LogError("json data need include in [ ]"); - return false; - } - jsonData = jsonData.Substring(startIndex + 1, endIndex - startIndex - 1); - return true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs.meta b/Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs.meta deleted file mode 100644 index 045abf1..0000000 --- a/Assets/XCharts/Editor/Windows/PraseExternalDataEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b41bbccd77d88460aba5bcf81b4920ce -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Windows/XCSettingsEditor.cs b/Assets/XCharts/Editor/Windows/XCSettingsEditor.cs deleted file mode 100644 index c03ef5b..0000000 --- a/Assets/XCharts/Editor/Windows/XCSettingsEditor.cs +++ /dev/null @@ -1,59 +0,0 @@ -using UnityEditor; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - [CustomEditor(typeof(XCSettings))] - public class XCSettingsEditor : UnityEditor.Editor - { - internal class Styles - { - public static readonly GUIContent defaultFontAssetLabel = new GUIContent("Default Font Asset", "The Font Asset that will be assigned by default to newly created text objects when no Font Asset is specified."); - public static readonly GUIContent defaultFontAssetPathLabel = new GUIContent("Path: Resources/", "The relative path to a Resources folder where the Font Assets and Material Presets are located.\nExample \"Fonts & Materials/\""); - } - } - -#if UNITY_2018_3_OR_NEWER - class XCResourceImporterProvider : SettingsProvider - { - XCResourcesImporter m_ResourceImporter; - - public XCResourceImporterProvider() : base("Project/XCharts", SettingsScope.Project) - { } - - public override void OnGUI(string searchContext) - { - if (m_ResourceImporter == null) - m_ResourceImporter = new XCResourcesImporter(); - - m_ResourceImporter.OnGUI(); - } - - public override void OnDeactivate() - { - if (m_ResourceImporter != null) - m_ResourceImporter.OnDestroy(); - } - - static UnityEngine.Object GetSettings() - { - return Resources.Load<XCSettings>("XCSettings"); - } - - [SettingsProviderGroup] - static SettingsProvider[] CreateXCSettingsProvider() - { - var providers = new System.Collections.Generic.List<SettingsProvider> { new XCResourceImporterProvider() }; - if (GetSettings() != null) - { - var provider = new AssetSettingsProvider("Project/XCharts/Settings", GetSettings); - provider.PopulateSearchKeywordsFromGUIContentProperties<XCSettingsEditor.Styles>(); - providers.Add(provider); - } - - return providers.ToArray(); - } - } -#endif -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Windows/XCSettingsEditor.cs.meta b/Assets/XCharts/Editor/Windows/XCSettingsEditor.cs.meta deleted file mode 100644 index dedbd2d..0000000 --- a/Assets/XCharts/Editor/Windows/XCSettingsEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4a1acb5e9cc3740aabbaaccd4ec9b8b8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/Windows/XChartsEditor.cs b/Assets/XCharts/Editor/Windows/XChartsEditor.cs deleted file mode 100644 index 47042a7..0000000 --- a/Assets/XCharts/Editor/Windows/XChartsEditor.cs +++ /dev/null @@ -1,197 +0,0 @@ -using UnityEditor; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XCharts.Runtime; - -namespace XCharts.Editor -{ - public class XChartsEditor : UnityEditor.Editor - { - private static Transform GetParent() - { - GameObject selectObj = Selection.activeGameObject; - if (selectObj == null) - { - var canvas = GameObject.FindObjectOfType<Canvas>(); - if (canvas != null) return canvas.transform; - else - { - var canvasObject = new GameObject(); - canvasObject.name = "Canvas"; - canvas = canvasObject.AddComponent<Canvas>(); - canvas.renderMode = RenderMode.ScreenSpaceOverlay; - canvasObject.AddComponent<CanvasScaler>(); - canvasObject.AddComponent<GraphicRaycaster>(); - var eventSystem = new GameObject(); - eventSystem.name = "EventSystem"; - eventSystem.AddComponent<EventSystem>(); - eventSystem.AddComponent<StandaloneInputModule>(); - return canvas.transform; - } - } - else - { - return selectObj.transform; - } - } - - private static string GetName(Transform parent, string name) - { - if (parent.Find(name) == null) return name; - for (int i = 1; i <= 10; i++) - { - var newName = string.Format("{0} ({1})", name, i); - if (parent.Find(newName) == null) - { - return newName; - } - } - return name; - } - - public static T AddChart<T>(string chartName) where T : BaseChart - { - var parent = GetParent(); - if (parent == null) return null; - XCThemeMgr.CheckReloadTheme(); - var chart = new GameObject(); - chart.name = GetName(parent, chartName); - var t = chart.AddComponent<T>(); - chart.transform.SetParent(parent); - chart.transform.localScale = Vector3.one; - chart.transform.localPosition = Vector3.zero; - var rect = chart.GetComponent<RectTransform>(); - rect.anchorMin = new Vector2(0.5f, 0.5f); - rect.anchorMax = new Vector2(0.5f, 0.5f); - rect.pivot = new Vector2(0.5f, 0.5f); - Selection.activeGameObject = chart; - EditorUtility.SetDirty(chart); - return t; - } - - [MenuItem("XCharts/EmptyChart", priority = 43)] - [MenuItem("GameObject/XCharts/EmptyChart", priority = 43)] - public static void AddBaseChart() - { - var chart = AddChart<BaseChart>("EmptyChart"); - chart.GetChartComponent<Title>().text = "EmptyChart"; - } - - [MenuItem("XCharts/LineChart", priority = 44)] - [MenuItem("GameObject/XCharts/LineChart", priority = 44)] - public static void AddLineChart() - { - AddChart<LineChart>("LineChart"); - } - - [MenuItem("XCharts/BarChart", priority = 45)] - [MenuItem("GameObject/XCharts/BarChart", priority = 45)] - public static void AddBarChart() - { - AddChart<BarChart>("BarChart"); - } - - [MenuItem("XCharts/PieChart", priority = 46)] - [MenuItem("GameObject/XCharts/PieChart", priority = 46)] - public static void AddPieChart() - { - AddChart<PieChart>("PieChart"); - } - - [MenuItem("XCharts/RadarChart", priority = 47)] - [MenuItem("GameObject/XCharts/RadarChart", priority = 47)] - public static void AddRadarChart() - { - AddChart<RadarChart>("RadarChart"); - } - - [MenuItem("XCharts/ScatterChart", priority = 48)] - [MenuItem("GameObject/XCharts/ScatterChart", priority = 48)] - public static void AddScatterChart() - { - AddChart<ScatterChart>("ScatterChart"); - } - - [MenuItem("XCharts/HeatmapChart", priority = 49)] - [MenuItem("GameObject/XCharts/HeatmapChart", priority = 49)] - public static void AddHeatmapChart() - { - AddChart<HeatmapChart>("HeatmapChart"); - } - - [MenuItem("XCharts/RingChart", priority = 51)] - [MenuItem("GameObject/XCharts/RingChart", priority = 51)] - public static void AddRingChart() - { - AddChart<RingChart>("RingChart"); - } - - [MenuItem("XCharts/CandlestickChart", priority = 54)] - [MenuItem("GameObject/XCharts/CandlestickChart", priority = 54)] - public static void CandlestickChart() - { - AddChart<CandlestickChart>("CandlestickChart"); - } - - [MenuItem("XCharts/PolarChart", priority = 54)] - [MenuItem("GameObject/XCharts/PolarChart", priority = 54)] - public static void PolarChart() - { - AddChart<PolarChart>("PolarChart"); - } - - [MenuItem("XCharts/ParallelChart", priority = 55)] - [MenuItem("GameObject/XCharts/ParallelChart", priority = 55)] - public static void ParallelChart() - { - AddChart<ParallelChart>("ParallelChart"); - } - - [MenuItem("XCharts/SimplifiedLineChart", priority = 56)] - [MenuItem("GameObject/XCharts/SimplifiedLineChart", priority = 56)] - public static void SimplifiedLineChart() - { - AddChart<SimplifiedLineChart>("SimplifiedLineChart"); - } - - [MenuItem("XCharts/SimplifiedBarChart", priority = 57)] - [MenuItem("GameObject/XCharts/SimplifiedBarChart", priority = 57)] - public static void SimplifiedBarChart() - { - AddChart<SimplifiedBarChart>("SimplifiedBarChart"); - } - - [MenuItem("XCharts/SimplifiedCandlestickChart", priority = 58)] - [MenuItem("GameObject/XCharts/SimplifiedCandlestickChart", priority = 58)] - public static void SimplifiedCandlestickChart() - { - AddChart<SimplifiedCandlestickChart>("SimplifiedCandlestickChart"); - } - - [MenuItem("XCharts/Themes Reload")] - public static void ReloadTheme() - { - XCThemeMgr.ReloadThemeList(); - } - - [MenuItem("XCharts/TextMeshPro Enable")] - public static void EnableTextMeshPro() - { - if (!XChartsMgr.IsExistTMPAssembly()) - { - Debug.LogError("TextMeshPro is not in the project, please import TextMeshPro package first."); - return; - } - XChartsMgr.EnableTextMeshPro(); - XChartsMgr.ModifyTMPRefence(); - } - - [MenuItem("XCharts/TextMeshPro Disable")] - public static void DisableTextMeshPro() - { - XChartsMgr.ModifyTMPRefence(true); - XChartsMgr.DisableTextMeshPro(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/Windows/XChartsEditor.cs.meta b/Assets/XCharts/Editor/Windows/XChartsEditor.cs.meta deleted file mode 100644 index 00e4a88..0000000 --- a/Assets/XCharts/Editor/Windows/XChartsEditor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 941beb76fdaa64a27a2df6561893157e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Editor/XCharts.Editor.asmdef b/Assets/XCharts/Editor/XCharts.Editor.asmdef deleted file mode 100644 index 4371b9b..0000000 --- a/Assets/XCharts/Editor/XCharts.Editor.asmdef +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "XCharts.Editor", - "references": [ - "XCharts.Runtime" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Assets/XCharts/Editor/XCharts.Editor.asmdef.meta b/Assets/XCharts/Editor/XCharts.Editor.asmdef.meta deleted file mode 100644 index a0fad90..0000000 --- a/Assets/XCharts/Editor/XCharts.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9639efc34ea6e4056830a23233b99b16 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples.meta b/Assets/XCharts/Examples.meta deleted file mode 100644 index 574f1ff..0000000 --- a/Assets/XCharts/Examples.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 0cfb5d7eeb260491b9d2545237eab7ce -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example00_CheatSheet.cs b/Assets/XCharts/Examples/Example00_CheatSheet.cs deleted file mode 100644 index 99bce3d..0000000 --- a/Assets/XCharts/Examples/Example00_CheatSheet.cs +++ /dev/null @@ -1,322 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - public class Example00_CheatSheet : MonoBehaviour - { - private LineChart chart; - private float speed = 100f; - - void Awake() - { - LoopDemo(); - } - - private void OnEnable() - { - LoopDemo(); - } - - void LoopDemo() - { - StopAllCoroutines(); - StartCoroutine(CheatSheet()); - } - - IEnumerator CheatSheet() - { - StartCoroutine(InitChart()); - StartCoroutine(ComponentTitle()); - yield return new WaitForSeconds(2); - StartCoroutine(ComponentAxis()); - yield return new WaitForSeconds(2); - StartCoroutine(ComponentGrid()); - yield return new WaitForSeconds(2); - StartCoroutine(ComponentSerie()); - yield return new WaitForSeconds(4); - StartCoroutine(ComponentLegend()); - yield return new WaitForSeconds(4); - StartCoroutine(ComponentTheme()); - yield return new WaitForSeconds(4); - StartCoroutine(ComponentDataZoom()); - yield return new WaitForSeconds(5); - StartCoroutine(ComponentVisualMap()); - yield return new WaitForSeconds(3); - LoopDemo(); - } - - IEnumerator InitChart() - { - chart = gameObject.GetComponent<LineChart>(); - if (chart == null) gameObject.AddComponent<LineChart>(); - - chart.GetChartComponent<Title>().show = true; - chart.GetChartComponent<Title>().text = "术语解析-组件"; - - var grid = chart.GetOrAddChartComponent<GridCoord>(); - grid.bottom = 30; - grid.right = 30; - grid.left = 50; - grid.top = 80; - - chart.RemoveChartComponent<VisualMap>(); - - chart.RemoveData(); - - chart.AddSerie<Bar>("Bar"); - chart.AddSerie<Line>("Line"); - - for (int i = 0; i < 8; i++) - { - chart.AddXAxisData("x" + (i + 1)); - chart.AddData(0, Random.Range(10, 100)); - chart.AddData(1, Random.Range(30, 100)); - } - yield return null; - } - - IEnumerator ComponentTitle() - { - chart.GetChartComponent<Title>().text = "术语解析 - 组件"; - chart.GetChartComponent<Title>().subText = "Title 标题:可指定主标题和子标题"; - chart.GetChartComponent<XAxis>().show = true; - chart.GetChartComponent<YAxis>().show = true; - chart.GetChartComponent<Legend>().show = false; - chart.series[0].show = false; - chart.series[1].show = false; - - for (int i = 0; i < 4; i++) - { - chart.GetChartComponent<Title>().show = !chart.GetChartComponent<Title>().show; - chart.RefreshChart(); - yield return new WaitForSeconds(0.2f); - } - chart.GetChartComponent<Title>().show = true; - chart.RefreshChart(); - } - - IEnumerator ComponentAxis() - { - chart.GetChartComponent<Title>().subText = "Axis 坐标轴:配置X和Y轴的轴线、刻度、标签等样式外观配置"; - chart.series[0].show = false; - chart.series[1].show = false; - var xAxis = chart.GetChartComponent<XAxis>(); - var yAxis = chart.GetChartComponent<YAxis>(); - for (int i = 0; i < 4; i++) - { - xAxis.show = !xAxis.show; - yAxis.show = !yAxis.show; - chart.RefreshChart(); - yield return new WaitForSeconds(0.2f); - } - xAxis.show = true; - yAxis.show = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - } - - IEnumerator ComponentGrid() - { - chart.GetChartComponent<Title>().subText = "Grid 网格:调整坐标系边距和颜色等"; - var grid = chart.GetChartComponent<GridCoord>(); - for (int i = 0; i < 4; i++) - { - grid.backgroundColor = i % 2 == 0 ? Color.clear : Color.grey; - chart.RefreshChart(); - yield return new WaitForSeconds(0.2f); - } - grid.backgroundColor = Color.clear; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - } - - IEnumerator ComponentSerie() - { - chart.GetChartComponent<Title>().subText = "Serie 系列:调整坐标系边距和颜色等"; - chart.series[0].show = true; - chart.series[1].show = true; - chart.AnimationReset(); - chart.RefreshChart(); - yield return new WaitForSeconds(1.2f); - for (int i = 0; i < 4; i++) - { - chart.series[0].show = !chart.series[0].show; - chart.series[1].show = !chart.series[1].show; - chart.RefreshChart(); - yield return new WaitForSeconds(0.2f); - } - chart.series[0].show = true; - chart.series[1].show = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - } - - IEnumerator ComponentLegend() - { - chart.GetChartComponent<Title>().subText = "Legend 图例:展示不同系列的名字和颜色,可控制系列显示等"; - var legend = chart.GetChartComponent<Legend>(); - legend.show = true; - var grid = chart.GetChartComponent<GridCoord>(); - grid.top = 80; - legend.location.top = 50; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - for (int i = 0; i < 4; i++) - { - legend.show = !legend.show; - chart.RefreshChart(); - yield return new WaitForSeconds(0.2f); - } - legend.show = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - chart.ClickLegendButton(0, "Line", false); - yield return new WaitForSeconds(0.2f); - chart.ClickLegendButton(0, "Line", true); - yield return new WaitForSeconds(0.5f); - - chart.ClickLegendButton(1, "Bar", false); - yield return new WaitForSeconds(0.2f); - chart.ClickLegendButton(1, "Bar", true); - yield return new WaitForSeconds(0.5f); - } - - IEnumerator ComponentTheme() - { - chart.GetChartComponent<Title>().subText = "Theme 主题:可从全局上配置图表的颜色、字体等效果,支持默认主题切换"; - yield return new WaitForSeconds(1f); - chart.GetChartComponent<Title>().subText = "Theme 主题:Light主题"; - chart.UpdateTheme(ThemeType.Light); - yield return new WaitForSeconds(1f); - chart.GetChartComponent<Title>().subText = "Theme 主题:Dark主题"; - chart.UpdateTheme(ThemeType.Dark); - yield return new WaitForSeconds(1f); - chart.GetChartComponent<Title>().subText = "Theme 主题:Default主题"; - chart.UpdateTheme(ThemeType.Default); - yield return new WaitForSeconds(1f); - } - - IEnumerator ComponentDataZoom() - { - chart.GetChartComponent<Title>().subText = "DataZoom 区域缩放:可通过拖、拽、缩小、放大来观察细节数据"; - var grid = chart.GetChartComponent<GridCoord>(); - grid.bottom = 70; - - var dataZoom = chart.GetOrAddChartComponent<DataZoom>(); - dataZoom.enable = true; - dataZoom.supportInside = true; - dataZoom.supportSlider = true; - dataZoom.start = 0; - dataZoom.end = 100; - - chart.RefreshChart(); - for (int i = 0; i < 4; i++) - { - dataZoom.supportSlider = !dataZoom.supportSlider; - chart.RefreshChart(); - yield return new WaitForSeconds(0.2f); - } - dataZoom.supportSlider = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - while (dataZoom.start < 40) - { - dataZoom.start += speed * Time.deltaTime * 0.8f; - chart.RefreshDataZoom(); - chart.RefreshChart(); - yield return null; - } - while (dataZoom.end > 60) - { - dataZoom.end -= speed * Time.deltaTime * 0.8f; - chart.RefreshDataZoom(); - chart.RefreshChart(); - yield return null; - } - while (dataZoom.start > 0) - { - dataZoom.start -= speed * Time.deltaTime * 0.8f; - dataZoom.end -= speed * Time.deltaTime * 0.8f; - chart.RefreshDataZoom(); - chart.RefreshChart(); - yield return null; - } - while (dataZoom.end < 100) - { - dataZoom.start += speed * Time.deltaTime * 0.8f; - dataZoom.end += speed * Time.deltaTime * 0.8f; - chart.RefreshDataZoom(); - chart.RefreshChart(); - yield return null; - } - while (dataZoom.start > 0 || dataZoom.end < 100) - { - dataZoom.start -= speed * Time.deltaTime * 0.8f; - dataZoom.end += speed * Time.deltaTime * 0.8f; - chart.RefreshDataZoom(); - chart.RefreshChart(); - yield return null; - } - } - - IEnumerator ComponentVisualMap() - { - chart.GetChartComponent<Title>().subText = "VisualMap 视觉映射:可从全局上配置图表的颜色、字体等效果,支持默认主题切换"; - - var visualMap = chart.GetOrAddChartComponent<VisualMap>(); - visualMap.show = true; - visualMap.showUI = true; - visualMap.orient = Orient.Vertical; - visualMap.calculable = true; - visualMap.min = 0; - visualMap.max = 100; - visualMap.range[0] = 0; - visualMap.range[1] = 100; - - var colors = new List<string> - { - "#313695", - "#4575b4", - "#74add1", - "#abd9e9", - "#e0f3f8", - "#ffffbf", - "#fee090", - "#fdae61", - "#f46d43", - "#d73027", - "#a50026" - }; - visualMap.AddColors(colors); - var grid = chart.GetChartComponent<GridCoord>(); - grid.left = 80; - grid.bottom = 100; - chart.RefreshChart(); - - yield return new WaitForSeconds(1f); - while (visualMap.rangeMin < 40) - { - visualMap.rangeMin += speed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - while (visualMap.rangeMax > 60) - { - visualMap.rangeMax -= speed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - while (visualMap.rangeMin > 0 || visualMap.rangeMax < 100) - { - visualMap.rangeMin -= speed * Time.deltaTime; - visualMap.rangeMax += speed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example00_CheatSheet.cs.meta b/Assets/XCharts/Examples/Example00_CheatSheet.cs.meta deleted file mode 100644 index 2cfe1ac..0000000 --- a/Assets/XCharts/Examples/Example00_CheatSheet.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 677b2673e728a4e308f26a5a9b236277 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example01_UpdateData.cs b/Assets/XCharts/Examples/Example01_UpdateData.cs deleted file mode 100644 index 171de5d..0000000 --- a/Assets/XCharts/Examples/Example01_UpdateData.cs +++ /dev/null @@ -1,46 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example01_UpdateData : MonoBehaviour - { - private float updateTime = 0; - BaseChart chart; - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - } - - void Update() - { - updateTime += Time.deltaTime; - if (chart && updateTime > 2) - { - updateTime = 0; - var serie = chart.GetSerie(0); - //serie.animation.dataChangeEnable = true; - var dataCount = serie.dataCount; - if (chart is RadarChart) - { - var dimension = serie.GetSerieData(0).data.Count - 1; - chart.UpdateData(0, 0, Random.Range(0, dimension + 1), Random.Range(0, 100)); - } - else if (chart is HeatmapChart) - { - var dimension = serie.GetSerieData(0).data.Count - 1; - for (int i = 0; i < dataCount; i++) - { - chart.UpdateData(0, i, dimension, Random.Range(0, 10)); - } - } - else - { - chart.UpdateData(0, Random.Range(0, dataCount), Random.Range(10, 90)); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example01_UpdateData.cs.meta b/Assets/XCharts/Examples/Example01_UpdateData.cs.meta deleted file mode 100644 index 827c051..0000000 --- a/Assets/XCharts/Examples/Example01_UpdateData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d369a0cba6716422cb15efa26bef0918 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example02_ChartEvent.cs b/Assets/XCharts/Examples/Example02_ChartEvent.cs deleted file mode 100644 index 59066a4..0000000 --- a/Assets/XCharts/Examples/Example02_ChartEvent.cs +++ /dev/null @@ -1,58 +0,0 @@ -using UnityEngine; -using UnityEngine.EventSystems; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example02_ChartEvent : MonoBehaviour - { - BaseChart chart; - - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<LineChart>(); - } - chart.onPointerEnter = OnPointerEnter; - chart.onPointerExit = OnPointerExit; - chart.onPointerDown = OnPointerDown; - chart.onPointerUp = OnPointerUp; - chart.onPointerClick = OnPointerClick; - chart.onScroll = OnScroll; - } - - void OnPointerEnter(PointerEventData eventData, BaseGraph chart) - { - //Debug.LogError("enter:" + chart); - } - - void OnPointerExit(PointerEventData eventData, BaseGraph chart) - { - //Debug.LogError("exit:" + chart); - } - - void OnPointerDown(PointerEventData eventData, BaseGraph chart) - { - //Debug.LogError("down:" + chart); - } - - void OnPointerUp(PointerEventData eventData, BaseGraph chart) - { - //Debug.LogError("up:" + chart); - } - - void OnPointerClick(PointerEventData eventData, BaseGraph chart) - { - //Debug.LogError("click:" + chart); - } - - void OnScroll(PointerEventData eventData, BaseGraph chart) - { - //Debug.LogError("scroll:" + chart); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example02_ChartEvent.cs.meta b/Assets/XCharts/Examples/Example02_ChartEvent.cs.meta deleted file mode 100644 index a57357a..0000000 --- a/Assets/XCharts/Examples/Example02_ChartEvent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c549dc496cd86467e8286252906562cc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example03_ChartAnimation.cs b/Assets/XCharts/Examples/Example03_ChartAnimation.cs deleted file mode 100644 index 736ff80..0000000 --- a/Assets/XCharts/Examples/Example03_ChartAnimation.cs +++ /dev/null @@ -1,37 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example03_ChartAnimation : MonoBehaviour - { - BaseChart chart; - - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<BarChart>(); - } - var serie = chart.GetSerie(0); - serie.animation.enable = true; - //自定义每个数据项的渐入延时 - serie.animation.fadeInDelayFunction = CustomFadeInDelay; - //自定义每个数据项的渐入时长 - serie.animation.fadeInDurationFunction = CustomFadeInDuration; - } - - float CustomFadeInDelay(int dataIndex) - { - return dataIndex * 1000; - } - - float CustomFadeInDuration(int dataIndex) - { - return dataIndex * 1000 + 1000; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example03_ChartAnimation.cs.meta b/Assets/XCharts/Examples/Example03_ChartAnimation.cs.meta deleted file mode 100644 index 93e6d6b..0000000 --- a/Assets/XCharts/Examples/Example03_ChartAnimation.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6258ca3b055714eac92804f501011b53 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example10_LineChart.cs b/Assets/XCharts/Examples/Example10_LineChart.cs deleted file mode 100644 index 1067b99..0000000 --- a/Assets/XCharts/Examples/Example10_LineChart.cs +++ /dev/null @@ -1,266 +0,0 @@ -using System.Collections; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - public class Example10_LineChart : MonoBehaviour - { - private LineChart chart; - private Serie serie; - private int m_DataNum = 8; - - void Awake() - { - LoopDemo(); - } - - private void OnEnable() - { - LoopDemo(); - } - - void LoopDemo() - { - StopAllCoroutines(); - StartCoroutine(PieDemo()); - } - - IEnumerator PieDemo() - { - StartCoroutine(AddSimpleLine()); - yield return new WaitForSeconds(2); - StartCoroutine(ChangeLineType()); - yield return new WaitForSeconds(8); - StartCoroutine(LineAreaStyleSettings()); - yield return new WaitForSeconds(5); - StartCoroutine(LineArrowSettings()); - yield return new WaitForSeconds(2); - StartCoroutine(LineSymbolSettings()); - yield return new WaitForSeconds(7); - StartCoroutine(LineLabelSettings()); - yield return new WaitForSeconds(3); - StartCoroutine(LineMutilSerie()); - yield return new WaitForSeconds(5); - LoopDemo(); - } - - IEnumerator AddSimpleLine() - { - chart = gameObject.GetComponent<LineChart>(); - if (chart == null) chart = gameObject.AddComponent<LineChart>(); - chart.GetChartComponent<Title>().text = "LineChart - 折线图"; - chart.GetChartComponent<Title>().subText = "普通折线图"; - - var yAxis = chart.GetChartComponent<YAxis>(); - yAxis.minMaxType = Axis.AxisMinMaxType.Custom; - yAxis.min = 0; - yAxis.max = 100; - - chart.RemoveData(); - serie = chart.AddSerie<Line>("Line"); - - for (int i = 0; i < m_DataNum; i++) - { - chart.AddXAxisData("x" + (i + 1)); - chart.AddData(0, UnityEngine.Random.Range(30, 90)); - } - yield return new WaitForSeconds(1); - } - - IEnumerator ChangeLineType() - { - chart.GetChartComponent<Title>().subText = "LineTyle - 曲线图"; - serie.lineType = LineType.Smooth; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "LineTyle - 阶梯线图"; - serie.lineType = LineType.StepStart; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - serie.lineType = LineType.StepMiddle; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - serie.lineType = LineType.StepEnd; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "LineTyle - 虚线"; - serie.lineStyle.type = LineStyle.Type.Dashed; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "LineTyle - 点线"; - serie.lineStyle.type = LineStyle.Type.Dotted; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "LineTyle - 点划线"; - serie.lineStyle.type = LineStyle.Type.DashDot; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "LineTyle - 双点划线"; - serie.lineStyle.type = LineStyle.Type.DashDotDot; - chart.RefreshChart(); - - serie.lineType = LineType.Normal; - chart.RefreshChart(); - } - - IEnumerator LineAreaStyleSettings() - { - chart.GetChartComponent<Title>().subText = "AreaStyle 面积图"; - - serie.AddExtraComponent<AreaStyle>(); - serie.areaStyle.show = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - - chart.GetChartComponent<Title>().subText = "AreaStyle 面积图"; - serie.lineType = LineType.Smooth; - serie.areaStyle.show = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1f); - - chart.GetChartComponent<Title>().subText = "AreaStyle 面积图 - 调整透明度"; - while (serie.areaStyle.opacity > 0.4) - { - serie.areaStyle.opacity -= 0.6f * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "AreaStyle 面积图 - 渐变"; - serie.areaStyle.toColor = Color.white; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - - IEnumerator LineArrowSettings() - { - chart.GetChartComponent<Title>().subText = "LineArrow 头部箭头"; - chart.GetSerie(0).AddExtraComponent<LineArrow>(); - serie.lineArrow.show = true; - serie.lineArrow.position = LineArrow.Position.Start; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "LineArrow 尾部箭头"; - serie.lineArrow.position = LineArrow.Position.End; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - serie.lineArrow.show = false; - } - - /// <summary> - /// SerieSymbol 相关设置 - /// </summary> - /// <returns></returns> - IEnumerator LineSymbolSettings() - { - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记"; - while (serie.symbol.size < 5) - { - serie.symbol.size += 2.5f * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 空心圆"; - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 实心圆"; - serie.symbol.type = SymbolType.Circle; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 三角形"; - serie.symbol.type = SymbolType.Triangle; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 正方形"; - serie.symbol.type = SymbolType.Rect; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记 - 菱形"; - serie.symbol.type = SymbolType.Diamond; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - chart.GetChartComponent<Title>().subText = "SerieSymbol 图形标记"; - serie.symbol.type = SymbolType.EmptyCircle; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - - /// <summary> - /// SerieLabel相关配置 - /// </summary> - /// <returns></returns> - IEnumerator LineLabelSettings() - { - chart.GetChartComponent<Title>().subText = "SerieLabel 文本标签"; - serie.AddExtraComponent<LabelStyle>(); - chart.RefreshChart(); - while (serie.label.offset[1] < 20) - { - serie.label.offset = new Vector3(serie.label.offset.x, serie.label.offset.y + 20f * Time.deltaTime); - chart.RefreshChart(); - yield return null; - } - yield return new WaitForSeconds(1); - - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - serie.label.textStyle.color = Color.white; - serie.label.background.color = Color.grey; - serie.labelDirty = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - serie.label.show = false; - chart.RefreshChart(); - } - - /// <summary> - /// 添加多条线图 - /// </summary> - /// <returns></returns> - IEnumerator LineMutilSerie() - { - chart.GetChartComponent<Title>().subText = "多系列"; - var serie2 = chart.AddSerie<Line>("Line2"); - serie2.lineType = LineType.Normal; - for (int i = 0; i < m_DataNum; i++) - { - chart.AddData(1, UnityEngine.Random.Range(30, 90)); - } - yield return new WaitForSeconds(1); - - var serie3 = chart.AddSerie<Line>("Line3"); - serie3.lineType = LineType.Normal; - for (int i = 0; i < m_DataNum; i++) - { - chart.AddData(2, UnityEngine.Random.Range(30, 90)); - } - yield return new WaitForSeconds(1); - - var yAxis = chart.GetChartComponent<YAxis>(); - yAxis.minMaxType = Axis.AxisMinMaxType.Default; - chart.GetChartComponent<Title>().subText = "多系列 - 堆叠"; - serie.stack = "samename"; - serie2.stack = "samename"; - serie3.stack = "samename"; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example10_LineChart.cs.meta b/Assets/XCharts/Examples/Example10_LineChart.cs.meta deleted file mode 100644 index b2fcde5..0000000 --- a/Assets/XCharts/Examples/Example10_LineChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6155c7e0df4504ebfaf0c671ae200197 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example11_AddSinCurve.cs b/Assets/XCharts/Examples/Example11_AddSinCurve.cs deleted file mode 100644 index 3149117..0000000 --- a/Assets/XCharts/Examples/Example11_AddSinCurve.cs +++ /dev/null @@ -1,62 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example11_AddSinCurve : MonoBehaviour - { - private float time; - public int angle; - private LineChart chart; - - void Awake() - { - chart = gameObject.GetComponent<LineChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<LineChart>(); - } - chart.GetChartComponent<Title>().show = true; - chart.GetChartComponent<Title>().text = "Sin Curve"; - - chart.GetChartComponent<Tooltip>().show = true; - chart.GetChartComponent<Legend>().show = false; - - var xAxis = chart.GetChartComponent<XAxis>(); - var yAxis = chart.GetChartComponent<YAxis>(); - - xAxis.show = true; - yAxis.show = true; - - xAxis.type = Axis.AxisType.Value; - yAxis.type = Axis.AxisType.Value; - - xAxis.boundaryGap = false; - xAxis.maxCache = 0; - chart.series[0].maxCache = 0; - - chart.RemoveData(); - - var serie = chart.AddSerie<Line>(); - serie.symbol.show = false; - serie.lineType = LineType.Normal; - for (angle = 0; angle < 1080; angle++) - { - float xvalue = Mathf.PI / 180 * angle; - float yvalue = Mathf.Sin(xvalue); - chart.AddData(0, xvalue, yvalue); - } - } - - void Update() - { - if (angle > 3000) return; - angle++; - float xvalue = Mathf.PI / 180 * angle; - float yvalue = Mathf.Sin(xvalue); - chart.AddData(0, xvalue, yvalue); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example11_AddSinCurve.cs.meta b/Assets/XCharts/Examples/Example11_AddSinCurve.cs.meta deleted file mode 100644 index 1f7901b..0000000 --- a/Assets/XCharts/Examples/Example11_AddSinCurve.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b380753d3cb4149c4a3a65a1816e0cc7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example12_CustomDrawing.cs b/Assets/XCharts/Examples/Example12_CustomDrawing.cs deleted file mode 100644 index ace1318..0000000 --- a/Assets/XCharts/Examples/Example12_CustomDrawing.cs +++ /dev/null @@ -1,41 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XCharts.Runtime; -using XUGL; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example12_CustomDrawing : MonoBehaviour - { - LineChart chart; - void Awake() - { - chart = gameObject.GetComponent<LineChart>(); - if (chart == null) return; - - chart.onDraw = delegate(VertexHelper vh) { }; - // or - chart.onDrawBeforeSerie = delegate(VertexHelper vh, Serie serie) { }; - // or - chart.onDrawAfterSerie = delegate(VertexHelper vh, Serie serie) - { - if (serie.index != 0) return; - var dataPoints = serie.context.dataPoints; - if (dataPoints.Count > 0) - { - var pos = dataPoints[3]; - var grid = chart.GetChartComponent<GridCoord>(); - var zeroPos = new Vector3(grid.context.x, grid.context.y); - var startPos = new Vector3(pos.x, zeroPos.y); - var endPos = new Vector3(pos.x, zeroPos.y + grid.context.height); - UGL.DrawLine(vh, startPos, endPos, chart.theme.serie.lineWidth, Color.blue); - UGL.DrawCricle(vh, pos, 5, Color.blue); - } - }; - // or - chart.onDrawTop = delegate(VertexHelper vh) { }; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example12_CustomDrawing.cs.meta b/Assets/XCharts/Examples/Example12_CustomDrawing.cs.meta deleted file mode 100644 index c81c939..0000000 --- a/Assets/XCharts/Examples/Example12_CustomDrawing.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: da550ad36be5f442e96ad021cc10ca68 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example13_LineSimple.cs b/Assets/XCharts/Examples/Example13_LineSimple.cs deleted file mode 100644 index 153ef57..0000000 --- a/Assets/XCharts/Examples/Example13_LineSimple.cs +++ /dev/null @@ -1,59 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example13_LineSimple : MonoBehaviour - { - void Awake() - { - AddData(); - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - AddData(); - } - } - - void AddData() - { - var chart = gameObject.GetComponent<SimplifiedLineChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<SimplifiedLineChart>(); - chart.Init(); - chart.SetSize(580, 300); - } - chart.GetOrAddChartComponent<Title>().show = true; - chart.GetOrAddChartComponent<Title>().text = "Line Simple"; - - chart.GetOrAddChartComponent<Tooltip>().show = true; - chart.GetOrAddChartComponent<Legend>().show = false; - - var xAxis = chart.GetOrAddChartComponent<XAxis>(); - var yAxis = chart.GetOrAddChartComponent<YAxis>(); - xAxis.show = true; - yAxis.show = true; - xAxis.type = Axis.AxisType.Category; - yAxis.type = Axis.AxisType.Value; - - xAxis.splitNumber = 10; - xAxis.boundaryGap = true; - - chart.RemoveData(); - chart.AddSerie<SimplifiedLine>(); - chart.AddSerie<SimplifiedLine>(); - for (int i = 0; i < 200; i++) - { - chart.AddXAxisData("x" + i); - chart.AddData(0, Random.Range(10, 20)); - chart.AddData(1, Random.Range(10, 20)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example13_LineSimple.cs.meta b/Assets/XCharts/Examples/Example13_LineSimple.cs.meta deleted file mode 100644 index 4587607..0000000 --- a/Assets/XCharts/Examples/Example13_LineSimple.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c6d0f65efd8e14ebdafa172e0ccbd562 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example20_BarChart.cs b/Assets/XCharts/Examples/Example20_BarChart.cs deleted file mode 100644 index 270321a..0000000 --- a/Assets/XCharts/Examples/Example20_BarChart.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System.Collections; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - public class Example20_BarChart : MonoBehaviour - { - private BarChart chart; - private Serie serie, serie2; - private int m_DataNum = 5; - - void Awake() - { - LoopDemo(); - } - - private void OnEnable() - { - LoopDemo(); - } - - void LoopDemo() - { - StopAllCoroutines(); - StartCoroutine(PieDemo()); - } - - IEnumerator PieDemo() - { - StartCoroutine(AddSimpleBar()); - yield return new WaitForSeconds(2); - StartCoroutine(BarMutilSerie()); - yield return new WaitForSeconds(3); - StartCoroutine(ZebraBar()); - yield return new WaitForSeconds(3); - StartCoroutine(SameBarAndNotStack()); - yield return new WaitForSeconds(3); - StartCoroutine(SameBarAndStack()); - yield return new WaitForSeconds(3); - StartCoroutine(SameBarAndPercentStack()); - yield return new WaitForSeconds(10); - - LoopDemo(); - } - - IEnumerator AddSimpleBar() - { - chart = gameObject.GetComponent<BarChart>(); - if (chart == null) chart = gameObject.AddComponent<BarChart>(); - chart.GetChartComponent<Title>().text = "BarChart - 柱状图"; - chart.GetChartComponent<Title>().subText = "普通柱状图"; - - var yAxis = chart.GetChartComponent<YAxis>(); - yAxis.minMaxType = Axis.AxisMinMaxType.Default; - - chart.RemoveData(); - serie = chart.AddSerie<Bar>("Bar1"); - - for (int i = 0; i < m_DataNum; i++) - { - chart.AddXAxisData("x" + (i + 1)); - chart.AddData(0, UnityEngine.Random.Range(30, 90)); - } - yield return new WaitForSeconds(1); - } - - IEnumerator BarMutilSerie() - { - chart.GetChartComponent<Title>().subText = "多条柱状图"; - - float now = serie.barWidth - 0.35f; - while (serie.barWidth > 0.35f) - { - serie.barWidth -= now * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - - serie2 = chart.AddSerie<Bar>("Bar2"); - serie2.lineType = LineType.Normal; - serie2.barWidth = 0.35f; - for (int i = 0; i < m_DataNum; i++) - { - chart.AddData(1, UnityEngine.Random.Range(20, 90)); - } - yield return new WaitForSeconds(1); - } - - IEnumerator ZebraBar() - { - chart.GetChartComponent<Title>().subText = "斑马柱状图"; - serie.barType = BarType.Zebra; - serie2.barType = BarType.Zebra; - serie.barZebraWidth = serie.barZebraGap = 4; - serie2.barZebraWidth = serie2.barZebraGap = 4; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - - IEnumerator SameBarAndNotStack() - { - chart.GetChartComponent<Title>().subText = "非堆叠同柱"; - serie.barType = serie2.barType = BarType.Normal; - serie.stack = ""; - serie2.stack = ""; - serie.barGap = -1; - serie2.barGap = -1; - yield return new WaitForSeconds(1); - } - - IEnumerator SameBarAndStack() - { - chart.GetChartComponent<Title>().subText = "堆叠同柱"; - serie.barType = serie2.barType = BarType.Normal; - serie.stack = "samename"; - serie2.stack = "samename"; - yield return new WaitForSeconds(1); - float now = 0.6f - serie.barWidth; - while (serie.barWidth < 0.6f) - { - serie.barWidth += now * Time.deltaTime; - serie2.barWidth += now * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - serie.barWidth = serie2.barWidth; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - - IEnumerator SameBarAndPercentStack() - { - chart.GetChartComponent<Title>().subText = "百分比堆叠同柱"; - serie.barType = serie2.barType = BarType.Normal; - serie.stack = "samename"; - serie2.stack = "samename"; - - serie.barPercentStack = true; - - serie.AddExtraComponent<LabelStyle>(); - serie.label.show = true; - serie.label.position = LabelStyle.Position.Center; - serie.label.textStyle.color = Color.white; - serie.label.formatter = "{d:f0}%"; - - serie2.label.show = true; - serie2.label.position = LabelStyle.Position.Center; - serie2.label.textStyle.color = Color.white; - serie2.label.formatter = "{d:f0}%"; - serie2.labelDirty = true; - - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example20_BarChart.cs.meta b/Assets/XCharts/Examples/Example20_BarChart.cs.meta deleted file mode 100644 index c5ef6fd..0000000 --- a/Assets/XCharts/Examples/Example20_BarChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 03916f7ca858b446883197ae17e50f16 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example21_BarRace.cs b/Assets/XCharts/Examples/Example21_BarRace.cs deleted file mode 100644 index c14e3ff..0000000 --- a/Assets/XCharts/Examples/Example21_BarRace.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Collections; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - public class Example21_BarRace : MonoBehaviour - { - private BarChart chart; - private float lastTime; - - void Awake() - { - chart = gameObject.GetComponent<BarChart>(); - chart.ClearData(); - for (int i = 0; i < 5; i++) - { - chart.AddYAxisData("y" + i); - chart.AddData(0, Random.Range(0, 200)); - } - } - - void Update() - { - if (Time.time - lastTime >= 3f) - { - lastTime = Time.time; - UpdateData(); - } - } - - void UpdateData() - { - var serie = chart.GetSerie(0); - - for (int i = 0; i < serie.dataCount; i++) - { - if (Random.Range(0, 1f) > 0.9f) - chart.UpdateData(0, i, chart.GetData(0, i) + Mathf.Round(Random.Range(0, 2000))); - else - chart.UpdateData(0, i, chart.GetData(0, i) + Mathf.Round(Random.Range(0, 200))); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example21_BarRace.cs.meta b/Assets/XCharts/Examples/Example21_BarRace.cs.meta deleted file mode 100644 index 70e9a19..0000000 --- a/Assets/XCharts/Examples/Example21_BarRace.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9842ca7fe07044666950b6f53ef65fdb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example30_PieChart.cs b/Assets/XCharts/Examples/Example30_PieChart.cs deleted file mode 100644 index e40f063..0000000 --- a/Assets/XCharts/Examples/Example30_PieChart.cs +++ /dev/null @@ -1,205 +0,0 @@ -using System.Collections; -using UnityEngine; -using UnityEngine.EventSystems; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - public class Example30_PieChart : MonoBehaviour - { - private PieChart chart; - private Serie serie, serie1; - private float m_RadiusSpeed = 100f; - private float m_CenterSpeed = 1f; - - void Awake() - { - LoopDemo(); - } - - private void OnEnable() - { - LoopDemo(); - } - - void LoopDemo() - { - StopAllCoroutines(); - StartCoroutine(PieDemo()); - } - - IEnumerator PieDemo() - { - StartCoroutine(PieAdd()); - yield return new WaitForSeconds(2); - StartCoroutine(PieShowLabel()); - yield return new WaitForSeconds(4); - StartCoroutine(Doughnut()); - yield return new WaitForSeconds(3); - StartCoroutine(DoublePie()); - yield return new WaitForSeconds(2); - StartCoroutine(RosePie()); - yield return new WaitForSeconds(5); - LoopDemo(); - } - - IEnumerator PieAdd() - { - chart = gameObject.GetComponent<PieChart>(); - if (chart == null) chart = gameObject.AddComponent<PieChart>(); - chart.GetChartComponent<Title>().text = "PieChart - 饼图"; - chart.GetChartComponent<Title>().subText = "基础饼图"; - - var legend = chart.GetChartComponent<Legend>(); - legend.show = true; - legend.location.align = Location.Align.TopLeft; - legend.location.top = 60; - legend.location.left = 2; - legend.itemWidth = 70; - legend.itemHeight = 20; - legend.orient = Orient.Vertical; - - chart.RemoveData(); - serie = chart.AddSerie<Bar>("访问来源"); - serie.radius[0] = 0; - serie.radius[1] = 110; - serie.center[0] = 0.5f; - serie.center[1] = 0.4f; - chart.AddData(0, 335, "直接访问"); - chart.AddData(0, 310, "邮件营销"); - chart.AddData(0, 243, "联盟广告"); - chart.AddData(0, 135, "视频广告"); - chart.AddData(0, 1548, "搜索引擎"); - - chart.onPointerClickPie = delegate(PointerEventData e, int serieIndex, int dataIndex) - { - - }; - yield return new WaitForSeconds(1); - } - - IEnumerator PieShowLabel() - { - chart.GetChartComponent<Title>().subText = "显示文本标签"; - - serie.AddExtraComponent<LabelStyle>(); - serie.label.show = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - serie.labelLine.lineType = LabelLine.LineType.Curves; - chart.RefreshChart(); - - yield return new WaitForSeconds(1); - serie.labelLine.lineType = LabelLine.LineType.HorizontalLine; - chart.RefreshChart(); - - yield return new WaitForSeconds(1); - serie.labelLine.lineType = LabelLine.LineType.BrokenLine; - chart.RefreshChart(); - - yield return new WaitForSeconds(1); - serie.labelLine.show = false; - chart.RefreshChart(); - } - - IEnumerator Doughnut() - { - chart.GetChartComponent<Title>().subText = "圆环图"; - serie.radius[0] = 2f; - while (serie.radius[0] < serie.radius[1] * 0.7f) - { - serie.radius[0] += m_RadiusSpeed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - serie.gap = 1f; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - serie.data[0].selected = true; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - - serie.gap = 0f; - serie.data[0].selected = false; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - - IEnumerator DoublePie() - { - chart.GetChartComponent<Title>().subText = "多图组合"; - - serie1 = chart.AddSerie<Pie>("访问来源2"); - chart.AddData(1, 335, "直达"); - chart.AddData(1, 679, "营销广告"); - chart.AddData(1, 1548, "搜索引擎"); - serie1.radius[0] = 0; - serie1.radius[1] = 2f; - serie1.center[0] = 0.5f; - serie1.center[1] = 0.4f; - chart.RefreshChart(); - while (serie1.radius[1] < serie.radius[0] * 0.75f) - { - serie1.radius[1] += m_RadiusSpeed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - - serie1.label.show = true; - serie1.label.position = LabelStyle.Position.Inside; - serie1.label.textStyle.color = Color.white; - serie1.label.textStyle.fontSize = 14; - - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - - IEnumerator RosePie() - { - chart.GetChartComponent<Title>().subText = "玫瑰图"; - chart.GetChartComponent<Legend>().show = false; - serie1.ClearData(); - serie.ClearData(); - serie1.radius = serie.radius = new float[2] { 0, 80 }; - serie1.label.position = LabelStyle.Position.Outside; - serie1.labelLine.lineType = LabelLine.LineType.Curves; - serie1.label.textStyle.color = Color.clear; - for (int i = 0; i < 2; i++) - { - chart.AddData(i, 10, "rose1"); - chart.AddData(i, 5, "rose2"); - chart.AddData(i, 15, "rose3"); - chart.AddData(i, 25, "rose4"); - chart.AddData(i, 20, "rose5"); - chart.AddData(i, 35, "rose6"); - chart.AddData(i, 30, "rose7"); - chart.AddData(i, 40, "rose8"); - } - - while (serie.center[0] > 0.25f || serie1.center[0] < 0.7f) - { - if (serie.center[0] > 0.25f) serie.center[0] -= m_CenterSpeed * Time.deltaTime; - if (serie1.center[0] < 0.7f) serie1.center[0] += m_CenterSpeed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - yield return new WaitForSeconds(1); - while (serie.radius[0] > 3f) - { - serie.radius[0] -= m_RadiusSpeed * Time.deltaTime; - serie1.radius[0] -= m_RadiusSpeed * Time.deltaTime; - chart.RefreshChart(); - yield return null; - } - - serie.radius[0] = 0; - serie1.radius[0] = 0; - serie.pieRoseType = RoseType.Area; - serie1.pieRoseType = RoseType.Radius; - chart.RefreshChart(); - yield return new WaitForSeconds(1); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example30_PieChart.cs.meta b/Assets/XCharts/Examples/Example30_PieChart.cs.meta deleted file mode 100644 index fb74aa5..0000000 --- a/Assets/XCharts/Examples/Example30_PieChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0b8649d38981b4b5bbdf16e8f303fa1e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example31_PieUpdateName.cs b/Assets/XCharts/Examples/Example31_PieUpdateName.cs deleted file mode 100644 index 8509105..0000000 --- a/Assets/XCharts/Examples/Example31_PieUpdateName.cs +++ /dev/null @@ -1,74 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example31_PieUpdateName : MonoBehaviour - { - PieChart chart; - - void Awake() - { - chart = gameObject.GetComponent<PieChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<PieChart>(); - } - var serieIndex = 0; - var serie = chart.GetSerie(serieIndex); - if (serie == null) return; - serie.AddExtraComponent<LabelStyle>(); - serie.label.show = true; - serie.label.position = LabelStyle.Position.Outside; - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - ClearAndAddData(); - //UpdateDataName(); - //UpdateDataName(); - } - } - - void UpdateDataName() - { - var serieIndex = 0; - var serie = chart.GetSerie(serieIndex); - if (serie == null) return; - for (int i = 0; i < serie.dataCount; i++) - { - var value = Random.Range(10, 100); - chart.UpdateData(serieIndex, i, value); - chart.UpdateDataName(serieIndex, i, "value=" + value); - } - } - - void ResetSameName() - { - var serieIndex = 0; - var serie = chart.GetSerie(serieIndex); - if (serie == null) return; - for (int i = 0; i < serie.dataCount; i++) - { - chart.UpdateDataName(serieIndex, i, "piename"); - } - } - - void ClearAndAddData() - { - var serieIndex = 0; - var serie = chart.GetSerie(serieIndex); - if (serie == null) return; - int count = serie.dataCount; - serie.ClearData(); - for (int i = 0; i < count; i++) - { - chart.AddData(0, Random.Range(0, 100), "pie" + i); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example31_PieUpdateName.cs.meta b/Assets/XCharts/Examples/Example31_PieUpdateName.cs.meta deleted file mode 100644 index 2afd8a2..0000000 --- a/Assets/XCharts/Examples/Example31_PieUpdateName.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 41195ee7a652f4ef79c22c365d314621 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example40_Radar.cs b/Assets/XCharts/Examples/Example40_Radar.cs deleted file mode 100644 index f33dc25..0000000 --- a/Assets/XCharts/Examples/Example40_Radar.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - public class Example40_Radar : MonoBehaviour - { - private RadarChart chart; - private Serie serie, serie1; - void Awake() - { - LoopDemo(); - } - - private void OnEnable() - { - LoopDemo(); - } - - void LoopDemo() - { - StopAllCoroutines(); - StartCoroutine(RadarDemo()); - } - - IEnumerator RadarDemo() - { - StartCoroutine(RadarAdd()); - yield return new WaitForSeconds(2); - StartCoroutine(RadarUpdate()); - yield return new WaitForSeconds(2); - StartCoroutine(RadarAddMultiple()); - yield return new WaitForSeconds(2); - LoopDemo(); - } - - IEnumerator RadarAdd() - { - chart = gameObject.GetComponent<RadarChart>(); - if (chart == null) chart = gameObject.AddComponent<RadarChart>(); - - chart.RemoveChartComponents<RadarCoord>(); - chart.RemoveData(); - - chart.GetChartComponent<Title>().text = "RadarChart - 雷达图"; - chart.GetChartComponent<Title>().subText = ""; - - var legend = chart.GetChartComponent<Legend>(); - legend.show = true; - legend.location.align = Location.Align.TopLeft; - legend.location.top = 60; - legend.location.left = 2; - legend.itemWidth = 70; - legend.itemHeight = 20; - legend.orient = Orient.Vertical; - - var radarCoord = chart.AddChartComponent<RadarCoord>(); - radarCoord.shape = RadarCoord.Shape.Polygon; - radarCoord.center[0] = 0.5f; - radarCoord.center[1] = 0.4f; - radarCoord.radius = 0.4f; - - radarCoord.AddIndicator("indicator1", 0, 100); - radarCoord.AddIndicator("indicator2", 0, 100); - radarCoord.AddIndicator("indicator3", 0, 100); - radarCoord.AddIndicator("indicator4", 0, 100); - radarCoord.AddIndicator("indicator5", 0, 100); - - serie = chart.AddSerie<Radar>("test"); - serie.radarIndex = 0; - chart.AddData(0, new List<double> { 10, 20, 60, 40, 20 }, "data1"); - chart.AddData(0, new List<double> { 40, 60, 90, 80, 70 }, "data2"); - yield return new WaitForSeconds(1); - } - - IEnumerator RadarUpdate() - { - var radarCoord = chart.GetChartComponent<RadarCoord>(); - radarCoord.UpdateIndicator(0, "new1", 0, 100); - chart.UpdateData(0, 0, new List<double> { 15, 30, 50, 60, 50 }); - chart.UpdateDataName(0, 0, "new1"); - yield return new WaitForSeconds(1); - } - - IEnumerator RadarAddMultiple() - { - chart.RemoveChartComponents<RadarCoord>(); - chart.RemoveData(); - - chart.GetChartComponent<Title>().text = "RadarChart - 多雷达图"; - chart.GetChartComponent<Title>().subText = ""; - - var legend = chart.GetChartComponent<Legend>(); - legend.show = true; - legend.location.align = Location.Align.TopLeft; - legend.location.top = 60; - legend.location.left = 2; - legend.itemWidth = 70; - legend.itemHeight = 20; - legend.orient = Orient.Vertical; - - var radarCoord = chart.AddChartComponent<RadarCoord>(); - radarCoord.shape = RadarCoord.Shape.Polygon; - radarCoord.center[0] = 0.25f; - radarCoord.center[1] = 0.4f; - radarCoord.radius = 0.25f; - for (int i = 1; i <= 5; i++) - { - radarCoord.AddIndicator("radar1" + i, 0, 100); - } - - var radarCoord2 = chart.AddChartComponent<RadarCoord>(); - radarCoord2.shape = RadarCoord.Shape.Polygon; - radarCoord2.center[0] = 0.75f; - radarCoord2.center[1] = 0.4f; - radarCoord2.radius = 0.25f; - for (int i = 1; i <= 5; i++) - { - radarCoord2.AddIndicator("radar2" + i, 0, 100); - } - - serie = chart.AddSerie<Radar>("test1"); - serie.radarIndex = 0; - chart.AddData(0, new List<double> { 10, 20, 60, 40, 20 }, "data1"); - - serie1 = chart.AddSerie<Radar>("test2"); - serie1.radarIndex = 1; - chart.AddData(1, new List<double> { 10, 20, 60, 40, 20 }, "data2"); - yield return new WaitForSeconds(1); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example40_Radar.cs.meta b/Assets/XCharts/Examples/Example40_Radar.cs.meta deleted file mode 100644 index 2421445..0000000 --- a/Assets/XCharts/Examples/Example40_Radar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 95a60d7e7a0fc41ecaec5f48823b70bd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example41_RadarUpdate.cs b/Assets/XCharts/Examples/Example41_RadarUpdate.cs deleted file mode 100644 index baaa46b..0000000 --- a/Assets/XCharts/Examples/Example41_RadarUpdate.cs +++ /dev/null @@ -1,73 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example41_RadarUpdate : MonoBehaviour - { - RadarChart chart; - int count = 0; - double max = 0; - - void Awake() - { - chart = gameObject.GetComponent<RadarChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<RadarChart>(); - } - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - UpdateData(); - count++; - } - UpdateMax(); - } - - void UpdateData() - { - var serieIndex = 0; - var serie = chart.GetSerie(serieIndex); - if (serie == null) return; - if (serie.radarType == RadarType.Multiple) - { - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.GetSerieData(i); - for (int j = 0; j < serieData.data.Count; j++) - { - var value = Random.Range(10, 100); - chart.UpdateData(serieIndex, i, j, value); - } - } - } - else - { - for (int i = 0; i < serie.dataCount; i++) - { - var value = Random.Range(10, 100); - chart.UpdateData(serieIndex, i, value); - } - } - chart.GetChartComponent<Title>().subText = "max:" + serie.context.dataMax; - } - - void UpdateMax() - { - var serieIndex = 0; - var serie = chart.GetSerie(serieIndex); - if (serie == null) return; - if (serie.context.dataMax != max) - { - chart.GetChartComponent<Title>().subText = "max:" + serie.context.dataMax; - max = serie.context.dataMax; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example41_RadarUpdate.cs.meta b/Assets/XCharts/Examples/Example41_RadarUpdate.cs.meta deleted file mode 100644 index b0a750e..0000000 --- a/Assets/XCharts/Examples/Example41_RadarUpdate.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7a2ad6907bd5045ec920b4f0e359535e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example50_Scatter.cs b/Assets/XCharts/Examples/Example50_Scatter.cs deleted file mode 100644 index 74b8d6c..0000000 --- a/Assets/XCharts/Examples/Example50_Scatter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example50_Scatter : MonoBehaviour - { - private ScatterChart chart; - - void Awake() - { - chart = gameObject.GetComponent<ScatterChart>(); - if (chart == null) return; - foreach (var serie in chart.series) - { - serie.symbol.sizeFunction = SymbolSize; - serie.symbol.selectedSizeFunction = SymbolSelectedSize; - } - } - - float SymbolSize(List<double> data) - { - return (float) (Math.Sqrt(data[2]) / 6e2); - } - - float SymbolSelectedSize(List<double> data) - { - return (float) (Math.Sqrt(data[2]) / 5e2); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example50_Scatter.cs.meta b/Assets/XCharts/Examples/Example50_Scatter.cs.meta deleted file mode 100644 index 62269c7..0000000 --- a/Assets/XCharts/Examples/Example50_Scatter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5e6c9b864ab644b45ae93df3878ab1dd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example60_Heatmap.cs b/Assets/XCharts/Examples/Example60_Heatmap.cs deleted file mode 100644 index 9627324..0000000 --- a/Assets/XCharts/Examples/Example60_Heatmap.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example60_Heatmap : MonoBehaviour - { - private HeatmapChart chart; - - void Awake() - { - chart = gameObject.GetComponent<HeatmapChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<HeatmapChart>(); - } - chart.GetChartComponent<Title>().text = "HeatmapChart"; - chart.GetChartComponent<Tooltip>().type = Tooltip.Type.None; - - var grid = chart.GetChartComponent<GridCoord>(); - grid.left = 100; - grid.right = 60; - grid.bottom = 60; - - var xAxis = chart.GetChartComponent<XAxis>(); - var yAxis = chart.GetChartComponent<YAxis>(); - //目前只支持Category - xAxis.type = Axis.AxisType.Category; - yAxis.type = Axis.AxisType.Category; - - xAxis.boundaryGap = true; - xAxis.boundaryGap = true; - - xAxis.splitNumber = 10; - yAxis.splitNumber = 10; - - //清空数据重新添加 - chart.RemoveData(); - var serie = chart.AddSerie<Heatmap>("serie1"); - - //设置样式 - serie.itemStyle.show = true; - serie.itemStyle.borderWidth = 1; - serie.itemStyle.borderColor = Color.clear; - - //设置高亮样式 - serie.AddExtraComponent<EmphasisItemStyle>(); - serie.emphasisItemStyle.show = true; - serie.emphasisItemStyle.borderWidth = 1; - serie.emphasisItemStyle.borderColor = Color.black; - - //设置视觉映射组件 - var visualMap = chart.GetChartComponent<VisualMap>(); - visualMap.max = 10; - visualMap.range[0] = 0f; - visualMap.range[1] = 10f; - visualMap.orient = Orient.Vertical; - visualMap.calculable = true; - visualMap.location.align = Location.Align.BottomLeft; - visualMap.location.bottom = 100; - visualMap.location.left = 30; - - //清空颜色重新添加 - - var heatmapGridWid = 10f; - int xSplitNumber = (int) (grid.context.width / heatmapGridWid); - int ySplitNumber = (int) (grid.context.height / heatmapGridWid); - var colors = new List<string> - { - "#313695", - "#4575b4", - "#74add1", - "#abd9e9", - "#e0f3f8", - "#ffffbf", - "#fee090", - "#fdae61", - "#f46d43", - "#d73027", - "#a50026" - }; - visualMap.AddColors(colors); - //添加xAxis的数据 - for (int i = 0; i < xSplitNumber; i++) - { - chart.AddXAxisData((i + 1).ToString()); - } - //添加yAxis的数据 - for (int i = 0; i < ySplitNumber; i++) - { - chart.AddYAxisData((i + 1).ToString()); - } - for (int i = 0; i < xSplitNumber; i++) - { - for (int j = 0; j < ySplitNumber; j++) - { - var value = 0f; - var rate = Random.Range(0, 101); - if (rate > 70) value = Random.Range(8f, 10f); - else value = Random.Range(1f, 8f); - var list = new List<double> { i, j, value }; - //至少是一个三位数据:(x,y,value) - chart.AddData(0, list); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example60_Heatmap.cs.meta b/Assets/XCharts/Examples/Example60_Heatmap.cs.meta deleted file mode 100644 index 9ec94e3..0000000 --- a/Assets/XCharts/Examples/Example60_Heatmap.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e702e0ac05be84dbe9622180d4f6ef71 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example80_Polar.cs b/Assets/XCharts/Examples/Example80_Polar.cs deleted file mode 100644 index fdfb0b0..0000000 --- a/Assets/XCharts/Examples/Example80_Polar.cs +++ /dev/null @@ -1,52 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example80_Polar : MonoBehaviour - { - private BaseChart chart; - private float updateTime; - - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<BaseChart>(); - } - chart.GetOrAddChartComponent<PolarCoord>(); - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - AddData(); - } - } - - void AddData() - { - chart.RemoveData(); - chart.GetChartComponent<Tooltip>().type = Tooltip.Type.Corss; - var angleAxis = chart.GetChartComponent<AngleAxis>(); - angleAxis.type = Axis.AxisType.Value; - angleAxis.minMaxType = Axis.AxisMinMaxType.Custom; - angleAxis.min = 0; - angleAxis.max = 360; - angleAxis.startAngle = Random.Range(0, 90); - chart.AddSerie<Line>("line1"); - - var rate = Random.Range(1, 4); - for (int i = 0; i <= 360; i++) - { - var t = i / 180f * Mathf.PI; - var r = Mathf.Sin(2 * t) * Mathf.Cos(2 * t) * rate; - chart.AddData(0, Mathf.Abs(r), i); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example80_Polar.cs.meta b/Assets/XCharts/Examples/Example80_Polar.cs.meta deleted file mode 100644 index ea734cf..0000000 --- a/Assets/XCharts/Examples/Example80_Polar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ca29783da761a4e0e9c5204d5b24b610 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example90_Candlestick.cs b/Assets/XCharts/Examples/Example90_Candlestick.cs deleted file mode 100644 index 895e305..0000000 --- a/Assets/XCharts/Examples/Example90_Candlestick.cs +++ /dev/null @@ -1,68 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example90_Candlestick : MonoBehaviour - { - private CandlestickChart chart; - private float updateTime; - public int dataCount = 100; - - void Awake() - { - chart = gameObject.GetComponent<CandlestickChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<CandlestickChart>(); - } - GenerateOHLC(dataCount); - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - AddData(); - } - } - - void AddData() { } - - void GenerateOHLC(int count) - { - chart.ClearData(); - - var xValue = System.DateTime.Now; - var baseValue = Random.Range(0f, 1f) * 12000; - var boxVals = new float[4]; - var dayRange = 12; - - for (int i = 0; i < count; i++) - { - baseValue = baseValue + Random.Range(0f, 1f) * 30 - 10; - for (int j = 0; j < 4; j++) - { - boxVals[j] = (Random.Range(0f, 1f) - 0.5f) * dayRange + baseValue; - } - System.Array.Sort(boxVals); - var openIdx = Mathf.RoundToInt(Random.Range(0f, 1f) * 3); - var closeIdx = Mathf.RoundToInt(Random.Range(0f, 1f) * 2); - if (openIdx == closeIdx) - { - closeIdx++; - } - //var volumn = boxVals[3]*(1000+Random.Range(0f,1f) * 500); - var open = boxVals[openIdx]; - var close = boxVals[closeIdx]; - var lowest = boxVals[0]; - var heighest = boxVals[3]; - - chart.AddXAxisData(i.ToString()); - chart.AddData(0, open, close, lowest, heighest); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example90_Candlestick.cs.meta b/Assets/XCharts/Examples/Example90_Candlestick.cs.meta deleted file mode 100644 index 189a372..0000000 --- a/Assets/XCharts/Examples/Example90_Candlestick.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 69c7f3bf337c843888b4a7031eef1027 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_AddChart.cs b/Assets/XCharts/Examples/Example_AddChart.cs deleted file mode 100644 index 8035976..0000000 --- a/Assets/XCharts/Examples/Example_AddChart.cs +++ /dev/null @@ -1,66 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - //[ExecuteInEditMode] - public class Example_AddChart : MonoBehaviour - { - BaseChart chart; - void Awake() - { - //AddChart(); - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - AddChart(); - } - } - - void AddChart() - { - chart = gameObject.GetComponent<BaseChart>(); - if (chart == null) - { - chart = gameObject.AddComponent<LineChart>(); - chart.Init(); - chart.SetSize(1200, 600); - } - var title = chart.GetOrAddChartComponent<Title>(); - title.text = "Simple LineChart"; - title.subText = "normal line"; - - var tooltip = chart.GetOrAddChartComponent<Tooltip>(); - tooltip.show = true; - - var legend = chart.GetOrAddChartComponent<Legend>(); - legend.show = false; - - var xAxis = chart.GetOrAddChartComponent<XAxis>(); - xAxis.splitNumber = 10; - xAxis.boundaryGap = true; - xAxis.type = Axis.AxisType.Category; - - var yAxis = chart.GetOrAddChartComponent<YAxis>(); - yAxis.type = Axis.AxisType.Value; - - chart.RemoveData(); - chart.AddSerie<Line>("line"); - - for (int i = 0; i < 5; i++) - { - chart.AddXAxisData("x" + i); - chart.AddData(0, Random.Range(10, 20)); - } - } - - void ModifyComponent() - { - - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_AddChart.cs.meta b/Assets/XCharts/Examples/Example_AddChart.cs.meta deleted file mode 100644 index 2fdb2ea..0000000 --- a/Assets/XCharts/Examples/Example_AddChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8e5c24ed461624b8d924dfb1285e0a95 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_Component.cs b/Assets/XCharts/Examples/Example_Component.cs deleted file mode 100644 index 9847c97..0000000 --- a/Assets/XCharts/Examples/Example_Component.cs +++ /dev/null @@ -1,35 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - //[ExecuteInEditMode] - public class Example_Component : MonoBehaviour - { - BaseChart chart; - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - } - - void ModifyComponent() - { - var title = chart.GetOrAddChartComponent<Title>(); - title.text = "Simple LineChart"; - title.subText = "normal line"; - - var serie1 = chart.AddSerie<Line>(); - //var serie2 = chart.GetSerie<Line>(); - - serie1.AddExtraComponent<AreaStyle>(); - var label = serie1.AddExtraComponent<LabelStyle>(); - label.offset = new Vector3(0, 20, 0); - - var serieData = chart.AddData(0, 20); - serieData.radius = 10; - var itemStyle = serieData.GetOrAddComponent<ItemStyle>(); - itemStyle.color = Color.blue; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_Component.cs.meta b/Assets/XCharts/Examples/Example_Component.cs.meta deleted file mode 100644 index add53bc..0000000 --- a/Assets/XCharts/Examples/Example_Component.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2e9941e7d67e44b18899e6048d4ef25a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_Dynamic.cs b/Assets/XCharts/Examples/Example_Dynamic.cs deleted file mode 100644 index e2a2f94..0000000 --- a/Assets/XCharts/Examples/Example_Dynamic.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - //[ExecuteInEditMode] - [RequireComponent(typeof(BaseChart))] - public class Example_Dynamic : MonoBehaviour - { - public int maxCacheDataNumber = 100; - public float initDataTime = 2; - public bool insertDataToHead = true; - - private BaseChart chart; - private float updateTime; - private float initTime; - private int initCount; - private int count; - private bool isInited; - private DateTime timeNow; - - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - var serie = chart.GetSerie(0); - serie.symbol.show = false; - serie.maxCache = maxCacheDataNumber; - - var xAxis = chart.GetOrAddChartComponent<XAxis>(); - xAxis.maxCache = maxCacheDataNumber; - timeNow = DateTime.Now; - timeNow = timeNow.AddSeconds(-maxCacheDataNumber); - - serie.insertDataToHead = insertDataToHead; - xAxis.insertDataToHead = insertDataToHead; - } - - void Update() - { - if (initCount < maxCacheDataNumber) - { - int count = (int) (maxCacheDataNumber / initDataTime * Time.deltaTime); - for (int i = 0; i < count; i++) - { - timeNow = timeNow.AddSeconds(1); - var category = timeNow.ToString("hh:mm:ss"); - var value = UnityEngine.Random.Range(60, 150); - chart.AddXAxisData(category); - chart.AddData(0, value); - initCount++; - if (initCount > maxCacheDataNumber) break; - } - chart.RefreshChart(); - } - updateTime += Time.deltaTime; - if (updateTime >= 1) - { - var category = DateTime.Now.ToString("hh:mm:ss"); - var value = UnityEngine.Random.Range(60, 150); - updateTime = 0; - count++; - chart.AddXAxisData(category); - chart.AddData(0, value); - chart.RefreshChart(); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_Dynamic.cs.meta b/Assets/XCharts/Examples/Example_Dynamic.cs.meta deleted file mode 100644 index 4dd42ea..0000000 --- a/Assets/XCharts/Examples/Example_Dynamic.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 310037ac5daa645058285cf176cc9eab -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_LargeData.cs b/Assets/XCharts/Examples/Example_LargeData.cs deleted file mode 100644 index 6165c14..0000000 --- a/Assets/XCharts/Examples/Example_LargeData.cs +++ /dev/null @@ -1,52 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - [RequireComponent(typeof(BaseChart))] - public class Example_LargeData : MonoBehaviour - { - public int maxCacheDataNumber = 1000; - public float initDataTime = 5; - - private BaseChart chart; - private float initTime; - private int initCount = 0; - private System.DateTime timeNow; - - void Awake() - { - chart = gameObject.GetComponentInChildren<BaseChart>(); - timeNow = System.DateTime.Now; - chart.ClearData(); - chart.SetMaxCache(maxCacheDataNumber); - chart.GetChartComponent<Title>().text = maxCacheDataNumber + "数据"; - } - - private double lastValue = 0d; - - private void Update() - { - if (initCount < maxCacheDataNumber) - { - for (int i = 0; i < 20; i++) - { - initCount++; - if (initCount > maxCacheDataNumber) break; - chart.GetChartComponent<Title>().text = initCount + "数据"; - - timeNow = timeNow.AddSeconds(1); - if (lastValue < 20) - lastValue += UnityEngine.Random.Range(0, 5); - else - lastValue += UnityEngine.Random.Range(-5f, 5f); - chart.AddData(0, lastValue); - - chart.AddXAxisData(timeNow.ToString("hh:mm:ss")); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_LargeData.cs.meta b/Assets/XCharts/Examples/Example_LargeData.cs.meta deleted file mode 100644 index f832dd3..0000000 --- a/Assets/XCharts/Examples/Example_LargeData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 188d38c155a804c7d9d31730d3b12885 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_PieChart.cs b/Assets/XCharts/Examples/Example_PieChart.cs deleted file mode 100644 index 173b55c..0000000 --- a/Assets/XCharts/Examples/Example_PieChart.cs +++ /dev/null @@ -1,40 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - [RequireComponent(typeof(PieChart))] - public class Example_PieChart : MonoBehaviour - { - private PieChart chart; - private float time; - private int count = 0; - - private void Awake() - { - chart = transform.GetComponent<PieChart>(); - chart.ClearData(); - } - - private void Update() - { - time += Time.deltaTime; - if (time > 1) - { - time = 0; - if (count < 5) - { - chart.AddData(0, Random.Range(10, 100), "time" + count); - } - else - { - int index = count % 5; - chart.UpdateData(0, Random.Range(10, 100), index); - } - count++; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_PieChart.cs.meta b/Assets/XCharts/Examples/Example_PieChart.cs.meta deleted file mode 100644 index 925d44c..0000000 --- a/Assets/XCharts/Examples/Example_PieChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a36ce96ed11a24212aafad603286a3ad -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_Test.cs b/Assets/XCharts/Examples/Example_Test.cs deleted file mode 100644 index f105bc7..0000000 --- a/Assets/XCharts/Examples/Example_Test.cs +++ /dev/null @@ -1,66 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example_Test : MonoBehaviour - { - BaseChart chart; - void Awake() - { - chart = gameObject.GetComponent<BaseChart>(); - var btnTrans = transform.parent.Find("Button"); - if (btnTrans) - { - btnTrans.gameObject.GetComponent<Button>().onClick.AddListener(OnTestBtn); - } - } - - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - AddData(); - //OnTestBtn(); - } - } - - void OnTestBtn() - { - object[][] m_TestData = new object[][] - { - new object[] { "01/06/20", 2.2d, 5.6d }, - new object[] { "22/06/20", 2.4d, 5.3d }, - new object[] { "04/08/21", 4.5d, 5.4d }, - new object[] { "05/08/21", 6.3d, 6.4d }, - new object[] { "06/08/21", 3.1d, 6.4d }, - new object[] { "09/08/21", 3.9d, 6.3d }, - new object[] { "10/08/21", 1.9d, 4.6d }, - }; - chart.ClearData(); - foreach (var list in m_TestData) - { - chart.AddXAxisData((string) list[0]); - chart.AddData(0, (double) list[1]); - chart.AddData(1, (double) list[2]); - } - } - - void AddData() - { - chart.ClearData(); - int count = Random.Range(5, 100); - for (int i = 0; i < count; i++) - { - chart.AddXAxisData("x" + i); - if (Random.Range(1, 3) == 2) - chart.AddData(0, Random.Range(-110, 200)); - else - chart.AddData(0, Random.Range(-100, 100)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_Test.cs.meta b/Assets/XCharts/Examples/Example_Test.cs.meta deleted file mode 100644 index 7ee7459..0000000 --- a/Assets/XCharts/Examples/Example_Test.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bac63bf58d06d47be8e1759189fbd9ed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/Example_TestTime.cs b/Assets/XCharts/Examples/Example_TestTime.cs deleted file mode 100644 index 59f813d..0000000 --- a/Assets/XCharts/Examples/Example_TestTime.cs +++ /dev/null @@ -1,50 +0,0 @@ -using UnityEngine; -using XCharts.Runtime; - -namespace XCharts.Example -{ - [DisallowMultipleComponent] - [ExecuteInEditMode] - public class Example_TestTime : MonoBehaviour - { - public int maxCache = 100; - LineChart chart; - int timestamp; - void Awake() - { - chart = gameObject.GetComponent<LineChart>(); - AddData(); - chart.SetMaxCache(maxCache); - } - - float m_LastTime = 0; - double m_Value = 100; - void Update() - { - if (Input.GetKeyDown(KeyCode.Space)) - { - //AddData(); - } - if (Time.time - m_LastTime > 0.1f) - { - timestamp += 3600; - m_Value += 10; - chart.AddData(0, timestamp, m_Value); - m_LastTime = Time.time; - - } - } - - void AddData() - { - chart.ClearData(); - timestamp = DateTimeUtil.GetTimestamp() - 10; - for (int i = 0; i < 10; i++) - { - timestamp += i * 3600; - double value = Random.Range(50, 200); - chart.AddData(0, timestamp, value); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/Example_TestTime.cs.meta b/Assets/XCharts/Examples/Example_TestTime.cs.meta deleted file mode 100644 index 98f3d2d..0000000 --- a/Assets/XCharts/Examples/Example_TestTime.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 43b48222f7ffc420098593a8fe4bfc24 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Examples/XCharts.Examples.asmdef b/Assets/XCharts/Examples/XCharts.Examples.asmdef deleted file mode 100644 index 638b296..0000000 --- a/Assets/XCharts/Examples/XCharts.Examples.asmdef +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "XCharts.Examples", - "references": [ - "XCharts.Runtime" - ], - "optionalUnityReferences": [], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [] -} \ No newline at end of file diff --git a/Assets/XCharts/Examples/XCharts.Examples.asmdef.meta b/Assets/XCharts/Examples/XCharts.Examples.asmdef.meta deleted file mode 100644 index 454b078..0000000 --- a/Assets/XCharts/Examples/XCharts.Examples.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9ca8daef375784f86b76407e76c9045a -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/LICENSE.md b/Assets/XCharts/LICENSE.md deleted file mode 100644 index f250a04..0000000 --- a/Assets/XCharts/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 - 2022 monitor1394 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Assets/XCharts/LICENSE.md.meta b/Assets/XCharts/LICENSE.md.meta deleted file mode 100644 index 6a70383..0000000 --- a/Assets/XCharts/LICENSE.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: effab8d087eba4ef1957a08a3607a0b1 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/README.md b/Assets/XCharts/README.md deleted file mode 100644 index 4f5bfd4..0000000 --- a/Assets/XCharts/README.md +++ /dev/null @@ -1,153 +0,0 @@ -<p align="center"> - <a href=""> - <img src="" alt="" width="" height=""> - </a> -</p> -<h2 align="center">XCharts</h3> -<p align="center"> - A powerful, easy-to-use, configurable charting and data visualization library for Unity. - <br> - Unity数据可视化图表插件。 - <br> - <a href="Documentation/README-EN.md">English README</a> -</p> -<p align="center"> - <a href="https://github.com/XCharts-Team/XCharts/blob/master/LICENSE"> - <img src="https://img.shields.io/github/license/XCharts-Team/XCharts"> - </a> - <a href="https://github.com/XCharts-Team/XCharts/releases"> - <img src="https://img.shields.io/github/v/release/XCharts-Team/XCharts?include_prereleases"> - </a> - <a href=""> - <img src="https://img.shields.io/github/repo-size/monitor1394/unity-ugui-xcharts"> - </a> - <a href=""> - <img src="https://img.shields.io/github/languages/code-size/monitor1394/unity-ugui-xcharts"> - </a> - <a href=""> - <img src="https://img.shields.io/badge/Unity-5.6+-green"> - </a> - <a href=""> - <img src="https://img.shields.io/badge/TextMeshPro-YES-green"> - </a> -</p> -<p align="center"> - <a href=""> - <img src="https://img.shields.io/github/stars/XCharts-Team/XCharts?style=social"> - </a> - <a href=""> - <img src="https://img.shields.io/github/forks/XCharts-Team/XCharts?style=social"> - </a> - <a href=""> - <img src="https://img.shields.io/github/issues-closed/XCharts-Team/XCharts?color=green&label=%20%20%20%20issues&logoColor=green&style=social"> - </a> -</p> - -一款基于`UGUI`的功能强大、易用、参数可配置的数据可视化图表插件。支持`折线图`、`柱状图`、`饼图`、`雷达图`、`散点图`、`热力图`、`环形图`、`K线图`、`极坐标`、`平行坐标`等十种常见免费内置图表,以及`3D饼图`、`3D柱图`、`3D金字塔`、`漏斗图`、`仪表盘`、`水位图`、`象形柱图`、`甘特图`、`矩形树图`等多种扩展图表。 - -[XCharts3.0 教程](Documentation/XChartsTutorial01-ZH.md) -[XCharts3.0 API](Documentation/XChartsAPI-ZH.md) -[XCharts3.0 问答](Documentation/XChartsFAQ-ZH.md) -[XCharts3.0 配置项手册](Documentation/XChartsConfiguration-ZH.md) -[XCharts3.0 更新日志](CHANGELOG.md) -[XCharts3.0 订阅服务](Documentation/SUPPORT.md) - -## 特性 - -- 参数可视化配置,效果实时预览,纯代码绘制,无需额外资源。 -- 支持折线图、柱状图、饼图、雷达图、散点图、热力图、环形图、K线图、极坐标、平行坐标等十种常见免费内置图表。 -- 支持3D柱图、漏斗图、金字塔、仪表盘、水位图、象形柱图、甘特图、矩形树图等多种付费扩展图表。 -- 支持直线图、曲线图、面积图、阶梯线图等折线图。 -- 支持并列柱图、堆叠柱图、堆积百分比柱图、斑马柱图等柱状图。 -- 支持环形图、玫瑰图等饼图。 -- 支持内置图表的任意组合,同一图表中可同时显示多个相同或不同类型的图表。 -- 支持实线、曲线、阶梯线、虚线、点线、点划线、双点划线等线条。 -- 支持主题定制、导入和导出,内置两种默认主题。 -- 支持自定义图表内容绘制,提供绘制点、直线、曲线、三角形、四边形、圆形、环形、扇形、边框、箭头等强大的绘图API。 -- 支持PC端和手机端上的数据筛选、视图缩放、细节展示等交互操作。 -- 支持万级大数据绘制。 -- 支持`TexMeshPro`。 - -## `XCharts3.0` 新功能 - -- 增加`Time`时间轴。 -- 增加`SingleAxis`单轴。 -- 增加多种坐标系:`Grid`、`Polar`、`Radar`、`SingleAxis`。 -- 增加多种动画方式。 -- 增加多种图表交互。 -- 增加国际化支持。 -- 增加`Widgets`小组件。 -- 增加多种扩展图表。 - -## `XCharts3.0` 相比 `XCharts2.0` 的改进 - -- 更健壮的底层框架。 -- 更强大的性能。 -- 更小的序列化文件。 -- 更好的交互体验。 -- 更多的组件支持。 -- 更强大的文本自述能力。 -- 更合理的组件调整。 -- 更灵活的组件插拔。 -- 更高效的二次开发。 -- 更丰富的Demo示例。 - -## `XCharts3.0` 和 `2.0` 数据对比 - -| Case | XCharts2.0 | XCharts3.0 | Note | -| -- | -- | -- | -- | -| 2000数据折线图的帧频 | `20` | `83` | 性能提升 `3` 倍 | -| 2000数据折线图的顶点数 | `36.5k` | `6.7k` | 顶点数减少 `4` 倍 | -| 2000数据折线图的Prefab大小 | `11.1MB` | `802KB` | 序列化文件大小减少 `10` 倍 | -| 单条折线图数据最大容量 | `4.1k` | `19k` | 单Serie数据容量提升 `4` 倍 | -| 支持的图表 | `11种` |`23种` | 支持的图表多 `1` 倍 | - -## 注意 - -- `XCharts3.0` 不兼容 `XCharts2.0` 版本,建议旧项目还是继续使用`XCharts2.0`,新项目使用`XCharts3.0`。 -- `XCharts2.0` 进入维护阶段,后续只修复严重`bug`,理论上不再加新功能。 -- `XCharts` 理论上支持`Unity 5.6`及以上版本,但由于版本测试有限难免疏漏,发现版本兼容问题可提`Issue`。 -- `XCharts` 内置图表都为常见的图表,可以免费使用;扩展图表大部分为不常使用的图表,有需要的可付费获取,详情[☞ 看这里](Documentation/SUPPORT.md) -- 本仓库只包含`XCharts`源码,不包含`Demo`示例部分。需要查看`Demo`示例请到[XCharts-Demo](https://github.com/XCharts-Team/XCharts-Demo) - -## 截图 - -![buildinchart](https://github.com/XCharts-Team/XCharts-Demo/blob/master/buildinchart.png) - -![extendchart](https://github.com/XCharts-Team/XCharts-Demo/blob/master/extendchart.png) - -更多示例请看 [XCharts-Demo](https://github.com/XCharts-Team/XCharts-Demo),也可以到 [在线Demo](https://xcharts-team.github.io/demo/) 查看`WebGL`下的运行效果。 - -## 使用 - -1. 导入`XCharts`的`unitypackage`或者源码到项目 -2. 在`Hierarchy`视图下右键选择`XCharts->LineChart`,即可创建一个默认的折线图 -3. 在`Inspector`试图可以调整各个组件的参数,并在`Game`视图看到实时效果 - -更多教程请看:[XCharts教程:5分钟上手教程](Documentation/XChartsTutorial01-ZH.md) - -## FAQ - -1. `XCharts`可以免费使用吗? - 答:`XCharts`使用`MIT`协议,可以免费使用。也可以订阅`VIP`享受更多增值服务。 - -2. `XCharts`支持代码动态添加和修改数据吗?支持从`Excel`或数据库中获取数据吗? - 答:支持代码动态添加和修改数据,但数据需要自己解析或获取,再调用`XCharts`的接口添加到`XCharts`。 - -3. 这个插件除了用在`Unity`,还能用在其他平台(如`Winform`或`WPF`)吗? - 答:目前只支持在`Unity`平台使用。理论上任何支持`UGUI`的`Unity`版本都能运行`XCharts`。 - -## 日志 - -[更新日志](CHANGELOG.md) - -## Licenses - -[MIT License](LICENSE.md) - -## 其他 - -邮箱:`monitor1394@gmail.com` -QQ群:XCharts交流群(`202030963`) -VIP群:XCharts技术支持VIP群(`867291970`) -捐助和技术支持:[☞ 看这里](Documentation/SUPPORT.md) diff --git a/Assets/XCharts/README.md.meta b/Assets/XCharts/README.md.meta deleted file mode 100644 index 760d09c..0000000 --- a/Assets/XCharts/README.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 393c8e8ab781b4041b141f93eb407380 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Resources.meta b/Assets/XCharts/Resources.meta index f5614c7..7803051 100644 --- a/Assets/XCharts/Resources.meta +++ b/Assets/XCharts/Resources.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 0e3168b99564b477a83640c24b713f0c +guid: a43c1f1e0de3e3148a7cc011f18d325c folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/XCharts/Resources/XCLang-EN.asset.meta b/Assets/XCharts/Resources/XCLang-EN.asset.meta index e0f7d44..478b6de 100644 --- a/Assets/XCharts/Resources/XCLang-EN.asset.meta +++ b/Assets/XCharts/Resources/XCLang-EN.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cfc5541268f414098950441fd8b6f4a7 +guid: 7ab75e442ccc331448579ee488a0e2f6 NativeFormatImporter: externalObjects: {} mainObjectFileID: 11400000 diff --git a/Assets/XCharts/Resources/XCLang-ZH.asset.meta b/Assets/XCharts/Resources/XCLang-ZH.asset.meta index f638b16..b77cc14 100644 --- a/Assets/XCharts/Resources/XCLang-ZH.asset.meta +++ b/Assets/XCharts/Resources/XCLang-ZH.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 79b252423c47d4cf380e489ed55e05d4 +guid: 06876e51e2b667f46bcffcffac65e222 NativeFormatImporter: externalObjects: {} mainObjectFileID: 0 diff --git a/Assets/XCharts/Resources/XCSettings.asset.meta b/Assets/XCharts/Resources/XCSettings.asset.meta index c83763d..4a251ee 100644 --- a/Assets/XCharts/Resources/XCSettings.asset.meta +++ b/Assets/XCharts/Resources/XCSettings.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 676e1e322123d4fe2a761de3ef14235f +guid: 8c6e30c5091a0514792d53e02d529a7e NativeFormatImporter: externalObjects: {} mainObjectFileID: 0 diff --git a/Assets/XCharts/Resources/XCTheme-Dark.asset.meta b/Assets/XCharts/Resources/XCTheme-Dark.asset.meta index c6e8422..adb9a84 100644 --- a/Assets/XCharts/Resources/XCTheme-Dark.asset.meta +++ b/Assets/XCharts/Resources/XCTheme-Dark.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 289d2fc7f4ce24f73b9ed8ec52639f72 +guid: 2d6d9eb3b43d4a94e98f3bf183836b70 NativeFormatImporter: externalObjects: {} mainObjectFileID: 0 diff --git a/Assets/XCharts/Resources/XCTheme-Default.asset.meta b/Assets/XCharts/Resources/XCTheme-Default.asset.meta index 059fff7..e733fc2 100644 --- a/Assets/XCharts/Resources/XCTheme-Default.asset.meta +++ b/Assets/XCharts/Resources/XCTheme-Default.asset.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: e1dc23a10de1e4c5dbfbaf74c4dfd218 +guid: 0e489d624f47a3f4092d9e9e574eb883 NativeFormatImporter: externalObjects: {} mainObjectFileID: 11400000 diff --git a/Assets/XCharts/Runtime.meta b/Assets/XCharts/Runtime.meta deleted file mode 100644 index bfcc193..0000000 --- a/Assets/XCharts/Runtime.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b33410c335fd5440483c5cabb05c3e5d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart.meta b/Assets/XCharts/Runtime/Chart.meta deleted file mode 100644 index 8fe8fd6..0000000 --- a/Assets/XCharts/Runtime/Chart.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 900b05585ba864df1aa05dcdb36b324b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/BarChart.cs b/Assets/XCharts/Runtime/Chart/BarChart.cs deleted file mode 100644 index 65cb0d7..0000000 --- a/Assets/XCharts/Runtime/Chart/BarChart.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/BarChart", 14)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class BarChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - AddChartComponentWhenNoExist<XAxis>(); - AddChartComponentWhenNoExist<YAxis>(); - - var tooltip = GetOrAddChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Shadow; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - Bar.AddDefaultSerie(this, GenerateDefaultSerieName()); - for (int i = 0; i < 5; i++) - { - AddXAxisData("x" + (i + 1)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/BarChart.cs.meta b/Assets/XCharts/Runtime/Chart/BarChart.cs.meta deleted file mode 100644 index 76be77d..0000000 --- a/Assets/XCharts/Runtime/Chart/BarChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 535d2697503c2a94a887354e22a5414d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/CandlestickChart.cs b/Assets/XCharts/Runtime/Chart/CandlestickChart.cs deleted file mode 100644 index be7e026..0000000 --- a/Assets/XCharts/Runtime/Chart/CandlestickChart.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/CandlestickChart", 23)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class CandlestickChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - AddChartComponentWhenNoExist<XAxis>(); - AddChartComponentWhenNoExist<YAxis>(); - - var tooltip = GetOrAddChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Shadow; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - var serie = Candlestick.AddDefaultSerie(this, GenerateDefaultSerieName()); - for (int i = 0; i < serie.dataCount; i++) - { - AddXAxisData("x" + (i + 1)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/CandlestickChart.cs.meta b/Assets/XCharts/Runtime/Chart/CandlestickChart.cs.meta deleted file mode 100644 index 359211c..0000000 --- a/Assets/XCharts/Runtime/Chart/CandlestickChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7b64f0bb738cc4acfa72fff2c30212b4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/HeatmapChart.cs b/Assets/XCharts/Runtime/Chart/HeatmapChart.cs deleted file mode 100644 index 421ae09..0000000 --- a/Assets/XCharts/Runtime/Chart/HeatmapChart.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/HeatmapChart", 18)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class HeatmapChart : BaseChart - { - protected override void DefaultChart() - { - var tooltip = GetChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.None; - tooltip.trigger = Tooltip.Trigger.Axis; - - var grid = GetOrAddChartComponent<GridCoord>(); - grid.left = 0.12f; - - var xAxis = GetOrAddChartComponent<XAxis>(); - xAxis.type = Axis.AxisType.Category; - xAxis.boundaryGap = true; - xAxis.splitNumber = 10; - - var yAxis = GetOrAddChartComponent<YAxis>(); - yAxis.type = Axis.AxisType.Category; - yAxis.boundaryGap = true; - yAxis.splitNumber = 10; - RemoveData(); - - var heatmapGridWid = 10f; - int xSplitNumber = (int) (grid.context.width / heatmapGridWid); - int ySplitNumber = (int) (grid.context.height / heatmapGridWid); - - Heatmap.AddDefaultSerie(this, GenerateDefaultSerieName()); - - var visualMap = GetOrAddChartComponent<VisualMap>(); - visualMap.max = 10; - visualMap.range[0] = 0f; - visualMap.range[1] = 10f; - visualMap.orient = Orient.Vertical; - visualMap.calculable = true; - visualMap.location.align = Location.Align.BottomLeft; - visualMap.location.bottom = 100; - visualMap.location.left = 30; - var colors = new List<string> - { - "#313695", - "#4575b4", - "#74add1", - "#abd9e9", - "#e0f3f8", - "#ffffbf", - "#fee090", - "#fdae61", - "#f46d43", - "#d73027", - "#a50026" - }; - visualMap.AddColors(colors); - for (int i = 0; i < xSplitNumber; i++) - { - xAxis.data.Add((i + 1).ToString()); - } - for (int i = 0; i < ySplitNumber; i++) - { - yAxis.data.Add((i + 1).ToString()); - } - for (int i = 0; i < xSplitNumber; i++) - { - for (int j = 0; j < ySplitNumber; j++) - { - var value = 0f; - var rate = Random.Range(0, 101); - if (rate > 70) value = Random.Range(8f, 10f); - else value = Random.Range(1f, 8f); - var list = new List<double> { i, j, value }; - AddData(0, list); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/HeatmapChart.cs.meta b/Assets/XCharts/Runtime/Chart/HeatmapChart.cs.meta deleted file mode 100644 index 0cceaa5..0000000 --- a/Assets/XCharts/Runtime/Chart/HeatmapChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 31aa03cd4ce594c239ae746791b3b59f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/LineChart.cs b/Assets/XCharts/Runtime/Chart/LineChart.cs deleted file mode 100644 index c5317f5..0000000 --- a/Assets/XCharts/Runtime/Chart/LineChart.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/LineChart", 13)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class LineChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - AddChartComponentWhenNoExist<XAxis>(); - AddChartComponentWhenNoExist<YAxis>(); - - var tooltip = GetOrAddChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Line; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - Line.AddDefaultSerie(this, GenerateDefaultSerieName()); - for (int i = 0; i < 5; i++) - { - AddXAxisData("x" + (i + 1)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/LineChart.cs.meta b/Assets/XCharts/Runtime/Chart/LineChart.cs.meta deleted file mode 100644 index f345666..0000000 --- a/Assets/XCharts/Runtime/Chart/LineChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b4f38bd00b4648c448cabfc167538f7c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/ParallelChart.cs b/Assets/XCharts/Runtime/Chart/ParallelChart.cs deleted file mode 100644 index 63abdf6..0000000 --- a/Assets/XCharts/Runtime/Chart/ParallelChart.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/ParallelChart", 25)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class ParallelChart : BaseChart - { - protected override void DefaultChart() - { - RemoveData(); - AddChartComponent<ParallelCoord>(); - - for (int i = 0; i < 3; i++) - { - var valueAxis = AddChartComponent<ParallelAxis>(); - valueAxis.type = Axis.AxisType.Value; - } - var categoryAxis = AddChartComponent<ParallelAxis>(); - categoryAxis.type = Axis.AxisType.Category; - categoryAxis.position = Axis.AxisPosition.Right; - categoryAxis.data = new List<string>() { "x1", "x2", "x3", "x4", "x5" }; - - Parallel.AddDefaultSerie(this, GenerateDefaultSerieName()); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/ParallelChart.cs.meta b/Assets/XCharts/Runtime/Chart/ParallelChart.cs.meta deleted file mode 100644 index e2e2f61..0000000 --- a/Assets/XCharts/Runtime/Chart/ParallelChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 161753d0d6ce541c89483f8c3a21343f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/PieChart.cs b/Assets/XCharts/Runtime/Chart/PieChart.cs deleted file mode 100644 index f6ef9d3..0000000 --- a/Assets/XCharts/Runtime/Chart/PieChart.cs +++ /dev/null @@ -1,20 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/PieChart", 15)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class PieChart : BaseChart - { - protected override void DefaultChart() - { - var legend = GetOrAddChartComponent<Legend>(); - legend.show = true; - - RemoveData(); - Pie.AddDefaultSerie(this, GenerateDefaultSerieName()); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/PieChart.cs.meta b/Assets/XCharts/Runtime/Chart/PieChart.cs.meta deleted file mode 100644 index a2a53c5..0000000 --- a/Assets/XCharts/Runtime/Chart/PieChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d44276ba809fd92408b296835f6f7658 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/PolarChart.cs b/Assets/XCharts/Runtime/Chart/PolarChart.cs deleted file mode 100644 index 580efb9..0000000 --- a/Assets/XCharts/Runtime/Chart/PolarChart.cs +++ /dev/null @@ -1,33 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/PolarChart", 23)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class PolarChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<PolarCoord>(); - AddChartComponentWhenNoExist<AngleAxis>(); - AddChartComponentWhenNoExist<RadiusAxis>(); - - var tooltip = GetChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Corss; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - var serie = Line.AddDefaultSerie(this, GenerateDefaultSerieName()); - serie.SetCoord<PolarCoord>(); - serie.ClearData(); - for (int i = 0; i <= 360; i++) - { - var t = i / 180f * Mathf.PI; - var r = Mathf.Sin(2 * t) * Mathf.Cos(2 * t) * 2; - AddData(0, Mathf.Abs(r), i); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/PolarChart.cs.meta b/Assets/XCharts/Runtime/Chart/PolarChart.cs.meta deleted file mode 100644 index 29ae5a6..0000000 --- a/Assets/XCharts/Runtime/Chart/PolarChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 574bcbd917fc148e8bb8735acda07f77 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/RadarChart.cs b/Assets/XCharts/Runtime/Chart/RadarChart.cs deleted file mode 100644 index ca01353..0000000 --- a/Assets/XCharts/Runtime/Chart/RadarChart.cs +++ /dev/null @@ -1,19 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/RadarChart", 16)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class RadarChart : BaseChart - { - protected override void DefaultChart() - { - RemoveData(); - RemoveChartComponents<RadarCoord>(); - AddChartComponent<RadarCoord>(); - Radar.AddDefaultSerie(this, GenerateDefaultSerieName()); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/RadarChart.cs.meta b/Assets/XCharts/Runtime/Chart/RadarChart.cs.meta deleted file mode 100644 index 2e638a3..0000000 --- a/Assets/XCharts/Runtime/Chart/RadarChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d2231a0d3e3a5b043b074f6739be4a86 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/RingChart.cs b/Assets/XCharts/Runtime/Chart/RingChart.cs deleted file mode 100644 index ae04dd2..0000000 --- a/Assets/XCharts/Runtime/Chart/RingChart.cs +++ /dev/null @@ -1,18 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/RingChart", 20)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class RingChart : BaseChart - { - protected override void DefaultChart() - { - GetChartComponent<Tooltip>().type = Tooltip.Type.Line; - RemoveData(); - Ring.AddDefaultSerie(this, GenerateDefaultSerieName()); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/RingChart.cs.meta b/Assets/XCharts/Runtime/Chart/RingChart.cs.meta deleted file mode 100644 index a46c903..0000000 --- a/Assets/XCharts/Runtime/Chart/RingChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0ad8949f652ee4376a4a4fe5cb32029f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/ScatterChart.cs b/Assets/XCharts/Runtime/Chart/ScatterChart.cs deleted file mode 100644 index a6ce4d9..0000000 --- a/Assets/XCharts/Runtime/Chart/ScatterChart.cs +++ /dev/null @@ -1,31 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/ScatterChart", 17)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class ScatterChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - - var tooltip = GetOrAddChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.None; - tooltip.trigger = Tooltip.Trigger.Item; - - var xAxis = GetOrAddChartComponent<XAxis>(); - xAxis.type = Axis.AxisType.Value; - xAxis.boundaryGap = false; - - var yAxis = GetOrAddChartComponent<YAxis>(); - yAxis.type = Axis.AxisType.Value; - yAxis.boundaryGap = false; - - RemoveData(); - Scatter.AddDefaultSerie(this, GenerateDefaultSerieName()); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/ScatterChart.cs.meta b/Assets/XCharts/Runtime/Chart/ScatterChart.cs.meta deleted file mode 100644 index efbd890..0000000 --- a/Assets/XCharts/Runtime/Chart/ScatterChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bf16aac0bd6c24a8da75846c34c5193e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs b/Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs deleted file mode 100644 index f2079b3..0000000 --- a/Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/SimplifiedBarChart", 27)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class SimplifiedBarChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - AddChartComponentWhenNoExist<XAxis>(); - AddChartComponentWhenNoExist<YAxis>(); - - var tooltip = GetChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Line; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - SimplifiedBar.AddDefaultSerie(this, GenerateDefaultSerieName()); - for (int i = 0; i < GetSerie(0).dataCount; i++) - { - AddXAxisData("x" + (i + 1)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs.meta b/Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs.meta deleted file mode 100644 index 7dcf138..0000000 --- a/Assets/XCharts/Runtime/Chart/SimplifiedBarChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aa86c3bbf8877409c9d45716fbaf92f4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs b/Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs deleted file mode 100644 index 0d2d8ef..0000000 --- a/Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/SimplifiedCandlestickChart", 28)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class SimplifiedCandlestickChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - AddChartComponentWhenNoExist<XAxis>(); - AddChartComponentWhenNoExist<YAxis>(); - - var tooltip = GetChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Shadow; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - SimplifiedCandlestick.AddDefaultSerie(this, GenerateDefaultSerieName()); - for (int i = 0; i < GetSerie(0).dataCount; i++) - { - AddXAxisData("x" + (i + 1)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs.meta b/Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs.meta deleted file mode 100644 index 26ff0a3..0000000 --- a/Assets/XCharts/Runtime/Chart/SimplifiedCandlestickChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6dcc9bd1ca8344d938f386e6b32e8946 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs b/Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs deleted file mode 100644 index 4553cbb..0000000 --- a/Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs +++ /dev/null @@ -1,29 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/SimplifiedLineChart", 26)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class SimplifiedLineChart : BaseChart - { - protected override void DefaultChart() - { - AddChartComponentWhenNoExist<GridCoord>(); - AddChartComponentWhenNoExist<XAxis>(); - AddChartComponentWhenNoExist<YAxis>(); - - var tooltip = GetChartComponent<Tooltip>(); - tooltip.type = Tooltip.Type.Line; - tooltip.trigger = Tooltip.Trigger.Axis; - - RemoveData(); - SimplifiedLine.AddDefaultSerie(this, GenerateDefaultSerieName()); - for (int i = 0; i < GetSerie(0).dataCount; i++) - { - AddXAxisData("x" + (i + 1)); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs.meta b/Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs.meta deleted file mode 100644 index 0ab5605..0000000 --- a/Assets/XCharts/Runtime/Chart/SimplifiedLineChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a8233997c1b324ecd875a03af4d90972 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component.meta b/Assets/XCharts/Runtime/Component.meta deleted file mode 100644 index 73353b5..0000000 --- a/Assets/XCharts/Runtime/Component.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3be5f1d3b129a47dd8e41cffe3b8e428 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Animation.meta b/Assets/XCharts/Runtime/Component/Animation.meta deleted file mode 100644 index 4c94e65..0000000 --- a/Assets/XCharts/Runtime/Component/Animation.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 9f827513754e8436bbc63e64c5b5e6c3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs b/Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs deleted file mode 100644 index 00761b4..0000000 --- a/Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs +++ /dev/null @@ -1,630 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public enum AnimationType - { - /// <summary> - /// he default. An animation playback mode will be selected according to the actual situation. - /// |默认。内部会根据实际情况选择一种动画播放方式。 - /// </summary> - Default, - /// <summary> - /// Play the animation from left to right. - /// |从左往右播放动画。 - /// </summary> - LeftToRight, - /// <summary> - /// Play the animation from bottom to top. - /// |从下往上播放动画。 - /// </summary> - BottomToTop, - /// <summary> - /// Play animations from the inside out. - /// |由内到外播放动画。 - /// </summary> - InsideOut, - /// <summary> - /// Play the animation along the path. - /// |沿着路径播放动画。 - /// </summary> - AlongPath, - /// <summary> - /// Play the animation clockwise. - /// |顺时针播放动画。 - /// </summary> - Clockwise, - } - - public enum AnimationEasing - { - Linear, - } - - /// <summary> - /// the animation of serie. - /// |动画表现。 - /// </summary> - [System.Serializable] - public class AnimationStyle : ChildComponent - { - [SerializeField] private bool m_Enable = true; - [SerializeField] private AnimationType m_Type; - [SerializeField] private AnimationEasing m_Easting; - [SerializeField] private int m_Threshold = 2000; - [SerializeField] private float m_FadeInDuration = 1000; - [SerializeField] private float m_FadeInDelay = 0; - [SerializeField] private float m_FadeOutDuration = 1000f; - [SerializeField] private float m_FadeOutDelay = 0; - [SerializeField] private bool m_DataChangeEnable = true; - [SerializeField] private float m_DataChangeDuration = 500; - [SerializeField] private float m_ActualDuration; - /// <summary> - /// 自定义渐入动画延时函数。返回ms值。 - /// </summary> - public AnimationDelayFunction fadeInDelayFunction; - /// <summary> - /// 自定义渐入动画时长函数。返回ms值。 - /// </summary> - public AnimationDurationFunction fadeInDurationFunction; - /// <summary> - /// 自定义渐出动画延时函数。返回ms值。 - /// </summary> - public AnimationDelayFunction fadeOutDelayFunction; - /// <summary> - /// 自定义渐出动画时长函数。返回ms值。 - /// </summary> - public AnimationDurationFunction fadeOutDurationFunction; - public AnimationStyleContext context = new AnimationStyleContext(); - - /// <summary> - /// Whether to enable animation. - /// |是否开启动画效果。 - /// </summary> - public bool enable { get { return m_Enable; } set { m_Enable = value; } } - /// <summary> - /// The type of animation. - /// |动画类型。 - /// </summary> - public AnimationType type { get { return m_Type; } set { m_Type = value; } } - /// <summary> - /// Easing method used for the first animation. - /// |动画的缓动效果。 - /// </summary> - //public Easing easting { get { return m_Easting; } set { m_Easting = value; } } - /// <summary> - /// The milliseconds duration of the fadeIn animation. - /// |设定的渐入动画时长(毫秒)。如果要设置单个数据项的渐入时长,可以用代码定制:customFadeInDuration。 - /// </summary> - public float fadeInDuration { get { return m_FadeInDuration; } set { m_FadeInDuration = value < 0 ? 0 : value; } } - /// <summary> - /// The milliseconds duration of the fadeOut animation. - /// |设定的渐出动画时长(毫秒)。如果要设置单个数据项的渐出时长,可以用代码定制:customFadeOutDuration。 - /// </summary> - public float fadeOutDuration { get { return m_FadeOutDuration; } set { m_FadeOutDuration = value < 0 ? 0 : value; } } - /// <summary> - /// The milliseconds actual duration of the first animation. - /// |实际的动画时长(毫秒)。 - /// </summary> - public float actualDuration { get { return m_ActualDuration; } } - /// <summary> - /// Whether to set graphic number threshold to animation. Animation will be disabled when graphic number is larger than threshold. - /// |是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。 - /// </summary> - public int threshold { get { return m_Threshold; } set { m_Threshold = value; } } - /// <summary> - /// The milliseconds delay before updating the first animation. - /// |渐入动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeInDelay。 - /// </summary> - public float fadeInDelay { get { return m_FadeInDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } } - /// <summary> - /// 渐出动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeOutDelay。 - /// </summary> - public float fadeOutDelay { get { return m_FadeOutDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } } - /// <summary> - /// 是否开启数据变更动画。 - /// </summary> - public bool dataChangeEnable { get { return m_DataChangeEnable; } set { m_DataChangeEnable = value; } } - /// <summary> - /// The milliseconds duration of the data change animation. - /// |数据变更的动画时长(毫秒)。 - /// </summary> - public float dataChangeDuration { get { return m_DataChangeDuration; } set { m_DataChangeDuration = value < 0 ? 0 : value; } } - /// <summary> - /// 渐入动画完成回调 - /// </summary> - public Action fadeInFinishCallback { get; set; } - /// <summary> - /// 渐出动画完成回调 - /// </summary> - public Action fadeOutFinishCallback { get; set; } - private Dictionary<int, float> m_ItemCurrProgress = new Dictionary<int, float>(); - private Dictionary<int, float> m_ItemDestProgress = new Dictionary<int, float>(); - private bool m_FadeIn = false; - private bool m_IsEnd = true; - private bool m_IsPause = false; - private bool m_FadeOut = false; - private bool m_FadeOuted = false; - private bool m_IsInit = false; - - private float startTime { get; set; } - private float m_CurrDetailProgress; - private float m_DestDetailProgress; - private float m_TotalDetailProgress; - private float m_CurrSymbolProgress; - private Vector3 m_LinePathLastPos; - - public void FadeIn() - { - if (m_FadeOut) - return; - - if (m_IsPause) - { - m_IsPause = false; - return; - } - - if (m_FadeIn) - return; - - startTime = Time.time; - m_FadeIn = true; - m_IsEnd = false; - m_IsInit = false; - m_IsPause = false; - m_FadeOuted = false; - m_CurrDetailProgress = 0; - m_DestDetailProgress = 1; - m_CurrSymbolProgress = 0; - m_ItemCurrProgress.Clear(); - m_ItemDestProgress.Clear(); - } - - public void Restart() - { - Reset(); - FadeIn(); - } - - public void FadeOut() - { - if (m_IsPause) - { - m_IsPause = false; - return; - } - - m_FadeOut = true; - startTime = Time.time; - m_FadeIn = true; - m_IsEnd = false; - m_IsInit = false; - m_IsPause = false; - m_CurrDetailProgress = 0; - m_DestDetailProgress = 1; - m_CurrSymbolProgress = 0; - m_ItemCurrProgress.Clear(); - m_ItemDestProgress.Clear(); - } - - public void Pause() - { - if (!m_IsPause) - { - m_IsPause = true; - } - } - - public void Resume() - { - if (m_IsPause) - { - m_IsPause = false; - } - } - - private void End() - { - if (m_IsEnd) - return; - - m_ActualDuration = (int) ((Time.time - startTime) * 1000) - (m_FadeOut ? fadeOutDelay : fadeInDelay); - m_IsEnd = true; - m_IsInit = false; - - if (m_FadeIn) - { - m_FadeIn = false; - if (fadeInFinishCallback != null) - { - fadeInFinishCallback(); - } - } - if (m_FadeOut) - { - m_FadeOut = false; - m_FadeOuted = true; - if (fadeOutFinishCallback != null) - { - fadeOutFinishCallback(); - } - } - } - - public void Reset() - { - m_FadeIn = false; - m_IsEnd = true; - m_IsInit = false; - m_IsPause = false; - m_FadeOut = false; - m_FadeOuted = false; - m_ItemCurrProgress.Clear(); - } - - public void InitProgress(float curr, float dest) - { - if (m_IsInit || m_IsEnd) - return; - if (curr > dest) - return; - - m_IsInit = true; - m_TotalDetailProgress = dest - curr; - - if (m_FadeOut) - { - m_CurrDetailProgress = dest; - m_DestDetailProgress = curr; - } - else - { - m_CurrDetailProgress = curr; - m_DestDetailProgress = dest; - } - } - - public void InitProgress(List<Vector3> paths, bool isY) - { - if (paths.Count < 1) return; - var sp = paths[0]; - var ep = paths[paths.Count - 1]; - var currDetailProgress = isY ? sp.y : sp.x; - var totalDetailProgress = isY ? ep.y : ep.x; - if (context.type == AnimationType.AlongPath) - { - currDetailProgress = 0; - totalDetailProgress = 0; - var lp = sp; - for (int i = 1; i < paths.Count; i++) - { - var np = paths[i]; - totalDetailProgress += Vector3.Distance(np, lp); - lp = np; - } - m_LinePathLastPos = sp; - context.currentPathDistance = 0; - } - InitProgress(currDetailProgress, totalDetailProgress); - } - - private void SetDataCurrProgress(int index, float state) - { - m_ItemCurrProgress[index] = state; - } - - private float GetDataCurrProgress(int index, float initValue, float destValue, ref bool isBarEnd) - { - if (IsInDelay()) - { - isBarEnd = false; - return initValue; - } - var c1 = !m_ItemCurrProgress.ContainsKey(index); - var c2 = !m_ItemDestProgress.ContainsKey(index); - if (c1 || c2) - { - if (c1) - m_ItemCurrProgress.Add(index, initValue); - - if (c2) - m_ItemDestProgress.Add(index, destValue); - - isBarEnd = false; - } - else - { - isBarEnd = m_ItemCurrProgress[index] == m_ItemDestProgress[index]; - } - return m_ItemCurrProgress[index]; - } - - public bool IsFinish() - { -#if UNITY_EDITOR - if (!Application.isPlaying) - return true; -#endif - if (!m_Enable || m_IsEnd) - return true; - - if (IsIndexAnimation()) - return m_CurrDetailProgress > m_DestDetailProgress; - if (IsItemAnimation()) - return false; - return true; - } - - public bool IsInFadeOut() - { - return m_FadeOut; - } - - public bool IsInDelay() - { - if (m_FadeOut) - return (fadeOutDelay > 0 && Time.time - startTime < fadeOutDelay / 1000); - else - return (fadeInDelay > 0 && Time.time - startTime < fadeInDelay / 1000); - } - - public bool IsItemAnimation() - { - return context.type == AnimationType.BottomToTop || context.type == AnimationType.InsideOut; - } - - public bool IsIndexAnimation() - { - return context.type == AnimationType.LeftToRight || - context.type == AnimationType.Clockwise || - context.type == AnimationType.AlongPath; - } - - public float GetIndexDelay(int dataIndex) - { - if (m_FadeOut && fadeOutDelayFunction != null) - return fadeOutDelayFunction(dataIndex); - else if (m_FadeIn && fadeInDelayFunction != null) - return fadeInDelayFunction(dataIndex); - else - return 0; - } - - public bool IsInIndexDelay(int dataIndex) - { - return Time.time - startTime < GetIndexDelay(dataIndex) / 1000f; - } - - public bool IsAllOutDelay(int dataCount) - { - var nowTime = Time.time - startTime; - for (int i = 0; i < dataCount; i++) - { - if (nowTime < GetIndexDelay(i) / 1000) - return false; - } - return true; - } - - public bool CheckDetailBreak(float detail) - { - if (!IsIndexAnimation()) - return false; - return !IsFinish() && detail > m_CurrDetailProgress; - } - - public bool CheckDetailBreak(Vector3 pos, bool isYAxis) - { - if (!IsIndexAnimation()) - return false; - - if (IsFinish()) - return false; - - if (context.type == AnimationType.AlongPath) - { - context.currentPathDistance += Vector3.Distance(pos, m_LinePathLastPos); - m_LinePathLastPos = pos; - return CheckDetailBreak(context.currentPathDistance); - } - else - { - if (isYAxis) - return pos.y > m_CurrDetailProgress; - else - return pos.x > m_CurrDetailProgress; - } - } - - public void CheckProgress() - { - if (IsItemAnimation() && context.isAllItemAnimationEnd) - { - End(); - return; - } - CheckProgress(m_TotalDetailProgress); - } - - public void CheckProgress(double total) - { - if (IsFinish()) - return; - - if (!m_IsInit || m_IsPause || m_IsEnd) - return; - - if (IsInDelay()) - return; - - m_ActualDuration = (int) ((Time.time - startTime) * 1000) - fadeInDelay; - var duration = GetCurrAnimationDuration(); - var delta = (float) (total / duration * Time.deltaTime); - if (m_FadeOut) - { - m_CurrDetailProgress -= delta; - if (m_CurrDetailProgress <= m_DestDetailProgress) - { - m_CurrDetailProgress = m_DestDetailProgress; - End(); - } - } - else - { - m_CurrDetailProgress += delta; - if (m_CurrDetailProgress >= m_DestDetailProgress) - { - m_CurrDetailProgress = m_DestDetailProgress; - End(); - } - } - } - - internal float GetCurrAnimationDuration(int dataIndex = -1) - { - if (dataIndex >= 0) - { - if (m_FadeOut && fadeOutDurationFunction != null) - return fadeOutDurationFunction(dataIndex) / 1000f; - if (m_FadeIn && fadeInDurationFunction != null) - return fadeInDurationFunction(dataIndex) / 1000f; - } - - if (m_FadeOut) - return m_FadeOutDuration > 0 ? m_FadeOutDuration / 1000 : 1f; - else - return m_FadeInDuration > 0 ? m_FadeInDuration / 1000 : 1f; - } - - internal float CheckItemProgress(int dataIndex, float destProgress, ref bool isEnd, float startProgress = 0) - { - isEnd = false; - var initHig = m_FadeOut ? destProgress : startProgress; - var destHig = m_FadeOut ? startProgress : destProgress; - var currHig = GetDataCurrProgress(dataIndex, initHig, destHig, ref isEnd); - if (isEnd || IsFinish()) - { - return m_FadeOuted ? startProgress : destProgress; - } - else if (IsInDelay() || IsInIndexDelay(dataIndex)) - { - return m_FadeOut ? destProgress : startProgress; - } - else if (m_IsPause) - { - return currHig; - } - else - { - var duration = GetCurrAnimationDuration(dataIndex); - var delta = (destProgress - startProgress) / duration * Time.deltaTime; - currHig = currHig + (m_FadeOut ? -delta : delta); - if (m_FadeOut) - { - if ((initHig > 0 && currHig <= 0) || (initHig < 0 && currHig >= 0)) - { - currHig = 0; - isEnd = true; - } - } - else - { - if ((destProgress - startProgress > 0 && currHig > destProgress) || - (destProgress - startProgress < 0 && currHig < destProgress)) - { - currHig = destProgress; - isEnd = true; - } - } - SetDataCurrProgress(dataIndex, currHig); - return currHig; - } - } - - public void CheckSymbol(float dest) - { - if (!enable || m_IsEnd || m_IsPause || !m_IsInit) - return; - - if (IsInDelay()) - return; - - var duration = GetCurrAnimationDuration(); - var delta = dest / duration * Time.deltaTime; - if (m_FadeOut) - { - m_CurrSymbolProgress -= delta; - if (m_CurrSymbolProgress < 0) - m_CurrSymbolProgress = 0; - } - else - { - m_CurrSymbolProgress += delta; - if (m_CurrSymbolProgress > dest) - m_CurrSymbolProgress = dest; - } - } - - public float GetSysmbolSize(float dest) - { -#if UNITY_EDITOR - if (!Application.isPlaying) - return dest; -#endif - if (!enable) - return dest; - - if (m_IsEnd) - return m_FadeOut ? 0 : dest; - - return m_CurrSymbolProgress; - } - - public float GetCurrDetail() - { -#if UNITY_EDITOR - if (!Application.isPlaying) - return m_DestDetailProgress; -#endif - return m_CurrDetailProgress; - } - - public float GetCurrRate() - { -#if UNITY_EDITOR - if (!Application.isPlaying) - return 1; -#endif - if (!enable || m_IsEnd) - return 1; - return m_CurrDetailProgress; - } - - public int GetCurrIndex() - { -#if UNITY_EDITOR - if (!Application.isPlaying) - return -1; -#endif - if (!enable || m_IsEnd) - return -1; - return (int) m_CurrDetailProgress; - } - - public float GetUpdateAnimationDuration() - { - if (m_Enable && m_DataChangeEnable && IsFinish()) - return m_DataChangeDuration; - else - return 0; - } - - public bool HasFadeOut() - { - return enable && m_FadeOuted && m_IsEnd; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs.meta b/Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs.meta deleted file mode 100644 index 87c8cd8..0000000 --- a/Assets/XCharts/Runtime/Component/Animation/AnimationStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e31c30f2ef61c48718a626f93307ce92 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs b/Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs deleted file mode 100644 index 9184e0a..0000000 --- a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public struct AnimationStyleContext - { - public AnimationType type; - public float currentPathDistance; - public bool isAllItemAnimationEnd; - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs.meta b/Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs.meta deleted file mode 100644 index 572eb5b..0000000 --- a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b3dc504960589413fa6a76267067775c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs b/Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs deleted file mode 100644 index 332236d..0000000 --- a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs +++ /dev/null @@ -1,65 +0,0 @@ -using UnityEngine; -using XUGL; - -namespace XCharts.Runtime -{ - public static class AnimationStyleHelper - { - public static float CheckDataAnimation(BaseChart chart, Serie serie, int dataIndex, float destProgress, float startPorgress = 0) - { - if (!serie.animation.IsItemAnimation()) - { - serie.animation.context.isAllItemAnimationEnd = false; - return destProgress; - } - if (serie.animation.IsFinish()) - { - serie.animation.context.isAllItemAnimationEnd = false; - return destProgress; - } - var isDataAnimationEnd = true; - var currHig = serie.animation.CheckItemProgress(dataIndex, destProgress, ref isDataAnimationEnd, startPorgress); - if (!isDataAnimationEnd) - { - serie.animation.context.isAllItemAnimationEnd = false; - } - return currHig; - } - - public static void UpdateSerieAnimation(Serie serie) - { - var serieType = serie.GetType(); - var animationType = AnimationType.LeftToRight; - if (serieType.IsDefined(typeof(DefaultAnimationAttribute), false)) - { - animationType = serieType.GetAttribute<DefaultAnimationAttribute>().type; - } - UpdateAnimationType(serie.animation, animationType); - } - - public static void UpdateAnimationType(AnimationStyle animation, AnimationType defaultType) - { - animation.context.type = animation.type == AnimationType.Default ? - defaultType : - animation.type; - } - - public static bool GetAnimationPosition(AnimationStyle animation, bool isY, Vector3 lp, Vector3 cp, float progress, ref Vector3 ip) - { - if (animation.context.type == AnimationType.AlongPath) - { - var dist = Vector3.Distance(lp, cp); - var rate = (dist - animation.context.currentPathDistance + animation.GetCurrDetail()) / dist; - ip = Vector3.Lerp(lp, cp, rate); - return true; - } - else - { - var startPos = isY ? new Vector3(-10000, progress) : new Vector3(progress, -10000); - var endPos = isY ? new Vector3(10000, progress) : new Vector3(progress, 10000); - - return UGLHelper.GetIntersection(lp, cp, startPos, endPos, ref ip); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs.meta b/Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs.meta deleted file mode 100644 index eed1235..0000000 --- a/Assets/XCharts/Runtime/Component/Animation/AnimationStyleHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 54cadaee0856b4f7085787fd450eec37 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis.meta b/Assets/XCharts/Runtime/Component/Axis.meta deleted file mode 100644 index 61797b1..0000000 --- a/Assets/XCharts/Runtime/Component/Axis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 194a62edf7ec2484fa2eebbf5bde3e95 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis.meta b/Assets/XCharts/Runtime/Component/Axis/AngleAxis.meta deleted file mode 100644 index 0b8a740..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 28b88ca3453f04fbdb23a53b5bcb4bf7 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs deleted file mode 100644 index 46909d7..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Angle axis of Polar Coordinate. - /// |极坐标系的角度轴。 - /// </summary> - [System.Serializable] - [RequireChartComponent(typeof(PolarCoord))] - [ComponentHandler(typeof(AngleAxisHandler), true)] - public class AngleAxis : Axis - { - [SerializeField] private float m_StartAngle = 0; - - /// <summary> - /// Starting angle of axis. 0 degrees by default, standing for right position of center. - /// |起始刻度的角度,默认为 0 度,即圆心的正右方。 - /// </summary> - public float startAngle - { - get { return m_StartAngle; } - set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); } - } - - public float GetValueAngle(float value) - { - return (value + context.startAngle + 360) % 360; - } - - public override void SetDefaultValue() - { - m_Show = true; - m_Type = AxisType.Value; - m_SplitNumber = 12; - m_StartAngle = 0; - m_BoundaryGap = false; - m_Data = new List<string>(12); - splitLine.show = true; - splitLine.lineStyle.type = LineStyle.Type.Solid; - axisLabel.textLimit.enable = false; - minMaxType = AxisMinMaxType.Custom; - min = 0; - max = 360; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs.meta deleted file mode 100644 index ea0bbb0..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 787015be923a74e1da4000c7abc2dcdf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs deleted file mode 100644 index b57b5a4..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ /dev/null @@ -1,164 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class AngleAxisHandler : AxisHandler<AngleAxis> - { - public override void InitComponent() - { - InitAngleAxis(component); - } - - public override void Update() - { - component.context.startAngle = 90 - component.startAngle; - UpdateAxisMinMaxValue(component); - UpdatePointerValue(component); - } - - public override void DrawBase(VertexHelper vh) - { - DrawAngleAxis(vh, component); - } - - private void UpdateAxisMinMaxValue(AngleAxis axis, bool updateChart = true) - { - if (axis.IsCategory() || !axis.show) return; - double tempMinValue = 0; - double tempMaxValue = 0; - SeriesHelper.GetYMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue, - out tempMaxValue, true); - AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); - if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue) - { - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.offset = 0; - axis.context.lastCheckInverse = axis.inverse; - UpdateAxisTickValueList(axis); - - if (updateChart) - { - UpdateAxisLabelText(axis); - chart.RefreshChart(); - } - } - } - - internal void UpdateAxisLabelText(AngleAxis axis) - { - var runtimeWidth = 360; - if (axis.context.labelObjectList.Count <= 0) - InitAngleAxis(axis); - else - axis.UpdateLabelText(runtimeWidth, null, false); - } - - private void InitAngleAxis(AngleAxis axis) - { - var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex); - if (polar == null) return; - PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight); - var radius = polar.context.radius; - axis.context.labelObjectList.Clear(); - axis.context.startAngle = 90 - axis.startAngle; - - string objName = component.GetType().Name + axis.index; - var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - axisObj.transform.localPosition = Vector3.zero; - axisObj.SetActive(axis.show); - axisObj.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(axisObj); - var splitNumber = AxisHelper.GetSplitNumber(axis, radius, null); - var totalAngle = axis.context.startAngle; - var total = 360; - var cenPos = polar.context.center; - var txtHig = axis.axisLabel.textStyle.GetFontSize(chart.theme.axis) + 2; - var margin = axis.axisLabel.distance + axis.axisTick.GetLength(chart.theme.axis.tickLength); - var isCategory = axis.IsCategory(); - var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series); - for (int i = 0; i < splitNumber; i++) - { - float scaleAngle = AxisHelper.GetScaleWidth(axis, total, i + 1, null); - bool inside = axis.axisLabel.inside; - var labelName = AxisHelper.GetLabelName(axis, total, i, axis.context.minValue, axis.context.maxValue, - null, isPercentStack); - var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, - new Vector2(scaleAngle, txtHig), axis, - chart.theme.axis, labelName, Color.clear); - label.text.SetAlignment(axis.axisLabel.textStyle.GetAlignment(TextAnchor.MiddleCenter)); - var pos = ChartHelper.GetPos(cenPos, radius + margin, - isCategory ? (totalAngle + scaleAngle / 2) : totalAngle, true); - AxisHelper.AdjustCircleLabelPos(label, pos, cenPos, txtHig, Vector3.zero); - if (i == 0) axis.axisLabel.SetRelatedText(label.text, scaleAngle); - axis.context.labelObjectList.Add(label); - - totalAngle += scaleAngle; - } - } - - private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis) - { - var polar = chart.GetChartComponent<PolarCoord>(angleAxis.polarIndex); - var radius = polar.context.radius; - var cenPos = polar.context.center; - var total = 360; - var size = AxisHelper.GetScaleNumber(angleAxis, total, null); - var currAngle = angleAxis.context.startAngle; - var tickWidth = angleAxis.axisTick.GetWidth(chart.theme.axis.tickWidth); - var tickLength = angleAxis.axisTick.GetLength(chart.theme.axis.tickLength); - var tickColor = angleAxis.axisTick.GetColor(chart.theme.axis.lineColor); - var lineColor = angleAxis.axisLine.GetColor(chart.theme.axis.lineColor); - var splitLineColor = angleAxis.splitLine.GetColor(chart.theme.axis.splitLineColor); - for (int i = 1; i < size; i++) - { - var scaleWidth = AxisHelper.GetScaleWidth(angleAxis, total, i); - var pos = ChartHelper.GetPos(cenPos, radius, currAngle, true); - if (angleAxis.show && angleAxis.splitLine.show) - { - var lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth); - UGL.DrawLine(vh, cenPos, pos, lineWidth, splitLineColor); - } - if (angleAxis.show && angleAxis.axisTick.show) - { - if ((i == 1 && angleAxis.axisTick.showStartTick) || - (i == size - 1 && angleAxis.axisTick.showEndTick) || - (i > 1 && i < size - 1)) - { - var tickY = radius + tickLength; - var tickPos = ChartHelper.GetPos(cenPos, tickY, currAngle, true); - UGL.DrawLine(vh, pos, tickPos, tickWidth, tickColor); - } - } - currAngle += scaleWidth; - } - if (angleAxis.show && angleAxis.axisLine.show) - { - var lineWidth = angleAxis.axisLine.GetWidth(chart.theme.axis.lineWidth); - var outsideRaidus = radius + lineWidth * 2; - UGL.DrawDoughnut(vh, cenPos, radius, outsideRaidus, lineColor, Color.clear); - } - } - - protected override void UpdatePointerValue(Axis axis) - { - var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex); - if (polar == null) - return; - - if (!polar.context.isPointerEnter) - { - axis.context.pointerValue = double.PositiveInfinity; - return; - } - - var dir = (chart.pointerPos - new Vector2(polar.context.center.x, polar.context.center.y)).normalized; - var angle = ChartHelper.GetAngle360(Vector2.up, dir); - axis.context.pointerValue = (angle - component.context.startAngle + 360) % 360; - axis.context.pointerLabelPosition = polar.context.center + new Vector3(dir.x, dir.y) * (polar.context.radius + 25); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs.meta deleted file mode 100644 index b3408f6..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 83f228c42435c4619943a2f187c98e7b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/Axis.cs b/Assets/XCharts/Runtime/Component/Axis/Axis.cs deleted file mode 100644 index 23f2c83..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/Axis.cs +++ /dev/null @@ -1,791 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// The axis in rectangular coordinate. - /// |直角坐标系的坐标轴组件。 - /// </summary> - [System.Serializable] - public class Axis : MainComponent - { - /// <summary> - /// the type of axis. - /// |坐标轴类型。 - /// </summary> - public enum AxisType - { - /// <summary> - /// Numerical axis, suitable for continuous data. - /// ||数值轴。适用于连续数据。 - /// </summary> - Value, - /// <summary> - /// Category axis, suitable for discrete category data. Data should only be set via data for this type. - /// ||类目轴。适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。 - /// </summary> - Category, - /// <summary> - /// Log axis, suitable for log data. - /// |对数轴。适用于对数数据。 - /// </summary> - Log, - /// <summary> - /// Time axis, suitable for continuous time series data. - /// |时间轴。适用于连续的时序数据。 - /// </summary> - Time - } - - /// <summary> - /// the type of axis min and max value. - /// |坐标轴最大最小刻度显示类型。 - /// </summary> - public enum AxisMinMaxType - { - /// <summary> - /// 0 - maximum. - /// |0-最大值。 - /// </summary> - Default, - /// <summary> - /// minimum - maximum. - /// |最小值-最大值。 - /// </summary> - MinMax, - /// <summary> - /// Customize the minimum and maximum. - /// |自定义最小值最大值。 - /// </summary> - Custom - } - /// <summary> - /// the position of axis in grid. - /// |坐标轴在Grid中的位置 - /// </summary> - public enum AxisPosition - { - Left, - Right, - Bottom, - Top - } - - [SerializeField] protected bool m_Show = true; - [SerializeField] protected AxisType m_Type; - [SerializeField] protected AxisMinMaxType m_MinMaxType; - [SerializeField] protected int m_GridIndex; - [SerializeField] protected int m_PolarIndex; - [SerializeField] protected int m_ParallelIndex; - [SerializeField] protected AxisPosition m_Position; - [SerializeField] protected float m_Offset; - [SerializeField] protected double m_Min; - [SerializeField] protected double m_Max; - [SerializeField] protected int m_SplitNumber = 0; - [SerializeField] protected double m_Interval = 0; - [SerializeField] protected bool m_BoundaryGap = true; - [SerializeField] protected int m_MaxCache = 0; - [SerializeField] protected float m_LogBase = 10; - [SerializeField] protected bool m_LogBaseE = false; - [SerializeField] protected int m_CeilRate = 0; - [SerializeField] protected bool m_Inverse = false; - [SerializeField] private bool m_Clockwise = true; - [SerializeField] private bool m_InsertDataToHead; - [SerializeField] protected List<Sprite> m_Icons = new List<Sprite>(); - [SerializeField] protected List<string> m_Data = new List<string>(); - [SerializeField] protected AxisLine m_AxisLine = AxisLine.defaultAxisLine; - [SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName; - [SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick; - [SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel; - [SerializeField] protected AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine; - [SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea; - - public AxisContext context = new AxisContext(); - - /// <summary> - /// Whether to show axis. - /// |是否显示坐标轴。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); } - } - /// <summary> - /// the type of axis. - /// |坐标轴类型。 - /// </summary> - public AxisType type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetAllDirty(); } - } - /// <summary> - /// the type of axis minmax. - /// |坐标轴刻度最大最小值显示类型。 - /// </summary> - public AxisMinMaxType minMaxType - { - get { return m_MinMaxType; } - set { if (PropertyUtil.SetStruct(ref m_MinMaxType, value)) SetAllDirty(); } - } - /// <summary> - /// The index of the grid on which the axis are located, by default, is in the first grid. - /// |坐标轴所在的 grid 的索引,默认位于第一个 grid。 - /// </summary> - public int gridIndex - { - get { return m_GridIndex; } - set { if (PropertyUtil.SetStruct(ref m_GridIndex, value)) SetAllDirty(); } - } - /// <summary> - /// The index of the polar on which the axis are located, by default, is in the first polar. - /// |坐标轴所在的 ploar 的索引,默认位于第一个 polar。 - /// </summary> - public int polarIndex - { - get { return m_PolarIndex; } - set { if (PropertyUtil.SetStruct(ref m_PolarIndex, value)) SetAllDirty(); } - } - /// <summary> - /// The index of the parallel on which the axis are located, by default, is in the first parallel. - /// |坐标轴所在的 parallel 的索引,默认位于第一个 parallel。 - /// </summary> - public int parallelIndex - { - get { return m_ParallelIndex; } - set { if (PropertyUtil.SetStruct(ref m_ParallelIndex, value)) SetAllDirty(); } - } - /// <summary> - /// the position of axis in grid. - /// |坐标轴在Grid中的位置。 - /// </summary> - public AxisPosition position - { - get { return m_Position; } - set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetAllDirty(); } - } - /// <summary> - /// the offset of axis from the default position. Useful when the same position has multiple axes. - /// |坐标轴相对默认位置的偏移。在相同position有多个坐标轴时有用。 - /// </summary> - public float offset - { - get { return m_Offset; } - set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); } - } - /// <summary> - /// The minimun value of axis.Valid when `minMaxType` is `Custom` - /// |设定的坐标轴刻度最小值,当minMaxType为Custom时有效。 - /// </summary> - public double min - { - get { return m_Min; } - set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetAllDirty(); } - } - /// <summary> - /// The maximum value of axis.Valid when `minMaxType` is `Custom` - /// |设定的坐标轴刻度最大值,当minMaxType为Custom时有效。 - /// </summary> - public double max - { - get { return m_Max; } - set { if (PropertyUtil.SetStruct(ref m_Max, value)) SetAllDirty(); } - } - /// <summary> - /// Number of segments that the axis is split into. - /// |坐标轴的期望的分割段数。默认为0表示自动分割。 - /// </summary> - public int splitNumber - { - get { return m_SplitNumber; } - set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); } - } - /// <summary> - /// Compulsively set segmentation interval for axis.This is unavailable for category axis. - /// |强制设置坐标轴分割间隔。无法在类目轴中使用。 - /// </summary> - public double interval - { - get { return m_Interval; } - set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetAllDirty(); } - } - /// <summary> - /// The boundary gap on both sides of a coordinate axis, which is valid only for category axis with type: 'Category'. - /// |坐标轴两边是否留白。只对类目轴有效。 - /// </summary> - public bool boundaryGap - { - get { return IsCategory() ? m_BoundaryGap : false; } - set { if (PropertyUtil.SetStruct(ref m_BoundaryGap, value)) SetAllDirty(); } - } - /// <summary> - /// Base of logarithm, which is valid only for numeric axes with type: 'Log'. - /// |对数轴的底数,只在对数轴(type:'Log')中有效。 - /// </summary> - public float logBase - { - get { return m_LogBase; } - set - { - if (value <= 0 || value == 1) value = 10; - if (PropertyUtil.SetStruct(ref m_LogBase, value)) SetAllDirty(); - } - } - /// <summary> - /// On the log axis, if base e is the natural number, and is true, logBase fails. - /// |对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。 - /// </summary> - public bool logBaseE - { - get { return m_LogBaseE; } - set { if (PropertyUtil.SetStruct(ref m_LogBaseE, value)) SetAllDirty(); } - } - /// <summary> - /// The max number of axis data cache. - /// |The first data will be remove when the size of axis data is larger then maxCache. - /// |可缓存的最大数据量。默认为0没有限制,大于0时超过指定值会移除旧数据再插入新数据。 - /// </summary> - public int maxCache - { - get { return m_MaxCache; } - set { if (PropertyUtil.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) SetAllDirty(); } - } - /// <summary> - /// The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated. - /// |最大最小值向上取整的倍率。默认为0时自动计算。 - /// </summary> - public int ceilRate - { - get { return m_CeilRate; } - set { if (PropertyUtil.SetStruct(ref m_CeilRate, value < 0 ? 0 : value)) SetAllDirty(); } - } - /// <summary> - /// Whether the axis are reversed or not. Invalid in `Category` axis. - /// |是否反向坐标轴。在类目轴中无效。 - /// </summary> - public bool inverse - { - get { return m_Inverse; } - set { if (m_Type == AxisType.Value && PropertyUtil.SetStruct(ref m_Inverse, value)) SetAllDirty(); } - } - /// <summary> - /// Whether the positive position of axis is in clockwise. True for clockwise by default. - /// |刻度增长是否按顺时针,默认顺时针。 - /// </summary> - public bool clockwise - { - get { return m_Clockwise; } - set { if (PropertyUtil.SetStruct(ref m_Clockwise, value)) SetAllDirty(); } - } - /// <summary> - /// Category data, available in type: 'Category' axis. - /// |类目数据,在类目轴(type: 'category')中有效。 - /// </summary> - public List<string> data - { - get { return m_Data; } - set { if (value != null) { m_Data = value; SetAllDirty(); } } - } - /// <summary> - /// 类目数据对应的图标。 - /// </summary> - public List<Sprite> icons - { - get { return m_Icons; } - set { if (value != null) { m_Icons = value; SetAllDirty(); } } - } - /// <summary> - /// axis Line. - /// |坐标轴轴线。 - /// </summary> - public AxisLine axisLine - { - get { return m_AxisLine; } - set { if (value != null) { m_AxisLine = value; SetVerticesDirty(); } } - } - /// <summary> - /// axis name. - /// |坐标轴名称。 - /// </summary> - public AxisName axisName - { - get { return m_AxisName; } - set { if (value != null) { m_AxisName = value; SetComponentDirty(); } } - } - /// <summary> - /// axis tick. - /// |坐标轴刻度。 - /// </summary> - public AxisTick axisTick - { - get { return m_AxisTick; } - set { if (value != null) { m_AxisTick = value; SetVerticesDirty(); } } - } - /// <summary> - /// axis label. - /// |坐标轴刻度标签。 - /// </summary> - public AxisLabel axisLabel - { - get { return m_AxisLabel; } - set { if (value != null) { m_AxisLabel = value; SetComponentDirty(); } } - } - /// <summary> - /// axis split line. - /// |坐标轴分割线。 - /// </summary> - public AxisSplitLine splitLine - { - get { return m_SplitLine; } - set { if (value != null) { m_SplitLine = value; SetVerticesDirty(); } } - } - /// <summary> - /// axis split area. - /// |坐标轴分割区域。 - /// </summary> - public AxisSplitArea splitArea - { - get { return m_SplitArea; } - set { if (value != null) { m_SplitArea = value; SetVerticesDirty(); } } - } - /// <summary> - /// Whether to add new data at the head or at the end of the list. - /// |添加新数据时是在列表的头部还是尾部加入。 - /// </summary> - public bool insertDataToHead - { - get { return m_InsertDataToHead; } - set { if (PropertyUtil.SetStruct(ref m_InsertDataToHead, value)) SetAllDirty(); } - } - - public override bool vertsDirty - { - get - { - return m_VertsDirty || - axisLine.anyDirty || - axisTick.anyDirty || - splitLine.anyDirty || - splitArea.anyDirty; - } - } - - public override bool componentDirty - { - get - { - return m_ComponentDirty || - axisName.anyDirty || - axisLabel.anyDirty; - } - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - axisName.ClearComponentDirty(); - axisLabel.ClearComponentDirty(); - } - - public override void ClearVerticesDirty() - { - base.ClearVerticesDirty(); - axisLine.ClearVerticesDirty(); - axisTick.ClearVerticesDirty(); - splitLine.ClearVerticesDirty(); - splitArea.ClearVerticesDirty(); - } - - public override void SetComponentDirty() - { - context.isNeedUpdateFilterData = true; - base.SetComponentDirty(); - } - - public Axis Clone() - { - var axis = new Axis(); - axis.show = show; - axis.type = type; - axis.gridIndex = 0; - axis.minMaxType = minMaxType; - axis.min = min; - axis.max = max; - axis.splitNumber = splitNumber; - axis.interval = interval; - axis.boundaryGap = boundaryGap; - axis.maxCache = maxCache; - axis.logBase = logBase; - axis.logBaseE = logBaseE; - axis.ceilRate = ceilRate; - axis.insertDataToHead = insertDataToHead; - axis.axisLine = axisLine.Clone(); - axis.axisName = axisName.Clone(); - axis.axisTick = axisTick.Clone(); - axis.axisLabel = axisLabel.Clone(); - axis.splitLine = splitLine.Clone(); - axis.splitArea = splitArea.Clone(); - axis.icons = new List<Sprite>(); - axis.data = new List<string>(); - ChartHelper.CopyList(axis.data, data); - return axis; - } - - public void Copy(Axis axis) - { - show = axis.show; - type = axis.type; - minMaxType = axis.minMaxType; - gridIndex = axis.gridIndex; - min = axis.min; - max = axis.max; - splitNumber = axis.splitNumber; - interval = axis.interval; - boundaryGap = axis.boundaryGap; - maxCache = axis.maxCache; - logBase = axis.logBase; - logBaseE = axis.logBaseE; - ceilRate = axis.ceilRate; - insertDataToHead = axis.insertDataToHead; - axisLine.Copy(axis.axisLine); - axisName.Copy(axis.axisName); - axisTick.Copy(axis.axisTick); - axisLabel.Copy(axis.axisLabel); - splitLine.Copy(axis.splitLine); - splitArea.Copy(axis.splitArea); - ChartHelper.CopyList(data, axis.data); - ChartHelper.CopyList<Sprite>(icons, axis.icons); - } - - /// <summary> - /// 清空类目数据 - /// </summary> - public override void ClearData() - { - m_Data.Clear(); - m_Icons.Clear(); - context.Clear(); - SetAllDirty(); - } - - /// <summary> - /// 是否为类目轴。 - /// </summary> - /// <returns></returns> - public bool IsCategory() - { - return m_Type == AxisType.Category; - } - - /// <summary> - /// 是否为数值轴。 - /// </summary> - /// <returns></returns> - public bool IsValue() - { - return m_Type == AxisType.Value; - } - - /// <summary> - /// 是否为对数轴。 - /// </summary> - /// <returns></returns> - public bool IsLog() - { - return m_Type == AxisType.Log; - } - - /// <summary> - /// 是否为时间轴。 - /// </summary> - public bool IsTime() - { - return m_Type == AxisType.Time; - } - - public bool IsLeft() - { - return m_Position == AxisPosition.Left; - } - - public bool IsRight() - { - return m_Position == AxisPosition.Right; - } - - public bool IsTop() - { - return m_Position == AxisPosition.Top; - } - - public bool IsBottom() - { - return m_Position == AxisPosition.Bottom; - } - - public void SetNeedUpdateFilterData() - { - context.isNeedUpdateFilterData = true; - } - - /// <summary> - /// 添加一个类目到类目数据列表 - /// </summary> - /// <param name="category"></param> - public void AddData(string category) - { - if (maxCache > 0) - { - while (m_Data.Count >= maxCache) - { - RemoveData(m_InsertDataToHead ? m_Data.Count - 1 : 0); - } - } - - if (m_InsertDataToHead) - m_Data.Insert(0, category); - else - m_Data.Add(category); - - SetAllDirty(); - } - - public void RemoveData(int dataIndex) - { - context.isNeedUpdateFilterData = true; - m_Data.RemoveAt(dataIndex); - } - - /// <summary> - /// 更新类目数据 - /// </summary> - /// <param name="index"></param> - /// <param name="category"></param> - public void UpdateData(int index, string category) - { - if (index >= 0 && index < m_Data.Count) - { - m_Data[index] = category; - SetComponentDirty(); - } - } - - /// <summary> - /// 添加图标 - /// </summary> - /// <param name="icon"></param> - public void AddIcon(Sprite icon) - { - if (maxCache > 0) - { - while (m_Icons.Count > maxCache) - { - m_Icons.RemoveAt(m_InsertDataToHead ? m_Icons.Count - 1 : 0); - } - } - if (m_InsertDataToHead) m_Icons.Insert(0, icon); - else m_Icons.Add(icon); - SetAllDirty(); - } - - /// <summary> - /// 更新图标 - /// </summary> - /// <param name="index"></param> - /// <param name="icon"></param> - public void UpdateIcon(int index, Sprite icon) - { - if (index >= 0 && index < m_Icons.Count) - { - m_Icons[index] = icon; - SetComponentDirty(); - } - } - - /// <summary> - /// 获得指定索引的类目数据 - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public string GetData(int index) - { - if (index >= 0 && index < m_Data.Count) - return m_Data[index]; - else - return null; - } - - /// <summary> - /// 获得在dataZoom范围内指定索引的类目数据 - /// </summary> - /// <param name="index">类目数据索引</param> - /// <param name="dataZoom">区域缩放</param> - /// <returns></returns> - public string GetData(int index, DataZoom dataZoom) - { - var showData = GetDataList(dataZoom); - if (index >= 0 && index < showData.Count) - return showData[index]; - else - return ""; - } - - public Sprite GetIcon(int index) - { - if (index >= 0 && index < m_Icons.Count) - return m_Icons[index]; - else - return null; - } - - /// <summary> - /// 获得值在坐标轴上的距离 - /// </summary> - /// <param name="value"></param> - /// <param name="axisLength"></param> - /// <returns></returns> - public float GetDistance(double value, float axisLength) - { - if (context.minMaxRange == 0) - return 0; - - if (IsCategory() && boundaryGap) - { - var each = axisLength / data.Count; - return (float) (each * (value + 0.5f)); - } - else - { - return axisLength * (float) ((value - context.minValue) / context.minMaxRange); - } - } - - /// <summary> - /// 获得指定区域缩放的类目数据列表 - /// </summary> - /// <param name="dataZoom">区域缩放</param> - /// <returns></returns> - internal List<string> GetDataList(DataZoom dataZoom) - { - if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this)) - { - UpdateFilterData(dataZoom); - return context.filterData; - } - else - { - return m_Data.Count > 0 ? m_Data : context.runtimeData; - } - } - - internal List<string> GetDataList() - { - return m_Data.Count > 0 ? m_Data : context.runtimeData; - } - - /// <summary> - /// 更新dataZoom对应的类目数据列表 - /// </summary> - /// <param name="dataZoom"></param> - internal void UpdateFilterData(DataZoom dataZoom) - { - if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this)) - { - var data = GetDataList(); - context.UpdateFilterData(data, dataZoom); - } - } - - /// <summary> - /// 获得类目数据个数 - /// </summary> - /// <param name="dataZoom"></param> - /// <returns></returns> - internal int GetDataCount(DataZoom dataZoom) - { - return IsCategory() ? GetDataList(dataZoom).Count : 0; - } - - /// <summary> - /// 更新刻度标签文字 - /// </summary> - /// <param name="dataZoom"></param> - internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent) - { - for (int i = 0; i < context.labelObjectList.Count; i++) - { - if (context.labelObjectList[i] != null) - { - var text = AxisHelper.GetLabelName(this, coordinateWidth, i, context.minValue, context.maxValue, dataZoom, forcePercent); - context.labelObjectList[i].SetText(text); - } - } - } - - internal Vector3 GetLabelObjectPosition(int index) - { - if (context.labelObjectList != null && index < context.labelObjectList.Count) - return context.labelObjectList[index].GetPosition(); - else - return Vector3.zero; - } - - internal void UpdateMinMaxValue(double minValue, double maxValue) - { - context.minValue = minValue; - context.maxValue = maxValue; - double tempRange = maxValue - minValue; - if (context.minMaxRange != tempRange) - { - context.minMaxRange = tempRange; - if (type == Axis.AxisType.Value && interval > 0) - { - SetComponentDirty(); - } - } - } - - public float GetLogValue(double value) - { - if (value <= 0 || value == 1) - return 0; - else - return logBaseE ? (float) Math.Log(value) : (float) Math.Log(value, logBase); - } - - public int GetLogMinIndex() - { - return logBaseE ? - (int) Math.Log(context.minValue) : - (int) Math.Log(context.minValue, logBase); - } - - public int GetLogMaxIndex() - { - return logBaseE ? - (int) Math.Log(context.maxValue) : - (int) Math.Log(context.maxValue, logBase); - } - - public double GetLabelValue(int index) - { - if (index < 0) - return context.minValue; - else if (index > context.labelValueList.Count - 1) - return context.maxValue; - else - return context.labelValueList[index]; - } - - public double GetLastLabelValue() - { - if (context.labelValueList.Count > 0) - return context.labelValueList[context.labelValueList.Count - 1]; - else - return 0; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/Axis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/Axis.cs.meta deleted file mode 100644 index c86a648..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/Axis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d5c29555575e04db98ee243c3b17f0ed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs b/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs deleted file mode 100644 index c47d5a6..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class AxisContext : MainComponentContext - { - public Orient orient; - public float x; - public float y; - public float zeroX; - public float zeroY; - public float width; - public float height; - public Vector3 position; - public float left; - public float right; - public float bottom; - public float top; - /// <summary> - /// the current minimun value. - /// |当前最小值。 - /// </summary> - public double minValue; - /// <summary> - /// the current maximum value. - /// |当前最大值。 - /// </summary> - public double maxValue; - /// <summary> - /// the offset of zero position. - /// |坐标轴原点在坐标轴的偏移。 - /// </summary> - public float offset; - public double minMaxRange; - public float scaleWidth; - public float startAngle; - public double pointerValue; - public Vector3 pointerLabelPosition; - public double axisTooltipValue; - public List<string> runtimeData { get { return m_RuntimeData; } } - public List<double> labelValueList { get { return m_LabelValueList; } } - public List<ChartLabel> labelObjectList { get { return m_AxisLabelList; } } - - internal List<string> filterData; - internal bool lastCheckInverse; - internal bool isNeedUpdateFilterData; - - private int filterStart; - private int filterEnd; - private int filterMinShow; - - private List<ChartLabel> m_AxisLabelList = new List<ChartLabel>(); - private List<double> m_LabelValueList = new List<double>(); - private List<string> m_RuntimeData = new List<string>(); - - internal void Clear() - { - m_RuntimeData.Clear(); - } - - private List<string> m_EmptyFliter = new List<string>(); - /// <summary> - /// 更新dataZoom对应的类目数据列表 - /// </summary> - /// <param name="dataZoom"></param> - internal void UpdateFilterData(List<string> data, DataZoom dataZoom) - { - int start = 0, end = 0; - var range = Mathf.RoundToInt(data.Count * (dataZoom.end - dataZoom.start) / 100); - if (range <= 0) - range = 1; - - if (dataZoom.context.invert) - { - end = Mathf.CeilToInt(data.Count * dataZoom.end / 100); - start = end - range; - if (start < 0) start = 0; - } - else - { - start = Mathf.FloorToInt(data.Count * dataZoom.start / 100); - end = start + range; - if (end > data.Count) end = data.Count; - } - - if (start != filterStart || - end != filterEnd || - dataZoom.minShowNum != filterMinShow || - isNeedUpdateFilterData) - { - filterStart = start; - filterEnd = end; - filterMinShow = dataZoom.minShowNum; - isNeedUpdateFilterData = false; - - if (data.Count > 0) - { - if (range < dataZoom.minShowNum) - { - if (dataZoom.minShowNum > data.Count) - range = data.Count; - else - range = dataZoom.minShowNum; - } - if (range > data.Count - start - 1) - start = data.Count - range - 1; - if (start >= 0) - filterData = data.GetRange(start, range); - else - filterData = data; - } - else - { - filterData = data; - } - } - else if (end == 0) - { - filterData = m_EmptyFliter; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs.meta deleted file mode 100644 index 5f2226c..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6525f065fa5d04663ab7026a3467f56e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs deleted file mode 100644 index 109fa87..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs +++ /dev/null @@ -1,782 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; -using XCharts.Runtime; -using XUGL; - -namespace XCharts -{ - public abstract class AxisHandler<T> : MainComponentHandler - where T : Axis - { - private static readonly string s_DefaultAxisName = "name"; - private double m_LastInterval = double.MinValue; - private int m_LastSplitNumber = int.MinValue; - public T component { get; internal set; } - - internal override void SetComponent(MainComponent component) - { - this.component = (T) component; - } - - protected virtual Vector3 GetLabelPosition(float scaleWid, int i) - { - return Vector3.zero; - } - - protected virtual float GetAxisLineXOrY() - { - return 0; - } - - protected virtual Orient orient { get; set; } - - protected virtual void UpdatePointerValue(Axis axis) - { - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - if (grid == null) - return; - if (!grid.context.isPointerEnter) - { - axis.context.pointerValue = double.PositiveInfinity; - } - else - { - var lastPointerValue = axis.context.pointerValue; - if (axis.IsCategory()) - { - var dataZoom = chart.GetDataZoomOfAxis(axis); - var dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0; - var local = chart.pointerPos; - if (axis is YAxis) - { - float splitWid = AxisHelper.GetDataWidth(axis, grid.context.height, dataCount, dataZoom); - for (int j = 0; j < axis.GetDataCount(dataZoom); j++) - { - float pY = grid.context.y + j * splitWid; - if ((axis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || - (!axis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) - { - axis.context.pointerValue = j; - axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j); - if (j != lastPointerValue) - { - if (chart.onAxisPointerValueChanged != null) - chart.onAxisPointerValueChanged(axis, j); - } - break; - } - } - } - else - { - float splitWid = AxisHelper.GetDataWidth(axis, grid.context.width, dataCount, dataZoom); - for (int j = 0; j < axis.GetDataCount(dataZoom); j++) - { - float pX = grid.context.x + j * splitWid; - if ((axis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || - (!axis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) - { - axis.context.pointerValue = j; - axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j); - if (j != lastPointerValue) - { - if (chart.onAxisPointerValueChanged != null) - chart.onAxisPointerValueChanged(axis, j); - } - break; - } - } - } - } - else - { - if (axis is YAxis) - { - var yRate = axis.context.minMaxRange / grid.context.height; - var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.offset); - if (axis.context.minValue > 0) - yValue += axis.context.minValue; - - var labelX = axis.GetLabelObjectPosition(0).x; - axis.context.pointerValue = yValue; - axis.context.pointerLabelPosition = new Vector3(labelX, chart.pointerPos.y); - if (yValue != lastPointerValue) - { - if (chart.onAxisPointerValueChanged != null) - chart.onAxisPointerValueChanged(axis, yValue); - } - } - else - { - var xRate = axis.context.minMaxRange / grid.context.width; - var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.offset); - if (axis.context.minValue > 0) - xValue += axis.context.minValue; - - var labelY = axis.GetLabelObjectPosition(0).y; - axis.context.pointerValue = xValue; - axis.context.pointerLabelPosition = new Vector3(chart.pointerPos.x, labelY); - if (xValue != lastPointerValue) - { - if (chart.onAxisPointerValueChanged != null) - chart.onAxisPointerValueChanged(axis, xValue); - } - } - } - } - } - - internal void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true) - { - if (!axis.show) - return; - - if (axis.IsCategory()) - { - axis.context.minValue = 0; - axis.context.maxValue = SeriesHelper.GetMaxSerieDataCount(chart.series) - 1; - axis.context.minMaxRange = axis.context.maxValue; - return; - } - - double tempMinValue = 0; - double tempMaxValue = 0; - chart.GetSeriesMinMaxValue(axis, axisIndex, out tempMinValue, out tempMaxValue); - - if (tempMinValue != axis.context.minValue || - tempMaxValue != axis.context.maxValue || - m_LastInterval != axis.interval || - m_LastSplitNumber != axis.splitNumber) - { - m_LastSplitNumber = axis.splitNumber; - m_LastInterval = axis.interval; - - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.offset = 0; - axis.context.lastCheckInverse = axis.inverse; - UpdateAxisTickValueList(axis); - - if (tempMinValue != 0 || tempMaxValue != 0) - { - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - if (grid != null && axis is XAxis && axis.IsValue()) - { - axis.context.offset = axis.context.minValue > 0 ? - 0 : - (axis.context.maxValue < 0 ? - grid.context.width : - (float) (Math.Abs(axis.context.minValue) * (grid.context.width / - (Math.Abs(axis.context.minValue) + Math.Abs(axis.context.maxValue)))) - ); - axis.context.x = grid.context.x; - axis.context.y = GetAxisLineXOrY(); - axis.context.zeroY = grid.context.y; - axis.context.zeroX = grid.context.x - (float) (axis.context.minValue * grid.context.width / axis.context.minMaxRange); - } - if (grid != null && axis is YAxis && axis.IsValue()) - { - axis.context.offset = axis.context.minValue > 0 ? - 0 : - (axis.context.maxValue < 0 ? - grid.context.height : - (float) (Math.Abs(axis.context.minValue) * (grid.context.height / - (Math.Abs(axis.context.minValue) + Math.Abs(axis.context.maxValue)))) - ); - axis.context.x = GetAxisLineXOrY(); - axis.context.y = grid.context.y; - axis.context.zeroX = grid.context.x; - axis.context.zeroY = grid.context.y - (float) (axis.context.minValue * grid.context.height / axis.context.minMaxRange); - } - } - var dataZoom = chart.GetDataZoomOfAxis(axis); - if (dataZoom != null && dataZoom.enable) - { - if (axis is XAxis) - dataZoom.SetXAxisIndexValueInfo(axisIndex, tempMinValue, tempMaxValue); - else - dataZoom.SetYAxisIndexValueInfo(axisIndex, tempMinValue, tempMaxValue); - } - if (updateChart) - { - UpdateAxisLabelText(axis); - chart.RefreshChart(); - } - } - } - - internal virtual void UpdateAxisLabelText(Axis axis) - { - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - if (grid == null || axis == null) - return; - - float runtimeWidth = axis is XAxis ? grid.context.width : grid.context.height; - var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series); - var dataZoom = chart.GetDataZoomOfAxis(axis); - - axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack); - } - - internal static void UpdateAxisTickValueList(Axis axis) - { - if (axis.IsTime()) - { - var lastCount = axis.context.labelValueList.Count; - DateTimeUtil.UpdateTimeAxisDateTimeList(axis.context.labelValueList, (int) axis.context.minValue, - (int) axis.context.maxValue, axis.splitNumber); - - if (axis.context.labelValueList.Count != lastCount) - axis.SetAllDirty(); - } - else if (axis.IsValue()) - { - var list = axis.context.labelValueList; - var lastCount = list.Count; - list.Clear(); - - var range = axis.context.maxValue - axis.context.minValue; - if (range <= 0) - return; - - double tick = axis.interval; - - if (axis.interval == 0) - { - if (axis.splitNumber > 0) - { - tick = range / axis.splitNumber; - } - else - { - var each = GetTick(range); - tick = each; - if (range / tick > 8) - tick = 2 * each; - else if (range / tick < 4) - tick = each / 2; - } - } - var value = 0d; - if (Mathf.Approximately((float) (axis.context.minValue % tick), 0)) - { - value = axis.context.minValue; - } - else - { - list.Add(axis.context.minValue); - value = Math.Ceiling(axis.context.minValue / tick) * tick; - } - while (value <= axis.context.maxValue) - { - list.Add(value); - value += tick; - - if (list.Count > 20) - break; - } - if (!ChartHelper.IsEquals(axis.context.maxValue, list[list.Count - 1])) - { - list.Add(axis.context.maxValue); - } - if (lastCount != list.Count) - { - axis.SetAllDirty(); - } - } - } - - private static double GetTick(double max) - { - if (max <= 1) return max / 5; - var bigger = Math.Ceiling(Math.Abs(max)); - int n = 1; - while (bigger / (Mathf.Pow(10, n)) > 10) - { - n++; - } - return Math.Pow(10, n); - } - - internal void CheckValueLabelActive(Axis axis, int i, ChartLabel label, Vector3 pos) - { - if (!axis.show || !axis.axisLabel.show) - { - label.SetTextActive(false); - return; - } - if (axis.IsValue()) - { - if (orient == Orient.Horizonal) - { - if (i == 0) - { - var dist = GetLabelPosition(0, 1).x - pos.x; - label.SetTextActive(dist > label.text.GetPreferredWidth()); - } - else if (i == axis.context.labelValueList.Count - 1) - { - var dist = pos.x - GetLabelPosition(0, i - 1).x; - label.SetTextActive(dist > label.text.GetPreferredWidth()); - } - } - else - { - if (i == 0) - { - var dist = GetLabelPosition(0, 1).y - pos.y; - label.SetTextActive(dist > label.text.GetPreferredHeight()); - } - else if (i == axis.context.labelValueList.Count - 1) - { - var dist = pos.y - GetLabelPosition(0, i - 1).y; - label.SetTextActive(dist > label.text.GetPreferredHeight()); - } - } - } - } - - protected void InitAxis(Axis relativedAxis, Orient orient, - float axisStartX, float axisStartY, float axisLength, float relativedLength) - { - Axis axis = component; - chart.InitAxisRuntimeData(axis); - - var objName = ChartCached.GetComponentObjectName(axis); - var axisObj = ChartHelper.AddObject(objName, - chart.transform, - chart.chartMinAnchor, - chart.chartMaxAnchor, - chart.chartPivot, - chart.chartSizeDelta); - - axisObj.SetActive(axis.show); - axisObj.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(axisObj); - - axis.gameObject = axisObj; - axis.context.labelObjectList.Clear(); - - if (!axis.show) - return; - - var axisLabelTextStyle = axis.axisLabel.textStyle; - var dataZoom = chart.GetDataZoomOfAxis(axis); - var splitNumber = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom); - var totalWidth = 0f; - var eachWidth = AxisHelper.GetEachWidth(axis, axisLength, dataZoom); - var gapWidth = axis.boundaryGap ? eachWidth / 2 : 0; - - var textWidth = axis.axisLabel.width > 0 ? - axis.axisLabel.width : - (orient == Orient.Horizonal ? - AxisHelper.GetScaleWidth(axis, axisLength, 0, dataZoom) : - (axisStartX - chart.chartX) - ); - - var textHeight = axis.axisLabel.height > 0 ? - axis.axisLabel.height : - 20f; - - var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series); - var inside = axis.axisLabel.inside; - var defaultAlignment = orient == Orient.Horizonal ? TextAnchor.MiddleCenter : - ((inside && axis.IsLeft()) || (!inside && axis.IsRight()) ? - TextAnchor.MiddleLeft : - TextAnchor.MiddleRight); - - if (axis.IsCategory() && axis.boundaryGap) - splitNumber -= 1; - - for (int i = 0; i < splitNumber; i++) - { - var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom); - var labelName = AxisHelper.GetLabelName(axis, axisLength, i, - axis.context.minValue, - axis.context.maxValue, - dataZoom, isPercentStack); - - var label = ChartHelper.AddAxisLabelObject(splitNumber, i, - ChartCached.GetAxisLabelName(i), - axisObj.transform, - new Vector2(textWidth, textHeight), - axis, chart.theme.axis, labelName, - Color.clear, - defaultAlignment); - - if (i == 0) - axis.axisLabel.SetRelatedText(label.text, labelWidth); - - var pos = GetLabelPosition(totalWidth + gapWidth, i); - label.SetPosition(pos); - CheckValueLabelActive(axis, i, label, pos); - - axis.context.labelObjectList.Add(label); - - totalWidth += labelWidth; - } - if (axis.axisName.show) - { - ChartLabel label = null; - var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset); - var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist); - var offset = axis.axisName.labelStyle.offset; - var autoColor = axis.axisLine.GetColor(chart.theme.axis.lineColor); - if (orient == Orient.Horizonal) - { - var posY = GetAxisLineXOrY() + offset.y; - switch (axis.axisName.labelStyle.position) - { - case LabelStyle.Position.Start: - - label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle, - chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleRight); - label.SetActive(axis.axisName.labelStyle.show); - label.SetPosition(axis.position == Axis.AxisPosition.Top ? - new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset) : - new Vector2(zeroPos.x - offset.x, posY)); - break; - - case LabelStyle.Position.Middle: - - label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle, - chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter); - label.SetActive(axis.axisName.labelStyle.show); - label.SetPosition(axis.position == Axis.AxisPosition.Top ? - new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY + relativedLength - offset.y + axis.offset) : - new Vector2(axisStartX + axisLength / 2 + offset.x, posY)); - break; - - default: - - label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle, - chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleLeft); - label.SetActive(axis.axisName.labelStyle.show); - label.SetPosition(axis.position == Axis.AxisPosition.Top ? - new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset) : - new Vector2(axisStartX + axisLength + offset.x, posY)); - break; - } - } - else - { - var posX = GetAxisLineXOrY() + offset.x; - switch (axis.axisName.labelStyle.position) - { - case LabelStyle.Position.Start: - - label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle, - chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter); - label.SetActive(axis.axisName.labelStyle.show); - label.SetPosition(axis.position == Axis.AxisPosition.Right ? - new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) : - new Vector2(posX, axisStartY - offset.y)); - break; - - case LabelStyle.Position.Middle: - - label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle, - chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter); - label.SetActive(axis.axisName.labelStyle.show); - label.SetPosition(axis.position == Axis.AxisPosition.Right ? - new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) : - new Vector2(posX, axisStartY + axisLength / 2 + offset.y)); - break; - - default: - //LabelStyle.Position - label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle, - chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter); - label.SetActive(axis.axisName.labelStyle.show); - label.SetPosition(axis.position == Axis.AxisPosition.Right ? - new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) : - new Vector2(posX, axisStartY + axisLength + offset.y)); - break; - } - } - } - } - - internal static Vector3 GetLabelPosition(int i, Orient orient, Axis axis, Axis relativedAxis, AxisTheme theme, - float scaleWid, float axisStartX, float axisStartY, float axisLength, float relativedLength) - { - var inside = axis.axisLabel.inside; - var fontSize = axis.axisLabel.textStyle.GetFontSize(theme); - var current = axis.offset; - - if (axis.IsTime() || axis.IsValue()) - { - scaleWid = axis.context.minMaxRange != 0 ? - axis.GetDistance(axis.GetLabelValue(i), axisLength) : - 0; - } - - if (orient == Orient.Horizonal) - { - if (axis.axisLabel.onZero && relativedAxis != null) - axisStartY += relativedAxis.context.offset; - - if (axis.IsTop()) - axisStartY += relativedLength; - - if ((inside && axis.IsBottom()) || (!inside && axis.IsTop())) - current += axisStartY + axis.axisLabel.distance + fontSize / 2; - else - current += axisStartY - axis.axisLabel.distance - fontSize / 2; - - return new Vector3(axisStartX + scaleWid, current) + axis.axisLabel.offset; - } - else - { - if (axis.axisLabel.onZero && relativedAxis != null) - axisStartX += relativedAxis.context.offset; - - if (axis.IsRight()) - axisStartX += relativedLength; - - if ((inside && axis.IsLeft()) || (!inside && axis.IsRight())) - current += axisStartX + axis.axisLabel.distance; - else - current += axisStartX - axis.axisLabel.distance; - - return new Vector3(current, axisStartY + scaleWid) + axis.axisLabel.offset; - } - } - - internal static void DrawAxisLine(VertexHelper vh, Axis axis, AxisTheme theme, Orient orient, - float startX, float startY, float axisLength) - { - var inverse = axis.IsValue() && axis.inverse; - var offset = AxisHelper.GetAxisLineArrowOffset(axis); - - var lineWidth = axis.axisLine.GetWidth(theme.lineWidth); - var lineType = axis.axisLine.GetType(theme.lineType); - var lineColor = axis.axisLine.GetColor(theme.lineColor); - - if (orient == Orient.Horizonal) - { - var left = new Vector3(startX - lineWidth - (inverse ? offset : 0), startY); - var right = new Vector3(startX + axisLength + lineWidth + (!inverse ? offset : 0), startY); - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, left, right, lineColor); - } - else - { - var bottom = new Vector3(startX, startY - lineWidth - (inverse ? offset : 0)); - var top = new Vector3(startX, startY + axisLength + lineWidth + (!inverse ? offset : 0)); - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, bottom, top, lineColor); - } - } - - internal static void DrawAxisTick(VertexHelper vh, Axis axis, AxisTheme theme, DataZoom dataZoom, - Orient orient, float startX, float startY, float axisLength) - { - var lineWidth = axis.axisLine.GetWidth(theme.lineWidth); - var tickLength = axis.axisTick.GetLength(theme.tickLength); - - if (AxisHelper.NeedShowSplit(axis)) - { - var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom); - - var current = orient == Orient.Horizonal ? - startX : - startY; - - for (int i = 0; i < size; i++) - { - var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom); - if (i == 0 && (!axis.axisTick.showStartTick || axis.axisTick.alignWithLabel)) - { - current += scaleWidth; - continue; - } - if (i == size - 1 && !axis.axisTick.showEndTick) - { - current += scaleWidth; - continue; - } - if (axis.axisTick.show) - { - if (orient == Orient.Horizonal) - { - float pX = axis.IsTime() ? - (startX + axis.GetDistance(axis.GetLabelValue(i), axisLength)) : - current; - - if (axis.boundaryGap && axis.axisTick.alignWithLabel) - pX -= scaleWidth / 2; - - var sY = 0f; - var eY = 0f; - if ((axis.axisTick.inside && axis.IsBottom()) || - (!axis.axisTick.inside && axis.IsTop())) - { - sY = startY + axis.offset + lineWidth; - eY = sY + tickLength; - } - else - { - sY = startY + axis.offset - lineWidth; - eY = sY - tickLength; - } - - UGL.DrawLine(vh, new Vector3(pX, sY), new Vector3(pX, eY), - axis.axisTick.GetWidth(theme.tickWidth), - axis.axisTick.GetColor(theme.tickColor)); - } - else - { - float pY = axis.IsTime() ? - (startY + axis.GetDistance(axis.GetLabelValue(i), axisLength)) : - current; - - if (axis.boundaryGap && axis.axisTick.alignWithLabel) - pY -= scaleWidth / 2; - - var sX = 0f; - var eX = 0f; - if ((axis.axisTick.inside && axis.IsLeft()) || - (!axis.axisTick.inside && axis.IsRight())) - { - sX = startX + axis.offset + lineWidth; - eX = sX + tickLength; - } - else - { - sX = startX + axis.offset - lineWidth; - eX = sX - tickLength; - } - - UGL.DrawLine(vh, new Vector3(sX, pY), new Vector3(eX, pY), - axis.axisTick.GetWidth(theme.tickWidth), - axis.axisTick.GetColor(theme.tickColor)); - } - } - current += scaleWidth; - } - } - if (axis.show && axis.axisLine.show && axis.axisLine.showArrow) - { - var lineY = startY + axis.offset; - var inverse = axis.IsValue() && axis.inverse; - var axisArrow = axis.axisLine.arrow; - if (orient == Orient.Horizonal) - { - if (inverse) - { - var startPos = new Vector3(startX + axisLength, lineY); - var arrowPos = new Vector3(startX, lineY); - UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height, - axisArrow.offset, axisArrow.dent, - axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor))); - } - else - { - var arrowPosX = startX + axisLength + lineWidth; - var startPos = new Vector3(startX, lineY); - var arrowPos = new Vector3(arrowPosX, lineY); - UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height, - axisArrow.offset, axisArrow.dent, - axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor))); - } - } - else - { - if (inverse) - { - var startPos = new Vector3(startX, startY + axisLength); - var arrowPos = new Vector3(startX, startY); - UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height, - axisArrow.offset, axisArrow.dent, - axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor))); - } - else - { - var startPos = new Vector3(startX, startY); - var arrowPos = new Vector3(startX, startY + axisLength + lineWidth); - UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height, - axisArrow.offset, axisArrow.dent, - axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor))); - } - } - } - } - - protected void DrawAxisSplit(VertexHelper vh, AxisTheme theme, DataZoom dataZoom, - Orient orient, float startX, float startY, float axisLength, float splitLength, Axis relativedAxis = null) - { - Axis axis = component; - var lineColor = axis.splitLine.GetColor(theme.splitLineColor); - var lineWidth = axis.splitLine.GetWidth(theme.lineWidth); - var lineType = axis.splitLine.GetType(theme.splitLineType); - - var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom); - if (axis.IsTime()) - { - size += 1; - if (!ChartHelper.IsEquals(axis.GetLastLabelValue(), axis.context.maxValue)) - size += 1; - } - - var current = orient == Orient.Horizonal ? - startX : - startY; - for (int i = 0; i < size; i++) - { - var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, axis.IsTime() ? i : i + 1, dataZoom); - - if (axis.boundaryGap && axis.axisTick.alignWithLabel) - current -= scaleWidth / 2; - - if (axis.splitArea.show && i <= size - 1) - { - if (orient == Orient.Horizonal) - { - UGL.DrawQuadrilateral(vh, - new Vector2(current, startY), - new Vector2(current, startY + splitLength), - new Vector2(current + scaleWidth, startY + splitLength), - new Vector2(current + scaleWidth, startY), - axis.splitArea.GetColor(i, theme)); - } - else - { - UGL.DrawQuadrilateral(vh, - new Vector2(startX, current), - new Vector2(startX + splitLength, current), - new Vector2(startX + splitLength, current + scaleWidth), - new Vector2(startX, current + scaleWidth), - axis.splitArea.GetColor(i, theme)); - } - - } - if (axis.splitLine.show) - { - if (axis.splitLine.NeedShow(i)) - { - if (orient == Orient.Horizonal) - { - if (relativedAxis == null || !MathUtil.Approximately(current, GetAxisLineXOrY())) - ChartDrawer.DrawLineStyle(vh, - lineType, - lineWidth, - new Vector3(current, startY), - new Vector3(current, startY + splitLength), - lineColor); - } - else - { - if (relativedAxis == null || !MathUtil.Approximately(current, GetAxisLineXOrY())) - ChartDrawer.DrawLineStyle(vh, - lineType, - lineWidth, - new Vector3(startX, current), - new Vector3(startX + splitLength, current), - lineColor); - } - } - } - current += scaleWidth; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs.meta deleted file mode 100644 index 319549f..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0babef8a2708b4745bbb0a0648913a35 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs b/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs deleted file mode 100644 index 8a1d31e..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs +++ /dev/null @@ -1,561 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class AxisHelper - { - - /// <summary> - /// 包含箭头偏移的轴线长度 - /// </summary> - /// <param name="axis"></param> - /// <returns></returns> - public static float GetAxisLineArrowOffset(Axis axis) - { - if (axis.axisLine.show && axis.axisLine.showArrow && axis.axisLine.arrow.offset > 0) - { - return axis.axisLine.arrow.offset; - } - return 0; - } - - /// <summary> - /// 获得分割段数 - /// </summary> - /// <param name="dataZoom"></param> - /// <returns></returns> - public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom) - { - if (axis.type == Axis.AxisType.Value) - { - return axis.context.labelValueList.Count - 1; - } - else if (axis.type == Axis.AxisType.Time) - { - return axis.context.labelValueList.Count; - } - else if (axis.type == Axis.AxisType.Log) - { - return axis.splitNumber > 0 ? axis.splitNumber : 4; - } - else if (axis.type == Axis.AxisType.Category) - { - int dataCount = axis.GetDataList(dataZoom).Count; - if (!axis.boundaryGap) - dataCount -= 1; - if (dataCount <= 0) - dataCount = 1; - - if (axis.splitNumber <= 0) - { - if (dataCount <= 10) return dataCount; - else - { - for (int i = 4; i < 6; i++) - { - if (dataCount % i == 0) return i; - } - return 5; - } - } - else - { - if (axis.splitNumber <= 0 || axis.splitNumber > dataCount) - return dataCount; - if (dataCount >= axis.splitNumber * 2) - return axis.splitNumber; - else - return dataCount; - } - } - return 0; - } - - /// <summary> - /// 获得一个类目数据在坐标系中代表的宽度 - /// </summary> - /// <param name="coordinateWidth"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom) - { - if (dataCount < 1) - dataCount = 1; - if (axis.IsValue()) - return dataCount > 1 ? coordinateWidth / (dataCount - 1) : coordinateWidth; - var categoryCount = axis.GetDataCount(dataZoom); - int segment = (axis.boundaryGap ? categoryCount : categoryCount - 1); - segment = segment <= 0 ? dataCount : segment; - if (segment <= 0) - segment = 1; - - return coordinateWidth / segment; - } - - /// <summary> - /// 获得标签显示的名称 - /// </summary> - /// <param name="index"></param> - /// <param name="minValue"></param> - /// <param name="maxValue"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public static string GetLabelName(Axis axis, float coordinateWidth, int index, double minValue, double maxValue, - DataZoom dataZoom, bool forcePercent) - { - int split = GetSplitNumber(axis, coordinateWidth, dataZoom); - if (axis.type == Axis.AxisType.Value) - { - if (minValue == 0 && maxValue == 0) - maxValue = axis.max != 0 ? axis.max : 1; - double value = 0; - if (forcePercent) - maxValue = 100; - - value = axis.GetLabelValue(index); - if (axis.inverse) - { - value = -value; - minValue = -minValue; - maxValue = -maxValue; - } - if (forcePercent) - return string.Format("{0}%", (int) value); - else - return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue); - } - else if (axis.type == Axis.AxisType.Log) - { - double value = axis.logBaseE ? - System.Math.Exp(axis.GetLogMinIndex() + index) : - System.Math.Pow(axis.logBase, axis.GetLogMinIndex() + index); - if (axis.inverse) - { - value = -value; - minValue = -minValue; - maxValue = -maxValue; - } - return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue, true); - } - else if (axis.type == Axis.AxisType.Time) - { - if (minValue == 0 && maxValue == 0) - return string.Empty; - if (index > axis.context.labelValueList.Count - 1) - return string.Empty; - - var value = axis.GetLabelValue(index); - return axis.axisLabel.GetFormatterDateTime(index, value, minValue, maxValue); - } - var showData = axis.GetDataList(dataZoom); - int dataCount = showData.Count; - if (dataCount <= 0) - return ""; - int rate = axis.boundaryGap ? (dataCount / split) : (dataCount - 1) / split; - if (rate == 0) rate = 1; - if (axis.insertDataToHead) - { - if (index > 0) - { - var residue = (dataCount - 1) - split * rate; - var newIndex = residue + (index - 1) * rate; - if (newIndex < 0) - newIndex = 0; - return axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]); - } - else - { - if (axis.boundaryGap && coordinateWidth / dataCount > 5) - return string.Empty; - else - return axis.axisLabel.GetFormatterContent(0, showData[0]); - } - } - else - { - int newIndex = index * rate; - if (newIndex < dataCount) - { - return axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]); - } - else - { - if (axis.boundaryGap && coordinateWidth / dataCount > 5) - return string.Empty; - else - return axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]); - } - } - } - - /// <summary> - /// 获得分割线条数 - /// </summary> - /// <param name="dataZoom"></param> - /// <returns></returns> - public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null) - { - int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom); - if (splitNum == 0) - return 0; - - if (axis.IsCategory()) - { - var dataCount = axis.GetDataList(dataZoom).Count; - var scaleNum = 0; - - if (axis.boundaryGap) - { - scaleNum = dataCount > 2 && dataCount % splitNum == 0 ? - splitNum + 1 : - splitNum + 2; - } - else - { - if (dataCount < splitNum) scaleNum = splitNum; - else scaleNum = dataCount > 2 && dataCount % splitNum == 0 ? - splitNum : - splitNum + 1; - } - return scaleNum; - } - else if (axis.IsTime()) - return splitNum; - else - return splitNum + 1; - } - - /// <summary> - /// 获得分割段宽度 - /// </summary> - /// <param name="coordinateWidth"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null) - { - if (index < 0) - return 0; - - int num = GetScaleNumber(axis, coordinateWidth, dataZoom); - int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom); - if (num <= 0) - num = 1; - - if (axis.IsTime() || axis.IsValue()) - { - var value = axis.GetLabelValue(index); - var lastValue = axis.GetLabelValue(index - 1); - return axis.context.minMaxRange == 0 ? - 0 : - (float) (coordinateWidth * (value - lastValue) / axis.context.minMaxRange); - } - else - { - var data = axis.GetDataList(dataZoom); - if (axis.IsCategory() && data.Count > 0) - { - var count = axis.boundaryGap ? data.Count : data.Count - 1; - int tick = count / splitNum; - if (count <= 0) - return 0; - - var each = coordinateWidth / count; - if (axis.insertDataToHead) - { - var max = axis.boundaryGap ? splitNum : splitNum - 1; - if (index == 1) - { - if (axis.axisTick.alignWithLabel) - return each * tick; - else - return coordinateWidth - each * tick * max; - } - else - { - if (count < splitNum) - return each; - else - return each * (count / splitNum); - } - } - else - { - var max = axis.boundaryGap ? num - 1 : num; - if (index >= max) - { - if (axis.axisTick.alignWithLabel) - return each * tick; - else - return coordinateWidth - each * tick * (index - 1); - } - else - { - if (count < splitNum) - return each; - else - return each * (count / splitNum); - } - } - } - else - { - if (splitNum <= 0) - return 0; - else - return coordinateWidth / splitNum; - } - } - } - - public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null) - { - var data = axis.GetDataList(dataZoom); - if (data.Count > 0) - { - var count = axis.boundaryGap ? data.Count : data.Count - 1; - return count > 0 ? coordinateWidth / count : coordinateWidth; - } - else - { - int num = GetScaleNumber(axis, coordinateWidth, dataZoom) - 1; - return num > 0 ? coordinateWidth / num : coordinateWidth; - } - } - - /// <summary> - /// 调整最大最小值 - /// </summary> - /// <param name="minValue"></param> - /// <param name="maxValue"></param> - public static void AdjustMinMaxValue(Axis axis, ref double minValue, ref double maxValue, bool needFormat, int ceilRate = 0) - { - if (axis.type == Axis.AxisType.Log) - { - int minSplit = 0; - int maxSplit = 0; - maxValue = ChartHelper.GetMaxLogValue(maxValue, axis.logBase, axis.logBaseE, out maxSplit); - minValue = ChartHelper.GetMinLogValue(minValue, axis.logBase, axis.logBaseE, out minSplit); - axis.splitNumber = (minSplit > 0 && maxSplit > 0) ? (maxSplit + minSplit - 1) : (maxSplit + minSplit); - return; - } - if (axis.type == Axis.AxisType.Time) - { } - else if (axis.minMaxType == Axis.AxisMinMaxType.Custom) - { - if (axis.min != 0 || axis.max != 0) - { - if (axis.inverse) - { - minValue = -axis.max; - maxValue = -axis.min; - } - else - { - minValue = axis.min; - maxValue = axis.max; - } - } - } - else - { - if (ceilRate == 0) ceilRate = axis.ceilRate; - switch (axis.minMaxType) - { - case Axis.AxisMinMaxType.Default: - - if (minValue == 0 && maxValue == 0) - { } - else if (minValue > 0 && maxValue > 0) - { - minValue = 0; - maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue; - } - else if (minValue < 0 && maxValue < 0) - { - minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue; - maxValue = 0; - } - else - { - minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue; - maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue; - } - break; - - case Axis.AxisMinMaxType.MinMax: - - minValue = ceilRate != 0 ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue; - maxValue = ceilRate != 0 ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue; - break; - } - } - } - - public static bool NeedShowSplit(Axis axis) - { - if (!axis.show) - return false; - if (axis.IsCategory() && axis.GetDataList().Count <= 0) - return false; - else - return true; - } - - public static void AdjustCircleLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset) - { - var txtWidth = txt.text.GetPreferredWidth(); - var sizeDelta = new Vector2(txtWidth, txt.text.GetPreferredHeight()); - txt.text.SetSizeDelta(sizeDelta); - var diff = pos.x - cenPos.x; - if (diff < -1f) //left - { - pos = new Vector3(pos.x - txtWidth / 2, pos.y); - } - else if (diff > 1f) //right - { - pos = new Vector3(pos.x + txtWidth / 2, pos.y); - } - else - { - float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2; - pos = new Vector3(pos.x, y); - } - txt.SetPosition(pos + offset); - } - - public static void AdjustRadiusAxisLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset) - { - var txtWidth = txt.text.GetPreferredWidth(); - var sizeDelta = new Vector2(txtWidth, txt.text.GetPreferredHeight()); - txt.text.SetSizeDelta(sizeDelta); - var diff = pos.y - cenPos.y; - if (diff > 20f) //left - { - pos = new Vector3(pos.x - txtWidth / 2, pos.y); - } - else if (diff < -20f) //right - { - pos = new Vector3(pos.x + txtWidth / 2, pos.y); - } - else - { - float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2; - pos = new Vector3(pos.x, y); - } - txt.SetPosition(pos); - } - - public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null) - { - var gridHeight = axis is YAxis ? grid.context.height : grid.context.width; - var gridXY = axis is YAxis ? grid.context.y : grid.context.x; - if (axis.IsCategory()) - { - if (dataCount == 0) dataCount = axis.data.Count; - var categoryIndex = (int) value; - var scaleWid = AxisHelper.GetDataWidth(axis, gridHeight, dataCount, dataZoom); - float startY = gridXY + (axis.boundaryGap ? scaleWid / 2 : 0); - return startY + scaleWid * categoryIndex; - } - else - { - var yDataHig = (axis.context.minMaxRange == 0) ? 0f : - (float) ((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight); - return gridXY + yDataHig; - - } - } - - public static double GetAxisPositionValue(GridCoord grid, Axis axis, Vector3 pos) - { - if (axis is YAxis) - return GetAxisPositionValue(pos.y, grid.context.height, axis.context.minMaxRange, grid.context.y, axis.context.offset); - else if (axis is XAxis) - return GetAxisPositionValue(pos.x, grid.context.width, axis.context.minMaxRange, grid.context.x, axis.context.offset); - else - return 0; - } - - public static double GetAxisPositionValue(float xy, float axisLength, double axisRange, float axisStart, float axisOffset) - { - var yRate = axisRange / axisLength; - return yRate * (xy - axisStart - axisOffset); - } - - /// <summary> - /// 获得数值value在坐标轴上的坐标位置 - /// </summary> - /// <param name="grid"></param> - /// <param name="axis"></param> - /// <param name="scaleWidth"></param> - /// <param name="value"></param> - /// <returns></returns> - public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value) - { - return GetAxisPositionInternal(grid, axis, scaleWidth, value, true, false); - } - - /// <summary> - /// 获得数值value在坐标轴上相对起点的距离 - /// </summary> - /// <param name="grid"></param> - /// <param name="axis"></param> - /// <param name="scaleWidth"></param> - /// <param name="value"></param> - /// <returns></returns> - public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value) - { - return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, false); - } - - /// <summary> - /// 获得数值value在坐标轴上对应的长度 - /// </summary> - /// <param name="grid"></param> - /// <param name="axis"></param> - /// <param name="scaleWidth"></param> - /// <param name="value"></param> - /// <returns></returns> - public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value) - { - return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, true); - } - - private static float GetAxisPositionInternal(GridCoord grid, Axis axis, float scaleWidth, double value, bool includeGridXY, bool realLength) - { - var isY = axis is YAxis; - var gridHeight = isY ? grid.context.height : grid.context.width; - var gridXY = isY ? grid.context.y : grid.context.x; - - if (axis.IsLog()) - { - int minIndex = axis.GetLogMinIndex(); - float nowIndex = axis.GetLogValue(value); - return includeGridXY ? - gridXY + (nowIndex - minIndex) / axis.splitNumber * gridHeight : - (nowIndex - minIndex) / axis.splitNumber * gridHeight; - } - else if (axis.IsCategory()) - { - var categoryIndex = (int) value; - return includeGridXY ? - gridXY + (axis.boundaryGap ? scaleWidth / 2 : 0) + scaleWidth * categoryIndex : - (axis.boundaryGap ? scaleWidth / 2 : 0) + scaleWidth * categoryIndex; - } - else - { - var yDataHig = 0f; - if (axis.context.minMaxRange != 0) - { - if (realLength) - yDataHig = (float) (value * gridHeight / axis.context.minMaxRange); - else - yDataHig = (float) ((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight); - } - return includeGridXY ? - gridXY + yDataHig : - yDataHig; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs.meta deleted file mode 100644 index ab5a3bc..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 566e3426780cc4339a1fb92d9604d21f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs b/Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs deleted file mode 100644 index acac616..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs +++ /dev/null @@ -1,230 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// Settings related to axis label. - /// |坐标轴刻度标签的相关设置。 - /// </summary> - [Serializable] - public class AxisLabel : LabelStyle - { - [SerializeField] private int m_Interval = 0; - [SerializeField] private bool m_Inside = false; - [SerializeField] private bool m_ShowAsPositiveNumber = false; - [SerializeField] private bool m_OnZero = false; - [SerializeField] private bool m_ShowStartLabel = true; - [SerializeField] private bool m_ShowEndLabel = true; - [SerializeField] private TextLimit m_TextLimit = new TextLimit(); - - /// <summary> - /// The display interval of the axis label. - /// |坐标轴刻度标签的显示间隔,在类目轴中有效。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 - /// </summary> - public int interval - { - get { return m_Interval; } - set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetComponentDirty(); } - } - /// <summary> - /// Set this to true so the axis labels face the inside direction. - /// |刻度标签是否朝内,默认朝外。 - /// </summary> - public bool inside - { - get { return m_Inside; } - set { if (PropertyUtil.SetStruct(ref m_Inside, value)) SetComponentDirty(); } - } - /// <summary> - /// Show negative number as positive number. - /// |将负数数值显示为正数。一般和`Serie`的`showAsPositiveNumber`配合使用。 - /// </summary> - public bool showAsPositiveNumber - { - get { return m_ShowAsPositiveNumber; } - set { if (PropertyUtil.SetStruct(ref m_ShowAsPositiveNumber, value)) SetComponentDirty(); } - } - - /// <summary> - /// 刻度标签显示在0刻度上。 - /// </summary> - public bool onZero - { - get { return m_OnZero; } - set { if (PropertyUtil.SetStruct(ref m_OnZero, value)) SetComponentDirty(); } - } - /// <summary> - /// Whether to display the first label. - /// |是否显示第一个文本。 - /// </summary> - public bool showStartLabel - { - get { return m_ShowStartLabel; } - set { if (PropertyUtil.SetStruct(ref m_ShowStartLabel, value)) SetComponentDirty(); } - } - /// <summary> - /// Whether to display the last label. - /// |是否显示最后一个文本。 - /// </summary> - public bool showEndLabel - { - get { return m_ShowEndLabel; } - set { if (PropertyUtil.SetStruct(ref m_ShowEndLabel, value)) SetComponentDirty(); } - } - /// <summary> - /// 文本限制。 - /// </summary> - public TextLimit textLimit - { - get { return m_TextLimit; } - set { if (value != null) { m_TextLimit = value; SetComponentDirty(); } } - } - - public override bool componentDirty { get { return m_ComponentDirty || m_TextLimit.componentDirty; } } - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - textLimit.ClearComponentDirty(); - } - - public static AxisLabel defaultAxisLabel - { - get - { - return new AxisLabel() - { - m_Show = true, - m_Interval = 0, - m_Inside = false, - m_Distance = 8, - m_TextStyle = new TextStyle(), - }; - } - } - - public new AxisLabel Clone() - { - var axisLabel = new AxisLabel(); - axisLabel.show = show; - axisLabel.formatter = formatter; - axisLabel.interval = interval; - axisLabel.inside = inside; - axisLabel.distance = distance; - axisLabel.numericFormatter = numericFormatter; - axisLabel.width = width; - axisLabel.height = height; - axisLabel.showStartLabel = showStartLabel; - axisLabel.showEndLabel = showEndLabel; - axisLabel.textLimit = textLimit.Clone(); - axisLabel.textStyle.Copy(textStyle); - return axisLabel; - } - - public void Copy(AxisLabel axisLabel) - { - show = axisLabel.show; - formatter = axisLabel.formatter; - interval = axisLabel.interval; - inside = axisLabel.inside; - distance = axisLabel.distance; - numericFormatter = axisLabel.numericFormatter; - width = axisLabel.width; - height = axisLabel.height; - showStartLabel = axisLabel.showStartLabel; - showEndLabel = axisLabel.showEndLabel; - textLimit.Copy(axisLabel.textLimit); - textStyle.Copy(axisLabel.textStyle); - } - - public void SetRelatedText(ChartText txt, float labelWidth) - { - m_TextLimit.SetRelatedText(txt, labelWidth); - } - - public string GetFormatterContent(int labelIndex, string category) - { - if (m_FormatterFunction != null) - { - return m_FormatterFunction(labelIndex, 0, category); - } - if (string.IsNullOrEmpty(category)) - return category; - - if (string.IsNullOrEmpty(m_Formatter)) - { - return m_TextLimit.GetLimitContent(category); - } - else - { - var content = m_Formatter; - FormatterHelper.ReplaceAxisLabelContent(ref content, category); - return m_TextLimit.GetLimitContent(content); - } - } - - public string GetFormatterContent(int labelIndex, double value, double minValue, double maxValue, bool isLog = false) - { - if (showAsPositiveNumber && value < 0) - { - value = Math.Abs(value); - } - if (m_FormatterFunction != null) - { - return m_FormatterFunction(labelIndex, value, null); - } - if (string.IsNullOrEmpty(m_Formatter)) - { - if (isLog) - { - return ChartCached.NumberToStr(value, numericFormatter); - } - if (minValue >= -1 && minValue <= 1 && maxValue >= -1 && maxValue <= 1) - { - int minAcc = ChartHelper.GetFloatAccuracy(minValue); - int maxAcc = ChartHelper.GetFloatAccuracy(maxValue); - int curAcc = ChartHelper.GetFloatAccuracy(value); - int acc = Mathf.Max(Mathf.Max(minAcc, maxAcc), curAcc); - return ChartCached.FloatToStr(value, numericFormatter, acc); - } - return ChartCached.NumberToStr(value, numericFormatter); - } - else - { - var content = m_Formatter; - FormatterHelper.ReplaceAxisLabelContent(ref content, numericFormatter, value); - return content; - } - } - - public string GetFormatterDateTime(int labelIndex, double value, double minValue, double maxValue) - { - if (m_FormatterFunction != null) - { - return m_FormatterFunction(labelIndex, value, null); - } - var timestamp = (int) value; - var dateTime = DateTimeUtil.GetDateTime(timestamp); - var dateString = string.Empty; - if (string.IsNullOrEmpty(numericFormatter)) - { - dateString = DateTimeUtil.GetDateTimeFormatString(dateTime, maxValue - minValue); - } - else - { - dateString = dateTime.ToString(numericFormatter); - } - if (!string.IsNullOrEmpty(m_Formatter)) - { - var content = m_Formatter; - FormatterHelper.ReplaceAxisLabelContent(ref content, dateString); - return m_TextLimit.GetLimitContent(content); - } - else - { - return m_TextLimit.GetLimitContent(dateString); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs.meta deleted file mode 100644 index a735687..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisLabel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 051f9473d1beb4e0bb35aa1600cb44bd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisLine.cs b/Assets/XCharts/Runtime/Component/Axis/AxisLine.cs deleted file mode 100644 index 289a7ad..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisLine.cs +++ /dev/null @@ -1,77 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Settings related to axis line. - /// |坐标轴轴线。 - /// </summary> - [System.Serializable] - public class AxisLine : BaseLine - { - [SerializeField] private bool m_OnZero; - [SerializeField] private bool m_ShowArrow; - [SerializeField] private ArrowStyle m_Arrow = new ArrowStyle(); - - /// <summary> - /// When mutiple axes exists, this option can be used to specify which axis can be "onZero" to. - /// |X 轴或者 Y 轴的轴线是否在另一个轴的 0 刻度上,只有在另一个轴为数值轴且包含 0 刻度时有效。 - /// </summary> - public bool onZero - { - get { return m_OnZero; } - set { if (PropertyUtil.SetStruct(ref m_OnZero, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to show the arrow symbol of axis. - /// |是否显示箭头。 - /// </summary> - public bool showArrow - { - get { return m_ShowArrow; } - set { if (PropertyUtil.SetStruct(ref m_ShowArrow, value)) SetVerticesDirty(); } - } - /// <summary> - /// the arrow of line. - /// |轴线箭头。 - /// </summary> - public ArrowStyle arrow - { - get { return m_Arrow; } - set { if (PropertyUtil.SetClass(ref m_Arrow, value)) SetVerticesDirty(); } - } - public static AxisLine defaultAxisLine - { - get - { - var axisLine = new AxisLine - { - m_Show = true, - m_OnZero = true, - m_ShowArrow = false, - m_Arrow = new ArrowStyle(), - m_LineStyle = new LineStyle(LineStyle.Type.None), - }; - return axisLine; - } - } - - public AxisLine Clone() - { - var axisLine = new AxisLine(); - axisLine.show = show; - axisLine.onZero = onZero; - axisLine.showArrow = showArrow; - axisLine.arrow = arrow.Clone(); - return axisLine; - } - - public void Copy(AxisLine axisLine) - { - base.Copy(axisLine); - onZero = axisLine.onZero; - showArrow = axisLine.showArrow; - arrow.Copy(axisLine.arrow); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisLine.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisLine.cs.meta deleted file mode 100644 index 7551798..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2748c2a8789724709aa76f6056eb708d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisName.cs b/Assets/XCharts/Runtime/Component/Axis/AxisName.cs deleted file mode 100644 index 412df3f..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisName.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// the name of axis. - /// |坐标轴名称。 - /// </summary> - [Serializable] - public class AxisName : ChildComponent - { - [SerializeField] private bool m_Show; - [SerializeField] private string m_Name; - [SerializeField] private LabelStyle m_LabelStyle = new LabelStyle(); - - /// <summary> - /// Whether to show axis name. - /// |是否显示坐标名称。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } - } - /// <summary> - /// the name of axis. - /// |坐标轴名称。 - /// </summary> - public string name - { - get { return m_Name; } - set { if (PropertyUtil.SetClass(ref m_Name, value)) SetComponentDirty(); } - } - /// <summary> - /// The text style of axis name. - /// |文本样式。 - /// </summary> - public LabelStyle labelStyle - { - get { return m_LabelStyle; } - set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); } - } - - public static AxisName defaultAxisName - { - get - { - var axisName = new AxisName() - { - m_Show = false, - m_Name = "axisName", - m_LabelStyle = new LabelStyle() - }; - axisName.labelStyle.position = LabelStyle.Position.End; - return axisName; - } - } - - public AxisName Clone() - { - var axisName = new AxisName(); - axisName.show = show; - axisName.name = name; - axisName.m_LabelStyle.Copy(m_LabelStyle); - return axisName; - } - - public void Copy(AxisName axisName) - { - show = axisName.show; - name = axisName.name; - m_LabelStyle.Copy(axisName.labelStyle); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisName.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisName.cs.meta deleted file mode 100644 index e217ba8..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisName.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 878555ba3c6b1479f94f38185700531e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs b/Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs deleted file mode 100644 index 1440f85..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Split area of axis in grid area, not shown by default. - /// |坐标轴在 grid 区域中的分隔区域,默认不显示。 - /// </summary> - [Serializable] - public class AxisSplitArea : ChildComponent - { - [SerializeField] private bool m_Show; - [SerializeField] private List<Color32> m_Color; - - /// <summary> - /// Set this to true to show the splitArea. - /// |是否显示分隔区域。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// Color of split area. SplitArea color could also be set in color array, - /// which the split lines would take as their colors in turns. - /// Dark and light colors in turns are used by default. - /// |分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。 - /// </summary> - public List<Color32> color - { - get { return m_Color; } - set { if (value != null) { m_Color = value; SetVerticesDirty(); } } - } - - public static AxisSplitArea defaultSplitArea - { - get - { - return new AxisSplitArea() - { - m_Show = false, - m_Color = new List<Color32>() { } - }; - } - } - - public AxisSplitArea Clone() - { - var axisSplitArea = new AxisSplitArea(); - axisSplitArea.show = show; - axisSplitArea.color = new List<Color32>(); - ChartHelper.CopyList(axisSplitArea.color, color); - return axisSplitArea; - } - - public void Copy(AxisSplitArea splitArea) - { - show = splitArea.show; - color.Clear(); - ChartHelper.CopyList(color, splitArea.color); - } - - public Color32 GetColor(int index, BaseAxisTheme theme) - { - if (color.Count > 0) - { - var i = index % color.Count; - return color[i]; - } - else - { - var i = index % theme.splitAreaColors.Count; - return theme.splitAreaColors[i]; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs.meta deleted file mode 100644 index 76dbcd5..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisSplitArea.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 18702fd7797054670af64546b7304bb4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs b/Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs deleted file mode 100644 index 8e34527..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Split line of axis in grid area. - /// |坐标轴在 grid 区域中的分隔线。 - /// </summary> - [Serializable] - public class AxisSplitLine : BaseLine - { - [SerializeField] private int m_Interval; - [SerializeField] private float m_Distance; - [SerializeField] private bool m_AutoColor; - - /// <summary> - /// The distance between the split line and axis line. - /// |刻度线与轴线的距离。 - /// </summary> - public float distance { get { return m_Distance; } set { m_Distance = value; } } - /// <summary> - /// auto color. - /// |自动设置颜色。 - /// </summary> - public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } } - /// <summary> - /// Interval of Axis splitLine. - /// |坐标轴分隔线的显示间隔。 - /// </summary> - public int interval - { - get { return m_Interval; } - set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); } - } - - public override bool vertsDirty { get { return m_VertsDirty || m_LineStyle.anyDirty; } } - public override void ClearVerticesDirty() - { - base.ClearVerticesDirty(); - m_LineStyle.ClearVerticesDirty(); - } - public static AxisSplitLine defaultSplitLine - { - get - { - return new AxisSplitLine() - { - m_Show = false, - }; - } - } - - public AxisSplitLine Clone() - { - var axisSplitLine = new AxisSplitLine(); - axisSplitLine.show = show; - axisSplitLine.interval = interval; - axisSplitLine.lineStyle = lineStyle.Clone(); - return axisSplitLine; - } - - public void Copy(AxisSplitLine splitLine) - { - base.Copy(splitLine); - interval = splitLine.interval; - } - - internal bool NeedShow(int index) - { - return show && (interval == 0 || index % (interval + 1) == 0); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs.meta deleted file mode 100644 index 4b8c3e4..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisSplitLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3da942a7a6bea44e2998ed993c0641ab -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs b/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs deleted file mode 100644 index ff3e719..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs +++ /dev/null @@ -1,110 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Settings related to axis tick. - /// |坐标轴刻度相关设置。 - /// </summary> - [System.Serializable] - public class AxisTick : BaseLine - { - [SerializeField] private bool m_AlignWithLabel; - [SerializeField] private bool m_Inside; - [SerializeField] private bool m_ShowStartTick; - [SerializeField] private bool m_ShowEndTick; - [SerializeField] private float m_Distance; - [SerializeField] protected int m_SplitNumber = 0; - [SerializeField] private bool m_AutoColor; - - /// <summary> - /// The distance between the tick line and axis line. - /// |刻度线与轴线的距离。 - /// </summary> - public float distance { get { return m_Distance; } set { m_Distance = value; } } - - /// <summary> - /// Align axis tick with label, which is available only when boundaryGap is set to be true in category axis. - /// |类目轴中在 boundaryGap 为 true 的时候有效,可以保证刻度线和标签对齐。 - /// </summary> - public bool alignWithLabel - { - get { return m_AlignWithLabel; } - set { if (PropertyUtil.SetStruct(ref m_AlignWithLabel, value)) SetVerticesDirty(); } - } - /// <summary> - /// Set this to true so the axis labels face the inside direction. - /// |坐标轴刻度是否朝内,默认朝外。 - /// </summary> - public bool inside - { - get { return m_Inside; } - set { if (PropertyUtil.SetStruct(ref m_Inside, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to display the first tick. - /// |是否显示第一个刻度。 - /// </summary> - public bool showStartTick - { - get { return m_ShowStartTick; } - set { if (PropertyUtil.SetStruct(ref m_ShowStartTick, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to display the last tick. - /// |是否显示最后一个刻度。 - /// </summary> - public bool showEndTick - { - get { return m_ShowEndTick; } - set { if (PropertyUtil.SetStruct(ref m_ShowEndTick, value)) SetVerticesDirty(); } - } - /// <summary> - /// Number of segments that the axis is split into. - /// |分隔线之间分割的刻度数。 - /// </summary> - public int splitNumber - { - get { return m_SplitNumber; } - set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); } - } - public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } } - - public static AxisTick defaultTick - { - get - { - var tick = new AxisTick - { - m_Show = true, - m_AlignWithLabel = false, - m_Inside = false, - m_ShowStartTick = true, - m_ShowEndTick = true - }; - return tick; - } - } - - public AxisTick Clone() - { - var axisTick = new AxisTick(); - axisTick.show = show; - axisTick.alignWithLabel = alignWithLabel; - axisTick.inside = inside; - axisTick.showStartTick = showStartTick; - axisTick.showEndTick = showEndTick; - axisTick.lineStyle = lineStyle.Clone(); - return axisTick; - } - - public void Copy(AxisTick axisTick) - { - show = axisTick.show; - alignWithLabel = axisTick.alignWithLabel; - inside = axisTick.inside; - showStartTick = axisTick.showStartTick; - showEndTick = axisTick.showEndTick; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs.meta b/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs.meta deleted file mode 100644 index c4fdfad..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 60278762ed892450d85e27b7df8f997e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis.meta b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis.meta deleted file mode 100644 index 7734a7d..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 24693180b2a2e41b2ab4025b2bbebf01 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs deleted file mode 100644 index 18f8605..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [RequireChartComponent(typeof(ParallelCoord))] - [ComponentHandler(typeof(ParallelAxisHander), true)] - public class ParallelAxis : Axis - { - public override void SetDefaultValue() - { - m_Show = true; - m_Type = AxisType.Value; - m_Min = 0; - m_Max = 0; - m_SplitNumber = 0; - m_BoundaryGap = true; - m_Position = AxisPosition.Bottom; - m_Offset = 0; - m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" }; - m_Icons = new List<Sprite>(5); - splitLine.show = false; - splitLine.lineStyle.type = LineStyle.Type.None; - axisLabel.textLimit.enable = true; - } - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs.meta deleted file mode 100644 index 4dd9fa4..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d7bc01c54f4d6485389fd57c37810c74 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs deleted file mode 100644 index 7615222..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs +++ /dev/null @@ -1,167 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class ParallelAxisHander : AxisHandler<ParallelAxis> - { - private Orient m_Orient; - private ParallelCoord m_Parallel; - - protected override Orient orient { get { return m_Orient; } } - - public override void InitComponent() - { - InitParallelAxis(component); - } - - public override void Update() - { - UpdateContext(component); - } - - public override void DrawBase(VertexHelper vh) - { - UpdateContext(component); - DrawParallelAxisSplit(vh, component); - DrawParallelAxisLine(vh, component); - DrawParallelAxisTick(vh, component); - } - - private void UpdateContext(ParallelAxis axis) - { - var parallel = chart.GetChartComponent<ParallelCoord>(axis.parallelIndex); - if (parallel == null) - return; - - m_Orient = parallel.orient; - m_Parallel = parallel; - var axisCount = chart.GetChartComponentNum<ParallelAxis>(); - - if (m_Orient == Orient.Horizonal) - { - var each = axisCount > 1 ? parallel.context.height / (axisCount - 1) : 0; - axis.context.x = parallel.context.x; - axis.context.y = parallel.context.y + (axis.index) * each; - axis.context.width = parallel.context.width; - } - else - { - var each = axisCount > 1 ? parallel.context.width / (axisCount - 1) : 0; - axis.context.x = parallel.context.x + (axis.index) * each; - axis.context.y = parallel.context.y; - axis.context.width = parallel.context.height; - } - axis.context.orient = m_Orient; - axis.context.height = 0; - axis.context.position = new Vector3(axis.context.x, axis.context.y); - } - - private void InitParallelAxis(ParallelAxis axis) - { - var theme = chart.theme; - var xAxisIndex = axis.index; - axis.painter = chart.painter; - axis.refreshComponent = delegate() - { - UpdateContext(axis); - InitAxis(null, - m_Orient, - axis.context.x, - axis.context.y, - axis.context.width, - axis.context.height); - }; - axis.refreshComponent(); - } - - internal override void UpdateAxisLabelText(Axis axis) - { - base.UpdateAxisLabelText(axis); - if (axis.IsTime() || axis.IsValue()) - { - for (int i = 0; i < axis.context.labelObjectList.Count; i++) - { - var label = axis.context.labelObjectList[i]; - if (label != null) - { - var pos = GetLabelPosition(0, i); - label.SetPosition(pos); - CheckValueLabelActive(component, i, label, pos); - } - } - } - } - - protected override Vector3 GetLabelPosition(float scaleWid, int i) - { - if (m_Parallel == null) - return Vector3.zero; - - return GetLabelPosition(i, m_Orient, component, null, - chart.theme.axis, - scaleWid, - component.context.x, - component.context.y, - component.context.width, - component.context.height); - } - - private void DrawParallelAxisSplit(VertexHelper vh, ParallelAxis axis) - { - if (AxisHelper.NeedShowSplit(axis)) - { - if (m_Parallel == null) - return; - - var dataZoom = chart.GetDataZoomOfAxis(axis); - - DrawAxisSplit(vh, chart.theme.axis, dataZoom, - m_Orient, - axis.context.x, - axis.context.y, - axis.context.width, - axis.context.height); - } - } - - private void DrawParallelAxisTick(VertexHelper vh, ParallelAxis axis) - { - if (AxisHelper.NeedShowSplit(axis)) - { - if (m_Parallel == null) - return; - - var dataZoom = chart.GetDataZoomOfAxis(axis); - - DrawAxisTick(vh, axis, chart.theme.axis, dataZoom, - m_Orient, - axis.context.x, - axis.context.y, - axis.context.width); - } - } - - private void DrawParallelAxisLine(VertexHelper vh, ParallelAxis axis) - { - if (axis.show && axis.axisLine.show) - { - if (m_Parallel == null) - return; - - DrawAxisLine(vh, axis, - chart.theme.axis, - m_Orient, - axis.context.x, - axis.context.y, - axis.context.width); - } - } - - protected override float GetAxisLineXOrY() - { - return component.context.y; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs.meta b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs.meta deleted file mode 100644 index 5b82d2f..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 26ab25bf702c54ad38461c91ba1451af -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis.meta b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis.meta deleted file mode 100644 index a418bc2..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7c8971958a94d47e68f7ebdff5872b71 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs deleted file mode 100644 index ab12414..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - /// <summary> - /// Radial axis of polar coordinate. - /// |极坐标系的径向轴。 - /// </summary> - [System.Serializable] - [RequireChartComponent(typeof(PolarCoord))] - [ComponentHandler(typeof(RadiusAxisHandler), true)] - public class RadiusAxis : Axis - { - public override void SetDefaultValue() - { - m_Show = true; - m_Type = AxisType.Value; - m_Min = 0; - m_Max = 0; - m_SplitNumber = 5; - m_BoundaryGap = false; - m_Data = new List<string>(5); - splitLine.show = true; - splitLine.lineStyle.type = LineStyle.Type.Solid; - axisLabel.textLimit.enable = false; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs.meta deleted file mode 100644 index d9c487e..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f6429398a27934726ba49d387d681728 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs deleted file mode 100644 index 630a061..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class RadiusAxisHandler : AxisHandler<RadiusAxis> - { - public override void InitComponent() - { - InitRadiusAxis(component); - } - - public override void Update() - { - UpdateAxisMinMaxValue(component); - UpdatePointerValue(component); - } - - public override void DrawBase(VertexHelper vh) - { - DrawRadiusAxis(vh, component); - } - - protected override void UpdatePointerValue(Axis axis) - { - var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex); - if (polar == null) - return; - - if (!polar.context.isPointerEnter) - { - axis.context.pointerValue = double.PositiveInfinity; - return; - } - - var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index); - if (angleAxis == null) - return; - - var dist = Vector3.Distance(chart.pointerPos, polar.context.center); - axis.context.pointerValue = axis.context.minValue + (dist / polar.context.radius) * axis.context.minMaxRange; - axis.context.pointerLabelPosition = GetLabelPosition(polar, axis, angleAxis.context.startAngle, dist); - } - - private void UpdateAxisMinMaxValue(RadiusAxis axis, bool updateChart = true) - { - if (axis.IsCategory() || !axis.show) return; - double tempMinValue = 0; - double tempMaxValue = 0; - SeriesHelper.GetXMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue, - out tempMaxValue, true); - AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); - if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue) - { - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.offset = 0; - axis.context.lastCheckInverse = axis.inverse; - UpdateAxisTickValueList(axis); - - if (updateChart) - { - UpdateAxisLabelText(axis); - chart.RefreshChart(); - } - } - } - - internal void UpdateAxisLabelText(RadiusAxis axis) - { - var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex); - if (axis.context.labelObjectList.Count <= 0) - InitRadiusAxis(axis); - else - axis.UpdateLabelText(polar.context.radius, null, false); - } - - private void InitRadiusAxis(RadiusAxis axis) - { - var polar = chart.GetChartComponent<PolarCoord>(axis.index); - if (polar == null) - return; - - var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index); - if (angleAxis == null) - return; - - PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight); - axis.context.labelObjectList.Clear(); - var radius = polar.context.radius; - var objName = component.GetType().Name + axis.index; - var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - axisObj.transform.localPosition = Vector3.zero; - axisObj.SetActive(axis.show && axis.axisLabel.show); - axisObj.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(axisObj); - var textStyle = axis.axisLabel.textStyle; - var splitNumber = AxisHelper.GetScaleNumber(axis, radius, null); - var totalWidth = 0f; - var txtHig = textStyle.GetFontSize(chart.theme.axis) + 2; - for (int i = 0; i < splitNumber; i++) - { - var labelWidth = AxisHelper.GetScaleWidth(axis, radius, i + 1, null); - var inside = axis.axisLabel.inside; - var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series); - var labelName = AxisHelper.GetLabelName(axis, radius, i, axis.context.minValue, axis.context.maxValue, - null, isPercentStack); - var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, - new Vector2(labelWidth, txtHig), axis, chart.theme.axis, labelName, Color.clear); - - if (i == 0) - axis.axisLabel.SetRelatedText(label.text, labelWidth); - - label.text.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter)); - label.SetText(labelName); - label.SetPosition(GetLabelPosition(polar, axis, angleAxis.context.startAngle, totalWidth)); - label.SetActive(true); - label.SetTextActive(true); - - axis.context.labelObjectList.Add(label); - - totalWidth += labelWidth; - } - } - - private Vector3 GetLabelPosition(PolarCoord polar, Axis axis, float startAngle, float totalWidth) - { - var cenPos = polar.context.center; - var dire = ChartHelper.GetDire(startAngle, true).normalized; - var tickLength = axis.axisTick.GetLength(chart.theme.axis.tickLength); - var tickVector = ChartHelper.GetVertialDire(dire) * - (tickLength + axis.axisLabel.distance); - return ChartHelper.GetPos(cenPos, totalWidth, startAngle, true) + tickVector; - } - - private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis) - { - var polar = chart.GetChartComponent<PolarCoord>(radiusAxis.polarIndex); - if (polar == null) - return; - - var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index); - if (angleAxis == null) - return; - - var startAngle = angleAxis.context.startAngle; - var radius = polar.context.radius; - var cenPos = polar.context.center; - var size = AxisHelper.GetScaleNumber(radiusAxis, radius, null); - var totalWidth = 0f; - var dire = ChartHelper.GetDire(startAngle, true).normalized; - var tickWidth = radiusAxis.axisTick.GetWidth(chart.theme.axis.tickWidth); - var tickLength = radiusAxis.axisTick.GetLength(chart.theme.axis.tickLength); - var tickVetor = ChartHelper.GetVertialDire(dire) * tickLength; - for (int i = 0; i <= size; i++) - { - var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i); - var pos = ChartHelper.GetPos(cenPos, totalWidth + tickWidth, startAngle, true); - if (radiusAxis.show && radiusAxis.splitLine.show) - { - var outsideRaidus = totalWidth + radiusAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth) * 2; - var splitLineColor = radiusAxis.splitLine.GetColor(chart.theme.axis.splitLineColor); - UGL.DrawDoughnut(vh, cenPos, totalWidth, outsideRaidus, splitLineColor, Color.clear); - } - if (radiusAxis.show && radiusAxis.axisTick.show) - { - if ((i == 0 && radiusAxis.axisTick.showStartTick) || - (i == size && radiusAxis.axisTick.showEndTick) || - (i > 0 && i < size)) - { - UGL.DrawLine(vh, pos, pos + tickVetor, tickWidth, chart.theme.axis.lineColor); - } - } - totalWidth += scaleWidth; - } - if (radiusAxis.show && radiusAxis.axisLine.show) - { - var lineStartPos = polar.context.center - dire * tickWidth; - var lineEndPos = polar.context.center + dire * (radius + tickWidth); - var lineWidth = radiusAxis.axisLine.GetWidth(chart.theme.axis.lineWidth); - UGL.DrawLine(vh, lineStartPos, lineEndPos, lineWidth, chart.theme.axis.lineColor); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs.meta b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs.meta deleted file mode 100644 index 5319e69..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3f2cb79bfe30c4f14a3117f9f30ed3bd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis.meta b/Assets/XCharts/Runtime/Component/Axis/SingleAxis.meta deleted file mode 100644 index 09c6e70..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 17498717d39c14b43a91c67401407410 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs deleted file mode 100644 index 263d37b..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Single axis. - /// |单轴。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(SingleAxisHander), true)] - public class SingleAxis : Axis, IUpdateRuntimeData - { - [SerializeField] protected Orient m_Orient = Orient.Horizonal; - [SerializeField] private float m_Left = 0.1f; - [SerializeField] private float m_Right = 0.1f; - [SerializeField] private float m_Top = 0f; - [SerializeField] private float m_Bottom = 0.2f; - [SerializeField] private float m_Width = 0; - [SerializeField] private float m_Height = 50; - - /// <summary> - /// Orientation of the axis. By default, it's 'Horizontal'. You can set it to be 'Vertical' to make a vertical axis. - /// |坐标轴朝向。默认为水平朝向。 - /// </summary> - public Orient orient - { - get { return m_Orient; } - set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the left side of the container. - /// |组件离容器左侧的距离。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the right side of the container. - /// |组件离容器右侧的距离。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the top side of the container. - /// |组件离容器上侧的距离。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the bottom side of the container. - /// |组件离容器下侧的距离。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); } - } - /// <summary> - /// width of axis. - /// |坐标轴宽。 - /// </summary> - public float width - { - get { return m_Width; } - set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); } - } - /// <summary> - /// height of axis. - /// |坐标轴高。 - /// </summary> - public float height - { - get { return m_Height; } - set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetAllDirty(); } - } - - public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight) - { - context.left = left <= 1 ? left * chartWidth : left; - context.bottom = bottom <= 1 ? bottom * chartHeight : bottom; - context.top = top <= 1 ? top * chartHeight : top; - context.right = right <= 1 ? right * chartWidth : right; - - context.height = height <= 1 ? height * chartHeight : height; - - if (m_Orient == Orient.Horizonal) - { - context.width = width == 0 ? - chartWidth - context.left - context.right : - (width <= 1 ? chartWidth * width : width); - } - else - { - context.width = width == 0 ? - chartHeight - context.top - context.bottom : - (width <= 1 ? chartHeight * width : width); - } - - if (context.left != 0 && context.right == 0) - context.x = chartX + context.left; - else if (context.left == 0 && context.right != 0) - context.x = chartX + chartWidth - context.right - context.width; - else - context.x = chartX + context.left; - - if (context.bottom != 0 && context.top == 0) - context.y = chartY + context.bottom; - else if (context.bottom == 0 && context.top != 0) - context.y = chartY + chartHeight - context.top - context.height; - else - context.y = chartY + context.bottom; - - context.position = new Vector3(context.x, context.y); - } - - public override void SetDefaultValue() - { - m_Show = true; - m_Type = AxisType.Category; - m_Min = 0; - m_Max = 0; - m_SplitNumber = 0; - m_BoundaryGap = true; - m_Position = AxisPosition.Bottom; - m_Offset = 0; - - m_Left = 0.1f; - m_Right = 0.1f; - m_Top = 0; - m_Bottom = 0.2f; - m_Width = 0; - m_Height = 50; - - m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" }; - m_Icons = new List<Sprite>(5); - splitLine.show = false; - splitLine.lineStyle.type = LineStyle.Type.None; - axisLabel.textLimit.enable = true; - axisTick.showStartTick = true; - axisTick.showEndTick = true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs.meta deleted file mode 100644 index 1fe393d..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aeb871d6555744e609bd651306c601a8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs deleted file mode 100644 index cea0476..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs +++ /dev/null @@ -1,125 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class SingleAxisHander : AxisHandler<SingleAxis> - { - protected override Orient orient { get { return component.orient; } } - - public override void InitComponent() - { - InitXAxis(component); - } - - public override void Update() - { - UpdateAxisMinMaxValue(component.index, component); - UpdatePointerValue(component); - } - - public override void DrawBase(VertexHelper vh) - { - DrawSingleAxisSplit(vh, component); - DrawSingleAxisLine(vh, component); - DrawSingleAxisTick(vh, component); - } - - private void InitXAxis(SingleAxis axis) - { - var theme = chart.theme; - var xAxisIndex = axis.index; - axis.painter = chart.painter; - axis.refreshComponent = delegate() - { - axis.UpdateRuntimeData(chart.chartX, - chart.chartY, - chart.chartWidth, - chart.chartHeight); - - InitAxis(null, - axis.orient, - axis.context.x, - axis.context.y, - axis.context.width, - axis.context.height); - }; - axis.refreshComponent(); - } - - internal override void UpdateAxisLabelText(Axis axis) - { - base.UpdateAxisLabelText(axis); - if (axis.IsTime() || axis.IsValue()) - { - for (int i = 0; i < axis.context.labelObjectList.Count; i++) - { - var label = axis.context.labelObjectList[i]; - if (label != null) - { - var pos = GetLabelPosition(0, i); - label.SetPosition(pos); - CheckValueLabelActive(component, i, label, pos); - } - } - } - } - - protected override Vector3 GetLabelPosition(float scaleWid, int i) - { - return GetLabelPosition(i, component.orient, component, null, - chart.theme.axis, - scaleWid, - component.context.x, - component.context.y, - component.context.width, - component.context.height); - } - - private void DrawSingleAxisSplit(VertexHelper vh, SingleAxis axis) - { - if (AxisHelper.NeedShowSplit(axis)) - { - var dataZoom = chart.GetDataZoomOfAxis(axis); - DrawAxisSplit(vh, chart.theme.axis, dataZoom, - axis.orient, - axis.context.x, - axis.context.y, - axis.context.width, - axis.context.height); - } - } - - private void DrawSingleAxisTick(VertexHelper vh, SingleAxis axis) - { - if (AxisHelper.NeedShowSplit(axis)) - { - var dataZoom = chart.GetDataZoomOfAxis(axis); - DrawAxisTick(vh, axis, chart.theme.axis, dataZoom, - axis.orient, - axis.context.x, - axis.context.y, - axis.context.width); - } - } - - private void DrawSingleAxisLine(VertexHelper vh, SingleAxis axis) - { - if (axis.show && axis.axisLine.show) - { - DrawAxisLine(vh, axis, - chart.theme.axis, - axis.orient, - axis.context.x, - GetAxisLineXOrY(), - axis.context.width); - } - } - - protected override float GetAxisLineXOrY() - { - return component.context.y + component.offset; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs.meta b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs.meta deleted file mode 100644 index 59d803e..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 50b3514e3079543ea9000d21d809cad3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/XAxis.meta b/Assets/XCharts/Runtime/Component/Axis/XAxis.meta deleted file mode 100644 index e35422e..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/XAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e5e50f8f0f8bb406b99fb32d6b5c7769 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs b/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs deleted file mode 100644 index 8605906..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// The x axis in cartesian(rectangular) coordinate. - /// |直角坐标系 grid 中的 x 轴。 - /// </summary> - [System.Serializable] - [RequireChartComponent(typeof(GridCoord))] - [ComponentHandler(typeof(XAxisHander), true)] - public class XAxis : Axis - { - public override void SetDefaultValue() - { - m_Show = true; - m_Type = AxisType.Category; - m_Min = 0; - m_Max = 0; - m_SplitNumber = 0; - m_BoundaryGap = true; - m_Position = AxisPosition.Bottom; - m_Offset = 0; - m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" }; - m_Icons = new List<Sprite>(5); - splitLine.show = false; - splitLine.lineStyle.type = LineStyle.Type.None; - axisLabel.textLimit.enable = true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs.meta deleted file mode 100644 index 11c03fd..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0a71be0d36b9745c2894e598b3d9188a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs b/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs deleted file mode 100644 index e4020e0..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs +++ /dev/null @@ -1,152 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class XAxisHander : AxisHandler<XAxis> - { - protected override Orient orient { get { return Orient.Horizonal; } } - - public override void InitComponent() - { - InitXAxis(component); - } - - public override void Update() - { - UpdateAxisMinMaxValue(component.index, component); - UpdatePointerValue(component); - } - - public override void DrawBase(VertexHelper vh) - { - DrawXAxisSplit(vh, component); - DrawXAxisLine(vh, component); - DrawXAxisTick(vh, component); - } - - private void InitXAxis(XAxis xAxis) - { - var theme = chart.theme; - var xAxisIndex = xAxis.index; - xAxis.painter = chart.painter; - xAxis.refreshComponent = delegate() - { - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - if (grid != null) - { - var yAxis = chart.GetChartComponent<YAxis>(xAxis.index); - InitAxis(yAxis, - orient, - grid.context.x, - grid.context.y, - grid.context.width, - grid.context.height); - } - }; - xAxis.refreshComponent(); - } - - internal override void UpdateAxisLabelText(Axis axis) - { - base.UpdateAxisLabelText(axis); - if (axis.IsTime() || axis.IsValue()) - { - for (int i = 0; i < axis.context.labelObjectList.Count; i++) - { - var label = axis.context.labelObjectList[i]; - if (label != null) - { - var pos = GetLabelPosition(0, i); - label.SetPosition(pos); - CheckValueLabelActive(component, i, label, pos); - } - } - } - } - - protected override Vector3 GetLabelPosition(float scaleWid, int i) - { - var grid = chart.GetChartComponent<GridCoord>(component.gridIndex); - if (grid == null) - return Vector3.zero; - - var yAxis = chart.GetChartComponent<YAxis>(component.index); - return GetLabelPosition(i, Orient.Horizonal, component, yAxis, - chart.theme.axis, - scaleWid, - grid.context.x, - grid.context.y, - grid.context.width, - grid.context.height); - } - - private void DrawXAxisSplit(VertexHelper vh, XAxis xAxis) - { - if (AxisHelper.NeedShowSplit(xAxis)) - { - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - if (grid == null) - return; - - var relativedAxis = chart.GetChartComponent<YAxis>(xAxis.gridIndex); - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - - DrawAxisSplit(vh, chart.theme.axis, dataZoom, - Orient.Horizonal, - grid.context.x, - grid.context.y, - grid.context.width, - grid.context.height, - relativedAxis); - } - } - - private void DrawXAxisTick(VertexHelper vh, XAxis xAxis) - { - if (AxisHelper.NeedShowSplit(xAxis)) - { - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - if (grid == null) - return; - - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - - DrawAxisTick(vh, xAxis, chart.theme.axis, dataZoom, - Orient.Horizonal, - grid.context.x, - GetAxisLineXOrY(), - grid.context.width); - } - } - - private void DrawXAxisLine(VertexHelper vh, XAxis xAxis) - { - if (xAxis.show && xAxis.axisLine.show) - { - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - if (grid == null) - return; - - DrawAxisLine(vh, xAxis, chart.theme.axis, - Orient.Horizonal, - grid.context.x, - GetAxisLineXOrY(), - grid.context.width); - } - } - - protected override float GetAxisLineXOrY() - { - var xAxis = component; - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - var startY = grid.context.y + xAxis.offset; - if (xAxis.IsTop()) - startY += grid.context.height; - else - startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis); - return startY; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs.meta b/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs.meta deleted file mode 100644 index 79717bd..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d7818e1175663412196de53f19b5ac08 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/YAxis.meta b/Assets/XCharts/Runtime/Component/Axis/YAxis.meta deleted file mode 100644 index ef2fe9c..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/YAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 69f8ba8fcc7d84b12b42f837f9f2b94b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs b/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs deleted file mode 100644 index aee2bd1..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - /// <summary> - /// The x axis in cartesian(rectangular) coordinate. - /// |直角坐标系 grid 中的 y 轴。 - /// </summary> - [System.Serializable] - [RequireChartComponent(typeof(GridCoord), typeof(XAxis))] - [ComponentHandler(typeof(YAxisHander), true)] - public class YAxis : Axis - { - public override void SetDefaultValue() - { - m_Show = true; - m_Type = AxisType.Value; - m_Min = 0; - m_Max = 0; - m_SplitNumber = 0; - m_BoundaryGap = false; - m_Position = AxisPosition.Left; - m_Data = new List<string>(5); - splitLine.show = true; - splitLine.lineStyle.type = LineStyle.Type.None; - axisLabel.textLimit.enable = false; - axisTick.showStartTick = true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs.meta b/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs.meta deleted file mode 100644 index 2e38816..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6ac60b8329f7a45c3898c7539d78f091 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs b/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs deleted file mode 100644 index 5d91b08..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs +++ /dev/null @@ -1,149 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class YAxisHander : AxisHandler<YAxis> - { - protected override Orient orient { get { return Orient.Vertical; } } - - public override void InitComponent() - { - InitYAxis(component); - } - - public override void Update() - { - UpdateAxisMinMaxValue(component.index, component); - UpdatePointerValue(component); - } - - public override void DrawBase(VertexHelper vh) - { - DrawYAxisSplit(vh, component.index, component); - DrawYAxisLine(vh, component.index, component); - DrawYAxisTick(vh, component.index, component); - } - - private void InitYAxis(YAxis yAxis) - { - var theme = chart.theme; - var yAxisIndex = yAxis.index; - yAxis.painter = chart.painter; - yAxis.refreshComponent = delegate() - { - var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex); - if (grid != null) - { - var xAxis = chart.GetChartComponent<YAxis>(yAxis.index); - InitAxis(xAxis, - orient, - grid.context.x, - grid.context.y, - grid.context.height, - grid.context.width); - } - }; - yAxis.refreshComponent(); - } - - internal override void UpdateAxisLabelText(Axis axis) - { - base.UpdateAxisLabelText(axis); - if (axis.IsTime() || axis.IsValue()) - { - for (int i = 0; i < axis.context.labelObjectList.Count; i++) - { - var label = axis.context.labelObjectList[i]; - if (label != null) - { - var pos = GetLabelPosition(0, i); - label.SetPosition(pos); - CheckValueLabelActive(axis, i, label, pos); - } - } - } - } - - protected override Vector3 GetLabelPosition(float scaleWid, int i) - { - var grid = chart.GetChartComponent<GridCoord>(component.gridIndex); - if (grid == null) - return Vector3.zero; - - return GetLabelPosition(i, Orient.Vertical, component, null, - chart.theme.axis, - scaleWid, - grid.context.x, - grid.context.y, - grid.context.height, - grid.context.width); - } - - private void DrawYAxisSplit(VertexHelper vh, int yAxisIndex, YAxis yAxis) - { - if (AxisHelper.NeedShowSplit(yAxis)) - { - var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex); - if (grid == null) - return; - var relativedAxis = chart.GetChartComponent<XAxis>(yAxis.gridIndex); - var dataZoom = chart.GetDataZoomOfAxis(yAxis); - DrawAxisSplit(vh, chart.theme.axis, dataZoom, - Orient.Vertical, - grid.context.x, - grid.context.y, - grid.context.height, - grid.context.width, - relativedAxis); - } - } - - private void DrawYAxisTick(VertexHelper vh, int yAxisIndex, YAxis yAxis) - { - if (AxisHelper.NeedShowSplit(yAxis)) - { - var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex); - if (grid == null) - return; - - var dataZoom = chart.GetDataZoomOfAxis(yAxis); - - DrawAxisTick(vh, yAxis, chart.theme.axis, dataZoom, - Orient.Vertical, - GetAxisLineXOrY(), - grid.context.y, - grid.context.height); - } - } - - private void DrawYAxisLine(VertexHelper vh, int yAxisIndex, YAxis yAxis) - { - if (yAxis.show && yAxis.axisLine.show) - { - var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex); - if (grid == null) - return; - - DrawAxisLine(vh, yAxis, chart.theme.axis, - Orient.Vertical, - GetAxisLineXOrY(), - grid.context.y, - grid.context.height); - } - } - - protected override float GetAxisLineXOrY() - { - var yAxis = component; - var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex); - var startX = grid.context.x + yAxis.offset; - if (yAxis.IsRight()) - startX += grid.context.width; - else - startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis); - return startX; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs.meta b/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs.meta deleted file mode 100644 index 0ea465d..0000000 --- a/Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f09b5dcb5fcc54583bcd7946f18dfa48 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Background.meta b/Assets/XCharts/Runtime/Component/Background.meta deleted file mode 100644 index 15e2676..0000000 --- a/Assets/XCharts/Runtime/Component/Background.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7db6fdcbbbfd148f58ff7a1f1a569d51 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Background/Background.cs b/Assets/XCharts/Runtime/Component/Background/Background.cs deleted file mode 100644 index 68f212c..0000000 --- a/Assets/XCharts/Runtime/Component/Background/Background.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// Background component. - /// | - /// 背景组件。 - /// </summary> - [Serializable] - [DisallowMultipleComponent] - [ComponentHandler(typeof(BackgroundHandler), false)] - public class Background : MainComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private Sprite m_Image; - [SerializeField] private Image.Type m_ImageType; - [SerializeField] private Color m_ImageColor = Color.white; - [SerializeField] private bool m_AutoColor = true; - - /// <summary> - /// Whether to enable the background component. - /// |是否启用背景组件。 - /// </summary> - public bool show - { - get { return m_Show; } - internal set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } - } - /// <summary> - /// the image of background. - /// |背景图。 - /// </summary> - public Sprite image - { - get { return m_Image; } - set { if (PropertyUtil.SetClass(ref m_Image, value)) SetComponentDirty(); } - } - - /// <summary> - /// the fill type of background image. - /// |背景图填充类型。 - /// </summary> - public Image.Type imageType - { - get { return m_ImageType; } - set { if (PropertyUtil.SetStruct(ref m_ImageType, value)) SetComponentDirty(); } - } - - /// <summary> - /// 背景图颜色。 - /// </summary> - public Color imageColor - { - get { return m_ImageColor; } - set { if (PropertyUtil.SetColor(ref m_ImageColor, value)) SetComponentDirty(); } - } - - /// <summary> - /// Whether to use theme background color for component color when the background component is on. - /// |当background组件开启时,是否自动使用主题背景色作为backgrounnd组件的颜色。当设置为false时,用imageColor作为颜色。 - /// </summary> - public bool autoColor - { - get { return m_AutoColor; } - set { if (PropertyUtil.SetStruct(ref m_AutoColor, value)) SetVerticesDirty(); } - } - - public override void SetDefaultValue() - { - m_Show = true; - m_Image = null; - m_ImageType = Image.Type.Sliced; - m_ImageColor = Color.white; - m_AutoColor = true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Background/Background.cs.meta b/Assets/XCharts/Runtime/Component/Background/Background.cs.meta deleted file mode 100644 index e531dbc..0000000 --- a/Assets/XCharts/Runtime/Component/Background/Background.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 524f7df5241cc4379ae241a73d5b2ff2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs b/Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs deleted file mode 100644 index e99535c..0000000 --- a/Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class BackgroundHandler : MainComponentHandler<Background> - { - private readonly string s_BackgroundObjectName = "background"; - public override void InitComponent() - { - component.painter = chart.painter; - component.refreshComponent = delegate() - { - var backgroundObj = ChartHelper.AddObject(s_BackgroundObjectName, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - component.gameObject = backgroundObj; - backgroundObj.hideFlags = chart.chartHideFlags; - - var backgroundImage = ChartHelper.GetOrAddComponent<Image>(backgroundObj); - ChartHelper.UpdateRectTransform(backgroundObj, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - backgroundImage.sprite = component.image; - backgroundImage.type = component.imageType; - backgroundImage.color = chart.theme.GetBackgroundColor(component); - - backgroundObj.transform.SetSiblingIndex(0); - backgroundObj.SetActive(component.show); - }; - component.refreshComponent(); - } - - public override void Update() - { - if (component.gameObject != null && component.gameObject.transform.GetSiblingIndex() != 0) - component.gameObject.transform.SetSiblingIndex(0); - } - - public override void DrawBase(VertexHelper vh) - { - if (!component.show) - return; - if (component.image != null) - return; - - var p1 = new Vector3(chart.chartX, chart.chartY + chart.chartHeight); - var p2 = new Vector3(chart.chartX + chart.chartWidth, chart.chartY + chart.chartHeight); - var p3 = new Vector3(chart.chartX + chart.chartWidth, chart.chartY); - var p4 = new Vector3(chart.chartX, chart.chartY); - var backgroundColor = chart.theme.GetBackgroundColor(component); - - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, backgroundColor); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs.meta b/Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs.meta deleted file mode 100644 index 89ce4b6..0000000 --- a/Assets/XCharts/Runtime/Component/Background/BackgroundHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f1cb3d1a2aa224bbe84eef2681cf3df4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child.meta b/Assets/XCharts/Runtime/Component/Child.meta deleted file mode 100644 index 3f52f89..0000000 --- a/Assets/XCharts/Runtime/Component/Child.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 20d31ade0390641698e6b846b4294b74 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/AreaStyle.cs b/Assets/XCharts/Runtime/Component/Child/AreaStyle.cs deleted file mode 100644 index 0b4a45b..0000000 --- a/Assets/XCharts/Runtime/Component/Child/AreaStyle.cs +++ /dev/null @@ -1,131 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// The style of area. - /// |区域填充样式。 - /// </summary> - [System.Serializable] - public class AreaStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent - { - /// <summary> - /// Origin position of area. - /// |图形区域的起始位置。默认情况下,图形会从坐标轴轴线到数据间进行填充。如果需要填充的区域是坐标轴最大值到数据间,或者坐标轴最小值到数据间,则可以通过这个配置项进行设置。 - /// </summary> - public enum AreaOrigin - { - /// <summary> - /// to fill between axis line to data. - /// |填充坐标轴轴线到数据间的区域。 - /// </summary> - Auto, - /// <summary> - /// to fill between min axis value (when not inverse) to data. - /// |填充坐标轴底部到数据间的区域。 - /// </summary> - Start, - /// <summary> - /// to fill between max axis value (when not inverse) to data. - /// |填充坐标轴顶部到数据间的区域。 - /// </summary> - End - } - - [SerializeField] private bool m_Show = true; - [SerializeField] private AreaOrigin m_Origin; - [SerializeField] private Color32 m_Color; - [SerializeField] private Color32 m_ToColor; - [SerializeField][Range(0, 1)] private float m_Opacity = 0.6f; - [SerializeField] private Color32 m_HighlightColor; - [SerializeField] private Color32 m_HighlightToColor; - - /// <summary> - /// Set this to false to prevent the areafrom showing. - /// |是否显示区域填充。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// the origin of area. - /// |区域填充的起始位置。 - /// </summary> - public AreaOrigin origin - { - get { return m_Origin; } - set { if (PropertyUtil.SetStruct(ref m_Origin, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of area,default use serie color. - /// |区域填充的颜色,如果toColor不是默认值,则表示渐变色的起点颜色。 - /// </summary> - public Color32 color - { - get { return m_Color; } - set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); } - } - /// <summary> - /// Gradient color, start color to toColor. - /// |渐变色的终点颜色。 - /// </summary> - public Color32 toColor - { - get { return m_ToColor; } - set { if (PropertyUtil.SetColor(ref m_ToColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// Opacity of the component. Supports value from 0 to 1, and the component will not be drawn when set to 0. - /// |图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 - /// </summary> - public float opacity - { - get { return m_Opacity; } - set { if (PropertyUtil.SetStruct(ref m_Opacity, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of area,default use serie color. - /// |高亮时区域填充的颜色,如果highlightToColor不是默认值,则表示渐变色的起点颜色。 - /// </summary> - public Color32 highlightColor - { - get { return m_HighlightColor; } - set { if (PropertyUtil.SetColor(ref m_HighlightColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// Gradient color, start highlightColor to highlightToColor. - /// |高亮时渐变色的终点颜色。 - /// </summary> - public Color32 highlightToColor - { - get { return m_HighlightToColor; } - set { if (PropertyUtil.SetColor(ref m_HighlightToColor, value)) SetVerticesDirty(); } - } - - public Color32 GetColor() - { - if (m_Opacity == 1) - return m_Color; - - var color = m_Color; - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetColor(Color32 themeColor) - { - if (!ChartHelper.IsClearColor(color)) - { - return GetColor(); - } - else - { - var color = themeColor; - color.a = (byte) (color.a * opacity); - return color; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/AreaStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/AreaStyle.cs.meta deleted file mode 100644 index 53d0f68..0000000 --- a/Assets/XCharts/Runtime/Component/Child/AreaStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ec0d95a9298bb4c159dcae36020beec9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs b/Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs deleted file mode 100644 index 1b78233..0000000 --- a/Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// </summary> - [Serializable] - public class ArrowStyle : ChildComponent - { - [SerializeField] private float m_Width = 10; - [SerializeField] private float m_Height = 15; - [SerializeField] private float m_Offset = 0; - [SerializeField] private float m_Dent = 3; - [SerializeField] private Color32 m_Color = Color.clear; - - /// <summary> - /// The widht of arrow. - /// |箭头宽。 - /// </summary> - public float width - { - get { return m_Width; } - set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetVerticesDirty(); } - } - /// <summary> - /// The height of arrow. - /// |箭头高。 - /// </summary> - public float height - { - get { return m_Height; } - set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetVerticesDirty(); } - } - /// <summary> - /// The offset of arrow. - /// |箭头偏移。 - /// </summary> - public float offset - { - get { return m_Offset; } - set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetVerticesDirty(); } - } - /// <summary> - /// The dent of arrow. - /// |箭头的凹度。 - /// </summary> - public float dent - { - get { return m_Dent; } - set { if (PropertyUtil.SetStruct(ref m_Dent, value)) SetVerticesDirty(); } - } - - /// <summary> - /// the color of arrow. - /// |箭头颜色。 - /// </summary> - public Color32 color - { - get { return m_Color; } - set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); } - } - - public ArrowStyle Clone() - { - var arrow = new ArrowStyle(); - arrow.width = width; - arrow.height = height; - arrow.offset = offset; - arrow.dent = dent; - arrow.color = color; - return arrow; - } - - public void Copy(ArrowStyle arrow) - { - width = arrow.width; - height = arrow.height; - offset = arrow.offset; - dent = arrow.dent; - color = arrow.color; - } - - public Color32 GetColor(Color32 defaultColor) - { - if (ChartHelper.IsClearColor(color)) - return defaultColor; - else - return color; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs.meta deleted file mode 100644 index 002958e..0000000 --- a/Assets/XCharts/Runtime/Component/Child/ArrowStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2232b812c68f042d29c44863e38d0417 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/BaseLine.cs b/Assets/XCharts/Runtime/Component/Child/BaseLine.cs deleted file mode 100644 index 5472b77..0000000 --- a/Assets/XCharts/Runtime/Component/Child/BaseLine.cs +++ /dev/null @@ -1,82 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Settings related to base line. - /// |线条基础配置。 - /// </summary> - [System.Serializable] - public class BaseLine : ChildComponent - { - [SerializeField] protected bool m_Show; - [SerializeField] protected LineStyle m_LineStyle = new LineStyle(); - - /// <summary> - /// Set this to false to prevent the axis line from showing. - /// |是否显示坐标轴轴线。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// 线条样式 - /// </summary> - public LineStyle lineStyle - { - get { return m_LineStyle; } - set { if (value != null) { m_LineStyle = value; SetVerticesDirty(); } } - } - - public static BaseLine defaultBaseLine - { - get - { - var axisLine = new BaseLine - { - m_Show = true, - m_LineStyle = new LineStyle() - }; - return axisLine; - } - } - - public BaseLine() - { - lineStyle = new LineStyle(); - } - - public BaseLine(bool show) : base() - { - m_Show = show; - } - - public void Copy(BaseLine axisLine) - { - show = axisLine.show; - lineStyle.Copy(axisLine.lineStyle); - } - - public LineStyle.Type GetType(LineStyle.Type themeType) - { - return lineStyle.GetType(themeType); - } - - public float GetWidth(float themeWidth) - { - return lineStyle.GetWidth(themeWidth); - } - - public float GetLength(float themeLength) - { - return lineStyle.GetLength(themeLength); - } - - public Color32 GetColor(Color32 themeColor) - { - return lineStyle.GetColor(themeColor); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/BaseLine.cs.meta b/Assets/XCharts/Runtime/Component/Child/BaseLine.cs.meta deleted file mode 100644 index de0a9fa..0000000 --- a/Assets/XCharts/Runtime/Component/Child/BaseLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c431b00ccffe4db4b61179b6df06eb2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/IconStyle.cs b/Assets/XCharts/Runtime/Component/Child/IconStyle.cs deleted file mode 100644 index 17d847c..0000000 --- a/Assets/XCharts/Runtime/Component/Child/IconStyle.cs +++ /dev/null @@ -1,118 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class IconStyle : ChildComponent - { - public enum Layer - { - /// <summary> - /// The icon is display under the label text. - /// 图标在标签文字下 - /// </summary> - UnderText, - /// <summary> - /// The icon is display above the label text. - /// 图标在标签文字上 - /// </summary> - AboveText - } - - [SerializeField] private bool m_Show = false; - [SerializeField] private Layer m_Layer; - [SerializeField] private Align m_Align = Align.Left; - [SerializeField] private Sprite m_Sprite; - [SerializeField] private Image.Type m_Type; - [SerializeField] private Color m_Color = Color.white; - [SerializeField] private float m_Width = 20; - [SerializeField] private float m_Height = 20; - [SerializeField] private Vector3 m_Offset; - [SerializeField] private bool m_AutoHideWhenLabelEmpty = false; - - public void Reset() - { - m_Show = false; - m_Layer = Layer.UnderText; - m_Sprite = null; - m_Color = Color.white; - m_Width = 20; - m_Height = 20; - m_Offset = Vector3.zero; - m_AutoHideWhenLabelEmpty = false; - } - /// <summary> - /// Whether the data icon is show. - /// |是否显示图标。 - /// </summary> - public bool show { get { return m_Show; } set { m_Show = value; } } - /// <summary> - /// 显示在上层还是在下层。 - /// </summary> - public Layer layer { get { return m_Layer; } set { m_Layer = value; } } - /// <summary> - /// The image of icon. - /// |图标的图片。 - /// </summary> - public Sprite sprite { get { return m_Sprite; } set { m_Sprite = value; } } - /// <summary> - /// How to display the icon. - /// |图片的显示类型。 - /// </summary> - public Image.Type type { get { return m_Type; } set { m_Type = value; } } - /// <summary> - /// 图标颜色。 - /// </summary> - public Color color { get { return m_Color; } set { m_Color = value; } } - /// <summary> - /// 图标宽。 - /// </summary> - public float width { get { return m_Width; } set { m_Width = value; } } - /// <summary> - /// 图标高。 - /// </summary> - public float height { get { return m_Height; } set { m_Height = value; } } - /// <summary> - /// 图标偏移。 - /// </summary> - public Vector3 offset { get { return m_Offset; } set { m_Offset = value; } } - /// <summary> - /// 水平方向对齐方式。 - /// </summary> - public Align align { get { return m_Align; } set { m_Align = value; } } - /// <summary> - /// 当label内容为空时是否自动隐藏图标 - /// </summary> - public bool autoHideWhenLabelEmpty { get { return m_AutoHideWhenLabelEmpty; } set { m_AutoHideWhenLabelEmpty = value; } } - public IconStyle Clone() - { - var iconStyle = new IconStyle(); - iconStyle.show = show; - iconStyle.layer = layer; - iconStyle.sprite = sprite; - iconStyle.type = type; - iconStyle.color = color; - iconStyle.width = width; - iconStyle.height = height; - iconStyle.offset = offset; - iconStyle.align = align; - iconStyle.autoHideWhenLabelEmpty = autoHideWhenLabelEmpty; - return iconStyle; - } - - public void Copy(IconStyle iconStyle) - { - show = iconStyle.show; - layer = iconStyle.layer; - sprite = iconStyle.sprite; - type = iconStyle.type; - color = iconStyle.color; - width = iconStyle.width; - height = iconStyle.height; - offset = iconStyle.offset; - align = iconStyle.align; - autoHideWhenLabelEmpty = iconStyle.autoHideWhenLabelEmpty; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/IconStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/IconStyle.cs.meta deleted file mode 100644 index 53609da..0000000 --- a/Assets/XCharts/Runtime/Component/Child/IconStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 82c4d360f7b5b4ee7845e9bbe611c8a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/ImageStyle.cs b/Assets/XCharts/Runtime/Component/Child/ImageStyle.cs deleted file mode 100644 index d37b392..0000000 --- a/Assets/XCharts/Runtime/Component/Child/ImageStyle.cs +++ /dev/null @@ -1,81 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class ImageStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private Sprite m_Sprite; - [SerializeField] private Image.Type m_Type; - [SerializeField] private bool m_AutoColor; - [SerializeField] private Color m_Color = Color.clear; - [SerializeField] private float m_Width = 0; - [SerializeField] private float m_Height = 0; - - public void Reset() - { - m_Show = false; - m_Type = Image.Type.Simple; - m_Sprite = null; - m_AutoColor = false; - m_Color = Color.white; - m_Width = 0; - m_Height = 0; - } - - /// <summary> - /// Whether the data icon is show. - /// |是否显示图标。 - /// </summary> - public bool show { get { return m_Show; } set { m_Show = value; } } - /// <summary> - /// The image of icon. - /// |图标的图片。 - /// </summary> - public Sprite sprite { get { return m_Sprite; } set { m_Sprite = value; } } - /// <summary> - /// How to display the image. - /// |图片的显示类型。 - /// </summary> - public Image.Type type { get { return m_Type; } set { m_Type = value; } } - /// <summary> - /// 是否自动颜色。 - /// </summary> - public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } } - /// <summary> - /// 图标颜色。 - /// </summary> - public Color color { get { return m_Color; } set { m_Color = value; } } - /// <summary> - /// 图标宽。 - /// </summary> - public float width { get { return m_Width; } set { m_Width = value; } } - /// <summary> - /// 图标高。 - /// </summary> - public float height { get { return m_Height; } set { m_Height = value; } } - public ImageStyle Clone() - { - var imageStyle = new ImageStyle(); - imageStyle.type = type; - imageStyle.sprite = sprite; - imageStyle.autoColor = autoColor; - imageStyle.color = color; - imageStyle.width = width; - imageStyle.height = height; - return imageStyle; - } - - public void Copy(ImageStyle imageStyle) - { - type = imageStyle.type; - sprite = imageStyle.sprite; - autoColor = imageStyle.autoColor; - color = imageStyle.color; - width = imageStyle.width; - height = imageStyle.height; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/ImageStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/ImageStyle.cs.meta deleted file mode 100644 index 8e9356e..0000000 --- a/Assets/XCharts/Runtime/Component/Child/ImageStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5a76d1129783c4f55b0773da2eda9b67 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/ItemStyle.cs b/Assets/XCharts/Runtime/Component/Child/ItemStyle.cs deleted file mode 100644 index 79e9403..0000000 --- a/Assets/XCharts/Runtime/Component/Child/ItemStyle.cs +++ /dev/null @@ -1,350 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 图形样式。 - /// </summary> - [System.Serializable] - public class ItemStyle : ChildComponent, ISerieDataComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private Color32 m_Color; - [SerializeField] private Color32 m_Color0; - [SerializeField] private Color32 m_ToColor; - [SerializeField] private Color32 m_ToColor2; - [SerializeField] private Color32 m_BackgroundColor; - [SerializeField] private float m_BackgroundWidth; - [SerializeField] private Color32 m_CenterColor; - [SerializeField] private float m_CenterGap; - [SerializeField] private float m_BorderWidth = 0; - [SerializeField] private float m_BorderGap = 0; - [SerializeField] private Color32 m_BorderColor; - [SerializeField] private Color32 m_BorderColor0; - [SerializeField] private Color32 m_BorderToColor; - [SerializeField][Range(0, 1)] private float m_Opacity = 1; - [SerializeField] private string m_ItemMarker; - [SerializeField] private string m_ItemFormatter; - [SerializeField] private string m_NumericFormatter = ""; - [SerializeField] private float[] m_CornerRadius = new float[] { 0, 0, 0, 0 }; - - public void Reset() - { - m_Show = false; - m_Color = Color.clear; - m_Color0 = Color.clear; - m_ToColor = Color.clear; - m_ToColor2 = Color.clear; - m_BackgroundColor = Color.clear; - m_BackgroundWidth = 0; - m_CenterColor = Color.clear; - m_CenterGap = 0; - m_BorderWidth = 0; - m_BorderGap = 0; - m_BorderColor = Color.clear; - m_BorderColor0 = Color.clear; - m_BorderToColor = Color.clear; - m_Opacity = 1; - m_ItemFormatter = null; - m_ItemMarker = null; - m_NumericFormatter = ""; - if (m_CornerRadius == null) - { - m_CornerRadius = new float[] { 0, 0, 0, 0 }; - } - else - { - for (int i = 0; i < m_CornerRadius.Length; i++) - m_CornerRadius[i] = 0; - } - } - - /// <summary> - /// 是否启用。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// 数据项颜色。 - /// </summary> - public Color32 color - { - get { return m_Color; } - set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); } - } - /// <summary> - /// 数据项颜色。 - /// </summary> - public Color32 color0 - { - get { return m_Color0; } - set { if (PropertyUtil.SetColor(ref m_Color0, value)) SetVerticesDirty(); } - } - /// <summary> - /// Gradient color1. - /// |渐变色的颜色1。 - /// </summary> - public Color32 toColor - { - get { return m_ToColor; } - set { if (PropertyUtil.SetColor(ref m_ToColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// Gradient color2.Only valid in line diagrams. - /// |渐变色的颜色2。只在折线图中有效。 - /// </summary> - public Color32 toColor2 - { - get { return m_ToColor2; } - set { if (PropertyUtil.SetColor(ref m_ToColor2, value)) SetVerticesDirty(); } - } - /// <summary> - /// 数据项背景颜色。 - /// </summary> - public Color32 backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_BackgroundColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// 数据项背景宽度。 - /// </summary> - public float backgroundWidth - { - get { return m_BackgroundWidth; } - set { if (PropertyUtil.SetStruct(ref m_BackgroundWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// 中心区域颜色。 - /// </summary> - public Color32 centerColor - { - get { return m_CenterColor; } - set { if (PropertyUtil.SetColor(ref m_CenterColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// 中心区域间隙。 - /// </summary> - public float centerGap - { - get { return m_CenterGap; } - set { if (PropertyUtil.SetStruct(ref m_CenterGap, value)) SetVerticesDirty(); } - } - /// <summary> - /// 边框的颜色。 - /// </summary> - public Color32 borderColor - { - get { return m_BorderColor; } - set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// 边框的颜色。 - /// </summary> - public Color32 borderColor0 - { - get { return m_BorderColor0; } - set { if (PropertyUtil.SetColor(ref m_BorderColor0, value)) SetVerticesDirty(); } - } - /// <summary> - /// 边框的渐变色。 - /// </summary> - public Color32 borderToColor - { - get { return m_BorderToColor; } - set { if (PropertyUtil.SetColor(ref m_BorderToColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// 边框宽。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// 边框间隙。 - /// </summary> - public float borderGap - { - get { return m_BorderGap; } - set { if (PropertyUtil.SetStruct(ref m_BorderGap, value)) SetVerticesDirty(); } - } - /// <summary> - /// 透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 - /// </summary> - public float opacity - { - get { return m_Opacity; } - set { if (PropertyUtil.SetStruct(ref m_Opacity, value)) SetVerticesDirty(); } - } - /// <summary> - /// 提示框单项的字符串模版格式器。具体配置参考`Tooltip`的`formatter` - /// </summary> - public string itemFormatter - { - get { return m_ItemFormatter; } - set { if (PropertyUtil.SetClass(ref m_ItemFormatter, value)) SetVerticesDirty(); } - } - /// <summary> - /// 提示框单项的字符标志。用在Tooltip中。 - /// </summary> - public string itemMarker - { - get { return m_ItemMarker; } - set { if (PropertyUtil.SetClass(ref m_ItemMarker, value)) SetVerticesDirty(); } - } - /// <summary> - /// Standard numeric format strings. - /// |标准数字格式字符串。用于将数值格式化显示为字符串。 - /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 - /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings - /// </summary> - /// <value></value> - public string numericFormatter - { - get { return m_NumericFormatter; } - set { if (PropertyUtil.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } - } - /// <summary> - /// The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)). - /// |圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 - /// </summary> - public float[] cornerRadius - { - get { return m_CornerRadius; } - set { if (PropertyUtil.SetClass(ref m_CornerRadius, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// 实际边框宽。边框不显示时为0。 - /// </summary> - public float runtimeBorderWidth { get { return NeedShowBorder() ? borderWidth : 0; } } - - /// <summary> - /// 是否需要显示边框。 - /// </summary> - public bool NeedShowBorder() - { - return borderWidth != 0 && !ChartHelper.IsClearColor(borderColor); - } - - public Color32 GetColor() - { - if (m_Opacity == 1 || m_Color.a == 0) - return m_Color; - - var color = m_Color; - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetToColor() - { - if (m_Opacity == 1 || m_ToColor.a == 0) - return m_ToColor; - - var color = m_ToColor; - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetColor0() - { - if (m_Opacity == 1 || m_Color0.a == 0) - return m_Color0; - - var color = m_Color0; - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetColor(Color32 defaultColor) - { - var color = ChartHelper.IsClearColor(m_Color) ? defaultColor : m_Color; - - if (m_Opacity == 1 || color.a == 0) - return color; - - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetColor0(Color32 defaultColor) - { - var color = ChartHelper.IsClearColor(m_Color0) ? defaultColor : m_Color0; - - if (m_Opacity == 1 || color.a == 0) - return color; - - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetBorderColor(Color32 defaultColor) - { - var color = ChartHelper.IsClearColor(m_BorderColor) ? defaultColor : m_BorderColor; - - if (m_Opacity == 1 || color.a == 0) - return color; - - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public Color32 GetBorderColor0(Color32 defaultColor) - { - var color = ChartHelper.IsClearColor(m_BorderColor0) ? defaultColor : m_BorderColor0; - - if (m_Opacity == 1 || color.a == 0) - return color; - - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public bool IsNeedGradient() - { - return !ChartHelper.IsClearColor(m_ToColor) || !ChartHelper.IsClearColor(m_ToColor2); - } - - public Color32 GetGradientColor(float value, Color32 defaultColor) - { - if (!IsNeedGradient()) - return ChartConst.clearColor32; - - value = Mathf.Clamp01(value); - var startColor = ChartHelper.IsClearColor(m_Color) ? defaultColor : m_Color; - Color32 color; - - if (!ChartHelper.IsClearColor(m_ToColor2)) - { - if (value <= 0.5f) - color = Color32.Lerp(startColor, m_ToColor, 2 * value); - else - color = Color32.Lerp(m_ToColor, m_ToColor2, 2 * (value - 0.5f)); - } - else - { - color = Color32.Lerp(startColor, m_ToColor, value); - } - if (m_Opacity != 1) - { - color.a = (byte) (color.a * m_Opacity); - } - return color; - } - - public bool IsNeedCorner() - { - if (m_CornerRadius == null) return false; - foreach (var value in m_CornerRadius) - { - if (value != 0) return true; - } - return false; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/ItemStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/ItemStyle.cs.meta deleted file mode 100644 index 83e8a6f..0000000 --- a/Assets/XCharts/Runtime/Component/Child/ItemStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3ca9b30f9779c4a16b60cc21334828b0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/LevelStyle.cs b/Assets/XCharts/Runtime/Component/Child/LevelStyle.cs deleted file mode 100644 index cdca241..0000000 --- a/Assets/XCharts/Runtime/Component/Child/LevelStyle.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class Level : ChildComponent - { - [SerializeField] private LabelStyle m_Label = new LabelStyle(); - [SerializeField] private LabelStyle m_UpperLabel = new LabelStyle(); - [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); - /// <summary> - /// 文本标签样式。 - /// </summary> - public LabelStyle label { get { return m_Label; } } - /// <summary> - /// 上方的文本标签样式。 - /// </summary> - public LabelStyle upperLabel { get { return m_UpperLabel; } } - /// <summary> - /// 数据项样式。 - /// </summary> - public ItemStyle itemStyle { get { return m_ItemStyle; } } - } - - [System.Serializable] - public class LevelStyle : ChildComponent - { - [SerializeField] private bool m_Show = false; - [SerializeField] private List<Level> m_Levels = new List<Level>() { new Level() }; - - /// <summary> - /// 是否启用LevelStyle - /// </summary> - public bool show { get { return m_Show; } set { m_Show = value; } } - /// <summary> - /// 各层节点对应的配置。当enableLevels为true时生效,levels[0]对应的第一层的配置,levels[1]对应第二层,依次类推。当levels中没有对应层时用默认的设置。 - /// </summary> - public List<Level> levels { get { return m_Levels; } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/LevelStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/LevelStyle.cs.meta deleted file mode 100644 index 1193963..0000000 --- a/Assets/XCharts/Runtime/Component/Child/LevelStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3760e89d324d7413d95a2ac1d434a546 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/LineArrow.cs b/Assets/XCharts/Runtime/Component/Child/LineArrow.cs deleted file mode 100644 index 8b45aa8..0000000 --- a/Assets/XCharts/Runtime/Component/Child/LineArrow.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// </summary> - [Serializable] - public class LineArrow : ChildComponent, ISerieExtraComponent - { - public enum Position - { - /// <summary> - /// 末端箭头 - /// </summary> - End, - /// <summary> - /// 头端箭头 - /// </summary> - Start - } - - [SerializeField] private bool m_Show; - [SerializeField] private Position m_Position; - [SerializeField] - private ArrowStyle m_Arrow = new ArrowStyle() - { - width = 10, - height = 15, - offset = 0, - dent = 3 - }; - - /// <summary> - /// Whether to show the arrow. - /// |是否显示箭头。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// The position of arrow. - /// |箭头位置。 - /// </summary> - public Position position - { - get { return m_Position; } - set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetVerticesDirty(); } - } - - /// <summary> - /// the arrow of line. - /// |箭头。 - /// </summary> - public ArrowStyle arrow - { - get { return m_Arrow; } - set { if (PropertyUtil.SetClass(ref m_Arrow, value)) SetVerticesDirty(); } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/LineArrow.cs.meta b/Assets/XCharts/Runtime/Component/Child/LineArrow.cs.meta deleted file mode 100644 index ee3425a..0000000 --- a/Assets/XCharts/Runtime/Component/Child/LineArrow.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8f2455acb3ba34409896bf03ddba593e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/LineStyle.cs b/Assets/XCharts/Runtime/Component/Child/LineStyle.cs deleted file mode 100644 index d8909a6..0000000 --- a/Assets/XCharts/Runtime/Component/Child/LineStyle.cs +++ /dev/null @@ -1,238 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// The style of line. - /// |线条样式。 - /// 注: 修改 lineStyle 中的颜色不会影响图例颜色,如果需要图例颜色和折线图颜色一致,需修改 itemStyle.color,线条颜色默认也会取该颜色。 - /// toColor,toColor2可设置水平方向的渐变,如需要设置垂直方向的渐变,可使用VisualMap。 - /// </summary> - [System.Serializable] - public class LineStyle : ChildComponent, ISerieDataComponent - { - /// <summary> - /// 线的类型。 - /// </summary> - public enum Type - { - /// <summary> - /// 实线 - /// </summary> - Solid, - /// <summary> - /// 虚线 - /// </summary> - Dashed, - /// <summary> - /// 点线 - /// </summary> - Dotted, - /// <summary> - /// 点划线 - /// </summary> - DashDot, - /// <summary> - /// 双点划线 - /// </summary> - DashDotDot, - None, - } - - [SerializeField] private bool m_Show = true; - [SerializeField] private Type m_Type = Type.Solid; - [SerializeField] private Color32 m_Color; - [SerializeField] private Color32 m_ToColor; - [SerializeField] private Color32 m_ToColor2; - [SerializeField] private float m_Width = 0; - [SerializeField] private float m_Length = 0; - [SerializeField][Range(0, 1)] private float m_Opacity = 1; - - /// <summary> - /// Whether show line. - /// |是否显示线条。当作为子组件,它的父组件有参数控制是否显示时,改参数无效。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// the type of line. - /// |线的类型。 - /// </summary> - public Type type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of line, default use serie color. - /// |线的颜色。 - /// </summary> - public Color32 color - { - get { return m_Color; } - set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); } - } - /// <summary> - /// the middle color of line, default use serie color. - /// |线的渐变颜色(需要水平方向渐变时)。 - /// </summary> - public Color32 toColor - { - get { return m_ToColor; } - set { if (PropertyUtil.SetColor(ref m_ToColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// the end color of line, default use serie color. - /// |线的渐变颜色2(需要水平方向三个渐变色的渐变时)。 - /// </summary> - public Color32 toColor2 - { - get { return m_ToColor2; } - set { if (PropertyUtil.SetColor(ref m_ToColor2, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of line. - /// |线宽。 - /// </summary> - public float width - { - get { return m_Width; } - set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetVerticesDirty(); } - } - /// <summary> - /// the length of line. - /// |线长。 - /// </summary> - public float length - { - get { return m_Length; } - set { if (PropertyUtil.SetStruct(ref m_Length, value)) SetVerticesDirty(); } - } - /// <summary> - /// Opacity of the line. Supports value from 0 to 1, and the line will not be drawn when set to 0. - /// |线的透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 - /// </summary> - public float opacity - { - get { return m_Opacity; } - set { if (PropertyUtil.SetStruct(ref m_Opacity, value)) SetVerticesDirty(); } - } - - public LineStyle() - { } - - public LineStyle(float width) - { - this.width = width; - } - - public LineStyle(LineStyle.Type type) - { - this.type = type; - } - - public LineStyle(LineStyle.Type type, float width) - { - this.type = type; - this.width = width; - } - - public LineStyle Clone() - { - var lineStyle = new LineStyle(); - lineStyle.show = show; - lineStyle.type = type; - lineStyle.color = color; - lineStyle.toColor = toColor; - lineStyle.toColor2 = toColor2; - lineStyle.width = width; - lineStyle.opacity = opacity; - return lineStyle; - } - - public void Copy(LineStyle lineStyle) - { - show = lineStyle.show; - type = lineStyle.type; - color = lineStyle.color; - toColor = lineStyle.toColor; - toColor2 = lineStyle.toColor2; - width = lineStyle.width; - opacity = lineStyle.opacity; - } - - public Color32 GetColor() - { - if (m_Opacity == 1) - return m_Color; - - var color = m_Color; - color.a = (byte) (color.a * m_Opacity); - return color; - } - - public bool IsNeedGradient() - { - return !ChartHelper.IsClearColor(m_ToColor) || !ChartHelper.IsClearColor(m_ToColor2); - } - - public Color32 GetGradientColor(float value, Color32 defaultColor) - { - var color = ChartConst.clearColor32; - if (!IsNeedGradient()) - return color; - - value = Mathf.Clamp01(value); - var startColor = ChartHelper.IsClearColor(m_Color) ? defaultColor : m_Color; - - if (!ChartHelper.IsClearColor(m_ToColor2)) - { - if (value <= 0.5f) - color = Color32.Lerp(startColor, m_ToColor, 2 * value); - else - color = Color32.Lerp(m_ToColor, m_ToColor2, 2 * (value - 0.5f)); - } - else - { - color = Color32.Lerp(startColor, m_ToColor, value); - } - if (m_Opacity != 1) - { - color.a = (byte) (color.a * m_Opacity); - } - return color; - } - - public Type GetType(Type themeType) - { - return type == Type.None ? themeType : type; - } - - public float GetWidth(float themeWidth) - { - return width == 0 ? themeWidth : width; - } - - public float GetLength(float themeLength) - { - return length == 0 ? themeLength : length; - } - - public Color32 GetColor(Color32 themeColor) - { - if (!ChartHelper.IsClearColor(color)) - { - return GetColor(); - } - else - { - var color = themeColor; - color.a = (byte) (color.a * opacity); - return color; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/LineStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/LineStyle.cs.meta deleted file mode 100644 index 2856b89..0000000 --- a/Assets/XCharts/Runtime/Component/Child/LineStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 092f08a2daa4b4013a72ffc3c9a18f85 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/Location.cs b/Assets/XCharts/Runtime/Component/Child/Location.cs deleted file mode 100644 index 819e356..0000000 --- a/Assets/XCharts/Runtime/Component/Child/Location.cs +++ /dev/null @@ -1,321 +0,0 @@ -using System; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - /// <summary> - /// Location type. Quick to set the general location. - /// |位置类型。通过Align快速设置大体位置,再通过left,right,top,bottom微调具体位置。 - /// </summary> - [Serializable] - public class Location : ChildComponent, IPropertyChanged - { - /// <summary> - /// 对齐方式 - /// </summary> - public enum Align - { - TopLeft, - TopRight, - TopCenter, - BottomLeft, - BottomRight, - BottomCenter, - Center, - CenterLeft, - CenterRight - } - - [SerializeField] private Align m_Align = Align.TopCenter; - [SerializeField] private float m_Left; - [SerializeField] private float m_Right; - [SerializeField] private float m_Top; - [SerializeField] private float m_Bottom; - - private TextAnchor m_TextAlignment; -#if dUI_TextMeshPro - private TextAlignmentOptions m_TMPTextAlignment; -#endif - private Vector2 m_AnchorMin; - private Vector2 m_AnchorMax; - private Vector2 m_Pivot; - - /// <summary> - /// 对齐方式。 - /// </summary> - public Align align - { - get { return m_Align; } - set { if (PropertyUtil.SetStruct(ref m_Align, value)) { SetComponentDirty(); UpdateAlign(); } } - } - /// <summary> - /// Distance between component and the left side of the container. - /// |离容器左侧的距离。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) { SetComponentDirty(); UpdateAlign(); } } - } - /// <summary> - /// Distance between component and the left side of the container. - /// |离容器右侧的距离。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) { SetComponentDirty(); UpdateAlign(); } } - } - /// <summary> - /// Distance between component and the left side of the container. - /// |离容器上侧的距离。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) { SetComponentDirty(); UpdateAlign(); } } - } - /// <summary> - /// Distance between component and the left side of the container. - /// |离容器下侧的距离。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) { SetComponentDirty(); UpdateAlign(); } } - } - - /// <summary> - /// the anchor of text. - /// |Location对应的Anchor锚点 - /// </summary> - /// <value></value> - public TextAnchor runtimeTextAlignment { get { return m_TextAlignment; } } - -#if dUI_TextMeshPro - public TextAlignmentOptions runtimeTMPTextAlignment { get { return m_TMPTextAlignment; } } -#endif - /// <summary> - /// the minimum achor. - /// |Location对应的anchorMin。 - /// </summary> - public Vector2 runtimeAnchorMin { get { return m_AnchorMin; } } - /// <summary> - /// the maximun achor. - /// |Location对应的anchorMax. - /// |</summary> - public Vector2 runtimeAnchorMax { get { return m_AnchorMax; } } - /// <summary> - /// the povot. - /// |Loation对应的中心点。 - /// </summary> - public Vector2 runtimePivot { get { return m_Pivot; } } - public float runtimeLeft { get; private set; } - public float runtimeRight { get; private set; } - public float runtimeBottom { get; private set; } - public float runtimeTop { get; private set; } - - public static Location defaultLeft - { - get - { - return new Location() - { - align = Align.CenterLeft, - left = 0.03f, - right = 0, - top = 0, - bottom = 0 - }; - } - } - - public static Location defaultRight - { - get - { - return new Location() - { - align = Align.CenterRight, - left = 0, - right = 0.03f, - top = 0, - bottom = 0 - }; - } - } - - public static Location defaultTop - { - get - { - return new Location() - { - align = Align.TopCenter, - left = 0, - right = 0, - top = 0.03f, - bottom = 0 - }; - } - } - - public static Location defaultBottom - { - get - { - return new Location() - { - align = Align.BottomCenter, - left = 0, - right = 0, - top = 0, - bottom = 0.03f - }; - } - } - - private void UpdateAlign() - { - switch (m_Align) - { - case Align.BottomCenter: - m_TextAlignment = TextAnchor.LowerCenter; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.Bottom; -#endif - m_AnchorMin = new Vector2(0.5f, 0); - m_AnchorMax = new Vector2(0.5f, 0); - m_Pivot = new Vector2(0.5f, 0); - break; - case Align.BottomLeft: - m_TextAlignment = TextAnchor.LowerLeft; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.BottomLeft; -#endif - m_AnchorMin = new Vector2(0, 0); - m_AnchorMax = new Vector2(0, 0); - m_Pivot = new Vector2(0, 0); - break; - case Align.BottomRight: - m_TextAlignment = TextAnchor.LowerRight; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.BottomRight; -#endif - m_AnchorMin = new Vector2(1, 0); - m_AnchorMax = new Vector2(1, 0); - m_Pivot = new Vector2(1, 0); - break; - case Align.Center: - m_TextAlignment = TextAnchor.MiddleCenter; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.Center; -#endif - m_AnchorMin = new Vector2(0.5f, 0.5f); - m_AnchorMax = new Vector2(0.5f, 0.5f); - m_Pivot = new Vector2(0.5f, 0.5f); - break; - case Align.CenterLeft: - m_TextAlignment = TextAnchor.MiddleLeft; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.Left; -#endif - m_AnchorMin = new Vector2(0, 0.5f); - m_AnchorMax = new Vector2(0, 0.5f); - m_Pivot = new Vector2(0, 0.5f); - break; - case Align.CenterRight: - m_TextAlignment = TextAnchor.MiddleRight; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.Right; -#endif - m_AnchorMin = new Vector2(1, 0.5f); - m_AnchorMax = new Vector2(1, 0.5f); - m_Pivot = new Vector2(1, 0.5f); - break; - case Align.TopCenter: - m_TextAlignment = TextAnchor.UpperCenter; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.Top; -#endif - m_AnchorMin = new Vector2(0.5f, 1); - m_AnchorMax = new Vector2(0.5f, 1); - m_Pivot = new Vector2(0.5f, 1); - break; - case Align.TopLeft: - m_TextAlignment = TextAnchor.UpperLeft; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.TopLeft; -#endif - m_AnchorMin = new Vector2(0, 1); - m_AnchorMax = new Vector2(0, 1); - m_Pivot = new Vector2(0, 1); - break; - case Align.TopRight: - m_TextAlignment = TextAnchor.UpperRight; -#if dUI_TextMeshPro - m_TMPTextAlignment = TextAlignmentOptions.TopRight; -#endif - m_AnchorMin = new Vector2(1, 1); - m_AnchorMax = new Vector2(1, 1); - m_Pivot = new Vector2(1, 1); - break; - default: - break; - } - } - - public void UpdateRuntimeData(float chartWidth, float chartHeight) - { - runtimeLeft = left <= 1 ? left * chartWidth : left; - runtimeRight = right <= 1 ? right * chartWidth : right; - runtimeTop = top <= 1 ? top * chartHeight : top; - runtimeBottom = bottom <= 1 ? bottom * chartHeight : bottom; - } - - /// <summary> - /// 返回在坐标系中的具体位置 - /// </summary> - /// <param name="chartWidth"></param> - /// <param name="chartHeight"></param> - /// <returns></returns> - public Vector3 GetPosition(float chartWidth, float chartHeight) - { - UpdateRuntimeData(chartWidth, chartHeight); - switch (align) - { - case Align.BottomCenter: - return new Vector3(chartWidth / 2, runtimeBottom); - case Align.BottomLeft: - return new Vector3(runtimeLeft, runtimeBottom); - case Align.BottomRight: - return new Vector3(chartWidth - runtimeRight, runtimeBottom); - case Align.Center: - return new Vector3(chartWidth / 2, chartHeight / 2); - case Align.CenterLeft: - return new Vector3(runtimeLeft, chartHeight / 2); - case Align.CenterRight: - return new Vector3(chartWidth - runtimeRight, chartHeight / 2); - case Align.TopCenter: - return new Vector3(chartWidth / 2, chartHeight - runtimeTop); - case Align.TopLeft: - return new Vector3(runtimeLeft, chartHeight - runtimeTop); - case Align.TopRight: - return new Vector3(chartWidth - runtimeRight, chartHeight - runtimeTop); - default: - return Vector2.zero; - } - } - - /// <summary> - /// 属性变更时更新textAnchor,minAnchor,maxAnchor,pivot - /// </summary> - public void OnChanged() - { - UpdateAlign(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/Location.cs.meta b/Assets/XCharts/Runtime/Component/Child/Location.cs.meta deleted file mode 100644 index b209c7c..0000000 --- a/Assets/XCharts/Runtime/Component/Child/Location.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7922ce86a6b0f4813a7f34e004b92e9a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs b/Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs deleted file mode 100644 index 34865a8..0000000 --- a/Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// The way to get serie symbol size. - /// |获取标记图形大小的方式。 - /// </summary> - public enum SymbolSizeType - { - /// <summary> - /// Specify constant for symbol size. - /// |自定义大小。 - /// </summary> - Custom, - /// <summary> - /// Specify the dataIndex and dataScale to calculate symbol size. - /// |通过 dataIndex 从数据中获取,再乘以一个比例系数 dataScale 。 - /// </summary> - FromData, - /// <summary> - /// Specify function for symbol size. - /// |通过委托函数获取。 - /// </summary> - Function, - } - - /// <summary> - /// 系列数据项的标记的图形 - /// </summary> - [System.Serializable] - public class SerieSymbol : SymbolStyle, ISerieDataComponent - { - [SerializeField] private SymbolSizeType m_SizeType = SymbolSizeType.Custom; - [SerializeField] private float m_SelectedSize = 0f; - [SerializeField] private int m_DataIndex = 1; - [SerializeField] private float m_DataScale = 1; - [SerializeField] private float m_SelectedDataScale = 1.5f; - [SerializeField] private SymbolSizeFunction m_SizeFunction; - [SerializeField] private SymbolSizeFunction m_SelectedSizeFunction; - [SerializeField] private int m_StartIndex; - [SerializeField] private int m_Interval; - [SerializeField] private bool m_ForceShowLast = false; - [SerializeField] private bool m_Repeat = false; - - public override void Reset() - { - base.Reset(); - m_SizeType = SymbolSizeType.Custom; - m_SelectedSize = 0f; - m_DataIndex = 1; - m_DataScale = 1; - m_SelectedDataScale = 1.5f; - m_SizeFunction = null; - m_SelectedSizeFunction = null; - m_StartIndex = 0; - m_Interval = 0; - m_ForceShowLast = false; - m_Repeat = false; - } - - /// <summary> - /// the type of symbol size. - /// |标记图形的大小获取方式。 - /// </summary> - public SymbolSizeType sizeType - { - get { return m_SizeType; } - set { if (PropertyUtil.SetStruct(ref m_SizeType, value)) SetVerticesDirty(); } - } - /// <summary> - /// the size of selected symbol. - /// |被选中的标记的大小。 - /// </summary> - public float selectedSize - { - get { return m_SelectedSize; } - set { if (PropertyUtil.SetStruct(ref m_SelectedSize, value)) SetVerticesDirty(); } - } - /// <summary> - /// whitch data index is when the sizeType assined as FromData. - /// |当sizeType指定为FromData时,指定的数据源索引。 - /// </summary> - public int dataIndex - { - get { return m_DataIndex; } - set { if (PropertyUtil.SetStruct(ref m_DataIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// the scale of data when sizeType assined as FromData. - /// |当sizeType指定为FromData时,指定的倍数系数。 - /// </summary> - public float dataScale - { - get { return m_DataScale; } - set { if (PropertyUtil.SetStruct(ref m_DataScale, value)) SetVerticesDirty(); } - } - /// <summary> - /// the scale of selected data when sizeType assined as FromData. - /// |当sizeType指定为FromData时,指定的高亮倍数系数。 - /// </summary> - public float selectedDataScale - { - get { return m_SelectedDataScale; } - set { if (PropertyUtil.SetStruct(ref m_SelectedDataScale, value)) SetVerticesDirty(); } - } - /// <summary> - /// the function of size when sizeType assined as Function. - /// |当sizeType指定为Function时,指定的委托函数。 - /// </summary> - public SymbolSizeFunction sizeFunction - { - get { return m_SizeFunction; } - set { if (PropertyUtil.SetClass(ref m_SizeFunction, value)) SetVerticesDirty(); } - } - /// <summary> - /// the function of size when sizeType assined as Function. - /// |当sizeType指定为Function时,指定的高亮委托函数。 - /// </summary> - public SymbolSizeFunction selectedSizeFunction - { - get { return m_SelectedSizeFunction; } - set { if (PropertyUtil.SetClass(ref m_SelectedSizeFunction, value)) SetVerticesDirty(); } - } - /// <summary> - /// the index start to show symbol. - /// |开始显示图形标记的索引。 - /// </summary> - public int startIndex - { - get { return m_StartIndex; } - set { if (PropertyUtil.SetStruct(ref m_StartIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// the interval of show symbol. - /// |显示图形标记的间隔。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。 - /// </summary> - public int interval - { - get { return m_Interval; } - set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); } - } - /// <summary> - /// whether to show the last symbol. - /// |是否强制显示最后一个图形标记。 - /// </summary> - public bool forceShowLast - { - get { return m_ForceShowLast; } - set { if (PropertyUtil.SetStruct(ref m_ForceShowLast, value)) SetVerticesDirty(); } - } - /// <summary> - /// 图形是否重复。 - /// </summary> - public bool repeat - { - get { return m_Repeat; } - set { if (PropertyUtil.SetStruct(ref m_Repeat, value)) SetAllDirty(); } - } - /// <summary> - /// 根据指定的sizeType获得标记的大小 - /// </summary> - /// <param name="data"></param> - /// <returns></returns> - public float GetSize(List<double> data, float themeSize) - { - switch (m_SizeType) - { - case SymbolSizeType.Custom: - return size == 0 ? themeSize : size; - case SymbolSizeType.FromData: - if (data != null && dataIndex >= 0 && dataIndex < data.Count) - { - return (float) data[dataIndex] * m_DataScale; - } - else - { - return size == 0 ? themeSize : size; - } - case SymbolSizeType.Function: - if (data != null && sizeFunction != null) return sizeFunction(data); - else return size == 0 ? themeSize : size; - default: - return size == 0 ? themeSize : size; - } - } - - /// <summary> - /// 根据sizeType获得高亮时的标记大小 - /// </summary> - /// <param name="data"></param> - /// <returns></returns> - public float GetSelectedSize(List<double> data, float themeSelectedSize) - { - switch (m_SizeType) - { - case SymbolSizeType.Custom: - - return selectedSize == 0 ? themeSelectedSize : selectedSize; - - case SymbolSizeType.FromData: - - if (data != null && dataIndex >= 0 && dataIndex < data.Count) - { - return (float) data[dataIndex] * m_SelectedDataScale; - } - else - { - return selectedSize == 0 ? themeSelectedSize : selectedSize; - } - - case SymbolSizeType.Function: - - if (data != null && selectedSizeFunction != null) - return selectedSizeFunction(data); - else - return selectedSize == 0 ? themeSelectedSize : selectedSize; - - default: - return selectedSize == 0 ? themeSelectedSize : selectedSize; - } - } - - public bool ShowSymbol(int dataIndex, int dataCount) - { - if (!show) - return false; - - if (dataIndex < startIndex) - return false; - - if (m_Interval <= 0) - return true; - - if (m_ForceShowLast && dataIndex == dataCount - 1) - return true; - - return (dataIndex - startIndex) % (m_Interval + 1) == 0; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs.meta b/Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs.meta deleted file mode 100644 index ccbf533..0000000 --- a/Assets/XCharts/Runtime/Component/Child/SerieSymbl.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cd2852f4c46ae4dbd8c105e62dcce9a2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/StageColor.cs b/Assets/XCharts/Runtime/Component/Child/StageColor.cs deleted file mode 100644 index 592d971..0000000 --- a/Assets/XCharts/Runtime/Component/Child/StageColor.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class StageColor : ChildComponent - { - [SerializeField] private float m_Percent; - [SerializeField] private Color32 m_Color; - /// <summary> - /// 结束位置百分比。 - /// </summary> - public float percent { get { return m_Percent; } set { m_Percent = value; } } - /// <summary> - /// 颜色。 - /// </summary> - public Color32 color { get { return m_Color; } set { m_Color = value; } } - - public StageColor(float percent, Color32 color) - { - m_Percent = percent; - m_Color = color; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/StageColor.cs.meta b/Assets/XCharts/Runtime/Component/Child/StageColor.cs.meta deleted file mode 100644 index 4be512d..0000000 --- a/Assets/XCharts/Runtime/Component/Child/StageColor.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d40f9dfbc90e744858784753e0d7109d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs b/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs deleted file mode 100644 index 3b8677a..0000000 --- a/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// the type of symbol. - /// |标记图形的类型。 - /// </summary> - public enum SymbolType - { - /// <summary> - /// 不显示标记。 - /// </summary> - None, - /// <summary> - /// 自定义标记。 - /// </summary> - Custom, - /// <summary> - /// 圆形。 - /// </summary> - Circle, - /// <summary> - /// 空心圆。 - /// </summary> - EmptyCircle, - /// <summary> - /// 正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。 - /// </summary> - Rect, - /// <summary> - /// 空心正方形。 - /// </summary> - EmptyRect, - /// <summary> - /// 三角形。 - /// </summary> - Triangle, - /// <summary> - /// 空心三角形。 - /// </summary> - EmptyTriangle, - /// <summary> - /// 菱形。 - /// </summary> - Diamond, - /// <summary> - /// 空心菱形。 - /// </summary> - EmptyDiamond, - /// <summary> - /// 箭头。 - /// </summary> - Arrow, - /// <summary> - /// 空心箭头。 - /// </summary> - EmptyArrow - } - - /// <summary> - /// 系列数据项的标记的图形 - /// </summary> - [System.Serializable] - public class SymbolStyle : ChildComponent - { - [SerializeField] protected bool m_Show = true; - [SerializeField] protected SymbolType m_Type = SymbolType.EmptyCircle; - [SerializeField] protected float m_Size = 0f; - [SerializeField] protected float m_Gap = 0; - [SerializeField] protected float m_Width = 0f; - [SerializeField] protected float m_Height = 0f; - [SerializeField] protected Vector2 m_Offset = Vector2.zero; - [SerializeField] protected Sprite m_Image; - [SerializeField] protected Image.Type m_ImageType; - [SerializeField] protected Color32 m_Color; - - public virtual void Reset() - { - m_Show = false; - m_Type = SymbolType.EmptyCircle; - m_Size = 0f; - m_Gap = 0; - m_Width = 0f; - m_Height = 0f; - m_Offset = Vector2.zero; - m_Image = null; - m_ImageType = Image.Type.Simple; - } - - /// <summary> - /// Whether the symbol is showed. - /// |是否显示标记。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); } - } - /// <summary> - /// the type of symbol. - /// |标记类型。 - /// </summary> - public SymbolType type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); } - } - /// <summary> - /// the size of symbol. - /// |标记的大小。 - /// </summary> - public float size - { - get { return m_Size; } - set { if (PropertyUtil.SetStruct(ref m_Size, value)) SetVerticesDirty(); } - } - /// <summary> - /// the gap of symbol and line segment. - /// |图形标记和线条的间隙距离。 - /// </summary> - public float gap - { - get { return m_Gap; } - set { if (PropertyUtil.SetStruct(ref m_Gap, value)) SetVerticesDirty(); } - } - /// <summary> - /// 图形的宽。 - /// </summary> - public float width - { - get { return m_Width; } - set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); } - } - /// <summary> - /// 图形的高。 - /// </summary> - public float height - { - get { return m_Height; } - set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetAllDirty(); } - } - /// <summary> - /// 自定义的标记图形。 - /// </summary> - public Sprite image - { - get { return m_Image; } - set { if (PropertyUtil.SetClass(ref m_Image, value)) SetAllDirty(); } - } - /// <summary> - /// the fill type of image. - /// |图形填充类型。 - /// </summary> - public Image.Type imageType - { - get { return m_ImageType; } - set { if (PropertyUtil.SetStruct(ref m_ImageType, value)) SetAllDirty(); } - } - /// <summary> - /// 图形的偏移。 - /// </summary> - public Vector2 offset - { - get { return m_Offset; } - set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); } - } - /// <summary> - /// 图形的颜色。 - /// </summary> - public Color32 color - { - get { return m_Color; } - set { if (PropertyUtil.SetStruct(ref m_Color, value)) SetAllDirty(); } - } - public Vector3 offset3 { get { return new Vector3(m_Offset.x, m_Offset.y, 0); } } - private List<float> m_AnimationSize = new List<float>() { 0, 5, 10 }; - /// <summary> - /// the setting for effect scatter. - /// |带有涟漪特效动画的散点图的动画参数。 - /// </summary> - public List<float> animationSize { get { return m_AnimationSize; } } - - public Color32 GetColor(Color32 defaultColor) - { - return ChartHelper.IsClearColor(m_Color) ? defaultColor : m_Color; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs.meta deleted file mode 100644 index 5913032..0000000 --- a/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 837d37f4d6f614b38bef9f075a64b6dc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/TextLimit.cs b/Assets/XCharts/Runtime/Component/Child/TextLimit.cs deleted file mode 100644 index 0d27623..0000000 --- a/Assets/XCharts/Runtime/Component/Child/TextLimit.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// Text character limitation and adaptation component. When the length of the text exceeds the set length, - /// it is cropped and suffixes are appended to the end.Only valid in the category axis. - /// |文本字符限制和自适应。当文本长度超过设定的长度时进行裁剪,并将后缀附加在最后。 - /// 只在类目轴中有效。 - /// </summary> - [Serializable] - public class TextLimit : ChildComponent - { - [SerializeField] private bool m_Enable = false; - [SerializeField] private float m_MaxWidth = 0; - [SerializeField] private float m_Gap = 1; - [SerializeField] private string m_Suffix = "..."; - - /// <summary> - /// Whether to enable text limit. - /// |是否启用文本自适应。 - /// [default:true] - /// </summary> - public bool enable - { - get { return m_Enable; } - set { if (PropertyUtil.SetStruct(ref m_Enable, value)) SetComponentDirty(); } - } - /// <summary> - /// Set the maximum width. A default of 0 indicates automatic fetch; otherwise, custom. - /// |Clipping occurs when the width of the text is greater than this value. - /// |设定最大宽度。默认为0表示自动获取,否则表示自定义。当文本的宽度大于该值进行裁剪。 - /// </summary> - public float maxWidth - { - get { return m_MaxWidth; } - set { if (PropertyUtil.SetStruct(ref m_MaxWidth, value)) SetComponentDirty(); } - } - /// <summary> - /// White pixel distance at both ends. - /// |两边留白像素距离。 - /// [default:10f] - /// </summary> - public float gap - { - get { return m_Gap; } - set { if (PropertyUtil.SetStruct(ref m_Gap, value)) SetComponentDirty(); } - } - /// <summary> - /// Suffixes when the length exceeds. - /// |长度超出时的后缀。 - /// [default: "..."] - /// </summary> - public string suffix - { - get { return m_Suffix; } - set { if (PropertyUtil.SetClass(ref m_Suffix, value)) SetComponentDirty(); } - } - - private ChartText m_RelatedText; - private float m_RelatedTextWidth = 0; - - public TextLimit Clone() - { - var textLimit = new TextLimit(); - textLimit.enable = enable; - textLimit.maxWidth = maxWidth; - textLimit.gap = gap; - textLimit.suffix = suffix; - return textLimit; - } - - public void Copy(TextLimit textLimit) - { - enable = textLimit.enable; - maxWidth = textLimit.maxWidth; - gap = textLimit.gap; - suffix = textLimit.suffix; - } - - public void SetRelatedText(ChartText txt, float labelWidth) - { - m_RelatedText = txt; - m_RelatedTextWidth = labelWidth; - } - - public string GetLimitContent(string content) - { - float checkWidth = m_MaxWidth > 0 ? m_MaxWidth : m_RelatedTextWidth; - if (m_RelatedText == null || checkWidth <= 0) - { - return content; - } - else - { - if (m_Enable) - { - float len = m_RelatedText.GetPreferredWidth(content); - float suffixLen = m_RelatedText.GetPreferredWidth(suffix); - if (len >= checkWidth - m_Gap * 2) - { - return content.Substring(0, GetAdaptLength(content, suffixLen)) + suffix; - } - else - { - return content; - } - } - else - { - return content; - } - } - } - - private int GetAdaptLength(string content, float suffixLen) - { - int start = 0; - int middle = content.Length / 2; - int end = content.Length; - float checkWidth = m_MaxWidth > 0 ? m_MaxWidth : m_RelatedTextWidth; - - float limit = checkWidth - m_Gap * 2 - suffixLen; - if (limit < 0) - return 0; - - float len = 0; - while (len != limit && middle != start) - { - len = m_RelatedText.GetPreferredWidth(content.Substring(0, middle)); - if (len < limit) - { - start = middle; - } - else if (len > limit) - { - end = middle; - } - else - { - break; - } - middle = (start + end) / 2; - } - return middle; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/TextLimit.cs.meta b/Assets/XCharts/Runtime/Component/Child/TextLimit.cs.meta deleted file mode 100644 index da76507..0000000 --- a/Assets/XCharts/Runtime/Component/Child/TextLimit.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3f49509a5de044535b1dd3f192f7008c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/TextPadding.cs b/Assets/XCharts/Runtime/Component/Child/TextPadding.cs deleted file mode 100644 index 7031f4f..0000000 --- a/Assets/XCharts/Runtime/Component/Child/TextPadding.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Settings related to text. - /// |文本的内边距设置。 - /// </summary> - [Serializable] - public class TextPadding : ChildComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private float m_Top = 2; - [SerializeField] private float m_Right = 4; - [SerializeField] private float m_Left = 4; - [SerializeField] private float m_Bottom = 2; - - public TextPadding() { } - - public TextPadding(float top, float right, float bottom, float left) - { - SetPadding(top, right, bottom, left); - } - - public void SetPadding(float top, float right, float bottom, float left) - { - m_Top = top;; - m_Right = right; - m_Bottom = bottom; - m_Left = left; - } - /// <summary> - /// show padding. - /// 是否显示。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } - } - /// <summary> - /// padding of top. - /// |顶部间距。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetComponentDirty(); } - } - /// <summary> - /// padding of right. - /// |右部间距。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetComponentDirty(); } - } - /// <summary> - /// padding of bottom. - /// |底部间距。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetComponentDirty(); } - } - /// <summary> - /// padding of left. - /// |左边间距。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetComponentDirty(); } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/TextPadding.cs.meta b/Assets/XCharts/Runtime/Component/Child/TextPadding.cs.meta deleted file mode 100644 index cff9472..0000000 --- a/Assets/XCharts/Runtime/Component/Child/TextPadding.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 407bba126a0854199a4686b44cc9407e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/TextStyle.cs b/Assets/XCharts/Runtime/Component/Child/TextStyle.cs deleted file mode 100644 index d8c4179..0000000 --- a/Assets/XCharts/Runtime/Component/Child/TextStyle.cs +++ /dev/null @@ -1,234 +0,0 @@ -using System; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - /// <summary> - /// Settings related to text. - /// |文本的相关设置。 - /// </summary> - [Serializable] - public class TextStyle : ChildComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private Font m_Font; - [SerializeField] private bool m_AutoWrap = false; - [SerializeField] private bool m_AutoAlign = true; - [SerializeField] private float m_Rotate = 0; - [SerializeField] private bool m_AutoColor = false; - [SerializeField] private Color m_Color = Color.clear; - [SerializeField] private int m_FontSize = 0; - [SerializeField] private FontStyle m_FontStyle = FontStyle.Normal; - [SerializeField] private float m_LineSpacing = 1f; - [SerializeField] private TextAnchor m_Alignment = TextAnchor.MiddleCenter; -#if dUI_TextMeshPro - [SerializeField] private TMP_FontAsset m_TMPFont; - [SerializeField] private FontStyles m_TMPFontStyle = FontStyles.Normal; - [SerializeField] private TextAlignmentOptions m_TMPAlignment = TextAlignmentOptions.Left; -#endif - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } - } - /// <summary> - /// Rotation of text. - /// |文本的旋转。 - /// [default: `0f`] - /// </summary> - public float rotate - { - get { return m_Rotate; } - set { if (PropertyUtil.SetStruct(ref m_Rotate, value)) SetComponentDirty(); } - } - /// <summary> - /// 是否开启自动颜色。当开启时,会自动设置颜色。 - /// </summary> - public bool autoColor - { - get { return m_AutoColor; } - set { if (PropertyUtil.SetStruct(ref m_AutoColor, value)) SetAllDirty(); } - } - /// <summary> - /// the color of text. - /// |文本的颜色。 - /// [default: `Color.clear`] - /// </summary> - public Color color - { - get { return m_Color; } - set { if (PropertyUtil.SetColor(ref m_Color, value)) SetComponentDirty(); } - } - /// <summary> - /// the font of text. When `null`, the theme's font is used by default. - /// |文本字体。 - /// [default: null] - /// </summary> - public Font font - { - get { return m_Font; } - set { if (PropertyUtil.SetClass(ref m_Font, value)) SetComponentDirty(); } - } - /// <summary> - /// font size. - /// |文本字体大小。 - /// [default: 18] - /// </summary> - public int fontSize - { - get { return m_FontSize; } - set { if (PropertyUtil.SetStruct(ref m_FontSize, value)) SetComponentDirty(); } - } - /// <summary> - /// font style. - /// |文本字体的风格。 - /// [default: FontStyle.Normal] - /// </summary> - public FontStyle fontStyle - { - get { return m_FontStyle; } - set { if (PropertyUtil.SetStruct(ref m_FontStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// text line spacing. - /// |行间距。 - /// [default: 1f] - /// </summary> - public float lineSpacing - { - get { return m_LineSpacing; } - set { if (PropertyUtil.SetStruct(ref m_LineSpacing, value)) SetComponentDirty(); } - } - /// <summary> - /// 是否自动换行。 - /// </summary> - public bool autoWrap - { - get { return m_AutoWrap; } - set { if (PropertyUtil.SetStruct(ref m_AutoWrap, value)) SetComponentDirty(); } - } - /// <summary> - /// 文本是否让系统自动选对齐方式。为false时才会用alignment。 - /// </summary> - public bool autoAlign - { - get { return m_AutoAlign; } - set { if (PropertyUtil.SetStruct(ref m_AutoAlign, value)) SetComponentDirty(); } - } - /// <summary> - /// 对齐方式。 - /// </summary> - public TextAnchor alignment - { - get { return m_Alignment; } - set { if (PropertyUtil.SetStruct(ref m_Alignment, value)) SetComponentDirty(); } - } -#if dUI_TextMeshPro - /// <summary> - /// the font of textmeshpro. - /// |TextMeshPro字体。 - /// </summary> - public TMP_FontAsset tmpFont - { - get { return m_TMPFont; } - set { if (PropertyUtil.SetClass(ref m_TMPFont, value)) SetComponentDirty(); } - } - /// <summary> - /// the font style of TextMeshPro. - /// |TextMeshPro字体类型。 - /// </summary> - public FontStyles tmpFontStyle - { - get { return m_TMPFontStyle; } - set { if (PropertyUtil.SetStruct(ref m_TMPFontStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// the text alignment of TextMeshPro. - /// |TextMeshPro字体对齐方式。 - /// </summary> - public TextAlignmentOptions tmpFontStyle - { - get { return m_TMPAlignment; } - set { if (PropertyUtil.SetStruct(ref m_TMPAlignment, value)) SetComponentDirty(); } - } -#endif - - public TextStyle() { } - - public TextStyle(int fontSize) - { - this.fontSize = fontSize; - } - - public TextStyle(int fontSize, FontStyle fontStyle) - { - this.fontSize = fontSize; - this.fontStyle = fontStyle; - } - - public TextStyle(int fontSize, FontStyle fontStyle, Color color) - { - this.fontSize = fontSize; - this.fontStyle = fontStyle; - this.color = color; - } - - public TextStyle(int fontSize, FontStyle fontStyle, Color color, int rorate) - { - this.fontSize = fontSize; - this.fontStyle = fontStyle; - this.color = color; - this.rotate = rotate; - } - - public void Copy(TextStyle textStyle) - { - font = textStyle.font; - rotate = textStyle.rotate; - color = textStyle.color; - fontSize = textStyle.fontSize; - fontStyle = textStyle.fontStyle; - lineSpacing = textStyle.lineSpacing; - alignment = textStyle.alignment; - autoWrap = textStyle.autoWrap; - autoAlign = textStyle.autoAlign; -#if dUI_TextMeshPro - m_TMPFont = textStyle.tmpFont; - m_TMPFontStyle = textStyle.tmpFontStyle; -#endif - } - - public void UpdateAlignmentByLocation(Location location) - { -#if dUI_TextMeshPro - m_TMPAlignment = location.runtimeTMPTextAlignment; -#else - m_Alignment = location.runtimeTextAlignment; -#endif - } - - public Color GetColor(Color defaultColor) - { - if (ChartHelper.IsClearColor(color)) - return defaultColor; - else - return color; - } - - public int GetFontSize(ComponentTheme defaultTheme) - { - if (fontSize == 0) - return defaultTheme.fontSize; - else - return fontSize; - } - - public TextAnchor GetAlignment(TextAnchor defaultAlignment) - { - return m_AutoAlign ? defaultAlignment : alignment; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Child/TextStyle.cs.meta b/Assets/XCharts/Runtime/Component/Child/TextStyle.cs.meta deleted file mode 100644 index c429b3b..0000000 --- a/Assets/XCharts/Runtime/Component/Child/TextStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e8f6b652968894ab195666501dda672c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Comment.meta b/Assets/XCharts/Runtime/Component/Comment.meta deleted file mode 100644 index 27242bf..0000000 --- a/Assets/XCharts/Runtime/Component/Comment.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 81fe767917cd3492a9f587f5d5e3a037 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Comment/Comment.cs b/Assets/XCharts/Runtime/Component/Comment/Comment.cs deleted file mode 100644 index b2cb70a..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/Comment.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// comment of chart. - /// |图表注解组件。 - /// </summary> - [Serializable] - [ComponentHandler(typeof(CommentHander), true)] - public class Comment : MainComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private LabelStyle m_LabelStyle = new LabelStyle(); - [SerializeField] private CommentMarkStyle m_MarkStyle; - [SerializeField] private List<CommentItem> m_Items = new List<CommentItem>() { new CommentItem() }; - - /// <summary> - /// Set this to false to prevent the comment from showing. - /// |是否显示注解组件。 - /// </summary> - public bool show { get { return m_Show; } set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } } - public List<CommentItem> items { get { return m_Items; } set { m_Items = value; SetComponentDirty(); } } - /// <summary> - /// The text style of all comments. - /// |所有组件的文本样式。 - /// </summary> - public LabelStyle labelStyle - { - get { return m_LabelStyle; } - set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// The text style of all comments. - /// |所有组件的文本样式。 - /// </summary> - public CommentMarkStyle markStyle - { - get { return m_MarkStyle; } - set { if (PropertyUtil.SetClass(ref m_MarkStyle, value)) SetVerticesDirty(); } - } - - public LabelStyle GetLabelStyle(int index) - { - if (index >= 0 && index < items.Count) - { - var labelStyle = items[index].labelStyle; - if (labelStyle.show) return labelStyle; - } - return m_LabelStyle; - } - - public CommentMarkStyle GetMarkStyle(int index) - { - if (index >= 0 && index < items.Count) - { - var markStyle = items[index].markStyle; - if (markStyle.show) return markStyle; - } - return m_MarkStyle; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Comment/Comment.cs.meta b/Assets/XCharts/Runtime/Component/Comment/Comment.cs.meta deleted file mode 100644 index 3a9af59..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/Comment.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ec99dd6b13a3b4e9789d007f23ffa499 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Comment/CommentHander.cs b/Assets/XCharts/Runtime/Component/Comment/CommentHander.cs deleted file mode 100644 index f1c93ab..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/CommentHander.cs +++ /dev/null @@ -1,71 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class CommentHander : MainComponentHandler<Comment> - { - private static readonly string s_CommentObjectName = "comment"; - - public override void InitComponent() - { - var comment = component; - comment.painter = null; - comment.refreshComponent = delegate() - { - var objName = ChartCached.GetComponentObjectName(comment); - var commentObj = ChartHelper.AddObject(objName, - chart.transform, - chart.chartMinAnchor, - chart.chartMaxAnchor, - chart.chartPivot, - chart.chartSizeDelta); - - commentObj.SetActive(comment.show); - commentObj.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(commentObj); - for (int i = 0; i < comment.items.Count; i++) - { - var item = comment.items[i]; - var labelStyle = comment.GetLabelStyle(i); - var label = ChartHelper.AddChartLabel(s_CommentObjectName + i, commentObj.transform, labelStyle, chart.theme.common, - GetContent(item), Color.clear, TextAnchor.MiddleCenter); - label.SetActive(comment.show && item.show); - label.SetPosition(item.position + labelStyle.offset); - } - }; - comment.refreshComponent(); - } - - private string GetContent(CommentItem item) - { - if (item.content.IndexOf("{") >= 0) - { - var content = item.content; - FormatterHelper.ReplaceContent(ref content, 0, item.labelStyle.numericFormatter, null, chart); - return content; - } - else - { - return item.content; - } - } - - public override void DrawTop(VertexHelper vh) - { - for (int i = 0; i < component.items.Count; i++) - { - var item = component.items[i]; - var markStyle = component.GetMarkStyle(i); - if (!markStyle.show) continue; - var color = ChartHelper.IsClearColor(markStyle.lineStyle.color) ? - chart.theme.axis.splitLineColor : - markStyle.lineStyle.color; - var width = markStyle.lineStyle.width == 0 ? 1 : markStyle.lineStyle.width; - UGL.DrawBorder(vh, item.markRect, width, color); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Comment/CommentHander.cs.meta b/Assets/XCharts/Runtime/Component/Comment/CommentHander.cs.meta deleted file mode 100644 index a1e30c8..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/CommentHander.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 45362c4eed0e54d2880f2ed359ce9385 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Comment/CommentItem.cs b/Assets/XCharts/Runtime/Component/Comment/CommentItem.cs deleted file mode 100644 index 5a3a891..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/CommentItem.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// comment of chart. - /// |注解项。 - /// </summary> - [Serializable] - public class CommentItem : ChildComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private string m_Content = "comment"; - [SerializeField] private Vector3 m_Position; - [SerializeField] private Rect m_MarkRect; - [SerializeField] private CommentMarkStyle m_MarkStyle = new CommentMarkStyle() { show = false }; - [SerializeField] private LabelStyle m_LabelStyle = new LabelStyle() { show = false }; - - /// <summary> - /// Set this to false to prevent this comment item from showing. - /// |是否显示当前注解项。 - /// </summary> - public bool show { get { return m_Show; } set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } } - /// <summary> - /// position of comment. - /// |注解项的位置坐标。 - /// </summary> - public Vector3 position { get { return m_Position; } set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetComponentDirty(); } } - /// <summary> - /// content of comment. - /// |注解的文本内容。支持模板参数,可以参考Tooltip的itemFormatter。 - /// </summary> - public string content { get { return m_Content; } set { if (PropertyUtil.SetClass(ref m_Content, value)) SetComponentDirty(); } } - /// <summary> - /// the mark rect of comment. - /// |注解区域。 - /// </summary> - public Rect markRect { get { return m_MarkRect; } set { if (PropertyUtil.SetStruct(ref m_MarkRect, value)) SetVerticesDirty(); } } - /// <summary> - /// the mark rect style. - /// |注解标记区域样式。 - /// </summary> - public CommentMarkStyle markStyle { get { return m_MarkStyle; } set { if (PropertyUtil.SetClass(ref m_MarkStyle, value)) SetVerticesDirty(); } } - /// <summary> - /// The text style of all comments. - /// |注解项的文本样式。 - /// </summary> - public LabelStyle labelStyle - { - get { return m_LabelStyle; } - set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Comment/CommentItem.cs.meta b/Assets/XCharts/Runtime/Component/Comment/CommentItem.cs.meta deleted file mode 100644 index 29b3cd2..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/CommentItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f082815b255e546019b6b43ac20bf4cb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs b/Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs deleted file mode 100644 index 174c58a..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// the comment mark style. - /// |注解项区域样式。 - /// </summary> - [Serializable] - public class CommentMarkStyle : ChildComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private LineStyle m_LineStyle; - - /// <summary> - /// Set this to false to prevent this comment item from showing. - /// |是否显示当前注解项。 - /// </summary> - public bool show { get { return m_Show; } set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } } - /// <summary> - /// line style of comment mark area. - /// |线条样式。 - /// </summary> - public LineStyle lineStyle { get { return m_LineStyle; } set { if (PropertyUtil.SetClass(ref m_LineStyle, value)) SetVerticesDirty(); } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs.meta b/Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs.meta deleted file mode 100644 index 9e4c5dd..0000000 --- a/Assets/XCharts/Runtime/Component/Comment/CommentMarkStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 764734b787d72455782bf75bb38e465e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/DataZoom.meta b/Assets/XCharts/Runtime/Component/DataZoom.meta deleted file mode 100644 index c51556f..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a017b088954fb499eae363f4182fbeed -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs b/Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs deleted file mode 100644 index 33692b6..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs +++ /dev/null @@ -1,687 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// DataZoom component is used for zooming a specific area, - /// which enables user to investigate data in detail, - /// or get an overview of the data, or get rid of outlier points. - /// |DataZoom 组件 用于区域缩放,从而能自由关注细节的数据信息,或者概览数据整体,或者去除离群点的影响。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(DataZoomHandler), true)] - public class DataZoom : MainComponent, IUpdateRuntimeData - { - /// <summary> - /// Generally dataZoom component zoom or roam coordinate system through data filtering - /// and set the windows of axes internally. - /// Its behaviours vary according to filtering mode settings. - /// |dataZoom 的运行原理是通过 数据过滤 来达到 数据窗口缩放 的效果。数据过滤模式的设置不同,效果也不同。 - /// </summary> - public enum FilterMode - { - /// <summary> - /// data that outside the window will be filtered, which may lead to some changes of windows of other axes. - /// For each data item, it will be filtered if one of the relevant dimensions is out of the window. - /// |当前数据窗口外的数据,被 过滤掉。即 会 影响其他轴的数据范围。每个数据项,只要有一个维度在数据窗口外,整个数据项就会被过滤掉。 - /// </summary> - Filter, - /// <summary> - /// data that outside the window will be filtered, which may lead to some changes of windows of other axes. - /// For each data item, it will be filtered only if all of the relevant dimensions are out of the same side of the window. - /// |当前数据窗口外的数据,被 过滤掉。即 会 影响其他轴的数据范围。每个数据项,只有当全部维度都在数据窗口同侧外部,整个数据项才会被过滤掉。 - /// </summary> - WeakFilter, - /// <summary> - /// data that outside the window will be set to NaN, which will not lead to changes of windows of other axes. - /// |当前数据窗口外的数据,被 设置为空。即 不会 影响其他轴的数据范围。 - /// </summary> - Empty, - /// <summary> - /// Do not filter data. - /// |不过滤数据,只改变数轴范围。 - /// </summary> - None - } - /// <summary> - /// The value type of start and end.取值类型 - /// </summary> - public enum RangeMode - { - //Value, - /// <summary> - /// percent value. - /// |百分比。 - /// </summary> - Percent - } - - [SerializeField] private bool m_Enable = true; - [SerializeField] private FilterMode m_FilterMode; - [SerializeField] private List<int> m_XAxisIndexs = new List<int>() { 0 }; - [SerializeField] private List<int> m_YAxisIndexs = new List<int>() { }; - [SerializeField] private bool m_SupportInside; - [SerializeField] private bool m_SupportInsideScroll = true; - [SerializeField] private bool m_SupportInsideDrag = true; - [SerializeField] private bool m_SupportSlider; - [SerializeField] private bool m_SupportSelect; - [SerializeField] private bool m_ShowDataShadow; - [SerializeField] private bool m_ShowDetail; - [SerializeField] private bool m_ZoomLock; - //[SerializeField] private bool m_Realtime; - [SerializeField] protected Color32 m_FillerColor; - [SerializeField] protected Color32 m_BorderColor; - [SerializeField] protected float m_BorderWidth; - [SerializeField] protected Color32 m_BackgroundColor; - [SerializeField] private float m_Left; - [SerializeField] private float m_Right; - [SerializeField] private float m_Top; - [SerializeField] private float m_Bottom; - [SerializeField] private RangeMode m_RangeMode; - [SerializeField] private float m_Start; - [SerializeField] private float m_End; - //[SerializeField] private float m_StartValue; - //[SerializeField] private float m_EndValue; - [SerializeField] private int m_MinShowNum = 1; - [Range(1f, 20f)] - [SerializeField] private float m_ScrollSensitivity = 1.1f; - [SerializeField] private Orient m_Orient = Orient.Horizonal; - [SerializeField] private LabelStyle m_LabelStyle = new LabelStyle(); - [SerializeField] private LineStyle m_LineStyle = new LineStyle(LineStyle.Type.Solid); - [SerializeField] private AreaStyle m_AreaStyle = new AreaStyle(); - - public DataZoomContext context = new DataZoomContext(); - - /// <summary> - /// Whether to show dataZoom. - /// |是否显示缩放区域。 - /// </summary> - public bool enable - { - get { return m_Enable; } - set { if (PropertyUtil.SetStruct(ref m_Enable, value)) SetVerticesDirty(); } - } - /// <summary> - /// The mode of data filter. - /// |数据过滤类型。 - /// </summary> - public FilterMode filterMode - { - get { return m_FilterMode; } - set { if (PropertyUtil.SetStruct(ref m_FilterMode, value)) SetVerticesDirty(); } - } - /// <summary> - /// Specify which xAxis is controlled by the dataZoom. - /// |控制的 x 轴索引列表。 - /// </summary> - public List<int> xAxisIndexs - { - get { return m_XAxisIndexs; } - set { if (PropertyUtil.SetClass(ref m_XAxisIndexs, value)) SetVerticesDirty(); } - } - /// <summary> - /// Specify which yAxis is controlled by the dataZoom. - /// |控制的 y 轴索引列表。 - /// </summary> - public List<int> yAxisIndexs - { - get { return m_YAxisIndexs; } - set { if (PropertyUtil.SetClass(ref m_YAxisIndexs, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether built-in support is supported. - /// Built into the coordinate system to allow the user to zoom in and out of the coordinate system by mouse dragging, - /// mouse wheel, finger swiping (on the touch screen). - /// |是否支持内置。内置于坐标系中,使用户可以在坐标系上通过鼠标拖拽、鼠标滚轮、手指滑动(触屏上)来缩放或漫游坐标系。 - /// </summary> - public bool supportInside - { - get { return m_SupportInside; } - set { if (PropertyUtil.SetStruct(ref m_SupportInside, value)) SetVerticesDirty(); } - } - /// <summary> - /// 是否支持坐标系内滚动 - /// </summary> - public bool supportInsideScroll - { - get { return m_SupportInsideScroll; } - set { if (PropertyUtil.SetStruct(ref m_SupportInsideScroll, value)) SetVerticesDirty(); } - } - /// <summary> - /// 是否支持坐标系内拖拽 - /// </summary> - public bool supportInsideDrag - { - get { return m_SupportInsideDrag; } - set { if (PropertyUtil.SetStruct(ref m_SupportInsideDrag, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether a slider is supported. There are separate sliders on which the user zooms or roams. - /// |是否支持滑动条。有单独的滑动条,用户在滑动条上进行缩放或漫游。 - /// </summary> - public bool supportSlider - { - get { return m_SupportSlider; } - set { if (PropertyUtil.SetStruct(ref m_SupportSlider, value)) SetVerticesDirty(); } - } - /// <summary> - /// 是否支持框选。提供一个选框进行数据区域缩放。 - /// </summary> - public bool supportSelect - { - get { return m_SupportSelect; } - set { if (PropertyUtil.SetStruct(ref m_SupportSelect, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to show data shadow, to indicate the data tendency in brief. - /// |是否显示数据阴影。数据阴影可以简单地反应数据走势。 - /// </summary> - public bool showDataShadow - { - get { return m_ShowDataShadow; } - set { if (PropertyUtil.SetStruct(ref m_ShowDataShadow, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to show detail, that is, show the detailed data information when dragging. - /// |是否显示detail,即拖拽时候显示详细数值信息。 - /// </summary> - public bool showDetail - { - get { return m_ShowDetail; } - set { if (PropertyUtil.SetStruct(ref m_ShowDetail, value)) SetVerticesDirty(); } - } - /// <summary> - /// Specify whether to lock the size of window (selected area). - /// |是否锁定选择区域(或叫做数据窗口)的大小。 - /// 如果设置为 true 则锁定选择区域的大小,也就是说,只能平移,不能缩放。 - /// </summary> - public bool zoomLock - { - get { return m_ZoomLock; } - set { if (PropertyUtil.SetStruct(ref m_ZoomLock, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to show data shadow in dataZoom-silder component, to indicate the data tendency in brief. - /// |拖动时,是否实时更新系列的视图。如果设置为 false,则只在拖拽结束的时候更新。默认为true,暂不支持修改。 - /// </summary> - public bool realtime { get { return true; } } - /// <summary> - /// The background color of the component. - /// |组件的背景颜色。 - /// </summary> - public Color backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetStruct(ref m_BackgroundColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of dataZoom data area. - /// |数据区域颜色。 - /// </summary> - public Color32 fillerColor - { - get { return m_FillerColor; } - set { if (PropertyUtil.SetColor(ref m_FillerColor, value)) SetVerticesDirty(); } - } - - /// <summary> - /// the color of dataZoom border. - /// |边框颜色。 - /// </summary> - public Color32 borderColor - { - get { return m_BorderColor; } - set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetComponentDirty(); } - } - /// <summary> - /// 边框宽。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetComponentDirty(); } - } - /// <summary> - /// Distance between dataZoom component and the bottom side of the container. - /// bottom value is a instant pixel value like 10 or float value [0-1]. - /// |组件离容器下侧的距离。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetVerticesDirty(); } - } - /// <summary> - /// Distance between dataZoom component and the top side of the container. - /// top value is a instant pixel value like 10 or float value [0-1]. - /// |组件离容器上侧的距离。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetVerticesDirty(); } - } - /// <summary> - /// Distance between dataZoom component and the left side of the container. - /// left value is a instant pixel value like 10 or float value [0-1]. - /// |组件离容器左侧的距离。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetVerticesDirty(); } - } - /// <summary> - /// Distance between dataZoom component and the right side of the container. - /// right value is a instant pixel value like 10 or float value [0-1]. - /// |组件离容器右侧的距离。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetVerticesDirty(); } - } - /// <summary> - /// Use absolute value or percent value in DataZoom.start and DataZoom.end. - /// |取绝对值还是百分比。 - /// </summary> - public RangeMode rangeMode - { - get { return m_RangeMode; } - set { if (PropertyUtil.SetStruct(ref m_RangeMode, value)) SetVerticesDirty(); } - } - /// <summary> - /// The start percentage of the window out of the data extent, in the range of 0 ~ 100. - /// |数据窗口范围的起始百分比。范围是:0 ~ 100。 - /// </summary> - public float start - { - get { return m_Start; } - set { m_Start = value; if (m_Start < 0) m_Start = 0; if (m_Start > 100) m_Start = 100; SetVerticesDirty(); } - } - /// <summary> - /// The end percentage of the window out of the data extent, in the range of 0 ~ 100. - /// |数据窗口范围的结束百分比。范围是:0 ~ 100。 - /// </summary> - public float end - { - get { return m_End; } - set { m_End = value; if (m_End < 0) m_End = 0; if (m_End > 100) m_End = 100; SetVerticesDirty(); } - } - /// <summary> - /// Minimum number of display data. Minimum number of data displayed when DataZoom is enlarged to maximum. - /// |最小显示数据个数。当DataZoom放大到最大时,最小显示的数据个数。 - /// </summary> - public int minShowNum - { - get { return m_MinShowNum; } - set { if (PropertyUtil.SetStruct(ref m_MinShowNum, value)) SetVerticesDirty(); } - } - /// <summary> - /// The sensitivity of dataZoom scroll. - /// The larger the number, the more sensitive it is. - /// |缩放区域组件的敏感度。值越高每次缩放所代表的数据越多。 - /// </summary> - public float scrollSensitivity - { - get { return m_ScrollSensitivity; } - set { if (PropertyUtil.SetStruct(ref m_ScrollSensitivity, value)) SetVerticesDirty(); } - } - /// <summary> - /// Specify whether the layout of dataZoom component is horizontal or vertical. What's more, - /// it indicates whether the horizontal axis or vertical axis is controlled by default in catesian coordinate system. - /// |布局方式是横还是竖。不仅是布局方式,对于直角坐标系而言,也决定了,缺省情况控制横向数轴还是纵向数轴。 - /// </summary> - public Orient orient - { - get { return m_Orient; } - set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetVerticesDirty(); } - } - /// <summary> - /// label style. - /// |文本标签格式。 - /// </summary> - public LabelStyle labelStyle - { - get { return m_LabelStyle; } - set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// 阴影线条样式。 - /// </summary> - public LineStyle lineStyle - { - get { return m_LineStyle; } - set { if (PropertyUtil.SetClass(ref m_LineStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// 阴影填充样式。 - /// </summary> - public AreaStyle areaStyle - { - get { return m_AreaStyle; } - set { if (PropertyUtil.SetClass(ref m_AreaStyle, value)) SetComponentDirty(); } - } - - class AxisIndexValueInfo - { - public double min; - public double max; - } - private Dictionary<int, AxisIndexValueInfo> m_XAxisIndexInfos = new Dictionary<int, AxisIndexValueInfo>(); - private Dictionary<int, AxisIndexValueInfo> m_YAxisIndexInfos = new Dictionary<int, AxisIndexValueInfo>(); - - /// <summary> - /// The start label. - /// |组件的开始信息文本。 - /// </summary> - private ChartLabel m_StartLabel { get; set; } - /// <summary> - /// The end label. - /// |组件的结束信息文本。 - /// </summary> - private ChartLabel m_EndLabel { get; set; } - - public override void SetDefaultValue() - { - supportInside = true; - supportSlider = true; - filterMode = FilterMode.None; - xAxisIndexs = new List<int>() { 0 }; - yAxisIndexs = new List<int>() { }; - showDataShadow = true; - showDetail = false; - zoomLock = false; - m_Bottom = 10; - m_Left = 10; - m_Right = 10; - m_Top = 0.9f; - rangeMode = RangeMode.Percent; - start = 30; - end = 70; - m_Orient = Orient.Horizonal; - m_ScrollSensitivity = 10; - m_LabelStyle = new LabelStyle(); - m_LineStyle = new LineStyle(LineStyle.Type.Solid) - { - opacity = 0.3f - }; - m_AreaStyle = new AreaStyle() - { - show = true, - opacity = 0.3f - }; - } - - /// <summary> - /// 给定的坐标是否在缩放区域内 - /// </summary> - /// <param name="pos"></param> - /// <param name="startX"></param> - /// <param name="width"></param> - /// <returns></returns> - public bool IsInZoom(Vector2 pos) - { - if (pos.x < context.x - 1 || pos.x > context.x + context.width + 1 || - pos.y < context.y - 1 || pos.y > context.y + context.height + 1) - { - return false; - } - return true; - } - - /// <summary> - /// 给定的坐标是否在选中区域内 - /// </summary> - /// <param name="pos"></param> - /// <returns></returns> - public bool IsInSelectedZoom(Vector2 pos) - { - switch (m_Orient) - { - case Orient.Horizonal: - var start = context.x + context.width * m_Start / 100; - var end = context.x + context.width * m_End / 100; - return ChartHelper.IsInRect(pos, start, end, context.y, context.y + context.height); - case Orient.Vertical: - start = context.y + context.height * m_Start / 100; - end = context.y + context.height * m_End / 100; - return ChartHelper.IsInRect(pos, context.x, context.x + context.width, start, end); - default: - return false; - } - } - - public bool IsInSelectedZoom(int totalIndex, int index, bool invert) - { - if (totalIndex <= 0) - return false; - - var tstart = invert ? 100 - end : start; - var tend = invert ? 100 - start : end; - var range = Mathf.RoundToInt(totalIndex * (tend - tstart) / 100); - var min = Mathf.FloorToInt(totalIndex * tstart / 100); - var max = Mathf.CeilToInt(totalIndex * tend / 100); - if (min == 0) max = min + range; - if (max == totalIndex) min = max - range; - var flag = index >= min && index < min + range; - return flag; - } - - /// <summary> - /// 给定的坐标是否在开始活动条触发区域内 - /// </summary> - /// <param name="pos"></param> - /// <param name="startX"></param> - /// <param name="width"></param> - /// <returns></returns> - public bool IsInStartZoom(Vector2 pos) - { - switch (m_Orient) - { - case Orient.Horizonal: - var start = context.x + context.width * m_Start / 100; - return ChartHelper.IsInRect(pos, start - 10, start + 10, context.y, context.y + context.height); - case Orient.Vertical: - start = context.y + context.height * m_Start / 100; - return ChartHelper.IsInRect(pos, context.x, context.x + context.width, start - 10, start + 10); - default: - return false; - } - } - - /// <summary> - /// 给定的坐标是否在结束活动条触发区域内 - /// </summary> - /// <param name="pos"></param> - /// <param name="startX"></param> - /// <param name="width"></param> - /// <returns></returns> - public bool IsInEndZoom(Vector2 pos) - { - switch (m_Orient) - { - case Orient.Horizonal: - var end = context.x + context.width * m_End / 100; - return ChartHelper.IsInRect(pos, end - 10, end + 10, context.y, context.y + context.height); - case Orient.Vertical: - end = context.y + context.height * m_End / 100; - return ChartHelper.IsInRect(pos, context.x, context.x + context.width, end - 10, end + 10); - default: - return false; - } - } - - public bool IsContainsAxis(Axis axis) - { - if (axis == null) - return false; - else if (axis is XAxis) - return xAxisIndexs.Contains(axis.index); - else if (axis is YAxis) - return yAxisIndexs.Contains(axis.index); - else - return false; - } - public bool IsContainsXAxis(int index) - { - return xAxisIndexs != null && xAxisIndexs.Contains(index); - } - - public bool IsContainsYAxis(int index) - { - return yAxisIndexs != null && yAxisIndexs.Contains(index); - } - - public Color32 GetFillerColor(Color32 themeColor) - { - if (ChartHelper.IsClearColor(fillerColor)) - return themeColor; - else - return fillerColor; - } - - public Color32 GetBackgroundColor(Color32 themeColor) - { - if (ChartHelper.IsClearColor(backgroundColor)) - return themeColor; - else - return backgroundColor; - } - public Color32 GetBorderColor(Color32 themeColor) - { - if (ChartHelper.IsClearColor(borderColor)) - return themeColor; - else - return borderColor; - } - - /// <summary> - /// 是否显示文本 - /// </summary> - /// <param name="flag"></param> - internal void SetLabelActive(bool flag) - { - m_StartLabel.SetActive(flag); - m_EndLabel.SetActive(flag); - } - - /// <summary> - /// 设置开始文本内容 - /// </summary> - /// <param name="text"></param> - internal void SetStartLabelText(string text) - { - if (m_StartLabel != null) m_StartLabel.SetText(text); - } - - /// <summary> - /// 设置结束文本内容 - /// </summary> - /// <param name="text"></param> - internal void SetEndLabelText(string text) - { - if (m_EndLabel != null) m_EndLabel.SetText(text); - } - - internal void SetStartLabel(ChartLabel startLabel) - { - m_StartLabel = startLabel; - } - - internal void SetEndLabel(ChartLabel endLabel) - { - m_EndLabel = endLabel; - } - - internal void UpdateStartLabelPosition(Vector3 pos) - { - m_StartLabel.SetPosition(pos); - } - - internal void UpdateEndLabelPosition(Vector3 pos) - { - m_EndLabel.SetPosition(pos); - } - - public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight) - { - var runtimeLeft = left <= 1 ? left * chartWidth : left; - var runtimeBottom = bottom <= 1 ? bottom * chartHeight : bottom; - var runtimeTop = top <= 1 ? top * chartHeight : top; - var runtimeRight = right <= 1 ? right * chartWidth : right; - context.x = chartX + runtimeLeft; - context.y = chartY + runtimeBottom; - context.width = chartWidth - runtimeLeft - runtimeRight; - context.height = chartHeight - runtimeTop - runtimeBottom; - } - - internal void SetXAxisIndexValueInfo(int xAxisIndex, double min, double max) - { - if (!m_XAxisIndexInfos.ContainsKey(xAxisIndex)) - { - m_XAxisIndexInfos[xAxisIndex] = new AxisIndexValueInfo() - { - min = min, - max = max - }; - } - else - { - m_XAxisIndexInfos[xAxisIndex].min = min; - m_XAxisIndexInfos[xAxisIndex].max = max; - } - } - - internal void SetYAxisIndexValueInfo(int yAxisIndex, double min, double max) - { - if (!m_YAxisIndexInfos.ContainsKey(yAxisIndex)) - { - m_YAxisIndexInfos[yAxisIndex] = new AxisIndexValueInfo() - { - min = min, - max = max - }; - } - else - { - m_YAxisIndexInfos[yAxisIndex].min = min; - m_YAxisIndexInfos[yAxisIndex].max = max; - } - } - - internal bool IsXAxisIndexValue(int axisIndex) - { - return m_XAxisIndexInfos.ContainsKey(axisIndex); - } - - internal bool IsYAxisIndexValue(int axisIndex) - { - return m_YAxisIndexInfos.ContainsKey(axisIndex); - } - - internal void GetXAxisIndexValue(int axisIndex, out double min, out double max) - { - min = 0; - max = 0; - if (m_XAxisIndexInfos.ContainsKey(axisIndex)) - { - var info = m_XAxisIndexInfos[axisIndex]; - min = info.min; - max = info.max; - } - } - internal void GetYAxisIndexValue(int axisIndex, out double min, out double max) - { - min = 0; - max = 0; - if (m_YAxisIndexInfos.ContainsKey(axisIndex)) - { - var info = m_YAxisIndexInfos[axisIndex]; - min = info.min; - max = info.max; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs.meta b/Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs.meta deleted file mode 100644 index 1f760ce..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoom.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dc01046451b8f406896eb1a5c50433db -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs b/Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs deleted file mode 100644 index 49cf852..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class DataZoomContext : MainComponentContext - { - public float x { get; internal set; } - public float y { get; internal set; } - public float width { get; internal set; } - public float height { get; internal set; } - public bool isDrag { get; internal set; } - public bool isCoordinateDrag { get; internal set; } - public bool isStartDrag { get; internal set; } - public bool isEndDrag { get; internal set; } - /// <summary> - /// 运行时实际范围的开始值 - /// </summary> - public double startValue { get; set; } - /// <summary> - /// 运行时实际范围的结束值 - /// </summary> - public double endValue { get; set; } - public bool invert { get; set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs.meta b/Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs.meta deleted file mode 100644 index 0bf1d45..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 899bbe0691c1c450c99f775d8d5f38c9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs b/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs deleted file mode 100644 index 6fce889..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs +++ /dev/null @@ -1,614 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class DataZoomHandler : MainComponentHandler<DataZoom> - { - private static readonly string s_DefaultDataZoom = "datazoom"; - private Vector2 m_LastTouchPos0; - private Vector2 m_LastTouchPos1; - private bool m_CheckDataZoomLabel; - private float m_DataZoomLastStartIndex; - private float m_DataZoomLastEndIndex; - - public override void InitComponent() - { - var dataZoom = component; - dataZoom.painter = chart.m_PainterTop; - dataZoom.refreshComponent = delegate() - { - var dataZoomObject = ChartHelper.AddObject(s_DefaultDataZoom + dataZoom.index, chart.transform, - chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - dataZoom.gameObject = dataZoomObject; - dataZoomObject.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(dataZoomObject); - - var startLabel = ChartHelper.AddChartLabel(s_DefaultDataZoom + "start", dataZoomObject.transform, - dataZoom.labelStyle, chart.theme.dataZoom, "", Color.clear, TextAnchor.MiddleRight); - startLabel.gameObject.SetActive(true); - - var endLabel = ChartHelper.AddChartLabel(s_DefaultDataZoom + "end", dataZoomObject.transform, - dataZoom.labelStyle, chart.theme.dataZoom, "", Color.clear, TextAnchor.MiddleLeft); - endLabel.gameObject.SetActive(true); - - dataZoom.SetStartLabel(startLabel); - dataZoom.SetEndLabel(endLabel); - dataZoom.SetLabelActive(false); - - foreach (var index in dataZoom.xAxisIndexs) - { - var xAxis = chart.GetChartComponent<XAxis>(index); - if (xAxis != null) - { - xAxis.UpdateFilterData(dataZoom); - } - } - - foreach (var serie in chart.series) - { - SerieHelper.UpdateFilterData(serie, dataZoom); - } - }; - dataZoom.refreshComponent(); - } - public override void Update() - { - CheckDataZoomScale(component); - CheckDataZoomLabel(component); - } - - public override void DrawTop(VertexHelper vh) - { - if (chart == null) - return; - - var dataZoom = component; - switch (dataZoom.orient) - { - case Orient.Horizonal: - DrawHorizonalDataZoomSlider(vh, dataZoom); - break; - case Orient.Vertical: - DrawVerticalDataZoomSlider(vh, dataZoom); - break; - } - } - - public override void OnBeginDrag(PointerEventData eventData) - { - if (chart == null) - return; - - if (Input.touchCount > 1) - return; - - Vector2 pos; - if (!chart.ScreenPointToChartPoint(eventData.position, out pos)) - return; - - var dataZoom = component; - if (!dataZoom.enable) - return; - - var grid = chart.GetGridOfDataZoom(dataZoom); - if (dataZoom.supportInside && dataZoom.supportInsideDrag) - { - if (grid.Contains(pos)) - { - dataZoom.context.isCoordinateDrag = true; - } - } - if (dataZoom.supportSlider) - { - if (!dataZoom.zoomLock) - { - if (dataZoom.IsInStartZoom(pos)) - { - dataZoom.context.isStartDrag = true; - } - else if (dataZoom.IsInEndZoom(pos)) - { - dataZoom.context.isEndDrag = true; - } - else if (dataZoom.IsInSelectedZoom(pos)) - { - dataZoom.context.isDrag = true; - } - } - else if (dataZoom.IsInSelectedZoom(pos)) - { - dataZoom.context.isDrag = true; - } - } - } - - public override void OnDrag(PointerEventData eventData) - { - if (chart == null) - return; - if (Input.touchCount > 1) - return; - - var dataZoom = component; - var grid = chart.GetGridOfDataZoom(dataZoom); - switch (dataZoom.orient) - { - case Orient.Horizonal: - var deltaPercent = eventData.delta.x / grid.context.width * 100; - OnDragInside(dataZoom, deltaPercent); - OnDragSlider(dataZoom, deltaPercent); - break; - case Orient.Vertical: - deltaPercent = eventData.delta.y / grid.context.height * 100; - OnDragInside(dataZoom, deltaPercent); - OnDragSlider(dataZoom, deltaPercent); - break; - } - } - - public override void OnEndDrag(PointerEventData eventData) - { - if (chart == null) - return; - - var dataZoom = component; - if (dataZoom.context.isDrag || dataZoom.context.isStartDrag || dataZoom.context.isEndDrag || - dataZoom.context.isCoordinateDrag) - { - chart.RefreshChart(); - } - dataZoom.context.isDrag = false; - dataZoom.context.isCoordinateDrag = false; - dataZoom.context.isStartDrag = false; - dataZoom.context.isEndDrag = false; - } - public override void OnPointerDown(PointerEventData eventData) - { - if (chart == null) - return; - if (Input.touchCount > 1) - return; - - Vector2 localPos; - if (!chart.ScreenPointToChartPoint(eventData.position, out localPos)) - return; - - var dataZoom = component; - var grid = chart.GetGridOfDataZoom(dataZoom); - if (dataZoom.IsInStartZoom(localPos) || - dataZoom.IsInEndZoom(localPos)) - { - return; - } - - if (dataZoom.IsInZoom(localPos) && - !dataZoom.IsInSelectedZoom(localPos)) - { - var pointerX = localPos.x; - var selectWidth = grid.context.width * (dataZoom.end - dataZoom.start) / 100; - var startX = pointerX - selectWidth / 2; - var endX = pointerX + selectWidth / 2; - if (startX < grid.context.x) - { - startX = grid.context.x; - endX = grid.context.x + selectWidth; - } - else if (endX > grid.context.x + grid.context.width) - { - endX = grid.context.x + grid.context.width; - startX = grid.context.x + grid.context.width - selectWidth; - } - var start = (startX - grid.context.x) / grid.context.width * 100; - var end = (endX - grid.context.x) / grid.context.width * 100; - UpdateDataZoomRange(dataZoom, start, end); - } - } - public override void OnScroll(PointerEventData eventData) - { - if (chart == null) - return; - if (Input.touchCount > 1) - return; - - Vector2 pos; - if (!chart.ScreenPointToChartPoint(eventData.position, out pos)) - return; - - var dataZoom = component; - if (!dataZoom.enable || dataZoom.zoomLock) - return; - - var grid = chart.GetGridOfDataZoom(dataZoom); - if ((dataZoom.supportInside && dataZoom.supportInsideScroll && grid.Contains(pos)) || - dataZoom.IsInZoom(pos)) - { - ScaleDataZoom(dataZoom, eventData.scrollDelta.y * dataZoom.scrollSensitivity); - } - } - - private void OnDragInside(DataZoom dataZoom, float deltaPercent) - { - if (deltaPercent == 0) - return; - if (Input.touchCount > 1) - return; - if (!dataZoom.supportInside || !dataZoom.supportInsideDrag) - return; - if (!dataZoom.context.isCoordinateDrag) - return; - - var diff = dataZoom.end - dataZoom.start; - if (deltaPercent > 0) - { - if (dataZoom.start > 0) - { - var start = dataZoom.start - deltaPercent; - if (start < 0) start = 0; - var end = start + diff; - UpdateDataZoomRange(dataZoom, start, end); - } - } - else - { - if (dataZoom.end < 100) - { - var end = dataZoom.end - deltaPercent; - if (end > 100) end = 100; - var start = end - diff; - UpdateDataZoomRange(dataZoom, start, end); - } - } - } - - private void OnDragSlider(DataZoom dataZoom, float deltaPercent) - { - if (Input.touchCount > 1) - return; - if (!dataZoom.supportSlider) - return; - - if (dataZoom.context.isStartDrag) - { - var start = dataZoom.start + deltaPercent; - if (start > dataZoom.end) - { - start = dataZoom.end; - dataZoom.context.isEndDrag = true; - dataZoom.context.isStartDrag = false; - } - UpdateDataZoomRange(dataZoom, start, dataZoom.end); - } - else if (dataZoom.context.isEndDrag) - { - var end = dataZoom.end + deltaPercent; - if (end < dataZoom.start) - { - end = dataZoom.start; - dataZoom.context.isStartDrag = true; - dataZoom.context.isEndDrag = false; - } - UpdateDataZoomRange(dataZoom, dataZoom.start, end); - } - else if (dataZoom.context.isDrag) - { - if (deltaPercent > 0) - { - if (dataZoom.end + deltaPercent > 100) deltaPercent = 100 - dataZoom.end; - } - else - { - if (dataZoom.start + deltaPercent < 0) deltaPercent = -dataZoom.start; - } - UpdateDataZoomRange(dataZoom, dataZoom.start + deltaPercent, dataZoom.end + deltaPercent); - } - } - - private void ScaleDataZoom(DataZoom dataZoom, float delta) - { - var grid = chart.GetGridOfDataZoom(dataZoom); - var deltaPercent = dataZoom.orient == Orient.Horizonal ? - Mathf.Abs(delta / grid.context.width * 100) : - Mathf.Abs(delta / grid.context.height * 100); - if (delta > 0) - { - if (dataZoom.end <= dataZoom.start) - return; - UpdateDataZoomRange(dataZoom, dataZoom.start + deltaPercent, dataZoom.end - deltaPercent); - } - else - { - UpdateDataZoomRange(dataZoom, dataZoom.start - deltaPercent, dataZoom.end + deltaPercent); - } - } - - public void UpdateDataZoomRange(DataZoom dataZoom, float start, float end) - { - if (end > 100) - end = 100; - - if (start < 0) - start = 0; - - if (end < start) - end = start; - - dataZoom.start = start; - dataZoom.end = end; - if (dataZoom.realtime) - { - chart.OnDataZoomRangeChanged(dataZoom); - chart.RefreshChart(); - } - } - - public void RefreshDataZoomLabel() - { - m_CheckDataZoomLabel = true; - } - - private void CheckDataZoomScale(DataZoom dataZoom) - { - if (!dataZoom.enable || dataZoom.zoomLock || !dataZoom.supportInside || !dataZoom.supportInsideDrag) - return; - - if (Input.touchCount == 2) - { - var touch0 = Input.GetTouch(0); - var touch1 = Input.GetTouch(1); - if (touch1.phase == TouchPhase.Began) - { - m_LastTouchPos0 = touch0.position; - m_LastTouchPos1 = touch1.position; - } - else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved) - { - var tempPos0 = touch0.position; - var tempPos1 = touch1.position; - var currDist = Vector2.Distance(tempPos0, tempPos1); - var lastDist = Vector2.Distance(m_LastTouchPos0, m_LastTouchPos1); - var delta = (currDist - lastDist); - ScaleDataZoom(dataZoom, delta / dataZoom.scrollSensitivity); - m_LastTouchPos0 = tempPos0; - m_LastTouchPos1 = tempPos1; - } - } - } - - private void CheckDataZoomLabel(DataZoom dataZoom) - { - if (dataZoom.enable && dataZoom.supportSlider && dataZoom.showDetail) - { - Vector2 local; - if (!chart.ScreenPointToChartPoint(Input.mousePosition, out local)) - { - dataZoom.SetLabelActive(false); - return; - } - if (dataZoom.IsInSelectedZoom(local) || - dataZoom.IsInStartZoom(local) || - dataZoom.IsInEndZoom(local)) - { - dataZoom.SetLabelActive(true); - RefreshDataZoomLabel(); - } - else - { - dataZoom.SetLabelActive(false); - } - } - if (m_CheckDataZoomLabel && dataZoom.xAxisIndexs.Count > 0) - { - m_CheckDataZoomLabel = false; - var xAxis = chart.GetChartComponent<XAxis>(dataZoom.xAxisIndexs[0]); - var startIndex = (int) ((xAxis.data.Count - 1) * dataZoom.start / 100); - var endIndex = (int) ((xAxis.data.Count - 1) * dataZoom.end / 100); - - if (m_DataZoomLastStartIndex != startIndex || m_DataZoomLastEndIndex != endIndex) - { - m_DataZoomLastStartIndex = startIndex; - m_DataZoomLastEndIndex = endIndex; - if (xAxis.data.Count > 0) - { - dataZoom.SetStartLabelText(xAxis.data[startIndex]); - dataZoom.SetEndLabelText(xAxis.data[endIndex]); - } - else if (xAxis.IsTime()) - { - //TODO: - dataZoom.SetStartLabelText(""); - dataZoom.SetEndLabelText(""); - } - xAxis.SetAllDirty(); - } - var start = dataZoom.context.x + dataZoom.context.width * dataZoom.start / 100; - var end = dataZoom.context.x + dataZoom.context.width * dataZoom.end / 100; - var hig = dataZoom.context.height; - dataZoom.UpdateStartLabelPosition(new Vector3(start - 10, chart.chartY + dataZoom.bottom + hig / 2)); - dataZoom.UpdateEndLabelPosition(new Vector3(end + 10, chart.chartY + dataZoom.bottom + hig / 2)); - } - } - - private void DrawHorizonalDataZoomSlider(VertexHelper vh, DataZoom dataZoom) - { - if (!dataZoom.enable || !dataZoom.supportSlider) - return; - var p1 = new Vector3(dataZoom.context.x, dataZoom.context.y); - var p2 = new Vector3(dataZoom.context.x, dataZoom.context.y + dataZoom.context.height); - var p3 = new Vector3(dataZoom.context.x + dataZoom.context.width, dataZoom.context.y + dataZoom.context.height); - var p4 = new Vector3(dataZoom.context.x + dataZoom.context.width, dataZoom.context.y); - - var lineColor = dataZoom.lineStyle.GetColor(chart.theme.dataZoom.dataLineColor); - var lineWidth = dataZoom.lineStyle.GetWidth(chart.theme.dataZoom.dataLineWidth); - var borderWidth = dataZoom.borderWidth == 0 ? chart.theme.dataZoom.borderWidth : dataZoom.borderWidth; - var borderColor = dataZoom.GetBorderColor(chart.theme.dataZoom.borderColor); - var backgroundColor = dataZoom.GetBackgroundColor(chart.theme.dataZoom.backgroundColor); - var areaColor = dataZoom.areaStyle.GetColor(chart.theme.dataZoom.dataAreaColor); - - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, backgroundColor); - - var centerPos = new Vector3(dataZoom.context.x + dataZoom.context.width / 2, - dataZoom.context.y + dataZoom.context.height / 2); - UGL.DrawBorder(vh, centerPos, dataZoom.context.width, dataZoom.context.height, borderWidth, borderColor); - if (dataZoom.showDataShadow && chart.series.Count > 0) - { - Serie serie = chart.series[0]; - Axis axis = chart.GetChartComponent<YAxis>(0); - var showData = serie.GetDataList(null); - float scaleWid = dataZoom.context.width / (showData.Count - 1); - Vector3 lp = Vector3.zero; - Vector3 np = Vector3.zero; - double minValue = 0; - double maxValue = 0; - SeriesHelper.GetYMinMaxValue(chart.series, null, 0, chart.IsAllAxisValue(), axis.inverse, out minValue, out maxValue); - AxisHelper.AdjustMinMaxValue(axis, ref minValue, ref maxValue, true); - - int rate = 1; - var sampleDist = serie.sampleDist < 2 ? 2 : serie.sampleDist; - var maxCount = showData.Count; - if (sampleDist > 0) - rate = (int) ((maxCount - serie.minShow) / (dataZoom.context.width / sampleDist)); - if (rate < 1) - rate = 1; - - var totalAverage = serie.sampleAverage > 0 ? serie.sampleAverage : - DataHelper.DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate); - var dataChanging = false; - - for (int i = 0; i < maxCount; i += rate) - { - double value = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage, i, - serie.animation.GetUpdateAnimationDuration(), ref dataChanging, axis); - float pX = dataZoom.context.x + i * scaleWid; - float dataHig = (float) ((maxValue - minValue) == 0 ? 0 : - (value - minValue) / (maxValue - minValue) * dataZoom.context.height); - np = new Vector3(pX, chart.chartY + dataZoom.bottom + dataHig); - if (i > 0) - { - UGL.DrawLine(vh, lp, np, lineWidth, lineColor); - Vector3 alp = new Vector3(lp.x, lp.y - lineWidth); - Vector3 anp = new Vector3(np.x, np.y - lineWidth); - - Vector3 tnp = new Vector3(np.x, chart.chartY + dataZoom.bottom + lineWidth); - Vector3 tlp = new Vector3(lp.x, chart.chartY + dataZoom.bottom + lineWidth); - UGL.DrawQuadrilateral(vh, alp, anp, tnp, tlp, areaColor); - } - lp = np; - } - if (dataChanging) - { - chart.RefreshTopPainter(); - } - } - switch (dataZoom.rangeMode) - { - case DataZoom.RangeMode.Percent: - var start = dataZoom.context.x + dataZoom.context.width * dataZoom.start / 100; - var end = dataZoom.context.x + dataZoom.context.width * dataZoom.end / 100; - var fillerColor = dataZoom.GetFillerColor(chart.theme.dataZoom.fillerColor); - - p1 = new Vector2(start, dataZoom.context.y); - p2 = new Vector2(start, dataZoom.context.y + dataZoom.context.height); - p3 = new Vector2(end, dataZoom.context.y + dataZoom.context.height); - p4 = new Vector2(end, dataZoom.context.y); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, fillerColor); - UGL.DrawLine(vh, p1, p2, lineWidth, fillerColor); - UGL.DrawLine(vh, p3, p4, lineWidth, fillerColor); - break; - } - } - - private void DrawVerticalDataZoomSlider(VertexHelper vh, DataZoom dataZoom) - { - if (!dataZoom.enable || !dataZoom.supportSlider) - return; - - var p1 = new Vector3(dataZoom.context.x, dataZoom.context.y); - var p2 = new Vector3(dataZoom.context.x, dataZoom.context.y + dataZoom.context.height); - var p3 = new Vector3(dataZoom.context.x + dataZoom.context.width, dataZoom.context.y + dataZoom.context.height); - var p4 = new Vector3(dataZoom.context.x + dataZoom.context.width, dataZoom.context.y); - var lineColor = dataZoom.lineStyle.GetColor(chart.theme.dataZoom.dataLineColor); - var lineWidth = dataZoom.lineStyle.GetWidth(chart.theme.dataZoom.dataLineWidth); - var borderWidth = dataZoom.borderWidth == 0 ? chart.theme.dataZoom.borderWidth : dataZoom.borderWidth; - var borderColor = dataZoom.GetBorderColor(chart.theme.dataZoom.borderColor); - var backgroundColor = dataZoom.GetBackgroundColor(chart.theme.dataZoom.backgroundColor); - var areaColor = dataZoom.areaStyle.GetColor(chart.theme.dataZoom.dataAreaColor); - - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, backgroundColor); - var centerPos = new Vector3(dataZoom.context.x + dataZoom.context.width / 2, - dataZoom.context.y + dataZoom.context.height / 2); - UGL.DrawBorder(vh, centerPos, dataZoom.context.width, dataZoom.context.height, borderWidth, borderColor); - - if (dataZoom.showDataShadow && chart.series.Count > 0) - { - Serie serie = chart.series[0]; - Axis axis = chart.GetChartComponent<YAxis>(0); - var showData = serie.GetDataList(null); - float scaleWid = dataZoom.context.height / (showData.Count - 1); - Vector3 lp = Vector3.zero; - Vector3 np = Vector3.zero; - double minValue = 0; - double maxValue = 0; - SeriesHelper.GetYMinMaxValue(chart.series, null, 0, chart.IsAllAxisValue(), axis.inverse, out minValue, out maxValue); - AxisHelper.AdjustMinMaxValue(axis, ref minValue, ref maxValue, true); - - int rate = 1; - var sampleDist = serie.sampleDist < 2 ? 2 : serie.sampleDist; - var maxCount = showData.Count; - if (sampleDist > 0) - rate = (int) ((maxCount - serie.minShow) / (dataZoom.context.height / sampleDist)); - if (rate < 1) - rate = 1; - - var totalAverage = serie.sampleAverage > 0 ? serie.sampleAverage : - DataHelper.DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate); - var dataChanging = false; - - for (int i = 0; i < maxCount; i += rate) - { - double value = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage, i, - serie.animation.GetUpdateAnimationDuration(), ref dataChanging, axis); - float pY = dataZoom.context.y + i * scaleWid; - float dataHig = (maxValue - minValue) == 0 ? 0 : - (float) ((value - minValue) / (maxValue - minValue) * dataZoom.context.width); - np = new Vector3(chart.chartX + chart.chartWidth - dataZoom.right - dataHig, pY); - if (i > 0) - { - UGL.DrawLine(vh, lp, np, lineWidth, lineColor); - Vector3 alp = new Vector3(lp.x, lp.y - lineWidth); - Vector3 anp = new Vector3(np.x, np.y - lineWidth); - - Vector3 tnp = new Vector3(np.x, chart.chartY + dataZoom.bottom + lineWidth); - Vector3 tlp = new Vector3(lp.x, chart.chartY + dataZoom.bottom + lineWidth); - UGL.DrawQuadrilateral(vh, alp, anp, tnp, tlp, areaColor); - } - lp = np; - } - if (dataChanging) - { - chart.RefreshTopPainter(); - } - } - switch (dataZoom.rangeMode) - { - case DataZoom.RangeMode.Percent: - var start = dataZoom.context.y + dataZoom.context.height * dataZoom.start / 100; - var end = dataZoom.context.y + dataZoom.context.height * dataZoom.end / 100; - var fillerColor = dataZoom.GetFillerColor(chart.theme.dataZoom.fillerColor); - - p1 = new Vector2(dataZoom.context.x, start); - p2 = new Vector2(dataZoom.context.x + dataZoom.context.width, start); - p3 = new Vector2(dataZoom.context.x + dataZoom.context.width, end); - p4 = new Vector2(dataZoom.context.x, end); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, fillerColor); - UGL.DrawLine(vh, p1, p2, lineWidth, fillerColor); - UGL.DrawLine(vh, p3, p4, lineWidth, fillerColor); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs.meta b/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs.meta deleted file mode 100644 index 5f39e61..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3f980f43c96a748e0913a1a0054ecd9d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs b/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs deleted file mode 100644 index c7f8b81..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace XCharts.Runtime -{ - public static class DataZoomHelper - { - public static void UpdateDataZoomRuntimeStartEndValue(DataZoom dataZoom, Serie serie) - { - if (dataZoom == null || serie == null) - return; - - double min = 0; - double max = 0; - SerieHelper.GetMinMaxData(serie, out min, out max, null); - dataZoom.context.startValue = min + (max - min) * dataZoom.start / 100; - dataZoom.context.endValue = min + (max - min) * dataZoom.end / 100; - } - - public static void UpdateDataZoomRuntimeStartEndValue<T>(BaseChart chart) where T : Serie - { - foreach (var component in chart.components) - { - if (component is DataZoom) - { - var dataZoom = component as DataZoom; - if (!dataZoom.enable) - continue; - - double min = double.MaxValue; - double max = double.MinValue; - foreach (var serie in chart.series) - { - if (!serie.show || !(serie is T)) - continue; - if (!dataZoom.IsContainsXAxis(serie.xAxisIndex)) - continue; - - var axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - - if (axis.minMaxType == Axis.AxisMinMaxType.Custom) - { - if (axis.min < min) - min = axis.min; - if (axis.max > max) - max = axis.max; - } - else - { - double serieMinValue = 0; - double serieMaxValue = 0; - SerieHelper.GetMinMaxData(serie, out serieMinValue, out serieMaxValue, null, 2); - if (serieMinValue < min) - min = serieMinValue; - if (serieMaxValue > max) - max = serieMaxValue; - } - } - dataZoom.context.startValue = min + (max - min) * dataZoom.start / 100; - dataZoom.context.endValue = min + (max - min) * dataZoom.end / 100; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs.meta b/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs.meta deleted file mode 100644 index 070730e..0000000 --- a/Assets/XCharts/Runtime/Component/DataZoom/DataZoomHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3cc7a61abc3a74004a079f796e51dfc9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Debug.meta b/Assets/XCharts/Runtime/Component/Debug.meta deleted file mode 100644 index aefd3c3..0000000 --- a/Assets/XCharts/Runtime/Component/Debug.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 76abe02f90a34419dbd45292ed7000d6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs b/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs deleted file mode 100644 index 5daca29..0000000 --- a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - public class DebugInfo - { -#pragma warning disable 0414 - [SerializeField] private bool m_Show = true; -#pragma warning restore 0414 - [SerializeField] private bool m_ShowDebugInfo = false; - [SerializeField] protected bool m_ShowAllChartObject = false; - [SerializeField] protected bool m_FoldSeries = false; - [SerializeField] - private LabelStyle m_LabelStyle = new LabelStyle() - { - background = new ImageStyle() - { - color = new Color32(32, 32, 32, 170) - }, - textStyle = new TextStyle() - { - fontSize = 18, - color = Color.white - } - }; - - private static StringBuilder s_Sb = new StringBuilder(); - - private static readonly float INTERVAL = 0.2f; - private static readonly float MAXCACHE = 20; - private int m_FrameCount = 0; - private float m_LastTime = 0f; - private float m_LastCheckShowTime = 0f; - private int m_LastRefreshCount = 0; - private BaseChart m_Chart; - private ChartLabel m_Label; - private List<float> m_FpsList = new List<float>(); - - public bool showAllChartObject { get { return m_ShowAllChartObject; } set { m_ShowAllChartObject = value; } } - public bool foldSeries { get { return m_FoldSeries; } set { m_FoldSeries = value; } } - public float fps { get; private set; } - public float avgFps { get; private set; } - public int refreshCount { get; internal set; } - internal int clickChartCount { get; set; } - - public void Init(BaseChart chart) - { - m_Chart = chart; - m_Label = AddDebugInfoObject("debug", chart.transform, m_LabelStyle, chart.theme); - } - - public void Update() - { - if (clickChartCount > 2) - { - m_ShowDebugInfo = !m_ShowDebugInfo; - ChartHelper.SetActive(m_Label.transform, m_ShowDebugInfo); - clickChartCount = 0; - m_LastCheckShowTime = Time.realtimeSinceStartup; - return; - } - if (Time.realtimeSinceStartup - m_LastCheckShowTime > 0.5f) - { - m_LastCheckShowTime = Time.realtimeSinceStartup; - clickChartCount = 0; - } - if (!m_ShowDebugInfo || m_Label == null) - return; - - m_FrameCount++; - if (Time.realtimeSinceStartup - m_LastTime >= INTERVAL) - { - fps = m_FrameCount / (Time.realtimeSinceStartup - m_LastTime); - m_FrameCount = 0; - m_LastTime = Time.realtimeSinceStartup; - if (m_LastRefreshCount == refreshCount) - { - m_LastRefreshCount = 0; - refreshCount = 0; - } - m_LastRefreshCount = refreshCount; - if (m_FpsList.Count > MAXCACHE) - { - m_FpsList.RemoveAt(0); - } - m_FpsList.Add(fps); - avgFps = GetAvg(m_FpsList); - if (m_Label != null) - { - s_Sb.Length = 0; - s_Sb.AppendFormat("v{0}\n", XChartsMgr.version); - s_Sb.AppendFormat("fps : {0:f0} / {1:f0}\n", fps, avgFps); - s_Sb.AppendFormat("draw : {0}\n", refreshCount); - - var dataCount = m_Chart.GetAllSerieDataCount(); - SetValueWithKInfo(s_Sb, "data", dataCount); - - var vertCount = 0; - foreach (var serie in m_Chart.series) - vertCount += serie.context.vertCount; - - SetValueWithKInfo(s_Sb, "b-vert", m_Chart.m_BasePainterVertCount); - SetValueWithKInfo(s_Sb, "s-vert", vertCount); - SetValueWithKInfo(s_Sb, "t-vert", m_Chart.m_TopPainterVertCount, false); - - var serie0 = m_Chart.GetSerie(0); - for (int i = 0; i < serie0.dataCount; i++) - { - var serieData = serie0.data[i]; - s_Sb.AppendFormat("{0}:{1}\n", i, serieData.interact.targetVaue); - } - - m_Label.SetText(s_Sb.ToString()); - } - } - } - - private static void SetValueWithKInfo(StringBuilder s_Sb, string key, int value, bool newLine = true) - { - if (value >= 1000) - s_Sb.AppendFormat("{0} : {1:f1}k", key, value * 0.001f); - else - s_Sb.AppendFormat("{0} : {1}", key, value); - if (newLine) - s_Sb.Append("\n"); - } - - private static float GetAvg(List<float> list) - { - var total = 0f; - foreach (var v in list) total += v; - return total / list.Count; - } - - private ChartLabel AddDebugInfoObject(string name, Transform parent, LabelStyle labelStyle, - ThemeStyle theme) - { - var anchorMax = new Vector2(0, 1); - var anchorMin = new Vector2(0, 1); - var pivot = new Vector2(0, 1); - var sizeDelta = new Vector2(100, 100); - - var labelGameObject = ChartHelper.AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta); - labelGameObject.transform.SetAsLastSibling(); - labelGameObject.hideFlags = m_Chart.chartHideFlags; - ChartHelper.SetActive(labelGameObject, m_ShowDebugInfo); - - var label = ChartHelper.AddChartLabel("info", labelGameObject.transform, labelStyle, theme.common, - "", Color.clear, TextAnchor.UpperLeft); - label.SetActive(labelStyle.show); - return label; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs.meta b/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs.meta deleted file mode 100644 index be8f760..0000000 --- a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d6accb0ff71304b56a019db8ee3139d9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Emphasis.meta b/Assets/XCharts/Runtime/Component/Emphasis.meta deleted file mode 100644 index 68dbdad..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4cd4074bb11fc40059363dd78b9ee98d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs b/Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs deleted file mode 100644 index 90d6464..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs +++ /dev/null @@ -1,74 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 高亮的图形样式和文本标签样式。 - /// </summary> - [System.Serializable] - public class Emphasis : ChildComponent, ISerieExtraComponent, ISerieDataComponent - { - [SerializeField] private bool m_Show; - [SerializeField] private LabelStyle m_Label = new LabelStyle(); - [SerializeField] private LabelLine m_LabelLine = new LabelLine(); - [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); - - public void Reset() - { - m_Show = false; - m_Label.Reset(); - m_LabelLine.Reset(); - m_ItemStyle.Reset(); - } - - /// <summary> - /// 是否启用高亮样式。 - /// </summary> - public bool show - { - get { return m_Show; } - set { m_Show = value; } - } - /// <summary> - /// 图形文本标签。 - /// </summary> - public LabelStyle label - { - get { return m_Label; } - set { if (PropertyUtil.SetClass(ref m_Label, value, true)) SetAllDirty(); } - } - /// <summary> - /// 图形文本引导线样式。 - /// </summary> - public LabelLine labelLine - { - get { return m_LabelLine; } - set { if (PropertyUtil.SetClass(ref m_LabelLine, value, true)) SetAllDirty(); } - } - /// <summary> - /// 图形样式。 - /// </summary> - public ItemStyle itemStyle - { - get { return m_ItemStyle; } - set { if (PropertyUtil.SetClass(ref m_ItemStyle, value, true)) SetVerticesDirty(); } - } - - public override bool vertsDirty { get { return m_VertsDirty || label.vertsDirty || itemStyle.vertsDirty; } } - - public override bool componentDirty { get { return m_ComponentDirty || label.componentDirty; } } - - public override void ClearVerticesDirty() - { - base.ClearVerticesDirty(); - label.ClearVerticesDirty(); - itemStyle.ClearVerticesDirty(); - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - label.ClearComponentDirty(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs.meta b/Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs.meta deleted file mode 100644 index 8aeb094..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/Emphasis.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6e0b1690532674b24952a87e0aead6fa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs b/Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs deleted file mode 100644 index ca5ad8e..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 高亮的图形样式 - /// </summary> - [System.Serializable] - public class EmphasisItemStyle : ItemStyle, ISerieExtraComponent, ISerieDataComponent - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs.meta b/Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs.meta deleted file mode 100644 index 73b3363..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisItemStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5d1095175540449f99bb9da27a5aaf04 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs b/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs deleted file mode 100644 index 9a132ad..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 高亮的标签引导线样式 - /// </summary> - [System.Serializable] - public class EmphasisLabelLine : LabelLine, ISerieExtraComponent, ISerieDataComponent - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs.meta b/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs.meta deleted file mode 100644 index b6bd83f..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a0d9ff3b8e09d464e9b5ea996b941314 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs b/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs deleted file mode 100644 index 0279fc6..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 高亮的标签样式 - /// </summary> - [System.Serializable] - public class EmphasisLabelStyle : LabelStyle, ISerieExtraComponent, ISerieDataComponent - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs.meta b/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs.meta deleted file mode 100644 index 77199dd..0000000 --- a/Assets/XCharts/Runtime/Component/Emphasis/EmphasisLabelStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3e025b0f4be6d4141aa08bdad0102aa7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Interaction.meta b/Assets/XCharts/Runtime/Component/Interaction.meta deleted file mode 100644 index 9dd74cb..0000000 --- a/Assets/XCharts/Runtime/Component/Interaction.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8445ec442e5314aa891cbbd6d4d966c4 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Interaction/InteractData.cs b/Assets/XCharts/Runtime/Component/Interaction/InteractData.cs deleted file mode 100644 index fd9122c..0000000 --- a/Assets/XCharts/Runtime/Component/Interaction/InteractData.cs +++ /dev/null @@ -1,207 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - public class InteractData - { - private float m_PreviousValue = 0; - private float m_TargetValue = 0; - private Color32 m_PreviousColor; - private Color32 m_TargetColor; - private Color32 m_PreviousToColor; - private Color32 m_TargetToColor; - private float m_UpdateTime = 0; - private bool m_UpdateFlag = false; - private bool m_ValueEnable = false; - - internal float targetVaue { get { return m_TargetValue; } } - - public void SetValue(ref bool needInteract, float size, bool highlight, float rate = 1.3f) - { - size = highlight ? size * rate : size; - SetValue(ref needInteract, size); - } - - public void SetValue(ref bool needInteract, float size) - { - if (m_TargetValue != size) - { - needInteract = true; - m_UpdateFlag = true; - m_ValueEnable = true; - m_UpdateTime = Time.time; - m_PreviousValue = m_TargetValue; - m_TargetValue = size; - } - } - - public void SetColor(ref bool needInteract, Color32 color) - { - if (!ChartHelper.IsValueEqualsColor(color, m_TargetColor)) - { - if (!ChartHelper.IsClearColor(m_TargetColor)) - { - needInteract = true; - m_UpdateFlag = true; - m_ValueEnable = true; - m_UpdateTime = Time.time; - m_PreviousColor = m_TargetColor; - } - m_TargetColor = color; - } - } - public void SetColor(ref bool needInteract, Color32 color, Color32 toColor) - { - SetColor(ref needInteract, color); - if (!ChartHelper.IsValueEqualsColor(toColor, m_TargetToColor)) - { - if (!ChartHelper.IsClearColor(m_TargetToColor)) - { - needInteract = true; - m_UpdateFlag = true; - m_ValueEnable = true; - m_UpdateTime = Time.time; - m_PreviousToColor = m_TargetToColor; - } - m_TargetToColor = toColor; - } - } - - public void SetValueAndColor(ref bool needInteract, float value, Color32 color) - { - SetValue(ref needInteract, value); - SetColor(ref needInteract, color); - } - - public void SetValueAndColor(ref bool needInteract, float value, Color32 color, Color32 toColor) - { - SetValue(ref needInteract, value); - SetColor(ref needInteract, color, toColor); - } - - public bool TryGetValue(ref float value, ref bool interacting, float animationDuration = 250) - { - if (!IsValueEnable() || m_PreviousValue == 0) - return false; - if (m_UpdateFlag) - { - var time = Time.time - m_UpdateTime; - var total = animationDuration / 1000; - var rate = time / total; - if (rate > 1) rate = 1; - if (rate < 1) - { - interacting = true; - value = Mathf.Lerp(m_PreviousValue, m_TargetValue, rate); - return true; - } - else - { - m_UpdateFlag = false; - } - } - value = m_TargetValue; - return true; - } - - public bool TryGetColor(ref Color32 color, ref bool interacting, float animationDuration = 250) - { - if (!IsValueEnable()) - return false; - if (m_UpdateFlag) - { - var time = Time.time - m_UpdateTime; - var total = animationDuration / 1000; - var rate = time / total; - if (rate > 1) rate = 1; - if (rate < 1) - { - interacting = true; - color = Color32.Lerp(m_PreviousColor, m_TargetColor, rate); - return true; - } - else - { - m_UpdateFlag = false; - } - } - color = m_TargetColor; - return true; - } - - public bool TryGetColor(ref Color32 color, ref Color32 toColor, ref bool interacting, float animationDuration = 250) - { - if (!IsValueEnable()) - return false; - if (m_UpdateFlag) - { - var time = Time.time - m_UpdateTime; - var total = animationDuration / 1000; - var rate = time / total; - if (rate > 1) rate = 1; - if (rate < 1) - { - interacting = true; - color = Color32.Lerp(m_PreviousColor, m_TargetColor, rate); - toColor = Color32.Lerp(m_PreviousToColor, m_TargetToColor, rate); - return true; - } - else - { - m_UpdateFlag = false; - } - } - color = m_TargetColor; - toColor = m_TargetToColor; - return true; - } - public bool TryGetValueAndColor(ref float value, ref Color32 color, ref Color32 toColor, ref bool interacting, float animationDuration = 250) - { - if (!IsValueEnable()) - return false; - if (m_UpdateFlag) - { - var time = Time.time - m_UpdateTime; - var total = animationDuration / 1000; - var rate = time / total; - if (rate > 1) rate = 1; - if (rate < 1) - { - interacting = true; - value = Mathf.Lerp(m_PreviousValue, m_TargetValue, rate); - color = Color32.Lerp(m_PreviousColor, m_TargetColor, rate); - toColor = Color32.Lerp(m_PreviousToColor, m_TargetToColor, rate); - return true; - } - else - { - m_UpdateFlag = false; - } - } - value = m_TargetValue; - color = m_TargetColor; - toColor = m_TargetToColor; - return true; - } - - public void Reset() - { - m_UpdateFlag = false; - m_ValueEnable = false; - m_PreviousValue = float.NaN; - m_TargetColor = ColorUtil.clearColor32; - m_TargetToColor = ColorUtil.clearColor32; - m_PreviousColor = ColorUtil.clearColor32; - m_PreviousToColor = ColorUtil.clearColor32; - } - - private bool IsValueEnable() - { -#if UNITY_EDITOR - if (!Application.isPlaying) - return false; -#endif - return m_ValueEnable; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Interaction/InteractData.cs.meta b/Assets/XCharts/Runtime/Component/Interaction/InteractData.cs.meta deleted file mode 100644 index 4e09507..0000000 --- a/Assets/XCharts/Runtime/Component/Interaction/InteractData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 42f150814cce84d66b931eed0a07d4ce -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Label.meta b/Assets/XCharts/Runtime/Component/Label.meta deleted file mode 100644 index 401c628..0000000 --- a/Assets/XCharts/Runtime/Component/Label.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ad378dd158b5d438a87405d35a3a6546 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs b/Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs deleted file mode 100644 index ecdd7e9..0000000 --- a/Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class EndLabelStyle : LabelStyle - { - public EndLabelStyle() - { - m_Offset = new Vector3(5, 0, 0); - m_TextStyle.alignment = TextAnchor.MiddleLeft; - m_NumericFormatter = "f0"; - m_Formatter = "{a}:{c}"; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs.meta b/Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs.meta deleted file mode 100644 index deca912..0000000 --- a/Assets/XCharts/Runtime/Component/Label/EndLabelStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b3ca55f3ab0314339ae171c8ac07c4e2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Label/LabelLine.cs b/Assets/XCharts/Runtime/Component/Label/LabelLine.cs deleted file mode 100644 index a0b1c2c..0000000 --- a/Assets/XCharts/Runtime/Component/Label/LabelLine.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 标签的引导线 - /// </summary> - [System.Serializable] - public class LabelLine : ChildComponent, ISerieExtraComponent, ISerieDataComponent - { - /// <summary> - /// 标签视觉引导线类型 - /// </summary> - public enum LineType - { - /// <summary> - /// 折线 - /// </summary> - BrokenLine, - /// <summary> - /// 曲线 - /// </summary> - Curves, - /// <summary> - /// 水平线 - /// </summary> - HorizontalLine - } - - [SerializeField] private bool m_Show = true; - [SerializeField] private LineType m_LineType = LineType.BrokenLine; - [SerializeField] private Color32 m_LineColor = ChartConst.clearColor32; - [SerializeField] private float m_LineAngle = 0; - [SerializeField] private float m_LineWidth = 1.0f; - [SerializeField] private float m_LineGap = 1.0f; - [SerializeField] private float m_LineLength1 = 25f; - [SerializeField] private float m_LineLength2 = 15f; - [SerializeField] private SymbolStyle m_StartSymbol = new SymbolStyle() { type = SymbolType.Circle, size = 3 }; - [SerializeField] private SymbolStyle m_EndSymbol = new SymbolStyle() { type = SymbolType.Circle, size = 3 }; - - public void Reset() - { - m_Show = false; - m_LineType = LineType.BrokenLine; - m_LineColor = Color.clear; - m_LineAngle = 0; - m_LineWidth = 1.0f; - m_LineGap = 1.0f; - m_LineLength1 = 25f; - m_LineLength2 = 15f; - } - - /// <summary> - /// Whether the label line is showed. - /// |是否显示视觉引导线。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); } - } - /// <summary> - /// the type of visual guide line. - /// |视觉引导线类型。 - /// </summary> - public LineType lineType - { - get { return m_LineType; } - set { if (PropertyUtil.SetStruct(ref m_LineType, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of visual guild line. - /// |视觉引导线颜色。默认和serie一致取自调色板。 - /// </summary> - public Color32 lineColor - { - get { return m_LineColor; } - set { if (PropertyUtil.SetStruct(ref m_LineColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// the angle of visual guild line. - /// |视觉引导线的固定角度。对折线和曲线有效。 - /// </summary> - public float lineAngle - { - get { return m_LineAngle; } - set { if (PropertyUtil.SetStruct(ref m_LineAngle, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of visual guild line. - /// |视觉引导线的宽度。 - /// </summary> - public float lineWidth - { - get { return m_LineWidth; } - set { if (PropertyUtil.SetStruct(ref m_LineWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the gap of container and guild line. - /// |视觉引导线和容器的间距。 - /// </summary> - public float lineGap - { - get { return m_LineGap; } - set { if (PropertyUtil.SetStruct(ref m_LineGap, value)) SetVerticesDirty(); } - } - /// <summary> - /// The length of the first segment of visual guide line. - /// |视觉引导线第一段的长度。 - /// </summary> - public float lineLength1 - { - get { return m_LineLength1; } - set { if (PropertyUtil.SetStruct(ref m_LineLength1, value)) SetVerticesDirty(); } - } - /// <summary> - /// The length of the second segment of visual guide line. - /// |视觉引导线第二段的长度。 - /// </summary> - public float lineLength2 - { - get { return m_LineLength2; } - set { if (PropertyUtil.SetStruct(ref m_LineLength2, value)) SetVerticesDirty(); } - } - /// <summary> - /// The symbol of the start point of labelline. - /// |起始点的图形标记。 - /// </summary> - public SymbolStyle startSymbol - { - get { return m_StartSymbol; } - set { if (PropertyUtil.SetClass(ref m_StartSymbol, value)) SetVerticesDirty(); } - } - /// <summary> - /// The symbol of the end point of labelline. - /// |结束点的图形标记。 - /// </summary> - public SymbolStyle endSymbol - { - get { return m_EndSymbol; } - set { if (PropertyUtil.SetClass(ref m_EndSymbol, value)) SetVerticesDirty(); } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Label/LabelLine.cs.meta b/Assets/XCharts/Runtime/Component/Label/LabelLine.cs.meta deleted file mode 100644 index 2f3d51f..0000000 --- a/Assets/XCharts/Runtime/Component/Label/LabelLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1c3977205b6f14d8a97ae32177691580 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Label/LabelStyle.cs b/Assets/XCharts/Runtime/Component/Label/LabelStyle.cs deleted file mode 100644 index 4d96a02..0000000 --- a/Assets/XCharts/Runtime/Component/Label/LabelStyle.cs +++ /dev/null @@ -1,319 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Text label of chart, to explain some data information about graphic item like value, name and so on. - /// |图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。 - /// </summary> - [System.Serializable] - public class LabelStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent - { - /// <summary> - /// The position of label. - /// |标签的位置。 - /// </summary> - public enum Position - { - Default, - /// <summary> - /// Outside of sectors of pie chart, which relates to corresponding sector through visual guide line. - /// |饼图扇区外侧,通过视觉引导线连到相应的扇区。 - /// </summary> - Outside, - /// <summary> - /// Inside the sectors of pie chart. - /// |饼图扇区内部。 - /// </summary> - Inside, - /// <summary> - /// In the center of pie chart. - /// |在饼图中心位置。 - /// </summary> - Center, - /// <summary> - /// top of symbol. - /// |图形标志的顶部。 - /// </summary> - Top, - /// <summary> - /// the bottom of symbol. - /// |图形标志的底部。 - /// </summary> - Bottom, - /// <summary> - /// the left of symbol. - /// |图形标志的左边。 - /// </summary> - Left, - /// <summary> - /// the right of symbol. - /// |图形标志的右边。 - /// </summary> - Right, - /// <summary> - /// the start of line. - /// |线的起始点。 - /// </summary> - Start, - /// <summary> - /// the middle of line. - /// |线的中点。 - /// </summary> - Middle, - /// <summary> - /// the end of line. - /// |线的结束点。 - /// </summary> - End - } - - [SerializeField] protected bool m_Show = true; - [SerializeField] Position m_Position = Position.Default; - [SerializeField] protected bool m_AutoOffset = false; - [SerializeField] protected Vector3 m_Offset; - [SerializeField] protected float m_Rotate; - [SerializeField] protected float m_Distance; - [SerializeField] protected string m_Formatter; - [SerializeField] protected string m_NumericFormatter = ""; - [SerializeField] protected float m_Width = 0; - [SerializeField] protected float m_Height = 0; - - [SerializeField] protected IconStyle m_Icon = new IconStyle(); - [SerializeField] protected ImageStyle m_Background = new ImageStyle(); - [SerializeField] protected TextPadding m_TextPadding = new TextPadding(); - [SerializeField] protected TextStyle m_TextStyle = new TextStyle(); - protected LabelFormatterFunction m_FormatterFunction; - - public void Reset() - { - m_Show = false; - m_Position = Position.Default; - m_Offset = Vector3.zero; - m_Distance = 0; - m_Rotate = 0; - m_Width = 0; - m_Height = 0; - m_NumericFormatter = ""; - m_AutoOffset = false; - } - - /// <summary> - /// Whether the label is showed. - /// |是否显示文本标签。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); } - } - /// <summary> - /// The position of label. - /// |标签的位置。 - /// </summary> - public Position position - { - get { return m_Position; } - set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetVerticesDirty(); } - } - /// <summary> - /// formatter of label. - /// |标签内容字符串模版格式器。支持用 \n 换行。 - /// 模板变量有: - /// {.}:圆点标记。 - /// {a}:系列名。 - /// {a}:系列名。 - /// {b}:类目值或数据名。 - /// {c}:数据值。 - /// {d}:百分比。 - /// {e}:数据名。 - /// {f}:数据和。 - /// 示例:“{b}:{c}” - /// </summary> - public string formatter - { - get { return m_Formatter; } - set { if (PropertyUtil.SetClass(ref m_Formatter, value)) SetVerticesDirty(); } - } - /// <summary> - /// offset to the host graphic element. - /// |距离图形元素的偏移 - /// </summary> - public Vector3 offset - { - get { return m_Offset; } - set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetVerticesDirty(); } - } - /// <summary> - /// Rotation of label. - /// |文本的旋转。 - /// </summary> - public float rotate - { - get { return m_Rotate; } - set { if (PropertyUtil.SetStruct(ref m_Rotate, value)) SetComponentDirty(); } - } - /// <summary> - /// 距离轴线的距离。 - /// </summary> - public float distance - { - get { return m_Distance; } - set { if (PropertyUtil.SetStruct(ref m_Distance, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of label. If set as default value 0, it means than the label width auto set as the text width. - /// |标签的宽度。一般不用指定,不指定时则自动是文字的宽度。 - /// </summary> - /// <value></value> - public float width - { - get { return m_Width; } - set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetComponentDirty(); } - } - /// <summary> - /// the height of label. If set as default value 0, it means than the label height auto set as the text height. - /// |标签的高度。一般不用指定,不指定时则自动是文字的高度。 - /// </summary> - /// <value></value> - public float height - { - get { return m_Height; } - set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetComponentDirty(); } - } - /// <summary> - /// the text padding of label. - /// |文本的边距。 - /// </summary> - public TextPadding textPadding - { - get { return m_TextPadding; } - set { if (PropertyUtil.SetClass(ref m_TextPadding, value)) SetComponentDirty(); } - } - /// <summary> - /// Standard numeric format strings. - /// |标准数字格式字符串。用于将数值格式化显示为字符串。 - /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 - /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings - /// </summary> - /// <value></value> - public string numericFormatter - { - get { return m_NumericFormatter; } - set { if (PropertyUtil.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } - } - /// <summary> - /// 是否开启自动偏移。当开启时,Y的偏移会自动判断曲线的开口来决定向上还是向下偏移。 - /// </summary> - public bool autoOffset - { - get { return m_AutoOffset; } - set { if (PropertyUtil.SetStruct(ref m_AutoOffset, value)) SetAllDirty(); } - } - /// <summary> - /// the sytle of background. - /// |背景图样式。 - /// </summary> - public ImageStyle background - { - get { return m_Background; } - set { if (PropertyUtil.SetClass(ref m_Background, value)) SetAllDirty(); } - } - /// <summary> - /// the sytle of icon. - /// |图标样式。 - /// </summary> - public IconStyle icon - { - get { return m_Icon; } - set { if (PropertyUtil.SetClass(ref m_Icon, value)) SetAllDirty(); } - } - /// <summary> - /// the sytle of text. - /// |文本样式。 - /// </summary> - public TextStyle textStyle - { - get { return m_TextStyle; } - set { if (PropertyUtil.SetClass(ref m_TextStyle, value)) SetAllDirty(); } - } - public LabelFormatterFunction formatterFunction - { - get { return m_FormatterFunction; } - set { m_FormatterFunction = value; } - } - - public bool IsInside() - { - return m_Position == Position.Inside || m_Position == Position.Center; - } - - public bool IsDefaultPosition(Position position) - { - return m_Position == Position.Default || m_Position == position; - } - - public bool IsAutoSize() - { - return width == 0 && height == 0; - } - - public Vector3 GetOffset(float radius) - { - var x = ChartHelper.GetActualValue(m_Offset.x, radius); - var y = ChartHelper.GetActualValue(m_Offset.y, radius); - var z = ChartHelper.GetActualValue(m_Offset.z, radius); - return new Vector3(x, y, z); - } - - public Color GetColor(Color defaultColor) - { - if (ChartHelper.IsClearColor(textStyle.color)) - { - return IsInside() ? Color.black : defaultColor; - } - else - { - return textStyle.color; - } - } - - public virtual LabelStyle Clone() - { - var label = new LabelStyle(); - label.m_Show = m_Show; - label.m_Position = m_Position; - label.m_Offset = m_Offset; - label.m_Rotate = m_Rotate; - label.m_Distance = m_Distance; - label.m_Formatter = m_Formatter; - label.m_Width = m_Width; - label.m_Height = m_Height; - label.m_NumericFormatter = m_NumericFormatter; - label.m_AutoOffset = m_AutoOffset; - label.m_Icon.Copy(m_Icon); - label.m_Background.Copy(m_Background); - label.m_TextPadding = m_TextPadding; - label.m_TextStyle.Copy(m_TextStyle); - return label; - } - - public virtual void Copy(LabelStyle label) - { - m_Show = label.m_Show; - m_Position = label.m_Position; - m_Offset = label.m_Offset; - m_Rotate = label.m_Rotate; - m_Distance = label.m_Distance; - m_Formatter = label.m_Formatter; - m_Width = label.m_Width; - m_Height = label.m_Height; - m_NumericFormatter = label.m_NumericFormatter; - m_AutoOffset = label.m_AutoOffset; - m_Icon.Copy(label.m_Icon); - m_Background.Copy(label.m_Background); - m_TextPadding = label.m_TextPadding; - m_TextStyle.Copy(label.m_TextStyle); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Label/LabelStyle.cs.meta b/Assets/XCharts/Runtime/Component/Label/LabelStyle.cs.meta deleted file mode 100644 index 9f25d62..0000000 --- a/Assets/XCharts/Runtime/Component/Label/LabelStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0b2c690f282f04752898422894f61738 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Legend.meta b/Assets/XCharts/Runtime/Component/Legend.meta deleted file mode 100644 index cbd5c63..0000000 --- a/Assets/XCharts/Runtime/Component/Legend.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5bf1d7d1b565e45b6aacd4a261ddef9f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Legend/Legend.cs b/Assets/XCharts/Runtime/Component/Legend/Legend.cs deleted file mode 100644 index 4c59156..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/Legend.cs +++ /dev/null @@ -1,425 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Legend component.The legend component shows different sets of tags, colors, and names. - /// You can control which series are not displayed by clicking on the legend. - /// |图例组件。 - /// 图例组件展现了不同系列的标记,颜色和名字。可以通过点击图例控制哪些系列不显示。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(LegendHandler), true)] - public class Legend : MainComponent, IPropertyChanged - { - public enum Type - { - /// <summary> - /// 自动匹配。 - /// </summary> - Auto, - /// <summary> - /// 自定义图标。 - /// </summary> - Custom, - /// <summary> - /// 空心圆。 - /// </summary> - EmptyCircle, - /// <summary> - /// 圆形。 - /// </summary> - Circle, - /// <summary> - /// 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。 - /// </summary> - Rect, - /// <summary> - /// 三角形。 - /// </summary> - Triangle, - /// <summary> - /// 菱形。 - /// </summary> - Diamond, - } - /// <summary> - /// Selected mode of legend, which controls whether series can be toggled displaying by clicking legends. - /// |图例选择的模式,控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。 - /// </summary> - public enum SelectedMode - { - /// <summary> - /// 多选。 - /// </summary> - Multiple, - /// <summary> - /// 单选。 - /// </summary> - Single, - /// <summary> - /// 无法选择。 - /// </summary> - None - } - - [SerializeField] private bool m_Show = true; - [SerializeField] private Type m_IconType = Type.Auto; - [SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple; - [SerializeField] private Orient m_Orient = Orient.Horizonal; - [SerializeField] private Location m_Location = new Location() { align = Location.Align.TopCenter, top = 0.125f }; - [SerializeField] private float m_ItemWidth = 25.0f; - [SerializeField] private float m_ItemHeight = 12.0f; - [SerializeField] private float m_ItemGap = 10f; - [SerializeField] private bool m_ItemAutoColor = true; - [SerializeField] private float m_ItemOpacity = 1; - [SerializeField] private string m_Formatter; - [SerializeField] protected string m_NumericFormatter = ""; - [SerializeField] private LabelStyle m_LabelStyle = new LabelStyle(); - [SerializeField] private List<string> m_Data = new List<string>(); - [SerializeField] private List<Sprite> m_Icons = new List<Sprite>(); - [SerializeField] private List<Color> m_Colors = new List<Color>(); - - public LegendContext context = new LegendContext(); - - /// <summary> - /// Whether to show legend component. - /// |是否显示图例组件。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } - } - /// <summary> - /// Type of legend. - /// |图例类型。 - /// [default:Type.Auto] - /// </summary> - public Type iconType - { - get { return m_IconType; } - set { if (PropertyUtil.SetStruct(ref m_IconType, value)) SetAllDirty(); } - } - /// <summary> - /// Selected mode of legend, which controls whether series can be toggled displaying by clicking legends. - /// |选择模式。控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。 - /// [default:SelectedMode.Multiple] - /// </summary> - public SelectedMode selectedMode - { - get { return m_SelectedMode; } - set { if (PropertyUtil.SetStruct(ref m_SelectedMode, value)) SetComponentDirty(); } - } - /// <summary> - /// Specify whether the layout of legend component is horizontal or vertical. - /// |布局方式是横还是竖。 - /// [default:Orient.Horizonal] - /// </summary> - public Orient orient - { - get { return m_Orient; } - set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetComponentDirty(); } - } - /// <summary> - /// The location of legend. - /// |图例显示的位置。 - /// [default:Location.defaultTop] - /// </summary> - public Location location - { - get { return m_Location; } - set { if (PropertyUtil.SetClass(ref m_Location, value)) SetComponentDirty(); } - } - /// <summary> - /// Image width of legend symbol. - /// |图例标记的图形宽度。 - /// [default:24f] - /// </summary> - public float itemWidth - { - get { return m_ItemWidth; } - set { if (PropertyUtil.SetStruct(ref m_ItemWidth, value)) SetComponentDirty(); } - } - /// <summary> - /// Image height of legend symbol. - /// |图例标记的图形高度。 - /// [default:12f] - /// </summary> - public float itemHeight - { - get { return m_ItemHeight; } - set { if (PropertyUtil.SetStruct(ref m_ItemHeight, value)) SetComponentDirty(); } - } - /// <summary> - /// The distance between each legend, horizontal distance in horizontal layout, and vertical distance in vertical layout. - /// |图例每项之间的间隔。横向布局时为水平间隔,纵向布局时为纵向间隔。 - /// [default:10f] - /// </summary> - public float itemGap - { - get { return m_ItemGap; } - set { if (PropertyUtil.SetStruct(ref m_ItemGap, value)) SetComponentDirty(); } - } - /// <summary> - /// Whether the legend symbol matches the color automatically. - /// |图例标记的图形是否自动匹配颜色。 - /// [default:true] - /// </summary> - public bool itemAutoColor - { - get { return m_ItemAutoColor; } - set { if (PropertyUtil.SetStruct(ref m_ItemAutoColor, value)) SetComponentDirty(); } - } - /// <summary> - /// the opacity of item color. - /// |图例标记的图形的颜色透明度。 - /// </summary> - public float itemOpacity - { - get { return m_ItemOpacity; } - set { if (PropertyUtil.SetStruct(ref m_ItemOpacity, value)) SetComponentDirty(); } - } - /// <summary> - /// Standard numeric format strings. - /// |标准数字格式字符串。用于将数值格式化显示为字符串。 - /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 - /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings - /// </summary> - /// <value></value> - public string numericFormatter - { - get { return m_NumericFormatter; } - set { if (PropertyUtil.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } - } - /// <summary> - /// Legend content string template formatter. Support for wrapping lines with \n. Template:{value}. - /// |图例内容字符串模版格式器。支持用 \n 换行。 - /// 模板变量为图例名称 {value}。其他模板变量参考Toolip的itemFormatter。 - /// </summary> - public string formatter - { - get { return m_Formatter; } - set { if (PropertyUtil.SetClass(ref m_Formatter, value)) SetComponentDirty(); } - } - /// <summary> - /// the style of text. - /// |文本样式。 - /// </summary> - public LabelStyle labelStyle - { - get { return m_LabelStyle; } - set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// Data array of legend. An array item is usually a name representing string. (If it is a pie chart, - /// it could also be the name of a single data in the pie chart) of a series. - /// |If data is not specified, it will be auto collected from series. - /// |图例的数据数组。数组项通常为一个字符串,每一项代表一个系列的 name(如果是饼图,也可以是饼图单个数据的 name)。 - /// 如果 data 没有被指定,会自动从当前系列中获取。指定data时里面的数据项和serie匹配时才会生效。 - /// </summary> - public List<string> data - { - get { return m_Data; } - set { if (value != null) { m_Data = value; SetComponentDirty(); } } - } - /// <summary> - /// 自定义的图例标记图形。 - /// </summary> - public List<Sprite> icons - { - get { return m_Icons; } - set { if (value != null) { m_Icons = value; SetComponentDirty(); } } - } - /// <summary> - /// the colors of legend item. - /// 图例标记的颜色列表。 - /// </summary> - public List<Color> colors - { - get { return m_Colors; } - set { if (value != null) { m_Colors = value; SetAllDirty(); } } - } - /// <summary> - /// 图表是否需要刷新(图例组件不需要刷新图表) - /// </summary> - public override bool vertsDirty { get { return false; } } - /// <summary> - /// 组件是否需要刷新 - /// </summary> - public override bool componentDirty - { - get { return m_ComponentDirty || location.componentDirty || labelStyle.componentDirty; } - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - location.ClearComponentDirty(); - labelStyle.ClearComponentDirty(); - } - - /// <summary> - /// Clear legend data. - /// |清空。 - /// </summary> - public override void ClearData() - { - m_Data.Clear(); - SetComponentDirty(); - } - - /// <summary> - /// Whether include in legend data by the specified name. - /// |是否包括由指定名字的图例 - /// </summary> - /// <param name="name"></param> - /// <returns></returns> - public bool ContainsData(string name) - { - return m_Data.Contains(name); - } - - /// <summary> - /// Removes the legend with the specified name. - /// |移除指定名字的图例。 - /// </summary> - /// <param name="name"></param> - public void RemoveData(string name) - { - if (m_Data.Contains(name)) - { - m_Data.Remove(name); - SetComponentDirty(); - } - } - - /// <summary> - /// Add legend data. - /// |添加图例。 - /// </summary> - /// <param name="name"></param> - public void AddData(string name) - { - if (!m_Data.Contains(name) && !string.IsNullOrEmpty(name)) - { - m_Data.Add(name); - SetComponentDirty(); - } - } - - /// <summary> - /// Gets the legend for the specified index. - /// |获得指定索引的图例。 - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public string GetData(int index) - { - if (index >= 0 && index < m_Data.Count) - { - return m_Data[index]; - } - return null; - } - - /// <summary> - /// Gets the index of the specified legend. - /// |获得指定图例的索引。 - /// </summary> - /// <param name="legendName"></param> - /// <returns></returns> - public int GetIndex(string legendName) - { - return m_Data.IndexOf(legendName); - } - - /// <summary> - /// Remove all legend buttons. - /// |移除所有图例按钮。 - /// </summary> - public void RemoveButton() - { - context.buttonList.Clear(); - } - - /// <summary> - /// Bind buttons to legends. - /// |给图例绑定按钮。 - /// </summary> - /// <param name="name"></param> - /// <param name="btn"></param> - /// <param name="total"></param> - public void SetButton(string name, LegendItem item, int total) - { - context.buttonList[name] = item; - int index = context.buttonList.Values.Count; - item.SetIconActive(iconType == Type.Custom); - item.SetActive(show); - } - - /// <summary> - /// Update the legend button color. - /// |更新图例按钮颜色。 - /// </summary> - /// <param name="name"></param> - /// <param name="color"></param> - public void UpdateButtonColor(string name, Color color) - { - if (context.buttonList.ContainsKey(name)) - { - context.buttonList[name].SetIconColor(color); - } - } - - /// <summary> - /// Update the text color of legend. - /// |更新图例文字颜色。 - /// </summary> - /// <param name="name"></param> - /// <param name="color"></param> - public void UpdateContentColor(string name, Color color) - { - if (context.buttonList.ContainsKey(name)) - { - context.buttonList[name].SetContentColor(color); - } - } - - /// <summary> - /// Gets the legend button for the specified index. - /// |获得指定索引的图例按钮。 - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public Sprite GetIcon(int index) - { - if (index >= 0 && index < m_Icons.Count) - { - return m_Icons[index]; - } - else - { - return null; - } - } - - public Color GetColor(int index) - { - if (index >= 0 && index < m_Colors.Count) - return m_Colors[index]; - else - return Color.white; - } - - /// <summary> - /// Callback handling when parameters change. - /// |参数变更时的回调处理。 - /// </summary> - public void OnChanged() - { - m_Location.OnChanged(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Legend/Legend.cs.meta b/Assets/XCharts/Runtime/Component/Legend/Legend.cs.meta deleted file mode 100644 index c0193d1..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/Legend.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c53210fe487d047b6a51bacc0d3e7a71 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Legend/LegendContext.cs b/Assets/XCharts/Runtime/Component/Legend/LegendContext.cs deleted file mode 100644 index 9bead40..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/LegendContext.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - - public class LegendContext : MainComponentContext - { - /// <summary> - /// 运行时图例的总宽度 - /// </summary> - public float width { get; internal set; } - /// <summary> - /// 运行时图例的总高度 - /// </summary> - public float height { get; internal set; } - /// <summary> - /// the button list of legend. - /// |图例按钮列表。 - /// </summary> - internal Dictionary<string, LegendItem> buttonList = new Dictionary<string, LegendItem>(); - /// <summary> - /// 多列时每列的宽度 - /// </summary> - internal Dictionary<int, float> eachWidthDict = new Dictionary<int, float>(); - /// <summary> - /// 单列高度 - /// </summary> - internal float eachHeight { get; set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Legend/LegendContext.cs.meta b/Assets/XCharts/Runtime/Component/Legend/LegendContext.cs.meta deleted file mode 100644 index 59d2e50..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/LegendContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c62c17c9d5b2b4a0fb260103c3ceb5ac -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs b/Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs deleted file mode 100644 index 75b7161..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class LegendHandler : MainComponentHandler<Legend> - { - private static readonly string s_LegendObjectName = "legend"; - - public override void InitComponent() - { - InitLegend(component); - } - - public override void CheckComponent(System.Text.StringBuilder sb) - { - var legend = component; - if (ChartHelper.IsColorAlphaZero(legend.labelStyle.textStyle.color)) - sb.AppendFormat("warning:legend{0}->textStyle->color alpha is 0\n", legend.index); - var serieNameList = SeriesHelper.GetLegalSerieNameList(chart.series); - if (serieNameList.Count == 0) - sb.AppendFormat("warning:legend{0} need serie.serieName or serieData.name not empty\n", legend.index); - foreach (var category in legend.data) - { - if (!serieNameList.Contains(category)) - { - sb.AppendFormat("warning:legend{0} [{1}] is invalid, must be one of serie.serieName or serieData.name\n", - legend.index, category); - } - } - } - public override void DrawTop(VertexHelper vh) - { - DrawLegend(vh); - } - - public override void OnSerieDataUpdate(int serieIndex) - { - if (FormatterHelper.NeedFormat(component.formatter)) - component.refreshComponent(); - } - - private void InitLegend(Legend legend) - { - legend.painter = null; - legend.refreshComponent = delegate() - { - legend.OnChanged(); - var legendObject = ChartHelper.AddObject(s_LegendObjectName + legend.index, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - legend.gameObject = legendObject; - legendObject.hideFlags = chart.chartHideFlags; - SeriesHelper.UpdateSerieNameList(chart, ref chart.m_LegendRealShowName); - List<string> datas; - if (legend.show && legend.data.Count > 0) - { - datas = new List<string>(); - foreach (var data in legend.data) - { - if (chart.m_LegendRealShowName.Contains(data) || chart.IsSerieName(data)) - datas.Add(data); - } - } - else - { - datas = chart.m_LegendRealShowName; - } - int totalLegend = 0; - for (int i = 0; i < datas.Count; i++) - { - if (!SeriesHelper.IsLegalLegendName(datas[i])) continue; - totalLegend++; - } - legend.RemoveButton(); - ChartHelper.HideAllObject(legendObject); - if (!legend.show) return; - for (int i = 0; i < datas.Count; i++) - { - if (!SeriesHelper.IsLegalLegendName(datas[i])) continue; - string legendName = GetFormatterContent(legend, i, datas[i]); - var readIndex = chart.m_LegendRealShowName.IndexOf(datas[i]); - var active = chart.IsActiveByLegend(datas[i]); - var bgColor = LegendHelper.GetIconColor(chart, legend, readIndex, datas[i], active); - bgColor.a = legend.itemOpacity; - var item = LegendHelper.AddLegendItem(chart, legend, i, datas[i], legendObject.transform, chart.theme, - legendName, bgColor, active, readIndex); - legend.SetButton(legendName, item, totalLegend); - ChartHelper.ClearEventListener(item.button.gameObject); - ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerDown, (data) => - { - if (data.selectedObject == null || legend.selectedMode == Legend.SelectedMode.None) return; - var temp = data.selectedObject.name.Split('_'); - string selectedName = temp[1]; - int clickedIndex = int.Parse(temp[0]); - if (legend.selectedMode == Legend.SelectedMode.Multiple) - { - OnLegendButtonClick(legend, clickedIndex, selectedName, !chart.IsActiveByLegend(selectedName)); - } - else - { - var btnList = legend.context.buttonList.Values.ToArray(); - if (btnList.Length == 1) - { - OnLegendButtonClick(legend, 0, selectedName, !chart.IsActiveByLegend(selectedName)); - } - else - { - for (int n = 0; n < btnList.Length; n++) - { - temp = btnList[n].name.Split('_'); - selectedName = btnList[n].legendName; - var index = btnList[n].index; - OnLegendButtonClick(legend, n, selectedName, index == clickedIndex ? true : false); - } - } - } - }); - ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerEnter, (data) => - { - if (item.button == null) return; - var temp = item.button.name.Split('_'); - string selectedName = temp[1]; - int index = int.Parse(temp[0]); - OnLegendButtonEnter(legend, index, selectedName); - }); - ChartHelper.AddEventListener(item.button.gameObject, EventTriggerType.PointerExit, (data) => - { - if (item.button == null) return; - var temp = item.button.name.Split('_'); - string selectedName = temp[1]; - int index = int.Parse(temp[0]); - OnLegendButtonExit(legend, index, selectedName); - }); - } - LegendHelper.ResetItemPosition(legend, chart.chartPosition, chart.chartWidth, chart.chartHeight); - }; - legend.refreshComponent(); - } - - private string GetFormatterContent(Legend legend, int dataIndex, string category) - { - if (string.IsNullOrEmpty(legend.formatter)) - return category; - else - { - var content = legend.formatter.Replace("{name}", category); - content = content.Replace("{value}", category); - var serie = chart.GetSerie(0); - FormatterHelper.ReplaceContent(ref content, dataIndex, legend.numericFormatter, serie, chart); - return content; - } - } - - private void OnLegendButtonClick(Legend legend, int index, string legendName, bool show) - { - chart.OnLegendButtonClick(index, legendName, show); - if (chart.onLegendClick != null) - chart.onLegendClick(legend, index, legendName, show); - } - - private void OnLegendButtonEnter(Legend legend, int index, string legendName) - { - chart.OnLegendButtonEnter(index, legendName); - if (chart.onLegendEnter != null) - chart.onLegendEnter(legend, index, legendName); - } - - private void OnLegendButtonExit(Legend legend, int index, string legendName) - { - chart.OnLegendButtonExit(index, legendName); - if (chart.onLegendExit != null) - chart.onLegendExit(legend, index, legendName); - } - - private void DrawLegend(VertexHelper vh) - { - if (chart.series.Count == 0) return; - var legend = component; - if (!legend.show) return; - if (legend.iconType == Legend.Type.Custom) return; - foreach (var kv in legend.context.buttonList) - { - var item = kv.Value; - var rect = item.GetIconRect(); - var radius = Mathf.Min(rect.width, rect.height) / 2; - var color = item.GetIconColor(); - var iconType = legend.iconType; - if (legend.iconType == Legend.Type.Auto) - { - var serie = chart.GetSerie(item.legendName); - if (serie != null && serie is Line) - { - var sp = new Vector3(rect.center.x - rect.width / 2, rect.center.y); - var ep = new Vector3(rect.center.x + rect.width / 2, rect.center.y); - UGL.DrawLine(vh, sp, ep, chart.settings.legendIconLineWidth, color); - if (!serie.symbol.show) continue; - switch (serie.symbol.type) - { - case SymbolType.None: - continue; - case SymbolType.Circle: - iconType = Legend.Type.Circle; - break; - case SymbolType.Diamond: - iconType = Legend.Type.Diamond; - break; - case SymbolType.EmptyCircle: - iconType = Legend.Type.EmptyCircle; - break; - case SymbolType.Rect: - iconType = Legend.Type.Rect; - break; - case SymbolType.Triangle: - iconType = Legend.Type.Triangle; - break; - } - } - else - { - iconType = Legend.Type.Rect; - } - } - switch (iconType) - { - case Legend.Type.Rect: - var cornerRadius = chart.settings.legendIconCornerRadius; - UGL.DrawRoundRectangle(vh, rect.center, rect.width, rect.height, color, color, - 0, cornerRadius, false, 0.5f); - break; - case Legend.Type.Circle: - UGL.DrawCricle(vh, rect.center, radius, color); - break; - case Legend.Type.Diamond: - UGL.DrawDiamond(vh, rect.center, radius, color); - break; - case Legend.Type.EmptyCircle: - var backgroundColor = chart.GetChartBackgroundColor(); - UGL.DrawEmptyCricle(vh, rect.center, radius, 2 * chart.settings.legendIconLineWidth, - color, color, backgroundColor, 1f); - break; - case Legend.Type.Triangle: - UGL.DrawTriangle(vh, rect.center, 1.2f * radius, color); - break; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs.meta b/Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs.meta deleted file mode 100644 index 3d332f8..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/LegendHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d05c7e75b9d3c4a839099bf152752af1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs b/Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs deleted file mode 100644 index 422eb2a..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs +++ /dev/null @@ -1,276 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public static class LegendHelper - { - public static Color GetContentColor(BaseChart chart, int legendIndex, string legendName, Legend legend, ThemeStyle theme, bool active) - { - var textStyle = legend.labelStyle.textStyle; - if (active) - { - if (legend.labelStyle.textStyle.autoColor) - return SeriesHelper.GetNameColor(chart, legendIndex, legendName); - else - return !ChartHelper.IsClearColor(textStyle.color) ? textStyle.color : theme.legend.textColor; - } - else return theme.legend.unableColor; - } - - public static Color GetIconColor(BaseChart chart, Legend legend, int readIndex, string legendName, bool active) - { - if (active) - { - if (legend.itemAutoColor) - { - return SeriesHelper.GetNameColor(chart, readIndex, legendName); - } - else - return legend.GetColor(readIndex); - } - else return chart.theme.legend.unableColor; - } - - public static LegendItem AddLegendItem(BaseChart chart, Legend legend, int i, string legendName, Transform parent, - ThemeStyle theme, string content, Color itemColor, bool active, int legendIndex) - { - var objName = i + "_" + legendName; - var anchorMin = new Vector2(0, 0.5f); - var anchorMax = new Vector2(0, 0.5f); - var pivot = new Vector2(0, 0.5f); - var sizeDelta = new Vector2(100, 30); - var iconSizeDelta = new Vector2(legend.itemWidth, legend.itemHeight); - var textStyle = legend.labelStyle.textStyle; - var contentColor = GetContentColor(chart, legendIndex, legendName, legend, theme, active); - - var objAnchorMin = new Vector2(0, 1); - var objAnchorMax = new Vector2(0, 1); - var objPivot = new Vector2(0, 1); - var btnObj = ChartHelper.AddObject(objName, parent, objAnchorMin, objAnchorMax, objPivot, sizeDelta, i); - var iconObj = ChartHelper.AddObject("icon", btnObj.transform, anchorMin, anchorMax, pivot, iconSizeDelta); - var img = ChartHelper.GetOrAddComponent<Image>(btnObj); - img.color = Color.clear; - ChartHelper.GetOrAddComponent<Button>(btnObj); - ChartHelper.GetOrAddComponent<Image>(iconObj); - - var label = ChartHelper.AddChartLabel("content", btnObj.transform, legend.labelStyle, theme.legend, - content, contentColor, TextAnchor.MiddleLeft); - label.SetActive(true); - - var item = new LegendItem(); - item.index = i; - item.name = objName; - item.legendName = legendName; - item.SetObject(btnObj); - item.SetIconSize(legend.itemWidth, legend.itemHeight); - item.SetIconColor(itemColor); - item.SetIconImage(legend.GetIcon(i)); - item.SetContentPosition(legend.labelStyle.offset); - item.SetContent(content); - return item; - } - - public static void ResetItemPosition(Legend legend, Vector3 chartPos, float chartWidth, float chartHeight) - { - legend.location.UpdateRuntimeData(chartWidth, chartHeight); - var startX = 0f; - var startY = 0f; - var legendMaxWidth = chartWidth - legend.location.runtimeLeft - legend.location.runtimeRight; - var legendMaxHeight = chartHeight - legend.location.runtimeTop - legend.location.runtimeBottom; - UpdateLegendWidthAndHeight(legend, legendMaxWidth, legendMaxHeight); - var legendRuntimeWidth = legend.context.width; - var legendRuntimeHeight = legend.context.height; - var isVertical = legend.orient == Orient.Vertical; - switch (legend.location.align) - { - case Location.Align.TopCenter: - startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2; - startY = chartPos.y + chartHeight - legend.location.runtimeTop; - break; - case Location.Align.TopLeft: - startX = chartPos.x + legend.location.runtimeLeft; - startY = chartPos.y + chartHeight - legend.location.runtimeTop; - break; - case Location.Align.TopRight: - startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.runtimeRight; - startY = chartPos.y + chartHeight - legend.location.runtimeTop; - break; - case Location.Align.Center: - startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2; - startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2; - break; - case Location.Align.CenterLeft: - startX = chartPos.x + legend.location.runtimeLeft; - startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2; - break; - case Location.Align.CenterRight: - startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.runtimeRight; - startY = chartPos.y + chartHeight / 2 + legendRuntimeHeight / 2; - break; - case Location.Align.BottomCenter: - startX = chartPos.x + chartWidth / 2 - legendRuntimeWidth / 2; - startY = chartPos.y + legendRuntimeHeight + legend.location.runtimeBottom; - break; - case Location.Align.BottomLeft: - startX = chartPos.x + legend.location.runtimeLeft; - startY = chartPos.y + legendRuntimeHeight + legend.location.runtimeBottom; - break; - case Location.Align.BottomRight: - startX = chartPos.x + chartWidth - legendRuntimeWidth - legend.location.runtimeRight; - startY = chartPos.y + legendRuntimeHeight + legend.location.runtimeBottom; - break; - } - if (isVertical) SetVerticalItemPosition(legend, legendMaxHeight, startX, startY); - else SetHorizonalItemPosition(legend, legendMaxWidth, startX, startY); - } - - private static void SetVerticalItemPosition(Legend legend, float legendMaxHeight, float startX, float startY) - { - var currHeight = 0f; - var offsetX = 0f; - var row = 0; - foreach (var kv in legend.context.buttonList) - { - var item = kv.Value; - if (currHeight + item.height > legendMaxHeight) - { - currHeight = 0; - offsetX += legend.context.eachWidthDict[row]; - row++; - } - item.SetPosition(new Vector3(startX + offsetX, startY - currHeight)); - currHeight += item.height + legend.itemGap; - } - } - private static void SetHorizonalItemPosition(Legend legend, float legendMaxWidth, float startX, float startY) - { - var currWidth = 0f; - var offsetY = 0f; - foreach (var kv in legend.context.buttonList) - { - var item = kv.Value; - if (currWidth + item.width > legendMaxWidth) - { - currWidth = 0; - offsetY += legend.context.eachHeight; - } - item.SetPosition(new Vector3(startX + currWidth, startY - offsetY)); - currWidth += item.width + legend.itemGap; - } - } - - private static void UpdateLegendWidthAndHeight(Legend legend, float maxWidth, float maxHeight) - { - var width = 0f; - var height = 0f; - var realHeight = 0f; - var realWidth = 0f; - legend.context.eachWidthDict.Clear(); - legend.context.eachHeight = 0; - if (legend.orient == Orient.Horizonal) - { - foreach (var kv in legend.context.buttonList) - { - if (width + kv.Value.width > maxWidth) - { - realWidth = width - legend.itemGap; - realHeight += height + legend.itemGap; - if (legend.context.eachHeight < height + legend.itemGap) - { - legend.context.eachHeight = height + legend.itemGap; - } - height = 0; - width = 0; - } - width += kv.Value.width + legend.itemGap; - if (kv.Value.height > height) - height = kv.Value.height; - } - width -= legend.itemGap; - legend.context.height = realHeight + height; - legend.context.width = realWidth > 0 ? realWidth : width; - } - else - { - var row = 0; - foreach (var kv in legend.context.buttonList) - { - if (height + kv.Value.height > maxHeight) - { - realHeight = height - legend.itemGap; - realWidth += width + legend.itemGap; - legend.context.eachWidthDict[row] = width + legend.itemGap; - row++; - height = 0; - width = 0; - } - height += kv.Value.height + legend.itemGap; - if (kv.Value.width > width) - width = kv.Value.width; - } - height -= legend.itemGap; - legend.context.height = realHeight > 0 ? realHeight : height; - legend.context.width = realWidth + width; - } - } - - private static bool IsBeyondWidth(Legend legend, float maxWidth) - { - var totalWidth = 0f; - foreach (var kv in legend.context.buttonList) - { - var item = kv.Value; - totalWidth += item.width + legend.itemGap; - if (totalWidth > maxWidth) return true; - } - return false; - } - - public static bool CheckDataShow(Serie serie, string legendName, bool show) - { - bool needShow = false; - if (legendName.Equals(serie.serieName)) - { - serie.show = show; - serie.highlight = false; - if (serie.show) needShow = true; - } - else - { - foreach (var data in serie.data) - { - if (legendName.Equals(data.name)) - { - data.show = show; - data.context.highlight = false; - if (data.show) needShow = true; - } - } - } - return needShow; - } - - public static bool CheckDataHighlighted(Serie serie, string legendName, bool heighlight) - { - bool show = false; - if (legendName.Equals(serie.serieName)) - { - serie.highlight = heighlight; - } - else - { - foreach (var data in serie.data) - { - if (legendName.Equals(data.name)) - { - data.context.highlight = heighlight; - if (data.context.highlight) show = true; - } - } - } - return show; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs.meta b/Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs.meta deleted file mode 100644 index 18e7596..0000000 --- a/Assets/XCharts/Runtime/Component/Legend/LegendHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cc1c14527667e4475a275768371b3b9a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Mark.meta b/Assets/XCharts/Runtime/Component/Mark.meta deleted file mode 100644 index 57971b8..0000000 --- a/Assets/XCharts/Runtime/Component/Mark.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 69bae12c156de4372a9680df180e91df -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkArea.cs b/Assets/XCharts/Runtime/Component/Mark/MarkArea.cs deleted file mode 100644 index 560d6af..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkArea.cs +++ /dev/null @@ -1,192 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 标域类型 - /// </summary> - public enum MarkAreaType - { - None, - /// <summary> - /// 最小值。 - /// </summary> - Min, - /// <summary> - /// 最大值。 - /// </summary> - Max, - /// <summary> - /// 平均值。 - /// </summary> - Average, - /// <summary> - /// 中位数。 - /// </summary> - Median - } - - /// <summary> - /// Used to mark an area in chart. For example, mark a time interval. - /// |图表标域,常用于标记图表中某个范围的数据。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(MarkAreaHandler), true)] - public class MarkArea : MainComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private string m_Text = ""; - [SerializeField] private int m_SerieIndex = 0; - [SerializeField] private MarkAreaData m_Start = new MarkAreaData(); - [SerializeField] private MarkAreaData m_End = new MarkAreaData(); - [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); - [SerializeField] private LabelStyle m_Label = new LabelStyle(); - public ChartLabel runtimeLabel { get; internal set; } - public Vector3 runtimeLabelPosition { get; internal set; } - public Rect runtimeRect { get; internal set; } - /// <summary> - /// 是否显示标域。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// The text of markArea. - /// 标域显示的文本。 - /// </summary> - public string text - { - get { return m_Text; } - set { if (PropertyUtil.SetClass(ref m_Text, value)) SetComponentDirty(); } - } - /// <summary> - /// Serie index of markArea. - /// 标域影响的Serie索引。 - /// </summary> - public int serieIndex - { - get { return m_SerieIndex; } - set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// 标域范围的起始数据。 - /// </summary> - public MarkAreaData start - { - get { return m_Start; } - set { if (PropertyUtil.SetClass(ref m_Start, value)) SetVerticesDirty(); } - } - /// <summary> - /// 标域范围的结束数据。 - /// </summary> - public MarkAreaData end - { - get { return m_End; } - set { if (PropertyUtil.SetClass(ref m_End, value)) SetVerticesDirty(); } - } - /// <summary> - /// 标域样式。 - /// </summary> - public ItemStyle itemStyle - { - get { return m_ItemStyle; } - set { if (PropertyUtil.SetClass(ref m_ItemStyle, value)) SetVerticesDirty(); } - } - /// <summary> - /// 标域文本样式。 - /// </summary> - public LabelStyle label - { - get { return m_Label; } - set { if (PropertyUtil.SetClass(ref m_Label, value)) SetComponentDirty(); } - } - public override void SetDefaultValue() - { - m_ItemStyle = new ItemStyle(); - m_ItemStyle.opacity = 0.6f; - m_Label = new LabelStyle(); - m_Label.show = true; - } - } - - /// <summary> - /// 标域的数据。 - /// </summary> - [System.Serializable] - public class MarkAreaData : ChildComponent - { - [SerializeField] private MarkAreaType m_Type = MarkAreaType.None; - [SerializeField] private string m_Name; - [SerializeField] private int m_Dimension = 1; - [SerializeField] private float m_XPosition; - [SerializeField] private float m_YPosition; - [SerializeField] private double m_XValue; - [SerializeField] private double m_YValue; - public double runtimeValue { get; internal set; } - /// <summary> - /// Name of the marker, which will display as a label. - /// |标注名称。会作为文字显示。 - /// </summary> - public string name - { - get { return m_Name; } - set { if (PropertyUtil.SetClass(ref m_Name, value)) SetVerticesDirty(); } - } - /// <summary> - /// Special markArea types, are used to label maximum value, minimum value and so on. - /// |特殊的标域类型,用于标注最大值最小值等。 - /// </summary> - public MarkAreaType type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); } - } - /// <summary> - /// From which dimension of data to calculate the maximum and minimum value and so on. - /// |从哪个维度的数据计算最大最小值等。 - /// </summary> - public int dimension - { - get { return m_Dimension; } - set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); } - } - /// <summary> - /// The x coordinate relative to the origin, in pixels. - /// |相对原点的 x 坐标,单位像素。当type为None时有效。 - /// </summary> - public float xPosition - { - get { return m_XPosition; } - set { if (PropertyUtil.SetStruct(ref m_XPosition, value)) SetVerticesDirty(); } - } - /// <summary> - /// The y coordinate relative to the origin, in pixels. - /// |相对原点的 y 坐标,单位像素。当type为None时有效。 - /// </summary> - public float yPosition - { - get { return m_YPosition; } - set { if (PropertyUtil.SetStruct(ref m_YPosition, value)) SetVerticesDirty(); } - } - /// <summary> - /// The value specified on the X-axis. A value specified when the X-axis is the category axis represents the index of the category axis data, otherwise a specific value. - /// |X轴上的指定值。当X轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 - /// </summary> - public double xValue - { - get { return m_XValue; } - set { if (PropertyUtil.SetStruct(ref m_XValue, value)) SetVerticesDirty(); } - } - /// <summary> - /// That's the value on the Y-axis. The value specified when the Y axis is the category axis represents the index of the category axis data, otherwise the specific value. - /// |Y轴上的指定值。当Y轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 - /// </summary> - public double yValue - { - get { return m_YValue; } - set { if (PropertyUtil.SetStruct(ref m_YValue, value)) SetVerticesDirty(); } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkArea.cs.meta b/Assets/XCharts/Runtime/Component/Mark/MarkArea.cs.meta deleted file mode 100644 index 3173d1c..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkArea.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1c7f98347a0d54e1c82866b041a473ca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs b/Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs deleted file mode 100644 index 9e1345b..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class MarkAreaHandler : MainComponentHandler<MarkArea> - { - private GameObject m_MarkLineLabelRoot; - private bool m_NeedUpdateLabelPosition; - - public override void InitComponent() - { - m_MarkLineLabelRoot = ChartHelper.AddObject("markarea" + component.index, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - m_MarkLineLabelRoot.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(m_MarkLineLabelRoot); - InitMarkArea(component); - } - - public override void DrawBase(VertexHelper vh) - { - DrawMarkArea(vh, component); - } - - public override void Update() - { - if (m_NeedUpdateLabelPosition) - { - m_NeedUpdateLabelPosition = false; - if (component.runtimeLabel != null) - { - component.runtimeLabel.SetPosition(component.runtimeLabelPosition); - } - } - } - - private void InitMarkArea(MarkArea markArea) - { - markArea.painter = chart.m_PainterTop; - markArea.refreshComponent = delegate() - { - var label = ChartHelper.AddChartLabel("label", m_MarkLineLabelRoot.transform, markArea.label, chart.theme.axis, - component.text, Color.clear, TextAnchor.MiddleCenter); - UpdateRuntimeData(component); - label.SetActive(markArea.label.show); - label.SetPosition(component.runtimeLabelPosition); - label.SetText(component.text); - markArea.runtimeLabel = label; - }; - markArea.refreshComponent(); - } - - private void DrawMarkArea(VertexHelper vh, MarkArea markArea) - { - if (!markArea.show) return; - var serie = chart.GetSerie(markArea.serieIndex); - if (serie == null || !serie.show || !markArea.show) return; - - UpdateRuntimeData(markArea); - - var colorIndex = chart.GetLegendRealShowNameIndex(serie.legendName); - var serieColor = SerieHelper.GetLineColor(serie, null, chart.theme, colorIndex, false); - var areaColor = markArea.itemStyle.GetColor(serieColor); - UGL.DrawRectangle(vh, markArea.runtimeRect, areaColor, areaColor); - } - - private void UpdateRuntimeData(MarkArea markArea) - { - var serie = chart.GetSerie(markArea.serieIndex); - if (serie == null || !serie.show || !markArea.show) return; - var yAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - var showData = serie.GetDataList(dataZoom); - - var lt = GetPosition(markArea.start, serie, dataZoom, xAxis, yAxis, grid, showData, true); - var rb = GetPosition(markArea.end, serie, dataZoom, xAxis, yAxis, grid, showData, false); - var lb = new Vector3(lt.x, rb.y); - - markArea.runtimeRect = new Rect(lb.x, lb.y, rb.x - lb.x, lt.y - lb.y); - UpdateLabelPosition(markArea); - } - - private void UpdateLabelPosition(MarkArea markArea) - { - if (!markArea.label.show) return; - m_NeedUpdateLabelPosition = true; - var rect = markArea.runtimeRect; - switch (markArea.label.position) - { - case LabelStyle.Position.Center: - markArea.runtimeLabelPosition = rect.center; - break; - case LabelStyle.Position.Left: - markArea.runtimeLabelPosition = rect.center + new Vector2(rect.width / 2, 0); - break; - case LabelStyle.Position.Right: - markArea.runtimeLabelPosition = rect.center - new Vector2(rect.width / 2, 0); - break; - case LabelStyle.Position.Top: - markArea.runtimeLabelPosition = rect.center + new Vector2(0, rect.height / 2); - break; - case LabelStyle.Position.Bottom: - markArea.runtimeLabelPosition = rect.center - new Vector2(0, rect.height / 2); - break; - default: - markArea.runtimeLabelPosition = rect.center + new Vector2(0, rect.height / 2); - break; - } - markArea.runtimeLabelPosition += markArea.label.offset; - } - - private Vector3 GetPosition(MarkAreaData data, Serie serie, DataZoom dataZoom, XAxis xAxis, YAxis yAxis, - GridCoord grid, List<SerieData> showData, bool start) - { - var pos = Vector3.zero; - switch (data.type) - { - case MarkAreaType.Min: - data.runtimeValue = SerieHelper.GetMinData(serie, data.dimension, dataZoom); - return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); - case MarkAreaType.Max: - data.runtimeValue = SerieHelper.GetMaxData(serie, data.dimension, dataZoom); - return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); - case MarkAreaType.Average: - data.runtimeValue = SerieHelper.GetAverageData(serie, data.dimension, dataZoom); - return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); - case MarkAreaType.Median: - data.runtimeValue = SerieHelper.GetMedianData(serie, data.dimension, dataZoom); - return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); - case MarkAreaType.None: - if (data.xPosition != 0 || data.yPosition != 0) - { - var pX = grid.context.x + data.xPosition; - var pY = grid.context.y + data.yPosition; - return new Vector3(pX, pY); - } - else if (data.yValue != 0) - { - data.runtimeValue = data.yValue; - if (yAxis.IsCategory()) - { - var pY = AxisHelper.GetAxisPosition(grid, yAxis, data.yValue, showData.Count, dataZoom); - return start ? - new Vector3(grid.context.x, pY) : - new Vector3(grid.context.x + grid.context.width, pY); - } - else - { - return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); - } - } - else - { - data.runtimeValue = data.xValue; - if (xAxis.IsCategory()) - { - var pX = AxisHelper.GetAxisPosition(grid, xAxis, data.xValue, showData.Count, dataZoom); - return start ? new Vector3(pX, grid.context.y + grid.context.height) : - new Vector3(pX, grid.context.y); - } - else - { - return GetPosition(xAxis, yAxis, grid, data.xValue, start); - } - } - default: - break; - } - return pos; - } - - private Vector3 GetPosition(Axis xAxis, Axis yAxis, GridCoord grid, double value, bool start) - { - if (yAxis.IsCategory()) - { - var pX = AxisHelper.GetAxisPosition(grid, xAxis, value); - return start ? - new Vector3(pX, grid.context.y + grid.context.height) : - new Vector3(pX, grid.context.y); - } - else - { - var pY = AxisHelper.GetAxisPosition(grid, yAxis, value); - return start ? - new Vector3(grid.context.x, pY + grid.context.height) : - new Vector3(grid.context.x + grid.context.width, pY); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs.meta b/Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs.meta deleted file mode 100644 index 534da72..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkAreaHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f5ffb2d23b0574e6eb5805a2f3783081 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLine.cs b/Assets/XCharts/Runtime/Component/Mark/MarkLine.cs deleted file mode 100644 index 7692929..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLine.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// 标线类型 - /// </summary> - public enum MarkLineType - { - None, - /// <summary> - /// 最小值。 - /// </summary> - Min, - /// <summary> - /// 最大值。 - /// </summary> - Max, - /// <summary> - /// 平均值。 - /// </summary> - Average, - /// <summary> - /// 中位数。 - /// </summary> - Median - } - - /// <summary> - /// Use a line in the chart to illustrate. - /// |图表标线。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(MarkLineHandler), true)] - public class MarkLine : MainComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private int m_SerieIndex = 0; - [SerializeField] private AnimationStyle m_Animation = new AnimationStyle(); - [SerializeField] private List<MarkLineData> m_Data = new List<MarkLineData>(); - - /// <summary> - /// Whether to display the marking line. - /// |是否显示标线。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// The serie index of markLine. - /// |标线影响的Serie索引。 - /// </summary> - public int serieIndex - { - get { return m_SerieIndex; } - set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// The animation of markline. - /// |标线的动画样式。 - /// </summary> - public AnimationStyle animation - { - get { return m_Animation; } - set { if (PropertyUtil.SetClass(ref m_Animation, value)) SetVerticesDirty(); } - } - /// <summary> - /// A list of marked data. When the group of data item is 0, each data item represents a line; - /// When the group is not 0, two data items of the same group represent the starting point and - /// the ending point of the line respectively to form a line. In this case, the relevant style - /// parameters of the line are the parameters of the starting point. - /// |标线的数据列表。当数据项的group为0时,每个数据项表示一条标线;当group不为0时,相同group的两个数据项分别表 - /// 示标线的起始点和终止点来组成一条标线,此时标线的相关样式参数取起始点的参数。 - /// </summary> - public List<MarkLineData> data - { - get { return m_Data; } - set { if (PropertyUtil.SetClass(ref m_Data, value)) SetVerticesDirty(); } - } - - public override void SetDefaultValue() - { - data.Clear(); - var item = new MarkLineData(); - item.name = "average"; - item.type = MarkLineType.Average; - item.lineStyle.type = LineStyle.Type.Dashed; - item.lineStyle.color = Color.clear; - item.startSymbol.show = true; - item.startSymbol.type = SymbolType.Circle; - item.startSymbol.size = 4; - item.endSymbol.show = true; - item.endSymbol.type = SymbolType.Arrow; - item.endSymbol.size = 5; - item.label.show = true; - item.label.numericFormatter = "f1"; - item.label.formatter = "{c}"; - data.Add(item); - } - } - /// <summary> - /// Data of marking line. - /// |图表标线的数据。 - /// </summary> - [System.Serializable] - public class MarkLineData : ChildComponent - { - [SerializeField] private MarkLineType m_Type = MarkLineType.None; - [SerializeField] private string m_Name; - [SerializeField] private int m_Dimension = 1; - [SerializeField] private float m_XPosition; - [SerializeField] private float m_YPosition; - [SerializeField] private double m_XValue; - [SerializeField] private double m_YValue; - [SerializeField] private int m_Group = 0; - [SerializeField] private bool m_ZeroPosition = false; - - [SerializeField] private SymbolStyle m_StartSymbol = new SymbolStyle(); - [SerializeField] private SymbolStyle m_EndSymbol = new SymbolStyle(); - [SerializeField] private LineStyle m_LineStyle = new LineStyle(); - [SerializeField] private LabelStyle m_Label = new LabelStyle(); - //[SerializeField] private Emphasis m_Emphasis = new Emphasis(); - - public Vector3 runtimeStartPosition { get; internal set; } - public Vector3 runtimeEndPosition { get; internal set; } - public Vector3 runtimeCurrentEndPosition { get; internal set; } - public ChartLabel runtimeLabel { get; internal set; } - public double runtimeValue { get; internal set; } - - /// <summary> - /// Name of the marker, which will display as a label. - /// |标线名称,将会作为文字显示。label的formatter可通过{b}显示名称,通过{c}显示数值。 - /// </summary> - public string name - { - get { return m_Name; } - set { if (PropertyUtil.SetClass(ref m_Name, value)) SetVerticesDirty(); } - } - /// <summary> - /// Special label types, are used to label maximum value, minimum value and so on. - /// |特殊的标线类型,用于标注最大值最小值等。 - /// </summary> - public MarkLineType type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); } - } - /// <summary> - /// From which dimension of data to calculate the maximum and minimum value and so on. - /// |从哪个维度的数据计算最大最小值等。 - /// </summary> - public int dimension - { - get { return m_Dimension; } - set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); } - } - /// <summary> - /// The x coordinate relative to the origin, in pixels. - /// |相对原点的 x 坐标,单位像素。当type为None时有效。 - /// </summary> - public float xPosition - { - get { return m_XPosition; } - set { if (PropertyUtil.SetStruct(ref m_XPosition, value)) SetVerticesDirty(); } - } - /// <summary> - /// The y coordinate relative to the origin, in pixels. - /// |相对原点的 y 坐标,单位像素。当type为None时有效。 - /// </summary> - public float yPosition - { - get { return m_YPosition; } - set { if (PropertyUtil.SetStruct(ref m_YPosition, value)) SetVerticesDirty(); } - } - /// <summary> - /// The value specified on the X-axis. A value specified when the X-axis is the category axis represents the index of the category axis data, otherwise a specific value. - /// |X轴上的指定值。当X轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 - /// </summary> - public double xValue - { - get { return m_XValue; } - set { if (PropertyUtil.SetStruct(ref m_XValue, value)) SetVerticesDirty(); } - } - /// <summary> - /// That's the value on the Y-axis. The value specified when the Y axis is the category axis represents the index of the category axis data, otherwise the specific value. - /// |Y轴上的指定值。当Y轴为类目轴时指定值表示类目轴数据的索引,否则为具体的值。当type为None时有效。 - /// </summary> - public double yValue - { - get { return m_YValue; } - set { if (PropertyUtil.SetStruct(ref m_YValue, value)) SetVerticesDirty(); } - } - /// <summary> - /// Grouping. When the group is not 0, it means that this data is the starting point or end point of the marking line. Data consistent with the group form a marking line. - /// |分组。当group不为0时,表示这个data是标线的起点或终点,group一致的data组成一条标线。 - /// </summary> - public int group - { - get { return m_Group; } - set { if (PropertyUtil.SetStruct(ref m_Group, value)) SetVerticesDirty(); } - } - /// <summary> - /// Is the origin of the coordinate system. - /// |是否为坐标系原点。 - /// </summary> - public bool zeroPosition - { - get { return m_ZeroPosition; } - set { if (PropertyUtil.SetStruct(ref m_ZeroPosition, value)) SetVerticesDirty(); } - } - /// <summary> - /// The symbol of the start point of markline. - /// |起始点的图形标记。 - /// </summary> - public SymbolStyle startSymbol - { - get { return m_StartSymbol; } - set { if (PropertyUtil.SetClass(ref m_StartSymbol, value)) SetVerticesDirty(); } - } - /// <summary> - /// The symbol of the end point of markline. - /// |结束点的图形标记。 - /// </summary> - public SymbolStyle endSymbol - { - get { return m_EndSymbol; } - set { if (PropertyUtil.SetClass(ref m_EndSymbol, value)) SetVerticesDirty(); } - } - /// <summary> - /// The line style of markline. - /// |标线样式。 - /// </summary> - public LineStyle lineStyle - { - get { return m_LineStyle; } - set { if (PropertyUtil.SetClass(ref m_LineStyle, value)) SetVerticesDirty(); } - } - /// <summary> - /// Text styles of label. You can set position to Start, Middle, and End to display text in different locations. - /// |文本样式。可设置position为Start、Middle和End在不同的位置显示文本。 - /// </summary> - public LabelStyle label - { - get { return m_Label; } - set { if (PropertyUtil.SetClass(ref m_Label, value)) SetVerticesDirty(); } - } - // public Emphasis emphasis - // { - // get { return m_Emphasis; } - // set { if (PropertyUtil.SetClass(ref m_Emphasis, value)) SetVerticesDirty(); } - // } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLine.cs.meta b/Assets/XCharts/Runtime/Component/Mark/MarkLine.cs.meta deleted file mode 100644 index 5bf2ec6..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6e728b47a96c74b3f986d9abe3b03934 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs b/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs deleted file mode 100644 index 5be581f..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs +++ /dev/null @@ -1,310 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class MarkLineHandler : MainComponentHandler<MarkLine> - { - private GameObject m_MarkLineLabelRoot; - private bool m_RefreshLabel = false; - - public override void InitComponent() - { - m_MarkLineLabelRoot = ChartHelper.AddObject("markline", chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - m_MarkLineLabelRoot.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(m_MarkLineLabelRoot); - InitMarkLine(component); - } - - public override void DrawTop(VertexHelper vh) - { - DrawMarkLine(vh, component); - } - - public override void Update() - { - if (m_RefreshLabel) - { - m_RefreshLabel = false; - var serie = chart.GetSerie(component.serieIndex); - if (!serie.show || !component.show) return; - foreach (var data in component.data) - { - if (data.runtimeLabel != null) - { - data.runtimeLabel.SetActive(data.label.show); - data.runtimeLabel.SetPosition(MarkLineHelper.GetLabelPosition(data)); - data.runtimeLabel.SetText(MarkLineHelper.GetFormatterContent(serie, data)); - } - } - } - } - - private void InitMarkLine(MarkLine markLine) - { - var serie = chart.GetSerie(markLine.serieIndex); - if (!serie.show || !markLine.show) return; - ResetTempMarkLineGroupData(markLine); - var serieColor = (Color) chart.GetItemColor(serie); - if (m_TempGroupData.Count > 0) - { - foreach (var kv in m_TempGroupData) - { - if (kv.Value.Count >= 2) - { - var data = kv.Value[0]; - InitMarkLineLabel(serie, data, serieColor); - } - } - } - foreach (var data in markLine.data) - { - if (data.group != 0) continue; - InitMarkLineLabel(serie, data, serieColor); - } - } - - private void InitMarkLineLabel(Serie serie, MarkLineData data, Color serieColor) - { - data.painter = chart.m_PainterTop; - data.refreshComponent = delegate() - { - var textName = string.Format("markLine_{0}_{1}", serie.index, data.index); - var content = MarkLineHelper.GetFormatterContent(serie, data); - var label = ChartHelper.AddChartLabel(textName, m_MarkLineLabelRoot.transform, data.label, chart.theme.axis, - content, Color.clear, TextAnchor.MiddleCenter); - - label.SetIconActive(false); - label.SetActive(data.label.show); - label.SetPosition(MarkLineHelper.GetLabelPosition(data)); - data.runtimeLabel = label; - }; - data.refreshComponent(); - } - - private Dictionary<int, List<MarkLineData>> m_TempGroupData = new Dictionary<int, List<MarkLineData>>(); - private void DrawMarkLine(VertexHelper vh, MarkLine markLine) - { - var serie = chart.GetSerie(markLine.serieIndex); - if (!serie.show || !markLine.show) return; - if (markLine.data.Count == 0) return; - var yAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - var animation = markLine.animation; - var showData = serie.GetDataList(dataZoom); - var sp = Vector3.zero; - var ep = Vector3.zero; - var colorIndex = chart.GetLegendRealShowNameIndex(serie.serieName); - var serieColor = SerieHelper.GetLineColor(serie, null, chart.theme, colorIndex, false); - animation.InitProgress(0, 1f); - ResetTempMarkLineGroupData(markLine); - if (m_TempGroupData.Count > 0) - { - foreach (var kv in m_TempGroupData) - { - if (kv.Value.Count >= 2) - { - sp = GetSinglePos(xAxis, yAxis, grid, serie, dataZoom, kv.Value[0], showData.Count); - ep = GetSinglePos(xAxis, yAxis, grid, serie, dataZoom, kv.Value[1], showData.Count); - kv.Value[0].runtimeStartPosition = sp; - kv.Value[1].runtimeEndPosition = ep; - DrawMakLineData(vh, kv.Value[0], animation, serie, grid, serieColor, sp, ep); - } - } - } - foreach (var data in markLine.data) - { - if (data.group != 0) continue; - switch (data.type) - { - case MarkLineType.Min: - data.runtimeValue = SerieHelper.GetMinData(serie, data.dimension, dataZoom); - GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep); - break; - case MarkLineType.Max: - data.runtimeValue = SerieHelper.GetMaxData(serie, data.dimension, dataZoom); - GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep); - break; - case MarkLineType.Average: - data.runtimeValue = SerieHelper.GetAverageData(serie, data.dimension, dataZoom); - GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep); - break; - case MarkLineType.Median: - data.runtimeValue = SerieHelper.GetMedianData(serie, data.dimension, dataZoom); - GetStartEndPos(xAxis, yAxis, grid, data.runtimeValue, ref sp, ref ep); - break; - case MarkLineType.None: - if (data.xPosition != 0) - { - data.runtimeValue = data.xPosition; - var pX = grid.context.x + data.xPosition; - sp = new Vector3(pX, grid.context.y); - ep = new Vector3(pX, grid.context.y + grid.context.height); - } - else if (data.yPosition != 0) - { - data.runtimeValue = data.yPosition; - var pY = grid.context.y + data.yPosition; - sp = new Vector3(grid.context.x, pY); - ep = new Vector3(grid.context.x + grid.context.width, pY); - } - else if (data.yValue != 0) - { - data.runtimeValue = data.yValue; - if (yAxis.IsCategory()) - { - var pY = AxisHelper.GetAxisPosition(grid, yAxis, data.yValue, showData.Count, dataZoom); - sp = new Vector3(grid.context.x, pY); - ep = new Vector3(grid.context.x + grid.context.width, pY); - } - else - { - GetStartEndPos(xAxis, yAxis, grid, data.yValue, ref sp, ref ep); - } - } - else - { - data.runtimeValue = data.xValue; - if (xAxis.IsCategory()) - { - var pX = AxisHelper.GetAxisPosition(grid, xAxis, data.xValue, showData.Count, dataZoom); - sp = new Vector3(pX, grid.context.y); - ep = new Vector3(pX, grid.context.y + grid.context.height); - } - else - { - GetStartEndPos(xAxis, yAxis, grid, data.xValue, ref sp, ref ep); - } - } - break; - default: - break; - } - data.runtimeStartPosition = sp; - data.runtimeEndPosition = ep; - DrawMakLineData(vh, data, animation, serie, grid, serieColor, sp, ep); - } - if (!animation.IsFinish()) - { - animation.CheckProgress(1f); - chart.RefreshTopPainter(); - } - } - - private void ResetTempMarkLineGroupData(MarkLine markLine) - { - m_TempGroupData.Clear(); - for (int i = 0; i < markLine.data.Count; i++) - { - var data = markLine.data[i]; - // data.index = i; - data.index = markLine.index; - if (data.group == 0) continue; - if (!m_TempGroupData.ContainsKey(data.group)) - { - m_TempGroupData[data.group] = new List<MarkLineData>(); - } - m_TempGroupData[data.group].Add(data); - } - } - - private void DrawMakLineData(VertexHelper vh, MarkLineData data, AnimationStyle animation, Serie serie, - GridCoord grid, Color32 serieColor, Vector3 sp, Vector3 ep) - { - if (!animation.IsFinish()) - ep = Vector3.Lerp(sp, ep, animation.GetCurrDetail()); - data.runtimeCurrentEndPosition = ep; - if (sp != Vector3.zero || ep != Vector3.zero) - { - m_RefreshLabel = true; - chart.ClampInChart(ref sp); - chart.ClampInChart(ref ep); - var theme = chart.theme.axis; - var lineColor = ChartHelper.IsClearColor(data.lineStyle.color) ? serieColor : data.lineStyle.color; - var lineWidth = data.lineStyle.width == 0 ? theme.lineWidth : data.lineStyle.width; - ChartDrawer.DrawLineStyle(vh, data.lineStyle, sp, ep, lineWidth, LineStyle.Type.Dashed, lineColor, lineColor); - if (data.startSymbol != null && data.startSymbol.show) - { - DrawMarkLineSymbol(vh, data.startSymbol, serie, grid, chart.theme, sp, sp, lineColor); - } - if (data.endSymbol != null && data.endSymbol.show) - { - DrawMarkLineSymbol(vh, data.endSymbol, serie, grid, chart.theme, ep, sp, lineColor); - } - } - } - - private void DrawMarkLineSymbol(VertexHelper vh, SymbolStyle symbol, Serie serie, GridCoord grid, ThemeStyle theme, - Vector3 pos, Vector3 startPos, Color32 lineColor) - { - var tickness = SerieHelper.GetSymbolBorder(serie, null, theme, false); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, null, theme, false); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, null, false); - chart.DrawClipSymbol(vh, symbol.type, symbol.size, tickness, pos, lineColor, lineColor, - ColorUtil.clearColor32, borderColor, symbol.gap, true, cornerRadius, grid, startPos); - } - - private void GetStartEndPos(Axis xAxis, Axis yAxis, GridCoord grid, double value, ref Vector3 sp, ref Vector3 ep) - { - if (xAxis.IsCategory()) - { - var pY = AxisHelper.GetAxisPosition(grid, yAxis, value); - sp = new Vector3(grid.context.x, pY); - ep = new Vector3(grid.context.x + grid.context.width, pY); - } - else - { - var pX = AxisHelper.GetAxisPosition(grid, xAxis, value); - sp = new Vector3(pX, grid.context.y); - ep = new Vector3(pX, grid.context.y + grid.context.height); - } - } - - private float GetAxisPosition(GridCoord grid, Axis axis, DataZoom dataZoom, int dataCount, double value) - { - return AxisHelper.GetAxisPosition(grid, axis, value, dataCount, dataZoom); - } - - private Vector3 GetSinglePos(Axis xAxis, Axis yAxis, GridCoord grid, Serie serie, DataZoom dataZoom, MarkLineData data, - int serieDataCount) - { - switch (data.type) - { - case MarkLineType.Min: - var serieData = SerieHelper.GetMinSerieData(serie, data.dimension, dataZoom); - data.runtimeValue = serieData.GetData(data.dimension); - var pX = GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, serieData.index); - var pY = GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.runtimeValue); - return new Vector3(pX, pY); - case MarkLineType.Max: - serieData = SerieHelper.GetMaxSerieData(serie, data.dimension, dataZoom); - data.runtimeValue = serieData.GetData(data.dimension); - pX = GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, serieData.index); - pY = GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.runtimeValue); - return new Vector3(pX, pY); - case MarkLineType.None: - if (data.zeroPosition) - { - data.runtimeValue = 0; - return grid.context.position; - } - else - { - pX = data.xPosition != 0 ? grid.context.x + data.xPosition : - GetAxisPosition(grid, xAxis, dataZoom, serieDataCount, data.xValue); - pY = data.yPosition != 0 ? grid.context.y + data.yPosition : - GetAxisPosition(grid, yAxis, dataZoom, serieDataCount, data.yValue); - data.runtimeValue = data.yValue; - return new Vector3(pX, pY); - } - default: - return grid.context.position; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs.meta b/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs.meta deleted file mode 100644 index 0b0c3dd..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: faa35bab8fc6e42d5b5d19731c1a20a0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs b/Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs deleted file mode 100644 index 98511fa..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs +++ /dev/null @@ -1,48 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - internal static class MarkLineHelper - { - public static string GetFormatterContent(Serie serie, MarkLineData data) - { - var serieLabel = data.label; - var numericFormatter = serieLabel.numericFormatter; - if (serieLabel.formatterFunction != null) - { - return serieLabel.formatterFunction(data.index, data.runtimeValue, null); - } - if (string.IsNullOrEmpty(serieLabel.formatter)) - return ChartCached.NumberToStr(data.runtimeValue, numericFormatter); - else - { - var content = serieLabel.formatter; - FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, serie.dataCount, data.runtimeValue, - 0, serie.serieName, data.name, data.name, Color.clear); - return content; - } - } - - public static Vector3 GetLabelPosition(MarkLineData data) - { - if (!data.label.show) return Vector3.zero; - var dir = (data.runtimeEndPosition - data.runtimeStartPosition).normalized; - var horizontal = Mathf.Abs(Vector3.Dot(dir, Vector3.right)) == 1; - var labelWidth = data.runtimeLabel == null ? 50 : data.runtimeLabel.GetTextWidth(); - var labelHeight = data.runtimeLabel == null ? 20 : data.runtimeLabel.GetTextHeight(); - switch (data.label.position) - { - case LabelStyle.Position.Start: - if (horizontal) return data.runtimeStartPosition + data.label.offset + labelWidth / 2 * Vector3.left; - else return data.runtimeStartPosition + data.label.offset + labelHeight / 2 * Vector3.down; - case LabelStyle.Position.Middle: - var center = (data.runtimeStartPosition + data.runtimeCurrentEndPosition) / 2; - if (horizontal) return center + data.label.offset + labelHeight / 2 * Vector3.up; - else return center + data.label.offset + labelWidth / 2 * Vector3.right; - default: - if (horizontal) return data.runtimeCurrentEndPosition + data.label.offset + labelWidth / 2 * Vector3.right; - else return data.runtimeCurrentEndPosition + data.label.offset + labelHeight / 2 * Vector3.up; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs.meta b/Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs.meta deleted file mode 100644 index e95ca4b..0000000 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLineHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b472a7e4755b74fb6a3ec2c410650833 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Radar.meta b/Assets/XCharts/Runtime/Component/Radar.meta deleted file mode 100644 index eae8071..0000000 --- a/Assets/XCharts/Runtime/Component/Radar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5fb4a3817487149f680a509a5247105e -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs b/Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs deleted file mode 100644 index 8a2c6bb..0000000 --- a/Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs +++ /dev/null @@ -1,447 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// Radar coordinate conponnet for radar charts. - /// 雷达图坐标系组件,只适用于雷达图。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(RadarCoordHandler), true)] - [CoordOptions(typeof(RadarCoord))] - public class RadarCoord : CoordSystem, ISerieContainer - { - /// <summary> - /// Radar render type, in which 'Polygon' and 'Circle' are supported. - /// |雷达图绘制类型,支持 'Polygon' 和 'Circle'。 - /// </summary> - public enum Shape - { - Polygon, - Circle - } - /// <summary> - /// The position type of radar. - /// |显示位置。 - /// </summary> - public enum PositionType - { - /// <summary> - /// Display at the vertex. - /// |显示在顶点处。 - /// </summary> - Vertice, - /// <summary> - /// Display at the middle of line. - /// |显示在两者之间。 - /// </summary> - Between, - } - /// <summary> - /// Indicator of radar chart, which is used to assign multiple variables(dimensions) in radar chart. - /// |雷达图的指示器,用来指定雷达图中的多个变量(维度)。 - /// </summary> - [System.Serializable] - public class Indicator - { - [SerializeField] private string m_Name; - [SerializeField] private double m_Max; - [SerializeField] private double m_Min; - [SerializeField] private double[] m_Range = new double[2] { 0, 0 }; - - /// <summary> - /// The name of indicator. - /// |指示器名称。 - /// </summary> - public string name { get { return FormatterHelper.TrimAndReplaceLine(m_Name); } set { m_Name = value; } } - /// <summary> - /// The maximum value of indicator, with default value of 0, but we recommend to set it manually. - /// |指示器的最大值,默认为 0 无限制。 - /// </summary> - public double max { get { return m_Max; } set { m_Max = value; } } - /// <summary> - /// The minimum value of indicator, with default value of 0. - /// |指示器的最小值,默认为 0 无限制。 - /// </summary> - public double min { get { return m_Min; } set { m_Min = value; } } - /// <summary> - /// the text conponent of indicator. - /// |指示器的文本组件。 - /// </summary> - public Text text { get; set; } - /// <summary> - /// Normal range. When the value is outside this range, the display color is automatically changed. - /// |正常值范围。当数值不在这个范围时,会自动变更显示颜色。 - /// </summary> - public double[] range - { - get { return m_Range; } - set { if (value != null && value.Length == 2) { m_Range = value; } } - } - - public bool IsInRange(double value) - { - if (m_Range == null || m_Range.Length < 2) return true; - if (m_Range[0] != 0 || m_Range[1] != 0) - return value >= m_Range[0] && value <= m_Range[1]; - else - return true; - } - } - - [SerializeField] private bool m_Show; - [SerializeField] private Shape m_Shape; - [SerializeField] private float m_Radius = 100; - [SerializeField] private int m_SplitNumber = 5; - [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.5f }; - [SerializeField] private AxisLine m_AxisLine = AxisLine.defaultAxisLine; - [SerializeField] private AxisName m_AxisName = AxisName.defaultAxisName; - [SerializeField] private AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine; - [SerializeField] private AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea; - [SerializeField] private bool m_Indicator = true; - [SerializeField] private PositionType m_PositionType = PositionType.Vertice; - [SerializeField] private float m_IndicatorGap = 10; - [SerializeField] private int m_CeilRate = 0; - [SerializeField] private bool m_IsAxisTooltip; - [SerializeField] private Color32 m_OutRangeColor = Color.red; - [SerializeField] private bool m_ConnectCenter = false; - [SerializeField] private bool m_LineGradient = true; - [SerializeField] private List<Indicator> m_IndicatorList = new List<Indicator>(); - - public RadarCoordContext context = new RadarCoordContext(); - - /// <summary> - /// [default:true] - /// Set this to false to prevent the radar from showing. - /// |是否显示雷达坐标系组件。 - /// </summary> - public bool show { get { return m_Show; } set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } } - /// <summary> - /// Radar render type, in which 'Polygon' and 'Circle' are supported. - /// |雷达图绘制类型,支持 'Polygon' 和 'Circle'。 - /// </summary> - /// <value></value> - public Shape shape - { - get { return m_Shape; } - set { if (PropertyUtil.SetStruct(ref m_Shape, value)) SetAllDirty(); } - } - /// <summary> - /// the radius of radar. - /// |雷达图的半径。 - /// </summary> - public float radius - { - get { return m_Radius; } - set { if (PropertyUtil.SetStruct(ref m_Radius, value)) SetAllDirty(); } - } - /// <summary> - /// Segments of indicator axis. - /// |指示器轴的分割段数。 - /// </summary> - public int splitNumber - { - get { return m_SplitNumber; } - set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); } - } - /// <summary> - /// the center of radar chart. - /// |雷达图的中心点。数组的第一项是横坐标,第二项是纵坐标。 - /// 当值为0-1之间时表示百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。 - /// </summary> - public float[] center - { - get { return m_Center; } - set { if (value != null) { m_Center = value; SetAllDirty(); } } - } - /// <summary> - /// axis line. - /// |轴线。 - /// </summary> - public AxisLine axisLine - { - get { return m_AxisLine; } - set { if (PropertyUtil.SetClass(ref m_AxisLine, value, true)) SetAllDirty(); } - } - /// <summary> - /// Name options for radar indicators. - /// |雷达图每个指示器名称的配置项。 - /// </summary> - public AxisName axisName - { - get { return m_AxisName; } - set { if (PropertyUtil.SetClass(ref m_AxisName, value, true)) SetAllDirty(); } - } - /// <summary> - /// split line. - /// |分割线。 - /// </summary> - public AxisSplitLine splitLine - { - get { return m_SplitLine; } - set { if (PropertyUtil.SetClass(ref m_SplitLine, value, true)) SetAllDirty(); } - } - /// <summary> - /// Split area of axis in grid area. - /// |分割区域。 - /// </summary> - public AxisSplitArea splitArea - { - get { return m_SplitArea; } - set { if (PropertyUtil.SetClass(ref m_SplitArea, value, true)) SetAllDirty(); } - } - /// <summary> - /// Whether to show indicator. - /// |是否显示指示器。 - /// </summary> - public bool indicator - { - get { return m_Indicator; } - set { if (PropertyUtil.SetStruct(ref m_Indicator, value)) SetComponentDirty(); } - } - /// <summary> - /// The gap of indicator and radar. - /// |指示器和雷达的间距。 - /// </summary> - public float indicatorGap - { - get { return m_IndicatorGap; } - set { if (PropertyUtil.SetStruct(ref m_IndicatorGap, value)) SetComponentDirty(); } - } - /// <summary> - /// The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated. - /// |最大最小值向上取整的倍率。默认为0时自动计算。 - /// </summary> - public int ceilRate - { - get { return m_CeilRate; } - set { if (PropertyUtil.SetStruct(ref m_CeilRate, value < 0 ? 0 : value)) SetAllDirty(); } - } - /// <summary> - /// 是否Tooltip显示轴线上的所有数据。 - /// </summary> - public bool isAxisTooltip - { - get { return m_IsAxisTooltip; } - set { if (PropertyUtil.SetStruct(ref m_IsAxisTooltip, value)) SetAllDirty(); } - } - /// <summary> - /// The position type of indicator. - /// |显示位置类型。 - /// </summary> - public PositionType positionType - { - get { return m_PositionType; } - set { if (PropertyUtil.SetStruct(ref m_PositionType, value)) SetAllDirty(); } - } - /// <summary> - /// The color displayed when data out of range. - /// |数值超出范围时显示的颜色。 - /// </summary> - public Color32 outRangeColor - { - get { return m_OutRangeColor; } - set { if (PropertyUtil.SetStruct(ref m_OutRangeColor, value)) SetAllDirty(); } - } - /// <summary> - /// Whether serie data connect to radar center with line. - /// |数值是否连线到中心点。 - /// </summary> - public bool connectCenter - { - get { return m_ConnectCenter; } - set { if (PropertyUtil.SetStruct(ref m_ConnectCenter, value)) SetAllDirty(); } - } - /// <summary> - /// Whether need gradient for data line. - /// |数值线段是否需要渐变。 - /// </summary> - public bool lineGradient - { - get { return m_LineGradient; } - set { if (PropertyUtil.SetStruct(ref m_LineGradient, value)) SetAllDirty(); } - } - /// <summary> - /// the indicator list. - /// |指示器列表。 - /// </summary> - public List<Indicator> indicatorList { get { return m_IndicatorList; } } - - public bool IsPointerEnter() - { - return context.isPointerEnter; - } - - public override void SetDefaultValue() - { - m_Show = true; - m_Shape = Shape.Polygon; - m_Radius = 0.35f; - m_SplitNumber = 5; - m_Indicator = true; - m_IndicatorList = new List<Indicator>(5) - { - new Indicator() { name = "indicator1", max = 0 }, - new Indicator() { name = "indicator2", max = 0 }, - new Indicator() { name = "indicator3", max = 0 }, - new Indicator() { name = "indicator4", max = 0 }, - new Indicator() { name = "indicator5", max = 0 }, - }; - center[0] = 0.5f; - center[1] = 0.4f; - splitLine.show = true; - splitArea.show = true; - axisName.show = true; - axisName.name = null; - } - - private bool IsEqualsIndicatorList(List<Indicator> indicators1, List<Indicator> indicators2) - { - if (indicators1.Count != indicators2.Count) return false; - for (int i = 0; i < indicators1.Count; i++) - { - var indicator1 = indicators1[i]; - var indicator2 = indicators2[i]; - if (!indicator1.Equals(indicator2)) return false; - } - return true; - } - - public bool IsInIndicatorRange(int index, double value) - { - var indicator = GetIndicator(index); - return indicator == null ? true : indicator.IsInRange(value); - } - - public double GetIndicatorMin(int index) - { - if (index >= 0 && index < m_IndicatorList.Count) - { - return m_IndicatorList[index].min; - } - return 0; - } - public double GetIndicatorMax(int index) - { - if (index >= 0 && index < m_IndicatorList.Count) - { - return m_IndicatorList[index].max; - } - return 0; - } - - internal void UpdateRadarCenter(Vector3 chartPosition, float chartWidth, float chartHeight) - { - if (center.Length < 2) return; - var centerX = center[0] <= 1 ? chartWidth * center[0] : center[0]; - var centerY = center[1] <= 1 ? chartHeight * center[1] : center[1]; - context.center = chartPosition + new Vector3(centerX, centerY); - if (radius <= 0) - { - context.radius = 0; - } - else if (radius <= 1) - { - context.radius = Mathf.Min(chartWidth, chartHeight) * radius; - } - else - { - context.radius = radius; - } - if (shape == RadarCoord.Shape.Polygon && positionType == PositionType.Between) - { - var angle = Mathf.PI / indicatorList.Count; - context.dataRadius = context.radius * Mathf.Cos(angle); - } - else - { - context.dataRadius = context.radius; - } - } - - public Vector3 GetIndicatorPosition(int index) - { - int indicatorNum = indicatorList.Count; - var angle = 0f; - switch (positionType) - { - case PositionType.Vertice: - angle = 2 * Mathf.PI / indicatorNum * index; - break; - case PositionType.Between: - angle = 2 * Mathf.PI / indicatorNum * (index + 0.5f); - break; - } - var x = context.center.x + (context.radius + indicatorGap) * Mathf.Sin(angle); - var y = context.center.y + (context.radius + indicatorGap) * Mathf.Cos(angle); - return new Vector3(x, y); - } - - public void AddIndicator(RadarCoord.Indicator indicator) - { - indicatorList.Add(indicator); - SetAllDirty(); - } - - public RadarCoord.Indicator AddIndicator(string name, float min, float max) - { - var indicator = new RadarCoord.Indicator(); - indicator.name = name; - indicator.min = min; - indicator.max = max; - indicatorList.Add(indicator); - SetAllDirty(); - return indicator; - } - - public bool UpdateIndicator(int indicatorIndex, string name, float min, float max) - { - var indicator = GetIndicator(indicatorIndex); - if (indicator == null) return false; - indicator.name = name; - indicator.min = min; - indicator.max = max; - SetAllDirty(); - return true; - } - - public RadarCoord.Indicator GetIndicator(int indicatorIndex) - { - if (indicatorIndex < 0 || indicatorIndex > indicatorList.Count - 1) return null; - return indicatorList[indicatorIndex]; - } - - public override void ClearData() - { - indicatorList.Clear(); - } - - public string GetFormatterIndicatorContent(int indicatorIndex) - { - var indicator = GetIndicator(indicatorIndex); - if (indicator == null) - return string.Empty; - else - return GetFormatterIndicatorContent(indicator.name); - } - - public string GetFormatterIndicatorContent(string indicatorName) - { - if (string.IsNullOrEmpty(indicatorName)) - return indicatorName; - - if (string.IsNullOrEmpty(m_AxisName.labelStyle.formatter)) - { - return indicatorName; - } - else - { - var content = m_AxisName.labelStyle.formatter; - FormatterHelper.ReplaceAxisLabelContent(ref content, indicatorName); - return content; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs.meta b/Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs.meta deleted file mode 100644 index 6d3d5aa..0000000 --- a/Assets/XCharts/Runtime/Component/Radar/RadarCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 876512c564bd144be99d0acbe079cf8b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs b/Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs deleted file mode 100644 index dc45f60..0000000 --- a/Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public class RadarCoordContext : MainComponentContext - { - /// <summary> - /// the center position of radar in container. - /// |雷达图在容器中的具体中心点。 - /// </summary> - public Vector3 center { get; internal set; } - /// <summary> - /// the true radius of radar. - /// |雷达图的运行时实际半径。 - /// </summary> - public float radius { get; internal set; } - public float dataRadius { get; internal set; } - public bool isPointerEnter { get; set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs.meta b/Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs.meta deleted file mode 100644 index 147702f..0000000 --- a/Assets/XCharts/Runtime/Component/Radar/RadarCoordContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5f7419e8466e048cb9689ab85d20e4de -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs b/Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs deleted file mode 100644 index 4c72ccb..0000000 --- a/Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class RadarCoordHandler : MainComponentHandler<RadarCoord> - { - private const string INDICATOR_TEXT = "indicator"; - - public override void InitComponent() - { - InitRadarCoord(component); - } - - public override void Update() - { - if (!chart.isPointerInChart) - { - component.context.isPointerEnter = false; - return; - } - var radar = component; - radar.context.isPointerEnter = radar.show && - Vector3.Distance(radar.context.center, chart.pointerPos) <= radar.context.radius; - } - - public override void DrawBase(VertexHelper vh) - { - DrawRadarCoord(vh, component); - } - - private void InitRadarCoord(RadarCoord radar) - { - float txtHig = 20; - radar.painter = chart.GetPainter(radar.index); - radar.refreshComponent = delegate() - { - radar.UpdateRadarCenter(chart.chartPosition, chart.chartWidth, chart.chartHeight); - var radarObject = ChartHelper.AddObject("Radar" + radar.index, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - radar.gameObject = radarObject; - radar.gameObject.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(radarObject.transform, INDICATOR_TEXT); - for (int i = 0; i < radar.indicatorList.Count; i++) - { - var indicator = radar.indicatorList[i]; - var pos = radar.GetIndicatorPosition(i); - var objName = INDICATOR_TEXT + "_" + i; - - var label = ChartHelper.AddChartLabel(objName, radarObject.transform, radar.axisName.labelStyle, - chart.theme.common, radar.GetFormatterIndicatorContent(i), Color.clear, TextAnchor.MiddleCenter); - label.SetActive(radar.indicator && radar.axisName.labelStyle.show); - AxisHelper.AdjustCircleLabelPos(label, pos, radar.context.center, txtHig, radar.axisName.labelStyle.offset); - } - chart.RefreshBasePainter(); - }; - radar.refreshComponent.Invoke(); - } - - private void DrawRadarCoord(VertexHelper vh, RadarCoord radar) - { - if (!radar.show) return; - radar.UpdateRadarCenter(chart.chartPosition, chart.chartWidth, chart.chartHeight); - if (radar.shape == RadarCoord.Shape.Circle) - { - DrawCricleRadar(vh, radar); - } - else - { - DrawPolygonRadar(vh, radar); - } - } - - private void DrawCricleRadar(VertexHelper vh, RadarCoord radar) - { - float insideRadius = 0, outsideRadius = 0; - float block = radar.context.radius / radar.splitNumber; - int indicatorNum = radar.indicatorList.Count; - Vector3 p = radar.context.center; - Vector3 p1; - float angle = 2 * Mathf.PI / indicatorNum; - var lineColor = radar.axisLine.GetColor(chart.theme.axis.splitLineColor); - var lineWidth = radar.axisLine.GetWidth(chart.theme.axis.lineWidth); - var lineType = radar.axisLine.GetType(chart.theme.axis.lineType); - var splitLineColor = radar.splitLine.GetColor(chart.theme.axis.splitLineColor); - var splitLineWidth = radar.splitLine.GetWidth(chart.theme.axis.splitLineWidth); - for (int i = 0; i < radar.splitNumber; i++) - { - var color = radar.splitArea.GetColor(i, chart.theme.axis); - outsideRadius = insideRadius + block; - if (radar.splitArea.show) - { - UGL.DrawDoughnut(vh, p, insideRadius, outsideRadius, color, Color.clear, - 0, 360, chart.settings.cicleSmoothness); - } - if (radar.splitLine.show) - { - UGL.DrawEmptyCricle(vh, p, outsideRadius, splitLineWidth, splitLineColor, - Color.clear, chart.settings.cicleSmoothness); - } - insideRadius = outsideRadius; - } - if (radar.axisLine.show) - { - for (int j = 0; j <= indicatorNum; j++) - { - float currAngle = j * angle; - p1 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle), - p.y + outsideRadius * Mathf.Cos(currAngle)); - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, p, p1, lineColor); - } - } - } - - private void DrawPolygonRadar(VertexHelper vh, RadarCoord radar) - { - float insideRadius = 0, outsideRadius = 0; - float block = radar.context.radius / radar.splitNumber; - int indicatorNum = radar.indicatorList.Count; - Vector3 p1, p2, p3, p4; - Vector3 p = radar.context.center; - float angle = 2 * Mathf.PI / indicatorNum; - var lineColor = radar.axisLine.GetColor(chart.theme.axis.splitLineColor); - var lineWidth = radar.axisLine.GetWidth(chart.theme.axis.lineWidth); - var lineType = radar.axisLine.GetType(chart.theme.axis.lineType); - var splitLineColor = radar.splitLine.GetColor(chart.theme.axis.splitLineColor); - var splitLineWidth = radar.splitLine.GetWidth(chart.theme.axis.splitLineWidth); - var splitLineType = radar.splitLine.GetType(chart.theme.axis.splitLineType); - for (int i = 0; i < radar.splitNumber; i++) - { - var color = radar.splitArea.GetColor(i, chart.theme.axis); - outsideRadius = insideRadius + block; - p1 = new Vector3(p.x + insideRadius * Mathf.Sin(0), p.y + insideRadius * Mathf.Cos(0)); - p2 = new Vector3(p.x + outsideRadius * Mathf.Sin(0), p.y + outsideRadius * Mathf.Cos(0)); - for (int j = 0; j <= indicatorNum; j++) - { - float currAngle = j * angle; - p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle), - p.y + outsideRadius * Mathf.Cos(currAngle)); - p4 = new Vector3(p.x + insideRadius * Mathf.Sin(currAngle), - p.y + insideRadius * Mathf.Cos(currAngle)); - if (radar.splitArea.show) - { - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, color); - } - if (radar.splitLine.NeedShow(i)) - { - ChartDrawer.DrawLineStyle(vh, splitLineType, splitLineWidth, p2, p3, splitLineColor); - } - p1 = p4; - p2 = p3; - } - insideRadius = outsideRadius; - } - if (radar.axisLine.show) - { - for (int j = 0; j <= indicatorNum; j++) - { - float currAngle = j * angle; - p3 = new Vector3(p.x + outsideRadius * Mathf.Sin(currAngle), - p.y + outsideRadius * Mathf.Cos(currAngle)); - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, p, p3, lineColor); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs.meta b/Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs.meta deleted file mode 100644 index 1c042d0..0000000 --- a/Assets/XCharts/Runtime/Component/Radar/RadarCoordHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 27622e3c95fec42daafff901970daf8f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Settings.meta b/Assets/XCharts/Runtime/Component/Settings.meta deleted file mode 100644 index d09a812..0000000 --- a/Assets/XCharts/Runtime/Component/Settings.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 592a52c7f32a046c689bd54aae7eff59 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Settings/Settings.cs b/Assets/XCharts/Runtime/Component/Settings/Settings.cs deleted file mode 100644 index 4d8bc80..0000000 --- a/Assets/XCharts/Runtime/Component/Settings/Settings.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Global parameter setting component. The default value can be used in general, and can be adjusted when necessary. - /// |全局参数设置组件。一般情况下可使用默认值,当有需要时可进行调整。 - /// </summary> - [Serializable] - public class Settings : MainComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField][Range(1, 20)] protected int m_MaxPainter = 10; - [SerializeField] protected bool m_ReversePainter = false; - [SerializeField] protected Material m_BasePainterMaterial; - [SerializeField] protected Material m_SeriePainterMaterial; - [SerializeField] protected Material m_TopPainterMaterial; - [SerializeField][Range(1, 10)] protected float m_LineSmoothStyle = 3f; - [SerializeField][Range(1f, 20)] protected float m_LineSmoothness = 2f; - [SerializeField][Range(0.5f, 20)] protected float m_LineSegmentDistance = 3f; - [SerializeField][Range(1, 10)] protected float m_CicleSmoothness = 2f; - [SerializeField] protected float m_LegendIconLineWidth = 2; - [SerializeField] private float[] m_LegendIconCornerRadius = new float[] { 0.25f, 0.25f, 0.25f, 0.25f }; - - public bool show { get { return m_Show; } } - /// <summary> - /// max painter. - /// |设定的painter数量。 - /// </summary> - public int maxPainter - { - get { return m_MaxPainter; } - set { if (PropertyUtil.SetStruct(ref m_MaxPainter, value < 0 ? 1 : value)) SetVerticesDirty(); } - } - /// <summary> - /// Painter是否逆序。逆序时index大的serie最先绘制。 - /// </summary> - public bool reversePainter - { - get { return m_ReversePainter; } - set { if (PropertyUtil.SetStruct(ref m_ReversePainter, value)) SetVerticesDirty(); } - } - /// <summary> - /// Base Pointer 材质球,设置后会影响Axis等。 - /// </summary> - public Material basePainterMaterial - { - get { return m_BasePainterMaterial; } - set { if (PropertyUtil.SetClass(ref m_BasePainterMaterial, value)) SetComponentDirty(); } - } - /// <summary> - /// Serie Pointer 材质球,设置后会影响所有Serie。 - /// </summary> - public Material seriePainterMaterial - { - get { return m_SeriePainterMaterial; } - set { if (PropertyUtil.SetClass(ref m_SeriePainterMaterial, value)) SetComponentDirty(); } - } - /// <summary> - /// Top Pointer 材质球,设置后会影响Tooltip等。 - /// </summary> - public Material topPainterMaterial - { - get { return m_TopPainterMaterial; } - set { if (PropertyUtil.SetClass(ref m_TopPainterMaterial, value)) SetComponentDirty(); } - } - /// <summary> - /// Curve smoothing factor. By adjusting the smoothing coefficient, the curvature of the curve can be changed, - /// and different curves with slightly different appearance can be obtained. - /// |曲线平滑系数。通过调整平滑系数可以改变曲线的曲率,得到外观稍微有变化的不同曲线。 - /// </summary> - public float lineSmoothStyle - { - get { return m_LineSmoothStyle; } - set { if (PropertyUtil.SetStruct(ref m_LineSmoothStyle, value < 0 ? 1f : value)) SetVerticesDirty(); } - } - /// <summary> - /// Smoothness of curve. The smaller the value, the smoother the curve, but the number of vertices will increase. - /// |When the area with gradient is filled, the larger the value, the worse the transition effect. - /// |曲线平滑度。值越小曲线越平滑,但顶点数也会随之增加。当开启有渐变的区域填充时,数值越大渐变过渡效果越差。 - /// </summary> - /// <value></value> - public float lineSmoothness - { - get { return m_LineSmoothness; } - set { if (PropertyUtil.SetStruct(ref m_LineSmoothStyle, value < 0 ? 1f : value)) SetVerticesDirty(); } - } - /// <summary> - /// The partition distance of a line segment. A line in a normal line chart is made up of many segments, - /// the number of which is determined by the change in value. The smaller the number of segments, - /// the higher the number of vertices. When the area with gradient is filled, the larger the value, the worse the transition effect. - /// |线段的分割距离。普通折线图的线是由很多线段组成,段数由该数值决定。值越小段数越多,但顶点数也会随之增加。当开启有渐变的区域填充时,数值越大渐变过渡效果越差。 - /// </summary> - /// <value></value> - public float lineSegmentDistance - { - get { return m_LineSegmentDistance; } - set { if (PropertyUtil.SetStruct(ref m_LineSegmentDistance, value < 0 ? 1f : value)) SetVerticesDirty(); } - } - /// <summary> - /// the smoothess of cricle. - /// |圆形的平滑度。数越小圆越平滑,但顶点数也会随之增加。 - /// </summary> - public float cicleSmoothness - { - get { return m_CicleSmoothness; } - set { if (PropertyUtil.SetStruct(ref m_CicleSmoothness, value < 0 ? 1f : value)) SetVerticesDirty(); } - } - - /// <summary> - /// the width of line serie legend. - /// |Line类型图例图标的线条宽度。 - /// </summary> - public float legendIconLineWidth - { - get { return m_LegendIconLineWidth; } - set { if (PropertyUtil.SetStruct(ref m_LegendIconLineWidth, value)) SetVerticesDirty(); } - } - - /// <summary> - /// The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)). - /// |图例圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。 - /// </summary> - public float[] legendIconCornerRadius - { - get { return m_LegendIconCornerRadius; } - set { if (PropertyUtil.SetClass(ref m_LegendIconCornerRadius, value, true)) SetVerticesDirty(); } - } - - public void Copy(Settings settings) - { - m_ReversePainter = settings.reversePainter; - m_MaxPainter = settings.maxPainter; - m_BasePainterMaterial = settings.basePainterMaterial; - m_SeriePainterMaterial = settings.seriePainterMaterial; - m_TopPainterMaterial = settings.topPainterMaterial; - m_LineSmoothStyle = settings.lineSmoothStyle; - m_LineSmoothness = settings.lineSmoothness; - m_LineSegmentDistance = settings.lineSegmentDistance; - m_CicleSmoothness = settings.cicleSmoothness; - m_LegendIconLineWidth = settings.legendIconLineWidth; - ChartHelper.CopyArray(m_LegendIconCornerRadius, settings.legendIconCornerRadius); - } - - public override void Reset() - { - Copy(DefaultSettings); - } - - public static Settings DefaultSettings - { - get - { - return new Settings() - { - m_ReversePainter = false, - m_MaxPainter = XCSettings.maxPainter, - m_LineSmoothStyle = XCSettings.lineSmoothStyle, - m_LineSmoothness = XCSettings.lineSmoothness, - m_LineSegmentDistance = XCSettings.lineSegmentDistance, - m_CicleSmoothness = XCSettings.cicleSmoothness, - m_LegendIconLineWidth = 2, - m_LegendIconCornerRadius = new float[] { 0.25f, 0.25f, 0.25f, 0.25f } - }; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Settings/Settings.cs.meta b/Assets/XCharts/Runtime/Component/Settings/Settings.cs.meta deleted file mode 100644 index b064a39..0000000 --- a/Assets/XCharts/Runtime/Component/Settings/Settings.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4e57c4afa48c2455b8a91b20eca25321 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Title.meta b/Assets/XCharts/Runtime/Component/Title.meta deleted file mode 100644 index 71e29ea..0000000 --- a/Assets/XCharts/Runtime/Component/Title.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: cea6be3fa2a9e4ae6be4b3fd882f7352 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Title/Title.cs b/Assets/XCharts/Runtime/Component/Title/Title.cs deleted file mode 100644 index ac4ca74..0000000 --- a/Assets/XCharts/Runtime/Component/Title/Title.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Title component, including main title and subtitle. - /// |标题组件,包含主标题和副标题。 - /// </summary> - [Serializable] - [ComponentHandler(typeof(TitleHander), true)] - public class Title : MainComponent, IPropertyChanged - { - [SerializeField] private bool m_Show = true; - [SerializeField] private string m_Text = "Chart Title"; - [SerializeField] private string m_SubText = ""; - [SerializeField] private LabelStyle m_LabelStyle = new LabelStyle(); - [SerializeField] private LabelStyle m_SubLabelStyle = new LabelStyle(); - [SerializeField] private float m_ItemGap = 0; - [SerializeField] private Location m_Location = Location.defaultTop; - - /// <summary> - /// [default:true] - /// Set this to false to prevent the title from showing. - /// |是否显示标题组件。 - /// </summary> - public bool show { get { return m_Show; } set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); } } - /// <summary> - /// The main title text, supporting \n for newlines. - /// |主标题文本,支持使用 \n 换行。 - /// </summary> - public string text { get { return m_Text; } set { if (PropertyUtil.SetClass(ref m_Text, value)) SetComponentDirty(); } } - /// <summary> - /// The text style of main title. - /// |主标题文本样式。 - /// </summary> - public LabelStyle labelStyle - { - get { return m_LabelStyle; } - set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// Subtitle text, supporting for \n for newlines. - /// |副标题文本,支持使用 \n 换行。 - /// </summary> - public string subText - { - get { return m_SubText; } - set { if (PropertyUtil.SetClass(ref m_SubText, value)) SetComponentDirty(); } - } - /// <summary> - /// The text style of sub title. - /// |副标题文本样式。 - /// </summary> - public LabelStyle subLabelStyle - { - get { return m_SubLabelStyle; } - set { if (PropertyUtil.SetClass(ref m_SubLabelStyle, value)) SetComponentDirty(); } - } - /// <summary> - /// [default:8] - /// The gap between the main title and subtitle. - /// |主副标题之间的间距。 - /// </summary> - public float itemGap - { - get { return m_ItemGap; } - set { if (PropertyUtil.SetStruct(ref m_ItemGap, value)) SetComponentDirty(); } - } - /// <summary> - /// The location of title component. - /// |标题显示位置。 - /// </summary> - public Location location - { - get { return m_Location; } - set { if (PropertyUtil.SetClass(ref m_Location, value)) SetComponentDirty(); } - } - - public override bool vertsDirty { get { return false; } } - public override bool componentDirty - { - get - { - return m_ComponentDirty || - location.componentDirty || - m_LabelStyle.componentDirty || - m_SubLabelStyle.componentDirty; - } - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - location.ClearComponentDirty(); - m_LabelStyle.ClearComponentDirty(); - m_SubLabelStyle.ClearComponentDirty(); - } - - public void OnChanged() - { - m_Location.OnChanged(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Title/Title.cs.meta b/Assets/XCharts/Runtime/Component/Title/Title.cs.meta deleted file mode 100644 index 1d57b56..0000000 --- a/Assets/XCharts/Runtime/Component/Title/Title.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0c4f5a39710624b94a3d015eb552f53a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Title/TitleHandler.cs b/Assets/XCharts/Runtime/Component/Title/TitleHandler.cs deleted file mode 100644 index 63e3294..0000000 --- a/Assets/XCharts/Runtime/Component/Title/TitleHandler.cs +++ /dev/null @@ -1,88 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class TitleHander : MainComponentHandler<Title> - { - private static readonly string s_TitleObjectName = "title"; - private static readonly string s_SubTitleObjectName = "title_sub"; - private ChartLabel m_LabelObject; - private ChartLabel m_SubLabelObject; - - public override void InitComponent() - { - var title = component; - title.painter = null; - title.refreshComponent = delegate() - { - title.OnChanged(); - var anchorMin = title.location.runtimeAnchorMin; - var anchorMax = title.location.runtimeAnchorMax; - var pivot = title.location.runtimePivot; - var objName = ChartCached.GetComponentObjectName(title); - var titleObject = ChartHelper.AddObject(objName, chart.transform, anchorMin, anchorMax, - pivot, chart.chartSizeDelta); - title.gameObject = titleObject; - title.gameObject.transform.SetSiblingIndex(chart.m_PainterTop.transform.GetSiblingIndex() + 1); - anchorMin = title.location.runtimeAnchorMin; - anchorMax = title.location.runtimeAnchorMax; - pivot = title.location.runtimePivot; - var fontSize = title.labelStyle.textStyle.GetFontSize(chart.theme.title); - ChartHelper.UpdateRectTransform(titleObject, anchorMin, anchorMax, pivot, new Vector2(chart.chartWidth, chart.chartHeight)); - var titlePosition = chart.GetTitlePosition(title); - var subTitlePosition = -new Vector3(0, fontSize + title.itemGap, 0); - - titleObject.transform.localPosition = titlePosition; - titleObject.hideFlags = chart.chartHideFlags; - ChartHelper.HideAllObject(titleObject); - - m_LabelObject = ChartHelper.AddChartLabel(s_TitleObjectName, titleObject.transform, title.labelStyle, chart.theme.title, - GetTitleText(title), Color.clear, title.location.runtimeTextAlignment); - m_LabelObject.SetActive(title.show && title.labelStyle.show); - - m_SubLabelObject = ChartHelper.AddChartLabel(s_SubTitleObjectName, titleObject.transform, title.subLabelStyle, chart.theme.subTitle, - GetSubTitleText(title), Color.clear, title.location.runtimeTextAlignment); - m_SubLabelObject.SetActive(title.show && title.subLabelStyle.show); - m_SubLabelObject.transform.localPosition = subTitlePosition + title.subLabelStyle.offset; - }; - title.refreshComponent(); - } - - public override void OnSerieDataUpdate(int serieIndex) - { - if (m_LabelObject != null && FormatterHelper.NeedFormat(component.text)) - m_LabelObject.SetText(GetTitleText(component)); - if (m_SubLabelObject != null && FormatterHelper.NeedFormat(component.subText)) - m_SubLabelObject.SetText(GetSubTitleText(component)); - } - - private string GetTitleText(Title title) - { - if (FormatterHelper.NeedFormat(title.text)) - { - var content = title.text; - FormatterHelper.ReplaceContent(ref content, 0, title.labelStyle.numericFormatter, null, chart); - return content; - } - else - { - return title.text; - } - } - - private string GetSubTitleText(Title title) - { - if (FormatterHelper.NeedFormat(title.subText)) - { - var content = title.subText; - FormatterHelper.ReplaceContent(ref content, 0, title.subLabelStyle.numericFormatter, null, chart); - return content; - } - else - { - return title.subText; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Title/TitleHandler.cs.meta b/Assets/XCharts/Runtime/Component/Title/TitleHandler.cs.meta deleted file mode 100644 index bc42e0d..0000000 --- a/Assets/XCharts/Runtime/Component/Title/TitleHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cbe3062b7770040e6b4a98026f0ad044 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Title/TitleStyle.cs b/Assets/XCharts/Runtime/Component/Title/TitleStyle.cs deleted file mode 100644 index 2befc2d..0000000 --- a/Assets/XCharts/Runtime/Component/Title/TitleStyle.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// the title of serie. - /// |标题相关设置。 - /// </summary> - [Serializable] - public class TitleStyle : LabelStyle, ISerieDataComponent, ISerieExtraComponent - { - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Title/TitleStyle.cs.meta b/Assets/XCharts/Runtime/Component/Title/TitleStyle.cs.meta deleted file mode 100644 index 1a44da0..0000000 --- a/Assets/XCharts/Runtime/Component/Title/TitleStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cd97375f7d84f4fd18dab048c465cdd8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Tooltip.meta b/Assets/XCharts/Runtime/Component/Tooltip.meta deleted file mode 100644 index 7161b85..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 17e248f354e9b4e3fa75170f7919e297 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs b/Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs deleted file mode 100644 index 8e13e31..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs +++ /dev/null @@ -1,549 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - /// <summary> - /// Tooltip component. - /// |提示框组件。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(TooltipHandler), true)] - public class Tooltip : MainComponent - { - /// <summary> - /// Indicator type. - /// |指示器类型。 - /// </summary> - public enum Type - { - /// <summary> - /// line indicator. - /// |直线指示器 - /// </summary> - Line, - /// <summary> - /// shadow crosshair indicator. - /// |阴影指示器 - /// </summary> - Shadow, - /// <summary> - /// no indicator displayed. - /// |无指示器 - /// </summary> - None, - /// <summary> - /// crosshair indicator, which is actually the shortcut of enable two axisPointers of two orthometric axes. - /// |十字准星指示器。坐标轴显示Label和交叉线。 - /// </summary> - Corss - } - - public enum Trigger - { - /// <summary> - /// Triggered by data item, which is mainly used for charts that don't have a category axis like scatter charts or pie charts. - /// |数据项图形触发,主要在散点图,饼图等无类目轴的图表中使用。 - /// </summary> - Item, - /// <summary> - /// Triggered by axes, which is mainly used for charts that have category axes, like bar charts or line charts. - /// |坐标轴触发,主要在柱状图,折线图等会使用类目轴的图表中使用。 - /// </summary> - Axis, - /// <summary> - /// Trigger nothing. - /// |什么都不触发。 - /// </summary> - None - } - - [SerializeField] private bool m_Show = true; - [SerializeField] private Type m_Type; - [SerializeField] private Trigger m_Trigger = Trigger.Item; - [SerializeField] private string m_ItemFormatter; - [SerializeField] private string m_TitleFormatter; - [SerializeField] private string m_Marker = "●"; - [SerializeField] private float m_FixedWidth = 0; - [SerializeField] private float m_FixedHeight = 0; - [SerializeField] private float m_MinWidth = 0; - [SerializeField] private float m_MinHeight = 0; - [SerializeField] private string m_NumericFormatter = ""; - [SerializeField] private int m_PaddingLeftRight = 10; - [SerializeField] private int m_PaddingTopBottom = 10; - [SerializeField] private bool m_IgnoreDataShow = false; - [SerializeField] private string m_IgnoreDataDefaultContent = "-"; - [SerializeField] private bool m_ShowContent = true; - [SerializeField] private bool m_AlwayShowContent = false; - [SerializeField] private Vector2 m_Offset = new Vector2(18f, -25f); - [SerializeField] private Sprite m_BackgroundImage; - [SerializeField] private Image.Type m_BackgroundType = Image.Type.Simple; - [SerializeField] private Color m_BackgroundColor; - [SerializeField] private float m_BorderWidth = 2f; - [SerializeField] private bool m_FixedXEnable = false; - [SerializeField] private float m_FixedX = 0f; - [SerializeField] private bool m_FixedYEnable = false; - [SerializeField] private float m_FixedY = 0f; - [SerializeField] private float m_TitleHeight = 25f; - [SerializeField] private float m_ItemHeight = 25f; - [SerializeField] private Color32 m_BorderColor = new Color32(230, 230, 230, 255); - [SerializeField] private LineStyle m_LineStyle = new LineStyle(LineStyle.Type.None); - [SerializeField] private LabelStyle m_IndicatorLabelStyle = new LabelStyle(); - [SerializeField] - private LabelStyle m_TitleLabelStyle = new LabelStyle() - { - textStyle = new TextStyle() { alignment = TextAnchor.MiddleLeft } - }; - [SerializeField] - private List<LabelStyle> m_ContentLabelStyles = new List<LabelStyle>() - { - new LabelStyle() { textPadding = new TextPadding(0, 5, 0, 0), textStyle = new TextStyle() { alignment = TextAnchor.MiddleLeft } }, - new LabelStyle() { textPadding = new TextPadding(0, 20, 0, 0), textStyle = new TextStyle() { alignment = TextAnchor.MiddleLeft } }, - new LabelStyle() { textPadding = new TextPadding(0, 0, 0, 0), textStyle = new TextStyle() { alignment = TextAnchor.MiddleRight } } - }; - - public TooltipContext context = new TooltipContext(); - public TooltipView view; - - /// <summary> - /// Whether to show the tooltip component. - /// |是否显示提示框组件。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) { SetAllDirty(); SetActive(value); } } - } - /// <summary> - /// Indicator type. - /// |提示框指示器类型。 - /// </summary> - public Type type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetAllDirty(); } - } - /// <summary> - /// Type of triggering. - /// |触发类型。 - /// </summary> - public Trigger trigger - { - get { return m_Trigger; } - set { if (PropertyUtil.SetStruct(ref m_Trigger, value)) SetAllDirty(); } - } - /// <summary> - /// The string template formatter for the tooltip title content. Support for wrapping lines with \n. - /// The placeholder {I} can be set separately to indicate that the title is ignored and not displayed. - /// Template see itemFormatter. - /// |提示框标题内容的字符串模版格式器。支持用 \n 换行。可以单独设置占位符{i}表示忽略不显示title。 - /// 模板变量参考Toolip的itemFormatter。 - /// </summary> - public string titleFormatter { get { return m_TitleFormatter; } set { m_TitleFormatter = value; } } - /// <summary> - /// a string template formatter for a single Serie or data item content. Support for wrapping lines with \n. - /// Template variables are {.}, {a}, {b}, {c}, {d}.</br> - /// {.} is the dot of the corresponding color of a Serie that is currently indicated or whose index is 0.</br> - /// {a} is the series name of the serie that is currently indicated or whose index is 0.</br> - /// {b} is the name of the data item serieData that is currently indicated or whose index is 0, or a category value (such as the X-axis of a line chart).</br> - /// {c} is the value of a Y-dimension (dimesion is 1) from a Serie that is currently indicated or whose index is 0.</br> - /// {d} is the percentage value of Y-dimensions (dimesion is 1) from serie that is currently indicated or whose index is 0, with no % sign.</br> - /// {e} is the name of the data item serieData that is currently indicated or whose index is 0.</br> - /// {f} is sum of data.</br> - /// {.1} represents a dot from serie corresponding color that specifies index as 1.</br> - /// 1 in {a1}, {b1}, {c1} represents a serie that specifies an index of 1.</br> - /// {c1:2} represents the third data from serie's current indication data item indexed to 1 (a data item has multiple data, index 2 represents the third data).</br> - /// {c1:2-2} represents the third data item from serie's third data item indexed to 1 (i.e., which data item must be specified to specify).</br> - /// {d1:2: F2} indicates that a formatted string with a value specified separately is F2 (numericFormatter is used when numericFormatter is not specified).</br> - /// {d:0.##} indicates that a formatted string with a value specified separately is 0.## (used for percentage, reserved 2 valid digits while avoiding the situation similar to "100.00%" when using f2 ).</br> - /// Example: "{a}, {c}", "{a1}, {c1: f1}", "{a1}, {c1:0: f1}", "{a1} : {c1:1-1: f1}"</br> - /// |提示框单个serie或数据项内容的字符串模版格式器。支持用 \n 换行。 - /// 模板变量有{.}、{a}、{b}、{c}、{d}、{e}。</br> - /// {.}为当前所指示或index为0的serie的对应颜色的圆点。</br> - /// {a}为当前所指示或index为0的serie的系列名name。</br> - /// {b}为当前所指示或index为0的serie的数据项serieData的name,或者类目值(如折线图的X轴)。</br> - /// {c}为当前所指示或index为0的serie的y维(dimesion为1)的数值。</br> - /// {d}为当前所指示或index为0的serie的y维(dimesion为1)百分比值,注意不带%号。</br> - /// {e}为当前所指示或index为0的serie的数据项serieData的name。</br> - /// {f}为数据总和。</br> - /// {.1}表示指定index为1的serie对应颜色的圆点。</br> - /// {a1}、{b1}、{c1}中的1表示指定index为1的serie。</br> - /// {c1:2}表示索引为1的serie的当前指示数据项的第3个数据(一个数据项有多个数据,index为2表示第3个数据)。</br> - /// {c1:2-2}表示索引为1的serie的第3个数据项的第3个数据(也就是要指定第几个数据项时必须要指定第几个数据)。</br> - /// {d1:2:f2}表示单独指定了数值的格式化字符串为f2(不指定时用numericFormatter)。</br> - /// {d:0.##} 表示单独指定了数值的格式化字符串为 0.## (用于百分比,保留2位有效数同时又能避免使用 f2 而出现的类似于"100.00%"的情况 )。</br> - /// 示例:"{a}:{c}"、"{a1}:{c1:f1}"、"{a1}:{c1:0:f1}"、"{a1}:{c1:1-1:f1}" - /// </summary> - public string itemFormatter { get { return m_ItemFormatter; } set { m_ItemFormatter = value; } } - /// <summary> - /// the marker of serie. - /// |serie的符号标志。 - /// </summary> - public string marker { get { return m_Marker; } set { m_Marker = value; } } - /// <summary> - /// Fixed width. Higher priority than minWidth. - /// |固定宽度。比 minWidth 优先。 - /// </summary> - public float fixedWidth { get { return m_FixedWidth; } set { m_FixedWidth = value; } } - /// <summary> - /// Fixed height. Higher priority than minHeight. - /// |固定高度。比 minHeight 优先。 - /// </summary> - public float fixedHeight { get { return m_FixedHeight; } set { m_FixedHeight = value; } } - /// <summary> - /// Minimum width. If fixedWidth has a value, get fixedWidth first. - /// |最小宽度。如若 fixedWidth 设有值,优先取 fixedWidth。 - /// </summary> - public float minWidth { get { return m_MinWidth; } set { m_MinWidth = value; } } - /// <summary> - /// Minimum height. If fixedHeight has a value, take priority over fixedHeight. - /// |最小高度。如若 fixedHeight 设有值,优先取 fixedHeight。 - /// </summary> - public float minHeight { get { return m_MinHeight; } set { m_MinHeight = value; } } - /// <summary> - /// Standard numeric format string. Used to format numeric values to display as strings. - /// Using 'Axx' form: 'A' is the single character of the format specifier, supporting 'C' currency, - /// 'D' decimal, 'E' exponent, 'F' number of vertices, 'G' regular, 'N' digits, 'P' percentage, - /// 'R' round tripping, 'X' hex etc. 'XX' is the precision specification, from '0' - '99'. - /// |标准数字格式字符串。用于将数值格式化显示为字符串。 - /// 使用Axx的形式:A是格式说明符的单字符,支持C货币、D十进制、E指数、F定点数、G常规、N数字、P百分比、R往返、X十六进制的。xx是精度说明,从0-99。 - /// 参考:https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/standard-numeric-format-strings - /// </summary> - /// <value></value> - public string numericFormatter - { - get { return m_NumericFormatter; } - set { if (PropertyUtil.SetClass(ref m_NumericFormatter, value)) SetComponentDirty(); } - } - /// <summary> - /// the text padding of left and right. defaut:5. - /// |左右边距。 - /// </summary> - public int paddingLeftRight { get { return m_PaddingLeftRight; } set { m_PaddingLeftRight = value; } } - /// <summary> - /// the text padding of top and bottom. defaut:5. - /// |上下边距。 - /// </summary> - public int paddingTopBottom { get { return m_PaddingTopBottom; } set { m_PaddingTopBottom = value; } } - /// <summary> - /// Whether to show ignored data on tooltip. - /// |是否显示忽略数据在tooltip上。 - /// </summary> - public bool ignoreDataShow { get { return m_IgnoreDataShow; } set { m_IgnoreDataShow = value; } } - /// <summary> - /// The default display character information for ignored data. - /// |被忽略数据的默认显示字符信息。 - /// </summary> - public string ignoreDataDefaultContent { get { return m_IgnoreDataDefaultContent; } set { m_IgnoreDataDefaultContent = value; } } - /// <summary> - /// The background image of tooltip. - /// |提示框的背景图片。 - /// </summary> - public Sprite backgroundImage { get { return m_BackgroundImage; } set { m_BackgroundImage = value; SetComponentDirty(); } } - /// <summary> - /// The background type of tooltip. - /// |提示框的背景图片显示类型。 - /// </summary> - public Image.Type backgroundType { get { return m_BackgroundType; } set { m_BackgroundType = value; SetComponentDirty(); } } - /// <summary> - /// The background color of tooltip. - /// |提示框的背景颜色。 - /// </summary> - public Color backgroundColor { get { return m_BackgroundColor; } set { m_BackgroundColor = value; SetComponentDirty(); } } - /// <summary> - /// Whether to trigger after always display. - /// |是否触发后一直显示提示框浮层。 - /// </summary> - public bool alwayShowContent { get { return m_AlwayShowContent; } set { m_AlwayShowContent = value; } } - /// <summary> - /// 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. - /// |是否显示提示框浮层,默认显示。只需tooltip触发事件或显示axisPointer而不需要显示内容时可配置该项为false。 - /// </summary> - public bool showContent { get { return m_ShowContent; } set { m_ShowContent = value; } } - /// <summary> - /// The position offset of tooltip relative to the mouse position. - /// |提示框相对于鼠标位置的偏移。 - /// </summary> - public Vector2 offset { get { return m_Offset; } set { m_Offset = value; } } - /// <summary> - /// the width of tooltip border. - /// |边框线宽。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of tooltip border. - /// |边框颜色。 - /// </summary> - public Color32 borderColor - { - get { return m_BorderColor; } - set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// enable fixedX. - /// |是否固定X位置。 - /// </summary> - public bool fixedXEnable - { - get { return m_FixedXEnable; } - set { if (PropertyUtil.SetStruct(ref m_FixedXEnable, value)) SetVerticesDirty(); } - } - /// <summary> - /// the x positionn of fixedX. - /// |固定X位置的坐标。 - /// </summary> - public float fixedX - { - get { return m_FixedX; } - set { if (PropertyUtil.SetStruct(ref m_FixedX, value)) SetVerticesDirty(); } - } - /// <summary> - /// enable fixedY. - /// |是否固定Y位置。 - /// </summary> - public bool fixedYEnable - { - get { return m_FixedYEnable; } - set { if (PropertyUtil.SetStruct(ref m_FixedYEnable, value)) SetVerticesDirty(); } - } - /// <summary> - /// the y position of fixedY. - /// |固定Y位置的坐标。 - /// </summary> - public float fixedY - { - get { return m_FixedY; } - set { if (PropertyUtil.SetStruct(ref m_FixedY, value)) SetVerticesDirty(); } - } - /// <summary> - /// height of title text. - /// |标题文本的高。 - /// </summary> - public float titleHeight - { - get { return m_TitleHeight; } - set { if (PropertyUtil.SetStruct(ref m_TitleHeight, value)) SetComponentDirty(); } - } - /// <summary> - /// height of content text. - /// |数据项文本的高。 - /// </summary> - public float itemHeight - { - get { return m_ItemHeight; } - set { if (PropertyUtil.SetStruct(ref m_ItemHeight, value)) SetComponentDirty(); } - } - /// <summary> - /// the label style of tooltip axis indicator label. - /// |提示框的坐标轴指示器文本的样式。 - /// </summary> - public LabelStyle indicatorLabelStyle - { - get { return m_IndicatorLabelStyle; } - set { if (value != null) { m_IndicatorLabelStyle = value; SetComponentDirty(); } } - } - /// <summary> - /// the textstyle of title. - /// |标题的文本样式。 - /// </summary> - public LabelStyle titleLabelStyle - { - get { return m_TitleLabelStyle; } - set { if (value != null) { m_TitleLabelStyle = value; SetComponentDirty(); } } - } - /// <summary> - /// the textstyle list of content. - /// |内容部分的文本样式列表。和列一一对应。 - /// </summary> - public List<LabelStyle> contentLabelStyles - { - get { return m_ContentLabelStyles; } - set { if (value != null) { m_ContentLabelStyles = value; SetComponentDirty(); } } - } - - /// <summary> - /// the line style of indicator line. - /// |指示线样式。 - /// </summary> - public LineStyle lineStyle - { - get { return m_LineStyle; } - set { if (value != null) m_LineStyle = value; SetComponentDirty(); } - } - - /// <summary> - /// 组件是否需要刷新 - /// </summary> - public override bool componentDirty - { - get { return m_ComponentDirty || lineStyle.componentDirty || indicatorLabelStyle.componentDirty; } - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - lineStyle.ClearComponentDirty(); - indicatorLabelStyle.ClearComponentDirty(); - } - /// <summary> - /// 当前提示框所指示的Serie索引(目前只对散点图有效)。 - /// </summary> - public Dictionary<int, List<int>> runtimeSerieIndex = new Dictionary<int, List<int>>(); - /// <summary> - /// The data index currently indicated by Tooltip. - /// |当前提示框所指示的数据项索引。 - /// </summary> - public List<int> runtimeDataIndex { get { return m_RuntimeDateIndex; } internal set { m_RuntimeDateIndex = value; } } - private List<int> m_RuntimeDateIndex = new List<int>() {-1, -1 }; - - /// <summary> - /// Keep Tooltiop displayed at the top. - /// |保持Tooltiop显示在最顶上 - /// </summary> - public void KeepTop() - { - gameObject.transform.SetAsLastSibling(); - } - - public override void ClearData() - { - ClearValue(); - } - - /// <summary> - /// 清除提示框指示数据 - /// </summary> - internal void ClearValue() - { - for (int i = 0; i < runtimeDataIndex.Count; i++) runtimeDataIndex[i] = -1; - } - - /// <summary> - /// 提示框是否显示 - /// </summary> - /// <returns></returns> - public bool IsActive() - { - return gameObject != null && gameObject.activeInHierarchy; - } - - /// <summary> - /// 设置Tooltip组件是否显示 - /// </summary> - /// <param name="flag"></param> - public void SetActive(bool flag) - { - if (gameObject && gameObject.activeInHierarchy != flag) - { - gameObject.SetActive(alwayShowContent ? true : flag); - } - SetContentActive(flag); - } - - /// <summary> - /// 更新文本框位置 - /// </summary> - /// <param name="pos"></param> - public void UpdateContentPos(Vector2 pos) - { - if (view != null) - { - if (fixedXEnable) pos.x = fixedX; - if (fixedYEnable) pos.y = fixedY; - view.UpdatePosition(pos); - } - } - - /// <summary> - /// 设置文本框是否显示 - /// </summary> - /// <param name="flag"></param> - public void SetContentActive(bool flag) - { - if (view == null) - return; - - view.SetActive(alwayShowContent ? true : flag); - } - - /// <summary> - /// 当前提示框是否选中数据项 - /// </summary> - /// <returns></returns> - public bool IsSelected() - { - foreach (var index in runtimeDataIndex) - if (index >= 0) return true; - return false; - } - - /// <summary> - /// 指定索引的数据项是否被提示框选中 - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public bool IsSelected(int index) - { - foreach (var temp in runtimeDataIndex) - if (temp == index) return true; - return false; - } - - public void ClearSerieDataIndex() - { - foreach (var kv in runtimeSerieIndex) - { - kv.Value.Clear(); - } - } - - public void AddSerieDataIndex(int serieIndex, int dataIndex) - { - if (!runtimeSerieIndex.ContainsKey(serieIndex)) - { - runtimeSerieIndex[serieIndex] = new List<int>(); - } - runtimeSerieIndex[serieIndex].Add(dataIndex); - } - - public bool isAnySerieDataIndex() - { - foreach (var kv in runtimeSerieIndex) - { - if (kv.Value.Count > 0) return true; - } - return false; - } - - public bool IsTriggerItem() - { - return trigger == Trigger.Item; - } - - public bool IsTriggerAxis() - { - return trigger == Trigger.Axis; - } - - public LabelStyle GetContentLabelStyle(int index) - { - if (m_ContentLabelStyles.Count == 0) - return null; - - if (index < 0) - index = 0; - else if (index > m_ContentLabelStyles.Count - 1) - index = m_ContentLabelStyles.Count - 1; - - return m_ContentLabelStyles[index]; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs.meta b/Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs.meta deleted file mode 100644 index 441a06e..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/Tooltip.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dff3b0d6d38ee49838f054d30ab9b733 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs b/Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs deleted file mode 100644 index f00c7d0..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - public class TooltipData - { - public string title; - public List<SerieParams> param = new List<SerieParams>(); - } - - public class TooltipContext - { - public Vector2 pointer; - public float width; - public float height; - public float angle; - public TooltipData data = new TooltipData(); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs.meta b/Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs.meta deleted file mode 100644 index 2dd6ed0..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7324ce36c9b2c475bb18abd6618b107c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs b/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs deleted file mode 100644 index e55d367..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs +++ /dev/null @@ -1,641 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class TooltipHandler : MainComponentHandler<Tooltip> - { - private List<ChartLabel> m_IndicatorLabels = new List<ChartLabel>(); - private GameObject m_LabelRoot; - private ISerieContainer m_PointerContainer; - - public override void InitComponent() - { - InitTooltip(component); - } - - public override void Update() - { - UpdateTooltip(component); - UpdateTooltipIndicatorLabelText(component); - if (component.view != null) - component.view.Update(); - } - - public override void DrawTop(VertexHelper vh) - { - DrawTooltipIndicator(vh, component); - } - - private void InitTooltip(Tooltip tooltip) - { - tooltip.painter = chart.m_PainterTop; - tooltip.refreshComponent = delegate() - { - var objName = ChartCached.GetComponentObjectName(tooltip); - tooltip.gameObject = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - var tooltipObject = tooltip.gameObject; - tooltipObject.transform.localPosition = Vector3.zero; - tooltipObject.hideFlags = chart.chartHideFlags; - var parent = tooltipObject.transform; - ChartHelper.HideAllObject(tooltipObject.transform); - - tooltip.view = TooltipView.CreateView(tooltip, chart.theme, parent); - tooltip.SetActive(false); - - m_LabelRoot = ChartHelper.AddObject("label", tooltip.gameObject.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - ChartHelper.HideAllObject(m_LabelRoot); - m_IndicatorLabels.Clear(); - for (int i = 0; i < 2; i++) - { - var labelName = "label_" + i; - var item = ChartHelper.AddTooltipIndicatorLabel(component, labelName, m_LabelRoot.transform, - chart.theme, TextAnchor.MiddleCenter); - item.SetActive(false); - m_IndicatorLabels.Add(item); - } - }; - tooltip.refreshComponent(); - } - - private ChartLabel GetIndicatorLabel(int index) - { - if (m_LabelRoot == null) return null; - if (index < m_IndicatorLabels.Count) return m_IndicatorLabels[index]; - else - { - var labelName = "label_" + index; - var item = ChartHelper.AddTooltipIndicatorLabel(component, labelName, m_LabelRoot.transform, - chart.theme, TextAnchor.MiddleCenter); - m_IndicatorLabels.Add(item); - return item; - } - } - - private void UpdateTooltip(Tooltip tooltip) - { - if (tooltip.trigger == Tooltip.Trigger.None) return; - if (!chart.isPointerInChart || !tooltip.show) - { - if (tooltip.IsActive()) - { - tooltip.ClearValue(); - tooltip.SetActive(false); - } - return; - } - var showTooltip = false; - for (int i = chart.series.Count - 1; i >= 0; i--) - { - var serie = chart.series[i]; - if (!(serie is INeedSerieContainer)) - { - if (SetSerieTooltip(tooltip, serie)) - { - showTooltip = true; - chart.RefreshTopPainter(); - return; - } - } - } - var containerSeries = ListPool<Serie>.Get(); - m_PointerContainer = GetPointerContainerAndSeries(tooltip, containerSeries); - if (containerSeries.Count > 0) - { - if (SetSerieTooltip(tooltip, containerSeries)) - showTooltip = true; - } - ListPool<Serie>.Release(containerSeries); - if (!showTooltip) - { - if (tooltip.type == Tooltip.Type.Corss && m_PointerContainer != null && m_PointerContainer.IsPointerEnter()) - { - tooltip.SetActive(true); - tooltip.SetContentActive(false); - } - else - { - tooltip.SetActive(false); - } - } - else - { - chart.RefreshTopPainter(); - } - } - - private void UpdateTooltipIndicatorLabelText(Tooltip tooltip) - { - if (!tooltip.show) return; - if (tooltip.type == Tooltip.Type.None) return; - if (m_PointerContainer != null) - { - if (tooltip.type == Tooltip.Type.Corss) - { - var labelCount = 0; - if (m_PointerContainer is GridCoord) - { - var grid = m_PointerContainer as GridCoord; - ChartHelper.HideAllObject(m_LabelRoot); - foreach (var component in chart.components) - { - if (component is XAxis || component is YAxis) - { - var axis = component as Axis; - if (axis.gridIndex == grid.index) - { - var label = GetIndicatorLabel(labelCount++); - SetTooltipIndicatorLabel(tooltip, axis, label); - } - } - } - } - else if (m_PointerContainer is PolarCoord) - { - var polar = m_PointerContainer as PolarCoord; - ChartHelper.HideAllObject(m_LabelRoot); - foreach (var component in chart.components) - { - if (component is AngleAxis || component is RadiusAxis) - { - var axis = component as Axis; - if (axis.polarIndex == polar.index) - { - var label = GetIndicatorLabel(labelCount++); - SetTooltipIndicatorLabel(tooltip, axis, label); - } - } - } - } - } - } - } - - private void SetTooltipIndicatorLabel(Tooltip tooltip, Axis axis, ChartLabel label) - { - if (label == null) return; - if (double.IsPositiveInfinity(axis.context.pointerValue)) return; - label.SetActive(true); - label.SetTextActive(true); - label.SetPosition(axis.context.pointerLabelPosition); - if (axis.IsCategory()) - label.SetText(axis.GetData((int) axis.context.pointerValue)); - else - label.SetText(axis.context.pointerValue.ToString("f2")); - var textColor = axis.axisLabel.textStyle.GetColor(chart.theme.axis.textColor); - if (ChartHelper.IsClearColor(tooltip.indicatorLabelStyle.background.color)) - label.color = textColor; - else - label.color = tooltip.indicatorLabelStyle.background.color; - label.SetTextColor(Color.white); - } - - private ISerieContainer GetPointerContainerAndSeries(Tooltip tooltip, List<Serie> list) - { - list.Clear(); - for (int i = chart.components.Count - 1; i >= 0; i--) - { - var component = chart.components[i]; - if (component is ISerieContainer) - { - var container = component as ISerieContainer; - if (container.IsPointerEnter()) - { - foreach (var serie in chart.series) - { - if (serie is INeedSerieContainer && - (serie as INeedSerieContainer).containterInstanceId == component.instanceId) - { - var isTriggerAxis = tooltip.IsTriggerAxis(); - if (container is GridCoord) - { - var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - var yAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - serie.context.pointerEnter = true; - UpdateAxisPointerDataIndex(serie, xAxis, yAxis, container as GridCoord, isTriggerAxis); - } - else if (container is PolarCoord) - { - var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, container.index); - tooltip.context.angle = (float) m_AngleAxis.context.pointerValue; - } - list.Add(serie); - if (!isTriggerAxis) - chart.RefreshTopPainter(); - } - } - return container; - } - } - } - return null; - } - - private void UpdateAxisPointerDataIndex(Serie serie, XAxis xAxis, YAxis yAxis, GridCoord grid, bool isTriggerAxis) - { - serie.context.pointerAxisDataIndexs.Clear(); - if (yAxis.IsCategory()) - { - serie.context.pointerAxisDataIndexs.Add((int) yAxis.context.pointerValue); - yAxis.context.axisTooltipValue = yAxis.context.pointerValue; - } - else if (yAxis.IsTime()) - { - if (isTriggerAxis) - GetSerieDataIndexByAxis(serie, yAxis, grid); - else - GetSerieDataIndexByItem(serie, yAxis, grid); - } - else if (xAxis.IsCategory()) - { - serie.context.pointerAxisDataIndexs.Add((int) xAxis.context.pointerValue); - xAxis.context.axisTooltipValue = xAxis.context.pointerValue; - } - else - { - if (isTriggerAxis) - GetSerieDataIndexByAxis(serie, xAxis, grid); - else - GetSerieDataIndexByItem(serie, xAxis, grid); - } - } - - private void GetSerieDataIndexByAxis(Serie serie, Axis axis, GridCoord grid, int dimension = 0) - { - var currValue = 0d; - var lastValue = 0d; - var nextValue = 0d; - var axisValue = axis.context.pointerValue; - var isTimeAxis = axis.IsTime(); - var dataCount = serie.dataCount; - var themeSymbolSize = chart.theme.serie.scatterSymbolSize; - var data = serie.data; - if (!isTimeAxis) - { - serie.context.sortedData.Clear(); - for (int i = 0; i < dataCount; i++) - { - var serieData = serie.data[i]; - serieData.index = i; - serie.context.sortedData.Add(serieData); - } - serie.context.sortedData.Sort(delegate(SerieData a, SerieData b) - { - return a.GetData(dimension).CompareTo(b.GetData(dimension)); - }); - data = serie.context.sortedData; - } - serie.context.pointerAxisDataIndexs.Clear(); - for (int i = 0; i < dataCount; i++) - { - var serieData = data[i]; - currValue = serieData.GetData(dimension); - if (i == 0) - { - nextValue = data[i + 1].GetData(dimension); - if (axisValue <= currValue + (nextValue - currValue) / 2) - { - serie.context.pointerAxisDataIndexs.Add(serieData.index); - break; - } - } - else if (i == dataCount - 1) - { - if (axisValue > lastValue + (currValue - lastValue) / 2) - { - serie.context.pointerAxisDataIndexs.Add(serieData.index); - break; - } - } - else - { - nextValue = data[i + 1].GetData(dimension); - if (axisValue > (currValue - (currValue - lastValue) / 2) && axisValue <= currValue + (nextValue - currValue) / 2) - { - serie.context.pointerAxisDataIndexs.Add(serieData.index); - break; - } - } - lastValue = currValue; - } - if (serie.context.pointerAxisDataIndexs.Count > 0) - { - var index = serie.context.pointerAxisDataIndexs[0]; - serie.context.pointerItemDataIndex = index; - axis.context.axisTooltipValue = serie.GetSerieData(index).GetData(dimension); - } - else - { - serie.context.pointerItemDataIndex = -1; - axis.context.axisTooltipValue = 0; - } - } - - private void GetSerieDataIndexByItem(Serie serie, Axis axis, GridCoord grid, int dimension = 0) - { - if (serie.context.pointerItemDataIndex >= 0) - { - axis.context.axisTooltipValue = serie.GetSerieData(serie.context.pointerItemDataIndex).GetData(dimension); - } - else if (component.type == Tooltip.Type.Corss) - { - axis.context.axisTooltipValue = axis.context.pointerValue; - } - else - { - axis.context.axisTooltipValue = 0; - } - } - - private bool SetSerieTooltip(Tooltip tooltip, Serie serie) - { - if (tooltip.trigger == Tooltip.Trigger.None) return false; - if (serie.context.pointerItemDataIndex < 0) return false; - - tooltip.context.data.param.Clear(); - tooltip.context.data.title = serie.serieName; - tooltip.context.pointer = chart.pointerPos; - - serie.handler.UpdateTooltipSerieParams(serie.context.pointerItemDataIndex, false, null, - tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter, - ref tooltip.context.data.param, - ref tooltip.context.data.title); - TooltipHelper.ResetTooltipParamsByItemFormatter(tooltip, chart); - - tooltip.SetActive(true); - tooltip.view.Refresh(); - TooltipHelper.LimitInRect(tooltip, chart.chartRect); - return true; - } - - private bool SetSerieTooltip(Tooltip tooltip, List<Serie> series) - { - if (tooltip.trigger == Tooltip.Trigger.None) - return false; - - if (series.Count <= 0) - return false; - - string category = null; - var showCategory = false; - var isTriggerByAxis = false; - var dataIndex = -1; - tooltip.context.data.param.Clear(); - tooltip.context.pointer = chart.pointerPos; - if (m_PointerContainer is GridCoord) - { - if (tooltip.trigger == Tooltip.Trigger.Axis) - { - isTriggerByAxis = true; - GetAxisCategory(m_PointerContainer.index, ref dataIndex, ref category); - if (series.Count <= 1) - { - showCategory = true; - tooltip.context.data.title = series[0].serieName; - } - else - tooltip.context.data.title = category; - } - } - - for (int i = 0; i < series.Count; i++) - { - var serie = series[i]; - serie.context.isTriggerByAxis = isTriggerByAxis; - if (isTriggerByAxis && dataIndex >= 0) - serie.context.pointerItemDataIndex = dataIndex; - serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category, - tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter, - ref tooltip.context.data.param, - ref tooltip.context.data.title); - } - TooltipHelper.ResetTooltipParamsByItemFormatter(tooltip, chart); - if (tooltip.context.data.param.Count > 0) - { - tooltip.SetActive(true); - if (tooltip.view != null) - tooltip.view.Refresh(); - TooltipHelper.LimitInRect(tooltip, chart.chartRect); - return true; - } - return false; - } - - private bool GetAxisCategory(int gridIndex, ref int dataIndex, ref string category) - { - foreach (var component in chart.components) - { - if (component is Axis) - { - var axis = component as Axis; - if (axis.gridIndex == gridIndex && axis.IsCategory()) - { - dataIndex = (int) axis.context.pointerValue; - category = axis.GetData(dataIndex); - return true; - } - } - } - return false; - } - - private void DrawTooltipIndicator(VertexHelper vh, Tooltip tooltip) - { - if (!tooltip.show) return; - if (tooltip.type == Tooltip.Type.None) return; - if (m_PointerContainer is GridCoord) - { - var grid = m_PointerContainer as GridCoord; - if (!grid.context.isPointerEnter) return; - if (IsYCategoryOfGrid(grid.index)) - DrawYAxisIndicator(vh, tooltip, grid); - else - DrawXAxisIndicator(vh, tooltip, grid); - } - else if (m_PointerContainer is PolarCoord) - { - DrawPolarIndicator(vh, tooltip, m_PointerContainer as PolarCoord); - } - } - - private bool IsYCategoryOfGrid(int gridIndex) - { - var yAxes = chart.GetChartComponents<YAxis>(); - foreach (var component in yAxes) - { - var yAxis = component as YAxis; - if (yAxis.gridIndex == gridIndex && yAxis.IsCategory()) return true; - } - return false; - } - - private void DrawXAxisIndicator(VertexHelper vh, Tooltip tooltip, GridCoord grid) - { - var xAxes = chart.GetChartComponents<XAxis>(); - var lineType = tooltip.lineStyle.GetType(chart.theme.tooltip.lineType); - var lineWidth = tooltip.lineStyle.GetWidth(chart.theme.tooltip.lineWidth); - foreach (var component in xAxes) - { - var xAxis = component as XAxis; - if (xAxis.gridIndex == grid.index) - { - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - int dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0; - float splitWidth = AxisHelper.GetDataWidth(xAxis, grid.context.width, dataCount, dataZoom); - switch (tooltip.type) - { - case Tooltip.Type.Corss: - case Tooltip.Type.Line: - float pX = grid.context.x; - pX += xAxis.IsCategory() ? - (float) (xAxis.context.pointerValue * splitWidth + (xAxis.boundaryGap ? splitWidth / 2 : 0)) : - xAxis.GetDistance(xAxis.context.axisTooltipValue, grid.context.width); - Vector2 sp = new Vector2(pX, grid.context.y); - Vector2 ep = new Vector2(pX, grid.context.y + grid.context.height); - var lineColor = TooltipHelper.GetLineColor(tooltip, chart.theme); - // if (xAxis.IsCategory() && tooltip.type == Tooltip.Type.Corss) - // { - // float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth; - // pX = (float)(grid.context.x + splitWidth * xAxis.context.pointerValue - - // (xAxis.boundaryGap ? 0 : splitWidth / 2)); - // float pY = grid.context.y + grid.context.height; - // Vector3 p1 = new Vector3(pX, grid.context.y); - // Vector3 p2 = new Vector3(pX, pY); - // Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY); - // Vector3 p4 = new Vector3(pX + tooltipSplitWid, grid.context.y); - // UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor); - // } - // else - { - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor); - } - if (tooltip.type == Tooltip.Type.Corss) - { - sp = new Vector2(grid.context.x, chart.pointerPos.y); - ep = new Vector2(grid.context.x + grid.context.width, chart.pointerPos.y); - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor); - } - break; - case Tooltip.Type.Shadow: - if (xAxis.IsCategory()) - { - float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth; - pX = (float) (grid.context.x + splitWidth * xAxis.context.pointerValue - - (xAxis.boundaryGap ? 0 : splitWidth / 2)); - float pY = grid.context.y + grid.context.height; - Vector3 p1 = new Vector3(pX, grid.context.y); - Vector3 p2 = new Vector3(pX, pY); - Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY); - Vector3 p4 = new Vector3(pX + tooltipSplitWid, grid.context.y); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor); - } - break; - } - } - } - } - private void DrawYAxisIndicator(VertexHelper vh, Tooltip tooltip, GridCoord grid) - { - var yAxes = chart.GetChartComponents<YAxis>(); - var lineType = tooltip.lineStyle.GetType(chart.theme.tooltip.lineType); - var lineWidth = tooltip.lineStyle.GetWidth(chart.theme.tooltip.lineWidth); - - foreach (var component in yAxes) - { - var yAxis = component as YAxis; - if (yAxis.gridIndex == grid.index) - { - var dataZoom = chart.GetDataZoomOfAxis(yAxis); - int dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0; - float splitWidth = AxisHelper.GetDataWidth(yAxis, grid.context.height, dataCount, dataZoom); - switch (tooltip.type) - { - case Tooltip.Type.Corss: - case Tooltip.Type.Line: - float pY = (float) (grid.context.y + yAxis.context.pointerValue * splitWidth + - (yAxis.boundaryGap ? splitWidth / 2 : 0)); - Vector2 sp = new Vector2(grid.context.x, pY); - Vector2 ep = new Vector2(grid.context.x + grid.context.width, pY); - var lineColor = TooltipHelper.GetLineColor(tooltip, chart.theme); - // if (yAxis.IsCategory() && tooltip.type == Tooltip.Type.Corss) - // { - // float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth; - // float pX = grid.context.x + grid.context.width; - // pY = (float)(grid.context.y + splitWidth * yAxis.context.pointerValue - - // (yAxis.boundaryGap ? 0 : splitWidth / 2)); - // Vector3 p1 = new Vector3(grid.context.x, pY); - // Vector3 p2 = new Vector3(grid.context.x, pY + tooltipSplitWid); - // Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid); - // Vector3 p4 = new Vector3(pX, pY); - // UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor); - // } - // else - { - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor); - } - if (tooltip.type == Tooltip.Type.Corss) - { - sp = new Vector2(chart.pointerPos.x, grid.context.y); - ep = new Vector2(chart.pointerPos.x, grid.context.y + grid.context.height); - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor); - } - break; - case Tooltip.Type.Shadow: - if (yAxis.IsCategory()) - { - float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth; - float pX = grid.context.x + grid.context.width; - pY = (float) (grid.context.y + splitWidth * yAxis.context.pointerValue - - (yAxis.boundaryGap ? 0 : splitWidth / 2)); - Vector3 p1 = new Vector3(grid.context.x, pY); - Vector3 p2 = new Vector3(grid.context.x, pY + tooltipSplitWid); - Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid); - Vector3 p4 = new Vector3(pX, pY); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor); - } - break; - } - } - } - } - - private void DrawPolarIndicator(VertexHelper vh, Tooltip tooltip, PolarCoord m_Polar) - { - if (tooltip.context.angle < 0) return; - var theme = chart.theme; - var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_Polar.index); - var lineColor = TooltipHelper.GetLineColor(tooltip, theme); - var lineType = tooltip.lineStyle.GetType(theme.tooltip.lineType); - var lineWidth = tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth); - var cenPos = m_Polar.context.center; - var radius = m_Polar.context.radius; - var sp = m_Polar.context.center; - var tooltipAngle = m_AngleAxis.GetValueAngle(tooltip.context.angle); - - var ep = ChartHelper.GetPos(sp, radius, tooltipAngle, true); - - switch (tooltip.type) - { - case Tooltip.Type.Corss: - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor); - var dist = Vector2.Distance(chart.pointerPos, cenPos); - if (dist > radius) dist = radius; - var outsideRaidus = dist + tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth) * 2; - UGL.DrawDoughnut(vh, cenPos, dist, outsideRaidus, lineColor, Color.clear); - break; - case Tooltip.Type.Line: - ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor); - break; - case Tooltip.Type.Shadow: - UGL.DrawSector(vh, cenPos, radius, lineColor, tooltipAngle - 2, tooltipAngle + 2, chart.settings.cicleSmoothness); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs.meta b/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs.meta deleted file mode 100644 index 7fb5702..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7d25a5b5e3d6f45b8a06b94e33792087 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs b/Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs deleted file mode 100644 index 9e099bd..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class TooltipHelper - { - internal static void ResetTooltipParamsByItemFormatter(Tooltip tooltip, BaseChart chart) - { - if (!string.IsNullOrEmpty(tooltip.titleFormatter)) - { - if (tooltip.titleFormatter.Equals("{i}", StringComparison.CurrentCultureIgnoreCase)) - { - tooltip.context.data.title = string.Empty; - } - else - { - tooltip.context.data.title = tooltip.titleFormatter; - FormatterHelper.ReplaceContent(ref tooltip.context.data.title, 0, - tooltip.numericFormatter, null, chart); - } - } - for (int i = tooltip.context.data.param.Count - 1; i >= 0; i--) - { - var param = tooltip.context.data.param[i]; - if (TooltipHelper.IsIgnoreItemFormatter(param.itemFormatter)) - { - tooltip.context.data.param.RemoveAt(i); - } - } - foreach (var param in tooltip.context.data.param) - { - if (!string.IsNullOrEmpty(param.itemFormatter)) - { - param.columns.Clear(); - var content = param.itemFormatter; - FormatterHelper.ReplaceSerieLabelContent(ref content, - param.numericFormatter, - param.dataCount, - param.value, - param.total, - param.serieName, - param.category, - param.serieData.name, - param.color); - foreach (var item in content.Split('|')) - { - param.columns.Add(item); - } - } - } - } - - public static bool IsIgnoreItemFormatter(string itemFormatter) - { - return "-".Equals(itemFormatter); - } - - public static void LimitInRect(Tooltip tooltip, Rect chartRect) - { - if (tooltip.view == null) - return; - - var pos = tooltip.view.GetTargetPos(); - if (pos.x + tooltip.context.width > chartRect.x + chartRect.width) - { - //pos.x = chartRect.x + chartRect.width - tooltip.context.width; - pos.x = pos.x - tooltip.context.width - tooltip.offset.x; - } - if (pos.y - tooltip.context.height < chartRect.y) - { - pos.y = chartRect.y + tooltip.context.height; - } - tooltip.UpdateContentPos(pos); - } - - public static string GetItemNumericFormatter(Tooltip tooltip, Serie serie, SerieData serieData) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - if (!string.IsNullOrEmpty(itemStyle.numericFormatter)) return itemStyle.numericFormatter; - else return tooltip.numericFormatter; - } - - public static Color32 GetLineColor(Tooltip tooltip, ThemeStyle theme) - { - var lineStyle = tooltip.lineStyle; - if (!ChartHelper.IsClearColor(lineStyle.color)) - { - return lineStyle.GetColor(); - } - else - { - var color = theme.tooltip.lineColor; - ChartHelper.SetColorOpacity(ref color, lineStyle.opacity); - return color; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs.meta b/Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs.meta deleted file mode 100644 index 169f2a5..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 184e190de6da6486b8b4d333a302477a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs b/Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs deleted file mode 100644 index 2fe075f..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs +++ /dev/null @@ -1,270 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - public class TooltipViewItem - { - public GameObject gameObject; - public List<ChartLabel> columns = new List<ChartLabel>(); - } - public class TooltipView - { - private static Vector2 anchorMax = new Vector2(0, 1); - private static Vector2 anchorMin = new Vector2(0, 1); - private static Vector2 pivot = new Vector2(0, 1); - private static Vector2 v2_0_05 = new Vector2(0, 0.5f); - - public Tooltip tooltip; - public ComponentTheme theme; - public GameObject gameObject; - public Transform transform; - public Image background; - public Outline border; - public VerticalLayoutGroup layout; - public ChartLabel title; - private List<TooltipViewItem> m_Items = new List<TooltipViewItem>(); - private List<float> m_ColumnMaxWidth = new List<float>(); - private bool m_Active = false; - private Vector3 m_TargetPos; - private Vector3 m_CurrentVelocity; - - public void Update() - { - if (!m_Active) - return; - transform.localPosition = Vector3.SmoothDamp(transform.localPosition, m_TargetPos, ref m_CurrentVelocity, 0.08f); - } - - public Vector3 GetCurrentPos() - { - return transform.localPosition; - } - - public Vector3 GetTargetPos() - { - return m_TargetPos; - } - - public void UpdatePosition(Vector3 pos) - { - m_TargetPos = pos; - } - - public void SetActive(bool flag) - { - m_Active = flag && tooltip.showContent; - ChartHelper.SetActive(gameObject, m_Active); - } - - public void Refresh() - { - if (tooltip == null) return; - var data = tooltip.context.data; - - var titleActive = !string.IsNullOrEmpty(data.title); - if (titleActive != title.gameObject.activeSelf) - title.gameObject.SetActive(titleActive); - title.SetText(data.title); - - m_ColumnMaxWidth.Clear(); - for (int i = 0; i < data.param.Count; i++) - { - var item = GetItem(i); - var param = data.param[i]; - if (param.columns.Count <= 0) - { - item.gameObject.SetActive(false); - continue; - } - item.gameObject.SetActive(true); - for (int j = 0; j < param.columns.Count; j++) - { - var column = GetItemColumn(item, j); - column.SetActive(true); - column.SetText(param.columns[j]); - - if (j == 0) - column.text.SetColor(param.color); - - if (j >= m_ColumnMaxWidth.Count) - m_ColumnMaxWidth.Add(0); - - var columnWidth = column.GetWidth(); - if (m_ColumnMaxWidth[j] < columnWidth) - m_ColumnMaxWidth[j] = columnWidth; - } - for (int j = param.columns.Count; j < item.columns.Count; j++) - { - item.columns[j].SetActive(false); - } - } - for (int i = data.param.Count; i < m_Items.Count; i++) - { - m_Items[i].gameObject.SetActive(false); - } - ResetSize(); - // border.effectColor = data.param.Count == 1 - // ? data.param[0].color - // : tooltip.borderColor; - UpdatePosition(tooltip.context.pointer + tooltip.offset); - tooltip.gameObject.transform.SetAsLastSibling(); - } - - private void ResetSize() - { - var maxHig = 0f; - var maxWid = 0f; - if (tooltip.fixedWidth > 0) - { - maxWid = tooltip.fixedWidth; - } - else - { - maxWid = TotalMaxWidth(); - var titleWid = title.GetTextWidth(); - if (maxWid < titleWid) - maxWid = titleWid; - } - - if (tooltip.fixedHeight > 0) - { - maxHig = tooltip.fixedHeight; - } - else - { - if (!string.IsNullOrEmpty(title.text.GetText())) - maxHig += tooltip.titleHeight; - maxHig += tooltip.itemHeight * tooltip.context.data.param.Count; - maxHig += tooltip.paddingTopBottom * 2; - } - - if (tooltip.minWidth > 0 && maxWid < tooltip.minWidth) - maxWid = tooltip.minWidth; - - if (tooltip.minHeight > 0 && maxHig < tooltip.minHeight) - maxHig = tooltip.minHeight; - - for (int i = 0; i < m_Items.Count; i++) - { - var item = m_Items[i]; - item.gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(maxWid, tooltip.itemHeight); - var xPos = 0f; - for (int j = 0; j < m_ColumnMaxWidth.Count; j++) - { - var deltaX = j == m_ColumnMaxWidth.Count - 1 ? maxWid - xPos : m_ColumnMaxWidth[j]; - item.columns[j].text.SetSizeDelta(new Vector2(deltaX, tooltip.itemHeight)); - item.columns[j].SetRectPosition(new Vector3(xPos, 0)); - xPos += m_ColumnMaxWidth[j]; - } - } - tooltip.context.width = maxWid + tooltip.paddingLeftRight * 2; - tooltip.context.height = maxHig; - background.GetComponent<RectTransform>().sizeDelta = new Vector2(tooltip.context.width, tooltip.context.height); - } - - private float TotalMaxWidth() - { - var total = 0f; - foreach (var max in m_ColumnMaxWidth) - total += max; - return total; - } - - private TooltipViewItem GetItem(int i) - { - if (i < 0) i = 0; - if (i < m_Items.Count) - { - return m_Items[i]; - } - else - { - var item = CreateViewItem(i, gameObject.transform, tooltip, theme); - m_Items.Add(item); - return item; - } - } - - private ChartLabel GetItemColumn(TooltipViewItem item, int i) - { - if (i < 0) i = 0; - if (i < item.columns.Count) - { - return item.columns[i]; - } - else - { - var column = CreateViewItemColumn(i, item.gameObject.transform, tooltip, theme); - item.columns.Add(column); - return column; - } - } - - public static TooltipView CreateView(Tooltip tooltip, ThemeStyle theme, Transform parent) - { - var view = new TooltipView(); - view.tooltip = tooltip; - view.theme = theme.tooltip; - - view.gameObject = ChartHelper.AddObject("view", parent, anchorMin, anchorMax, pivot, Vector3.zero); - view.gameObject.transform.localPosition = Vector3.zero; - view.transform = view.gameObject.transform; - - view.background = ChartHelper.GetOrAddComponent<Image>(view.gameObject); - view.background.sprite = tooltip.backgroundImage; - view.background.type = tooltip.backgroundType; - view.background.color = ChartHelper.IsClearColor(tooltip.backgroundColor) ? - Color.white : tooltip.backgroundColor; - - view.border = ChartHelper.GetOrAddComponent<Outline>(view.gameObject); - view.border.enabled = tooltip.borderWidth > 0; - view.border.useGraphicAlpha = false; - view.border.effectColor = tooltip.borderColor; - view.border.effectDistance = new Vector2(tooltip.borderWidth, -tooltip.borderWidth); - - view.layout = ChartHelper.GetOrAddComponent<VerticalLayoutGroup>(view.gameObject); - view.layout.childControlHeight = false; - view.layout.childControlWidth = false; - view.layout.childForceExpandHeight = false; - view.layout.childForceExpandWidth = false; - view.layout.padding = new RectOffset(tooltip.paddingLeftRight, - tooltip.paddingLeftRight, - tooltip.paddingTopBottom, - tooltip.paddingTopBottom); - - view.title = ChartHelper.AddChartLabel("title", view.gameObject.transform, tooltip.titleLabelStyle, theme.tooltip, - "", Color.clear, TextAnchor.MiddleLeft); - - var item = CreateViewItem(0, view.gameObject.transform, tooltip, theme.tooltip); - view.m_Items.Add(item); - - view.Refresh(); - - return view; - } - - private static TooltipViewItem CreateViewItem(int i, Transform parent, Tooltip tooltip, ComponentTheme theme) - { - GameObject item1 = ChartHelper.AddObject("item" + i, parent, anchorMin, anchorMax, v2_0_05, Vector3.zero); - - var item = new TooltipViewItem(); - item.gameObject = item1; - item.columns.Add(CreateViewItemColumn(0, item1.transform, tooltip, theme)); - item.columns.Add(CreateViewItemColumn(1, item1.transform, tooltip, theme)); - item.columns.Add(CreateViewItemColumn(2, item1.transform, tooltip, theme)); - return item; - } - - private static ChartLabel CreateViewItemColumn(int i, Transform parent, Tooltip tooltip, ComponentTheme theme) - { - var labelStyle = tooltip.GetContentLabelStyle(i); - var label = ChartHelper.AddChartLabel("column" + i, parent, labelStyle, theme, - "", Color.clear, TextAnchor.MiddleLeft); - return label; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs.meta b/Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs.meta deleted file mode 100644 index bdc9a34..0000000 --- a/Assets/XCharts/Runtime/Component/Tooltip/TooltipView.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 20bbaf6c402824f5d8abcaf1cee57865 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/VisualMap.meta b/Assets/XCharts/Runtime/Component/VisualMap.meta deleted file mode 100644 index 1077d02..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c21848eac9668493db23591788d54bf0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs b/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs deleted file mode 100644 index 165aa80..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs +++ /dev/null @@ -1,641 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class VisualMapRange : ChildComponent - { - [SerializeField] private double m_Min; - [SerializeField] private double m_Max; - [SerializeField] private string m_Label; - [SerializeField] private Color32 m_Color; - - /// <summary> - /// 范围最小值 - /// </summary> - public double min { get { return m_Min; } set { m_Min = value; } } - /// <summary> - /// 范围最大值 - /// </summary> - public double max { get { return m_Max; } set { m_Max = value; } } - /// <summary> - /// 文字描述 - /// </summary> - public string label { get { return m_Label; } set { m_Label = value; } } - /// <summary> - /// 颜色 - /// </summary> - public Color32 color { get { return m_Color; } set { m_Color = value; } } - - public bool Contains(double value, double minMaxRange) - { - if (m_Min == 0 && m_Max == 0) return false; - var cmin = System.Math.Abs(m_Min) < 1 ? minMaxRange * m_Min : m_Min; - var cmax = System.Math.Abs(m_Max) < 1 ? minMaxRange * m_Max : m_Max; - return value >= cmin && value < cmax; - } - } - - /// <summary> - /// VisualMap component. Mapping data to visual elements such as colors. - /// |视觉映射组件。用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。 - /// </summary> - [System.Serializable] - [ComponentHandler(typeof(VisualMapHandler), true)] - public class VisualMap : MainComponent - { - /// <summary> - /// 类型。分为连续型和分段型。 - /// </summary> - public enum Type - { - /// <summary> - /// 连续型。 - /// </summary> - Continuous, - /// <summary> - /// 分段型。 - /// </summary> - Piecewise - } - - /// <summary> - /// 选择模式 - /// </summary> - public enum SelectedMode - { - /// <summary> - /// 多选。 - /// </summary> - Multiple, - /// <summary> - /// 单选。 - /// </summary> - Single - } - - [SerializeField] private bool m_Show = true; - [SerializeField] private bool m_ShowUI = false; - [SerializeField] private Type m_Type = Type.Continuous; - [SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple; - [SerializeField] private int m_SerieIndex = 0; - [SerializeField] private double m_Min = 0; - [SerializeField] private double m_Max = 100; - - [SerializeField] private double[] m_Range = new double[2] { 0, 100 }; - [SerializeField] private string[] m_Text = new string[2] { "", "" }; - [SerializeField] private float[] m_TextGap = new float[2] { 10f, 10f }; - [SerializeField] private int m_SplitNumber = 5; - [SerializeField] private bool m_Calculable = false; - [SerializeField] private bool m_Realtime = true; - [SerializeField] private float m_ItemWidth = 20f; - [SerializeField] private float m_ItemHeight = 140f; - [SerializeField] private float m_ItemGap = 10f; - [SerializeField] private float m_BorderWidth = 0; - [SerializeField] private int m_Dimension = -1; - [SerializeField] private bool m_HoverLink = true; - [SerializeField] private bool m_AutoMinMax = true; - [SerializeField] private Orient m_Orient = Orient.Horizonal; - [SerializeField] private Location m_Location = Location.defaultLeft; - [SerializeField] private bool m_WorkOnLine = true; - [SerializeField] private bool m_WorkOnArea = false; - - [SerializeField] private List<VisualMapRange> m_OutOfRange = new List<VisualMapRange>() { new VisualMapRange() { color = Color.gray } }; - [SerializeField] private List<VisualMapRange> m_InRange = new List<VisualMapRange>(); - - public VisualMapContext context = new VisualMapContext(); - - /// <summary> - /// Whether to enable components. - /// |组件是否生效。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to display components. If set to false, it will not show up, but the data mapping function still exists. - /// |是否显示组件。如果设置为 false,不会显示,但是数据映射的功能还存在。 - /// </summary> - public bool showUI - { - get { return m_ShowUI; } - set { if (PropertyUtil.SetStruct(ref m_ShowUI, value)) SetVerticesDirty(); } - } - /// <summary> - /// the type of visualmap component. - /// |组件类型。 - /// </summary> - public Type type - { - get { return m_Type; } - set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetVerticesDirty(); } - } - /// <summary> - /// the selected mode for Piecewise visualMap. - /// |选择模式。 - /// </summary> - public SelectedMode selectedMode - { - get { return m_SelectedMode; } - set { if (PropertyUtil.SetStruct(ref m_SelectedMode, value)) SetVerticesDirty(); } - } - /// <summary> - /// the serie index of visualMap. - /// |影响的serie索引。 - /// </summary> - public int serieIndex - { - get { return m_SerieIndex; } - set { if (PropertyUtil.SetStruct(ref m_SerieIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// The minimum allowed. 'min' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap. - /// | - /// 允许的最小值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』。 - /// </summary> - public double min - { - get { return m_Min; } - set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetVerticesDirty(); } - } - /// <summary> - /// The maximum allowed. 'max' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap. - /// | - /// 允许的最大值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。 - /// </summary> - public double max - { - get { return m_Max; } - set { m_Max = (value < min ? min + 1 : value); SetVerticesDirty(); } - } - /// <summary> - /// Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max]. - /// | - /// 指定手柄对应数值的位置。range 应在[min,max]范围内。 - /// </summary> - public double[] range { get { return m_Range; } } - /// <summary> - /// Text on both ends. - /// |两端的文本,如 ['High', 'Low']。 - /// </summary> - public string[] text { get { return m_Text; } } - /// <summary> - /// The distance between the two text bodies. - /// |两端文字主体之间的距离,单位为px。 - /// </summary> - public float[] textGap { get { return m_TextGap; } } - /// <summary> - /// For continuous data, it is automatically evenly divided into several segments - /// and automatically matches the size of inRange color list when the default is 0. - /// | - /// 对于连续型数据,自动平均切分成几段,默认为0时自动匹配inRange颜色列表大小。 - /// </summary> - /// <value></value> - public int splitNumber - { - get { return m_SplitNumber; } - set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether the handle used for dragging is displayed (the handle can be dragged to adjust the selected range). - /// | - /// 是否显示拖拽用的手柄(手柄能拖拽调整选中范围)。 - /// </summary> - public bool calculable - { - get { return m_Calculable; } - set { if (PropertyUtil.SetStruct(ref m_Calculable, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to update in real time while dragging. - /// | - /// 拖拽时,是否实时更新。 - /// </summary> - public bool realtime - { - get { return m_Realtime; } - set { if (PropertyUtil.SetStruct(ref m_Realtime, value)) SetVerticesDirty(); } - } - /// <summary> - /// The width of the figure, that is, the width of the color bar. - /// | - /// 图形的宽度,即颜色条的宽度。 - /// </summary> - public float itemWidth - { - get { return m_ItemWidth; } - set { if (PropertyUtil.SetStruct(ref m_ItemWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// The height of the figure, that is, the height of the color bar. - /// | - /// 图形的高度,即颜色条的高度。 - /// </summary> - public float itemHeight - { - get { return m_ItemHeight; } - set { if (PropertyUtil.SetStruct(ref m_ItemHeight, value)) SetVerticesDirty(); } - } - /// <summary> - /// 每个图元之间的间隔距离。 - /// </summary> - public float itemGap - { - get { return m_ItemGap; } - set { if (PropertyUtil.SetStruct(ref m_ItemGap, value)) SetVerticesDirty(); } - } - /// <summary> - /// Border line width. - /// | - /// 边框线宽,单位px。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// Specifies "which dimension" of the data to map to the visual element. "Data" is series.data. - /// |Starting at 1, the default is 0 to take the last dimension in data. - /// | - /// 指定用数据的『哪个维度』,映射到视觉元素上。『数据』即 series.data。从1开始,默认为0取 data 中最后一个维度。 - /// </summary> - public int dimension - { - get { return m_Dimension; } - set { if (PropertyUtil.SetStruct(ref m_Dimension, value)) SetVerticesDirty(); } - } - /// <summary> - /// When the hoverLink function is turned on, when the mouse hovers over the visualMap component, - /// the corresponding value of the mouse position is highlighted in the corresponding graphic element in the diagram. - /// |Conversely, when the mouse hovers over a graphic element in a diagram, - /// the corresponding value of the visualMap component is triangulated in the corresponding position. - /// | - /// 打开 hoverLink 功能时,鼠标悬浮到 visualMap 组件上时,鼠标位置对应的数值 在 图表中对应的图形元素,会高亮。 - /// 反之,鼠标悬浮到图表中的图形元素上时,在 visualMap 组件的相应位置会有三角提示其所对应的数值。 - /// </summary> - /// <value></value> - public bool hoverLink - { - get { return m_HoverLink; } - set { if (PropertyUtil.SetStruct(ref m_HoverLink, value)) SetVerticesDirty(); } - } - /// <summary> - /// Automatically set min, Max value - /// 自动设置min,max的值 - /// </summary> - public bool autoMinMax - { - get { return m_AutoMinMax; } - set { if (PropertyUtil.SetStruct(ref m_AutoMinMax, value)) SetVerticesDirty(); } - } - /// <summary> - /// Specify whether the layout of component is horizontal or vertical. - /// | - /// 布局方式是横还是竖。 - /// </summary> - public Orient orient - { - get { return m_Orient; } - set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetVerticesDirty(); } - } - /// <summary> - /// The location of component. - /// |组件显示的位置。 - /// </summary> - public Location location - { - get { return m_Location; } - set { if (PropertyUtil.SetClass(ref m_Location, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether the visualmap is work on linestyle of linechart. - /// |组件是否对LineChart的LineStyle有效。 - /// </summary> - public bool workOnLine - { - get { return m_WorkOnLine; } - set { if (PropertyUtil.SetStruct(ref m_WorkOnLine, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether the visualmap is work on areaStyle of linechart. - /// |组件是否对LineChart的AreaStyle有效。 - /// </summary> - public bool workOnArea - { - get { return m_WorkOnArea; } - set { if (PropertyUtil.SetStruct(ref m_WorkOnArea, value)) SetVerticesDirty(); } - } - /// <summary> - /// Defines a visual color outside of the selected range. - /// |定义 在选中范围外 的视觉颜色。 - /// </summary> - public List<VisualMapRange> outOfRange - { - get { return m_OutOfRange; } - set { if (value != null) { m_OutOfRange = value; SetVerticesDirty(); } } - } - /// <summary> - /// 分段式每一段的相关配置。 - /// </summary> - public List<VisualMapRange> inRange - { - get { return m_InRange; } - set { if (value != null) { m_InRange = value; SetVerticesDirty(); } } - } - - public override bool vertsDirty { get { return m_VertsDirty || location.anyDirty; } } - public override void ClearVerticesDirty() - { - base.ClearVerticesDirty(); - location.ClearVerticesDirty(); - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - location.ClearComponentDirty(); - } - - public double rangeMin - { - get - { - if (m_Range[0] < min || m_Range[0] > max) return min; - else return m_Range[0]; - } - set - { - if (value >= min && value <= m_Range[1]) m_Range[0] = value; - } - } - - public double rangeMax - { - get - { - if (m_Range[1] >= m_Range[0] && m_Range[1] < max) return m_Range[1]; - else return max; - } - set - { - if (value >= m_Range[0] && value <= max) m_Range[1] = value; - } - } - - public float runtimeRangeMinHeight { get { return (float) ((rangeMin - min) / (max - min) * itemHeight); } } - public float runtimeRangeMaxHeight { get { return (float) ((rangeMax - min) / (max - min) * itemHeight); } } - - public void AddColors(List<Color32> colors) - { - m_InRange.Clear(); - foreach (var color in colors) - { - m_InRange.Add(new VisualMapRange() - { - color = color - }); - } - } - - public void AddColors(List<string> colors) - { - m_InRange.Clear(); - foreach (var str in colors) - { - m_InRange.Add(new VisualMapRange() - { - color = ThemeStyle.GetColor(str) - }); - } - } - - public Color32 GetColor(double value) - { - int index = GetIndex(value); - if (index == -1) - { - if (m_OutOfRange.Count > 0) - return m_OutOfRange[0].color; - else - return ChartConst.clearColor32; - } - - if (m_Type == VisualMap.Type.Piecewise) - { - return m_InRange[index].color; - } - else - { - int splitNumber = m_InRange.Count; - var diff = (m_Max - m_Min) / (splitNumber - 1); - var nowMin = m_Min + index * diff; - var rate = (value - nowMin) / diff; - if (index == splitNumber - 1) - return m_InRange[index].color; - else - return Color32.Lerp(m_InRange[index].color, m_InRange[index + 1].color, (float) rate); - } - } - - private bool IsNeedPieceColor(double value, out int index) - { - bool flag = false; - index = -1; - for (int i = 0; i < m_InRange.Count; i++) - { - var range = m_InRange[i]; - if (range.min != 0 || range.max != 0) - { - flag = true; - if (range.Contains(value, max - min)) - { - index = i; - return true; - } - } - } - return flag; - } - - private Color32 GetPiecesColor(double value) - { - foreach (var piece in m_InRange) - { - if (piece.Contains(value, max - min)) - { - return piece.color; - } - } - if (m_OutOfRange.Count > 0) - return m_OutOfRange[0].color; - else - return ChartConst.clearColor32; - } - - public int GetIndex(double value) - { - int splitNumber = m_InRange.Count; - if (splitNumber <= 0) - return -1; - var index = -1; - if (IsNeedPieceColor(value, out index)) - { - return index; - } - value = MathUtil.Clamp(value, m_Min, m_Max); - - var diff = (m_Max - m_Min) / (splitNumber - 1); - - for (int i = 0; i < splitNumber; i++) - { - if (value <= m_Min + (i + 1) * diff) - { - index = i; - break; - } - } - return index; - } - - public bool IsPiecewise() - { - return m_Type == VisualMap.Type.Piecewise; - } - - public bool IsInSelectedValue(double value) - { - if (context.pointerIndex < 0) - return true; - else - return context.pointerIndex == GetIndex(value); - } - - public double GetValue(Vector3 pos, Rect chartRect) - { - var vertical = orient == Orient.Vertical; - var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height); - var pos1 = centerPos + (vertical ? Vector3.down : Vector3.left) * itemHeight / 2; - var pos2 = centerPos + (vertical ? Vector3.up : Vector3.right) * itemHeight / 2; - - if (vertical) - { - if (pos.y < pos1.y) - return min; - else if (pos.y > pos2.y) - return max; - else - return min + (pos.y - pos1.y) / (pos2.y - pos1.y) * (max - min); - } - else - { - if (pos.x < pos1.x) - return min; - else if (pos.x > pos2.x) - return max; - else - return min + (pos.x - pos1.x) / (pos2.x - pos1.x) * (max - min); - } - } - - public bool IsInRect(Vector3 local, Rect chartRect, float triangleLen = 20) - { - var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height); - var diff = calculable ? triangleLen : 0; - - if (local.x >= centerPos.x - itemWidth / 2 - diff && - local.x <= centerPos.x + itemWidth / 2 + diff && - local.y >= centerPos.y - itemHeight / 2 - diff && - local.y <= centerPos.y + itemHeight / 2 + diff) - { - return true; - } - else - { - return false; - } - } - - public bool IsInRangeRect(Vector3 local, Rect chartRect) - { - var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height); - - if (orient == Orient.Vertical) - { - var pos1 = centerPos + Vector3.down * itemHeight / 2; - - return local.x >= centerPos.x - itemWidth / 2 && - local.x <= centerPos.x + itemWidth / 2 && - local.y >= pos1.y + runtimeRangeMinHeight && - local.y <= pos1.y + runtimeRangeMaxHeight; - } - else - { - var pos1 = centerPos + Vector3.left * itemHeight / 2; - return local.x >= pos1.x + runtimeRangeMinHeight && - local.x <= pos1.x + runtimeRangeMaxHeight && - local.y >= centerPos.y - itemWidth / 2 && - local.y <= centerPos.y + itemWidth / 2; - } - } - - public bool IsInRangeMinRect(Vector3 local, Rect chartRect, float triangleLen) - { - var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height); - - if (orient == Orient.Vertical) - { - var radius = triangleLen / 2; - var pos1 = centerPos + Vector3.down * itemHeight / 2; - var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + runtimeRangeMinHeight - radius); - - return local.x >= cpos.x - radius && - local.x <= cpos.x + radius && - local.y >= cpos.y - radius && - local.y <= cpos.y + radius; - } - else - { - var radius = triangleLen / 2; - var pos1 = centerPos + Vector3.left * itemHeight / 2; - var cpos = new Vector3(pos1.x + runtimeRangeMinHeight, pos1.y + itemWidth / 2 + radius); - - return local.x >= cpos.x - radius && - local.x <= cpos.x + radius && - local.y >= cpos.y - radius && - local.y <= cpos.y + radius; - } - } - - public bool IsInRangeMaxRect(Vector3 local, Rect chartRect, float triangleLen) - { - var centerPos = new Vector3(chartRect.x, chartRect.y) + location.GetPosition(chartRect.width, chartRect.height); - - if (orient == Orient.Vertical) - { - var radius = triangleLen / 2; - var pos1 = centerPos + Vector3.down * itemHeight / 2; - var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + runtimeRangeMaxHeight + radius); - - return local.x >= cpos.x - radius && - local.x <= cpos.x + radius && - local.y >= cpos.y - radius && - local.y <= cpos.y + radius; - } - else - { - var radius = triangleLen / 2; - var pos1 = centerPos + Vector3.left * itemHeight / 2; - var cpos = new Vector3(pos1.x + runtimeRangeMaxHeight + radius, pos1.y + itemWidth / 2 + radius); - - return local.x >= cpos.x - radius && - local.x <= cpos.x + radius && - local.y >= cpos.y - radius && - local.y <= cpos.y + radius; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs.meta b/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs.meta deleted file mode 100644 index 63b8bc2..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMap.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0a684cb32850c4df6aa39ed4fa5efb3f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs deleted file mode 100644 index 730b537..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class VisualMapContext : MainComponentContext - { - /// <summary> - /// 鼠标悬停选中的index - /// </summary> - public int pointerIndex { get; set; } - public double pointerValue { get; set; } - public bool minDrag { get; internal set; } - public bool maxDrag { get; internal set; } - - internal List<Color32> inRangeColors = new List<Color32>(); - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs.meta b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs.meta deleted file mode 100644 index b2eea4c..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b81ad95b4747442daa716953c7c02638 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs deleted file mode 100644 index a6f672d..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs +++ /dev/null @@ -1,371 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class VisualMapHandler : MainComponentHandler<VisualMap> - { - public override void OnBeginDrag(PointerEventData eventData) - { - OnDragVisualMapStart(component); - } - public override void OnDrag(PointerEventData eventData) - { - OnDragVisualMap(component); - } - - public override void OnEndDrag(PointerEventData eventData) - { - OnDragVisualMapEnd(component); - } - - public override void Update() - { - CheckVisualMap(component); - } - - public override void DrawBase(VertexHelper vh) - { - var visualMap = component; - if (!visualMap.show || !visualMap.showUI) return; - switch (visualMap.type) - { - case VisualMap.Type.Continuous: - DrawContinuousVisualMap(vh, visualMap); - break; - case VisualMap.Type.Piecewise: - //DrawPiecewiseVisualMap(vh, visualMap); - break; - } - } - - private void CheckVisualMap(VisualMap visualMap) - { - if (visualMap == null || !visualMap.show) - return; - - if (chart.canvas == null) - return; - - Vector2 local; - if (!chart.ScreenPointToChartPoint(Input.mousePosition, out local)) - { - if (visualMap.context.pointerIndex >= 0) - { - visualMap.context.pointerIndex = -1; - chart.RefreshChart(); - } - return; - } - - if (local.x < chart.chartX || - local.x > chart.chartX + chart.chartWidth || - local.y < chart.chartY || - local.y > chart.chartY + chart.chartHeight || - !visualMap.IsInRangeRect(local, chart.chartRect)) - { - if (visualMap.context.pointerIndex >= 0) - { - visualMap.context.pointerIndex = -1; - chart.RefreshChart(); - } - return; - } - - var pos1 = Vector3.zero; - var pos2 = Vector3.zero; - var halfHig = visualMap.itemHeight / 2; - var centerPos = chart.chartPosition + visualMap.location.GetPosition(chart.chartWidth, chart.chartHeight); - var selectedIndex = -1; - double value = 0; - - switch (visualMap.orient) - { - case Orient.Horizonal: - pos1 = centerPos + Vector3.left * halfHig; - pos2 = centerPos + Vector3.right * halfHig; - value = visualMap.min + (local.x - pos1.x) / (pos2.x - pos1.x) * (visualMap.max - visualMap.min); - selectedIndex = visualMap.GetIndex(value); - break; - - case Orient.Vertical: - pos1 = centerPos + Vector3.down * halfHig; - pos2 = centerPos + Vector3.up * halfHig; - value = visualMap.min + (local.y - pos1.y) / (pos2.y - pos1.y) * (visualMap.max - visualMap.min); - selectedIndex = visualMap.GetIndex(value); - break; - } - - visualMap.context.pointerValue = value; - visualMap.context.pointerIndex = selectedIndex; - chart.RefreshChart(); - } - - private void DrawContinuousVisualMap(VertexHelper vh, VisualMap visualMap) - { - var centerPos = chart.chartPosition + visualMap.location.GetPosition(chart.chartWidth, chart.chartHeight); - var pos1 = Vector3.zero; - var pos2 = Vector3.zero; - var dir = Vector3.zero; - var halfWid = visualMap.itemWidth / 2; - var halfHig = visualMap.itemHeight / 2; - var xRadius = 0f; - var yRadius = 0f; - var splitNum = visualMap.inRange.Count; - var splitWid = visualMap.itemHeight / (splitNum - 1); - var isVertical = false; - var colors = visualMap.inRange; - var triangeLen = chart.theme.visualMap.triangeLen; - - switch (visualMap.orient) - { - case Orient.Horizonal: - pos1 = centerPos + Vector3.left * halfHig; - pos2 = centerPos + Vector3.right * halfHig; - dir = Vector3.right; - xRadius = splitWid / 2; - yRadius = halfWid; - isVertical = false; - if (visualMap.calculable) - { - var p0 = pos1 + Vector3.right * visualMap.runtimeRangeMinHeight; - var p1 = p0 + Vector3.up * halfWid; - var p2 = p0 + Vector3.up * (halfWid + triangeLen); - var p3 = p2 + Vector3.left * triangeLen; - var color = visualMap.GetColor(visualMap.rangeMin); - UGL.DrawTriangle(vh, p1, p2, p3, color); - p0 = pos1 + Vector3.right * visualMap.runtimeRangeMaxHeight; - p1 = p0 + Vector3.up * halfWid; - p2 = p0 + Vector3.up * (halfWid + triangeLen); - p3 = p2 + Vector3.right * triangeLen; - color = visualMap.GetColor(visualMap.rangeMax); - UGL.DrawTriangle(vh, p1, p2, p3, color); - } - break; - - case Orient.Vertical: - pos1 = centerPos + Vector3.down * halfHig; - pos2 = centerPos + Vector3.up * halfHig; - dir = Vector3.up; - xRadius = halfWid; - yRadius = splitWid / 2; - isVertical = true; - if (visualMap.calculable) - { - var p0 = pos1 + Vector3.up * visualMap.runtimeRangeMinHeight; - var p1 = p0 + Vector3.right * halfWid; - var p2 = p0 + Vector3.right * (halfWid + triangeLen); - var p3 = p2 + Vector3.down * triangeLen; - var color = visualMap.GetColor(visualMap.rangeMin); - UGL.DrawTriangle(vh, p1, p2, p3, color); - p0 = pos1 + Vector3.up * visualMap.runtimeRangeMaxHeight; - p1 = p0 + Vector3.right * halfWid; - p2 = p0 + Vector3.right * (halfWid + triangeLen); - p3 = p2 + Vector3.up * triangeLen; - color = visualMap.GetColor(visualMap.rangeMax); - UGL.DrawTriangle(vh, p1, p2, p3, color); - } - break; - } - if (visualMap.calculable && - (visualMap.rangeMin > visualMap.min || visualMap.rangeMax < visualMap.max)) - { - var rangeMin = visualMap.rangeMin; - var rangeMax = visualMap.rangeMax; - var diff = (visualMap.max - visualMap.min) / (splitNum - 1); - for (int i = 1; i < splitNum; i++) - { - var splitMin = visualMap.min + (i - 1) * diff; - var splitMax = splitMin + diff; - if (rangeMin > splitMax || rangeMax < splitMin) - { - continue; - } - else if (rangeMin <= splitMin && rangeMax >= splitMax) - { - var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid; - var startColor = colors[i - 1].color; - var toColor = visualMap.IsPiecewise() ? startColor : colors[i].color; - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical); - } - else if (rangeMin > splitMin && rangeMax >= splitMax) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - var splitMaxPos = pos1 + dir * i * splitWid; - var splitPos = p0 + (splitMaxPos - p0) / 2; - var startColor = visualMap.GetColor(visualMap.rangeMin); - var toColor = visualMap.IsPiecewise() ? startColor : colors[i].color; - var yRadius1 = Vector3.Distance(p0, splitMaxPos) / 2; - - if (visualMap.orient == Orient.Vertical) - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); - else - UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); - } - else if (rangeMax < splitMax && rangeMin <= splitMin) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - var splitMinPos = pos1 + dir * (i - 1) * splitWid; - var splitPos = splitMinPos + (p0 - splitMinPos) / 2; - var startColor = colors[i - 1].color; - var toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(visualMap.rangeMax); - var yRadius1 = Vector3.Distance(p0, splitMinPos) / 2; - - if (visualMap.orient == Orient.Vertical) - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); - else - UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); - } - else - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - var splitPos = (p0 + p1) / 2; - var startColor = visualMap.GetColor(visualMap.rangeMin); - var toColor = visualMap.GetColor(visualMap.rangeMax); - var yRadius1 = Vector3.Distance(p0, p1) / 2; - - if (visualMap.orient == Orient.Vertical) - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); - else - UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); - } - } - } - else - { - for (int i = 1; i < splitNum; i++) - { - var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid; - var startColor = colors[i - 1].color; - var toColor = visualMap.IsPiecewise() ? startColor : colors[i].color; - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical); - } - } - - if (visualMap.rangeMin > visualMap.min) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - UGL.DrawRectangle(vh, pos1, p0, visualMap.itemWidth / 2, chart.theme.visualMap.backgroundColor); - } - if (visualMap.rangeMax < visualMap.max) - { - var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - UGL.DrawRectangle(vh, p1, pos2, visualMap.itemWidth / 2, chart.theme.visualMap.backgroundColor); - } - - if (visualMap.hoverLink) - { - if (visualMap.context.pointerIndex >= 0) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - var pointerPos = chart.pointerPos; - - if (visualMap.orient == Orient.Vertical) - { - var p2 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y + (triangeLen / 2), p0.y, p1.y)); - var p3 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y - (triangeLen / 2), p0.y, p1.y)); - var p4 = new Vector3(centerPos.x + halfWid + triangeLen / 2, pointerPos.y); - UGL.DrawTriangle(vh, p2, p3, p4, colors[visualMap.context.pointerIndex].color); - } - else - { - var p2 = new Vector3(Mathf.Clamp(pointerPos.x + (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); - var p3 = new Vector3(Mathf.Clamp(pointerPos.x - (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); - var p4 = new Vector3(pointerPos.x, centerPos.y + halfWid + triangeLen / 2); - UGL.DrawTriangle(vh, p2, p3, p4, colors[visualMap.context.pointerIndex].color); - } - } - } - } - - private void DrawPiecewiseVisualMap(VertexHelper vh, VisualMap visualMap) - { - var centerPos = chart.chartPosition + visualMap.location.GetPosition(chart.chartWidth, chart.chartHeight); - var pos1 = Vector3.zero; - var pos2 = Vector3.zero; - var dir = Vector3.zero; - var halfWid = visualMap.itemWidth / 2; - var halfHig = visualMap.itemHeight / 2; - - switch (visualMap.orient) - { - case Orient.Horizonal: - for (int i = 0; i < visualMap.inRange.Count; i++) - { - var piece = visualMap.inRange[i]; - } - break; - - case Orient.Vertical: - var each = visualMap.itemHeight + visualMap.itemGap; - for (int i = 0; i < visualMap.inRange.Count; i++) - { - var piece = visualMap.inRange[i]; - var pos = new Vector3(centerPos.x, centerPos.y - each * i); - UGL.DrawRectangle(vh, pos, halfWid, halfHig, piece.color); - } - break; - } - } - - private void OnDragVisualMapStart(VisualMap visualMap) - { - if (!visualMap.show || !visualMap.showUI || !visualMap.calculable) - return; - - var inMinRect = visualMap.IsInRangeMinRect(chart.pointerPos, chart.chartRect, chart.theme.visualMap.triangeLen); - var inMaxRect = visualMap.IsInRangeMaxRect(chart.pointerPos, chart.chartRect, chart.theme.visualMap.triangeLen); - - if (inMinRect || inMaxRect) - { - if (inMinRect) - { - visualMap.context.minDrag = true; - } - else - { - visualMap.context.maxDrag = true; - } - } - } - - private void OnDragVisualMap(VisualMap visualMap) - { - if (!visualMap.show || !visualMap.showUI || !visualMap.calculable) - return; - - if (!visualMap.context.minDrag && !visualMap.context.maxDrag) - return; - - var value = visualMap.GetValue(chart.pointerPos, chart.chartRect); - if (visualMap.context.minDrag) - { - visualMap.rangeMin = value; - } - else - { - visualMap.rangeMax = value; - } - chart.RefreshChart(); - } - - private void OnDragVisualMapEnd(VisualMap visualMap) - { - if (!visualMap.show || !visualMap.showUI || !visualMap.calculable) - return; - - if (visualMap.context.minDrag || visualMap.context.maxDrag) - { - chart.RefreshChart(); - visualMap.context.minDrag = false; - visualMap.context.maxDrag = false; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs.meta b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs.meta deleted file mode 100644 index 022611e..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8db5a57b5961a493db94ac8974238d18 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs deleted file mode 100644 index 6351dea..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class VisualMapHelper - { - public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis) - { - if (!IsNeedGradient(visualMap) || !visualMap.autoMinMax) - return; - - double min = 0; - double max = 0; - var xAxis = isY ? relativedAxis : axis; - var yAxis = isY ? axis : relativedAxis; - if (visualMap.dimension == 0) - { - min = xAxis.IsCategory() ? 0 : xAxis.context.minValue; - max = xAxis.IsCategory() ? serie.dataCount - 1 : xAxis.context.maxValue; - SetMinMax(visualMap, min, max); - } - else - { - min = yAxis.IsCategory() ? 0 : yAxis.context.minValue; - max = yAxis.IsCategory() ? serie.dataCount - 1 : yAxis.context.maxValue; - SetMinMax(visualMap, min, max); - } - } - - public static void SetMinMax(VisualMap visualMap, double min, double max) - { - if ((visualMap.min != min || visualMap.max != max)) - { - if (max >= min) - { - visualMap.min = min; - visualMap.max = max; - } - else - { - throw new Exception("SetMinMax:max < min:" + min + "," + max); - } - } - } - - public static void GetLineGradientColor(VisualMap visualMap, float xValue, float yValue, - out Color32 startColor, out Color32 toColor) - { - startColor = ChartConst.clearColor32; - toColor = ChartConst.clearColor32; - if (visualMap.dimension == 0) - { - startColor = visualMap.IsPiecewise() ? visualMap.GetColor(xValue) : visualMap.GetColor(xValue - 1); - toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(xValue); - } - else - { - startColor = visualMap.IsPiecewise() ? visualMap.GetColor(yValue) : visualMap.GetColor(yValue - 1); - toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(yValue); - } - } - - public static Color32 GetLineGradientColor(VisualMap visualMap, Vector3 pos, GridCoord grid, Axis axis, - Axis relativedAxis, Color32 defaultColor) - { - double value = 0; - double min = 0; - double max = 0; - - if (visualMap.dimension == 0) - { - min = axis.context.minValue; - max = axis.context.maxValue; - if (axis.IsCategory() && axis.boundaryGap) - { - float startX = grid.context.x + axis.context.scaleWidth / 2; - value = (min + (pos.x - startX) / (grid.context.width - axis.context.scaleWidth) * (max - min)); - if (visualMap.IsPiecewise()) - value = (int) value; - } - else - { - value = min + (pos.x - grid.context.x) / grid.context.width * (max - min); - } - } - else - { - min = relativedAxis.context.minValue; - max = relativedAxis.context.maxValue; - if (relativedAxis.IsCategory() && relativedAxis.boundaryGap) - { - float startY = grid.context.y + relativedAxis.context.scaleWidth / 2; - value = (min + (pos.y - startY) / (grid.context.height - relativedAxis.context.scaleWidth) * (max - min)); - if (visualMap.IsPiecewise()) - value = (int) value; - } - else - { - value = min + (pos.y - grid.context.y) / grid.context.height * (max - min); - } - } - - var color = visualMap.GetColor(value); - if (ChartHelper.IsClearColor(color)) - { - return defaultColor; - } - else - { - if (color.a != 0) - color.a = defaultColor.a; - - return color; - } - } - - public static Color32 GetItemStyleGradientColor(ItemStyle itemStyle, Vector3 pos, BaseChart chart, - Axis axis, Color32 defaultColor) - { - var min = axis.context.minValue; - var max = axis.context.maxValue; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - var value = min + (pos.x - grid.context.x) / grid.context.width * (max - min); - var rate = (value - min) / (max - min); - var color = itemStyle.GetGradientColor((float) rate, defaultColor); - - if (ChartHelper.IsClearColor(color)) - return defaultColor; - else - return color; - } - - public static Color32 GetLineStyleGradientColor(LineStyle lineStyle, Vector3 pos, GridCoord grid, - Axis axis, Color32 defaultColor) - { - var min = axis.context.minValue; - var max = axis.context.maxValue; - var value = min + (pos.x - grid.context.x) / grid.context.width * (max - min); - var rate = (value - min) / (max - min); - var color = lineStyle.GetGradientColor((float) rate, defaultColor); - - if (ChartHelper.IsClearColor(color)) - return defaultColor; - else - return color; - } - - public static bool IsNeedGradient(VisualMap visualMap) - { - if (visualMap == null) - return false; - if (!visualMap.show || (!visualMap.workOnLine && !visualMap.workOnArea)) - return false; - if (visualMap.inRange.Count <= 0) - return false; - return true; - } - public static bool IsNeedLineGradient(VisualMap visualMap) - { - if (visualMap == null) - return false; - if (!visualMap.show || !visualMap.workOnLine) - return false; - if (visualMap.inRange.Count <= 0) - return false; - return true; - } - public static bool IsNeedAreaGradient(VisualMap visualMap) - { - if (visualMap == null) - return false; - if (!visualMap.show || !visualMap.workOnArea) - return false; - if (visualMap.inRange.Count <= 0) - return false; - return true; - } - - public static int GetDimension(VisualMap visualMap, int serieDataCount) - { - var dimension = visualMap != null && visualMap.dimension >= 0 ? - visualMap.dimension : serieDataCount - 1; - - if (dimension > serieDataCount - 1) - dimension = serieDataCount - 1; - - return dimension; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs.meta b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs.meta deleted file mode 100644 index 7b98866..0000000 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eddf18450477b4502804d13fa724e45d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord.meta b/Assets/XCharts/Runtime/Coord.meta deleted file mode 100644 index fe2fbe1..0000000 --- a/Assets/XCharts/Runtime/Coord.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 19968e8512641421f82ca8213ca6a907 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Calendar.meta b/Assets/XCharts/Runtime/Coord/Calendar.meta deleted file mode 100644 index e62b633..0000000 --- a/Assets/XCharts/Runtime/Coord/Calendar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: da5534d24de514e54911c0efb7b7b2ba -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs b/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs deleted file mode 100644 index 8d16210..0000000 --- a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - [ComponentHandler(typeof(CalendarCoordHandler), true)] - public class CalendarCoord : CoordSystem, IUpdateRuntimeData, ISerieContainer - { - public bool IsPointerEnter() - { - return false; - } - - public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight) - { } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs.meta b/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs.meta deleted file mode 100644 index 457c73a..0000000 --- a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eccc042d880064df8a2a99be68969918 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs b/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs deleted file mode 100644 index 69eb333..0000000 --- a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class CalendarCoordHandler : MainComponentHandler<CalendarCoord> - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs.meta b/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs.meta deleted file mode 100644 index 6825dad..0000000 --- a/Assets/XCharts/Runtime/Coord/Calendar/CalendarCoordHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 57a6c8647580846888712d387da72d1a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Grid.meta b/Assets/XCharts/Runtime/Coord/Grid.meta deleted file mode 100644 index a6c4710..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7d09a247055fa44dcab4eb4c61401a9b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs b/Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs deleted file mode 100644 index f279faa..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System; -using UnityEngine; -using XUGL; - -namespace XCharts.Runtime -{ - /// <summary> - /// Grid component. - /// |Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart can be drawn in grid. - /// |网格组件。 - /// 直角坐标系内绘图网格。可以在网格上绘制折线图,柱状图,散点图。 - /// </summary> - [Serializable] - [ComponentHandler(typeof(GridCoordHandler), true)] - public class GridCoord : CoordSystem, IUpdateRuntimeData, ISerieContainer - { - [SerializeField] private bool m_Show = true; - [SerializeField] private float m_Left = 0.1f; - [SerializeField] private float m_Right = 0.08f; - [SerializeField] private float m_Top = 0.22f; - [SerializeField] private float m_Bottom = 0.12f; - [SerializeField] private Color32 m_BackgroundColor; - [SerializeField] private bool m_ShowBorder = false; - [SerializeField] private float m_BorderWidth = 0f; - [SerializeField] private Color32 m_BorderColor; - - public GridCoordContext context = new GridCoordContext(); - - /// <summary> - /// Whether to show the grid in rectangular coordinate. - /// |是否显示直角坐标系网格。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// Distance between grid component and the left side of the container. - /// |grid 组件离容器左侧的距离。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the right side of the container. - /// |grid 组件离容器右侧的距离。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the top side of the container. - /// |grid 组件离容器上侧的距离。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the bottom side of the container. - /// |grid 组件离容器下侧的距离。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); } - } - /// <summary> - /// Background color of grid, which is transparent by default. - /// |网格背景色,默认透明。 - /// </summary> - public Color32 backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_BackgroundColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to show the grid border. - /// |是否显示网格边框。 - /// </summary> - public bool showBorder - { - get { return m_ShowBorder; } - set { if (PropertyUtil.SetStruct(ref m_ShowBorder, value)) SetVerticesDirty(); } - } - /// <summary> - /// Border width of grid. - /// |网格边框宽。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// The color of grid border. - /// |网格边框颜色。 - /// </summary> - public Color32 borderColor - { - get { return m_BorderColor; } - set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetVerticesDirty(); } - } - - public bool IsPointerEnter() - { - return context.isPointerEnter; - } - - public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight) - { - context.left = left <= 1 ? left * chartWidth : left; - context.bottom = bottom <= 1 ? bottom * chartHeight : bottom; - context.top = top <= 1 ? top * chartHeight : top; - context.right = right <= 1 ? right * chartWidth : right; - context.x = chartX + context.left; - context.y = chartY + context.bottom; - context.width = chartWidth - context.left - context.right; - context.height = chartHeight - context.top - context.bottom; - context.position = new Vector3(context.x, context.y); - context.center = new Vector3(context.x + context.width / 2, context.y + context.height / 2); - } - - public bool Contains(Vector3 pos) - { - return Contains(pos.x, pos.y); - } - - public bool Contains(float x, float y) - { - if (x < context.x - 1 || x > context.x + context.width + 1 || - y < context.y - 1 || y > context.y + context.height + 1) - { - return false; - } - return true; - } - - /// <summary> - /// 给定的线段和Grid边界的交点 - /// </summary> - /// <param name="sp"></param> - /// <param name="ep"></param> - /// <returns></returns> - public bool BoundaryPoint(Vector3 sp, Vector3 ep, ref Vector3 point) - { - if (Contains(sp) && Contains(ep)) - { - point = ep; - return false; - } - var lb = new Vector3(context.x, context.y); - var lt = new Vector3(context.x, context.y + context.height); - var rt = new Vector3(context.x + context.width, context.y + context.height); - var rb = new Vector3(context.x + context.width, context.y); - if (UGLHelper.GetIntersection(sp, ep, rb, rt, ref point)) - return true; - if (UGLHelper.GetIntersection(sp, ep, lt, rt, ref point)) - return true; - if (UGLHelper.GetIntersection(sp, ep, lb, rb, ref point)) - return true; - if (UGLHelper.GetIntersection(sp, ep, lb, lt, ref point)) - return true; - return false; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs.meta b/Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs.meta deleted file mode 100644 index 9c3e968..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid/GridCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f99c74cc7f2c44bfcae9f5c40e6b7c46 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs b/Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs deleted file mode 100644 index be4ac7a..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class GridCoordContext : MainComponentContext - { - public float x; - public float y; - public float width; - public float height; - public Vector3 position; - public Vector3 center; - public float left; - public float right; - public float bottom; - public float top; - public bool isPointerEnter; - public List<ChartLabel> endLabelList = new List<ChartLabel>(); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs.meta b/Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs.meta deleted file mode 100644 index 13f0b39..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid/GridCoordContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6a7c139761fe64d93be4c65619a0fd38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs b/Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs deleted file mode 100644 index 03dec59..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class GridCoordHandler : MainComponentHandler<GridCoord> - { - public override void InitComponent() - { - var grid = component; - grid.painter = chart.painter; - grid.refreshComponent = delegate() - { - grid.UpdateRuntimeData(chart.chartX, chart.chartY, chart.chartWidth, chart.chartHeight); - chart.OnCoordinateChanged(); - }; - grid.refreshComponent(); - } - - public override void CheckComponent(StringBuilder sb) - { - var grid = component; - if (grid.left >= chart.chartWidth) - sb.Append("warning:grid->left > chartWidth\n"); - if (grid.right >= chart.chartWidth) - sb.Append("warning:grid->right > chartWidth\n"); - if (grid.top >= chart.chartHeight) - sb.Append("warning:grid->top > chartHeight\n"); - if (grid.bottom >= chart.chartHeight) - sb.Append("warning:grid->bottom > chartHeight\n"); - if (grid.left + grid.right >= chart.chartWidth) - sb.Append("warning:grid.left + grid.right > chartWidth\n"); - if (grid.top + grid.bottom >= chart.chartHeight) - sb.Append("warning:grid.top + grid.bottom > chartHeight\n"); - } - - public override void Update() - { - if (chart.isPointerInChart) - { - component.context.isPointerEnter = component.Contains(chart.pointerPos); - } - else - { - component.context.isPointerEnter = false; - } - } - - public override void DrawBase(VertexHelper vh) - { - if (!SeriesHelper.IsAnyClipSerie(chart.series)) - { - DrawCoord(vh, component); - } - } - public override void DrawTop(VertexHelper vh) - { - if (SeriesHelper.IsAnyClipSerie(chart.series)) - { - DrawCoord(vh, component); - } - } - - private void DrawCoord(VertexHelper vh, GridCoord grid) - { - if (!grid.show) return; - if (!ChartHelper.IsClearColor(grid.backgroundColor)) - { - var p1 = new Vector2(grid.context.x, grid.context.y); - var p2 = new Vector2(grid.context.x, grid.context.y + grid.context.height); - var p3 = new Vector2(grid.context.x + grid.context.width, grid.context.y + grid.context.height); - var p4 = new Vector2(grid.context.x + grid.context.width, grid.context.y); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, grid.backgroundColor); - } - if (grid.showBorder) - { - var borderWidth = grid.borderWidth == 0 ? chart.theme.axis.lineWidth * 2 : grid.borderWidth; - var borderColor = ChartHelper.IsClearColor(grid.borderColor) ? - chart.theme.axis.lineColor : - grid.borderColor; - UGL.DrawBorder(vh, grid.context.center, grid.context.width - borderWidth, - grid.context.height - borderWidth, borderWidth, borderColor); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs.meta b/Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs.meta deleted file mode 100644 index ed91ce7..0000000 --- a/Assets/XCharts/Runtime/Coord/Grid/GridCoordHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7e22a9b603e57459f97040b285f3936a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Parallel.meta b/Assets/XCharts/Runtime/Coord/Parallel.meta deleted file mode 100644 index 081c678..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 30b1519a34fcc4ca3a56834527584719 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs deleted file mode 100644 index 73147bc..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Grid component. - /// |Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart can be drawn in grid. - /// |网格组件。 - /// 直角坐标系内绘图网格。可以在网格上绘制折线图,柱状图,散点图。 - /// </summary> - [Serializable] - [ComponentHandler(typeof(ParallelCoordHandler), true)] - public class ParallelCoord : CoordSystem, IUpdateRuntimeData, ISerieContainer - { - [SerializeField] private bool m_Show = true; - [SerializeField] protected Orient m_Orient = Orient.Vertical; - [SerializeField] private float m_Left = 0.1f; - [SerializeField] private float m_Right = 0.08f; - [SerializeField] private float m_Top = 0.22f; - [SerializeField] private float m_Bottom = 0.12f; - [SerializeField] private Color m_BackgroundColor; - - public ParallelCoordContext context = new ParallelCoordContext(); - - /// <summary> - /// Whether to show the grid in rectangular coordinate. - /// |是否显示直角坐标系网格。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// Orientation of the axis. By default, it's 'Vertical'. You can set it to be 'Horizonal' to make a vertical axis. - /// |坐标轴朝向。默认为垂直朝向。 - /// </summary> - public Orient orient - { - get { return m_Orient; } - set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the left side of the container. - /// |grid 组件离容器左侧的距离。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the right side of the container. - /// |grid 组件离容器右侧的距离。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the top side of the container. - /// |grid 组件离容器上侧的距离。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between grid component and the bottom side of the container. - /// |grid 组件离容器下侧的距离。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); } - } - /// <summary> - /// Background color of grid, which is transparent by default. - /// |网格背景色,默认透明。 - /// </summary> - public Color backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_BackgroundColor, value)) SetVerticesDirty(); } - } - - public bool IsPointerEnter() - { - return context.runtimeIsPointerEnter; - } - - public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight) - { - context.left = left <= 1 ? left * chartWidth : left; - context.bottom = bottom <= 1 ? bottom * chartHeight : bottom; - context.top = top <= 1 ? top * chartHeight : top; - context.right = right <= 1 ? right * chartWidth : right; - context.x = chartX + context.left; - context.y = chartY + context.bottom; - context.width = chartWidth - context.left - context.right; - context.height = chartHeight - context.top - context.bottom; - context.position = new Vector3(context.x, context.y); - } - - public bool Contains(Vector3 pos) - { - return Contains(pos.x, pos.y); - } - - public bool Contains(float x, float y) - { - if (x < context.x - 1 || x > context.x + context.width + 1 || - y < context.y - 1 || y > context.y + context.height + 1) - { - return false; - } - return true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs.meta b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs.meta deleted file mode 100644 index 273d285..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a7be31c76736845a9b2c92a7b8051290 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs deleted file mode 100644 index 1d545f9..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class ParallelCoordContext : MainComponentContext - { - public float x; - public float y; - public float width; - public float height; - public Vector3 position; - public float left; - public float right; - public float bottom; - public float top; - public bool runtimeIsPointerEnter; - internal List<ParallelAxis> parallelAxes = new List<ParallelAxis>(); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs.meta b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs.meta deleted file mode 100644 index ac0ce5f..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 14f338556609b48568d2504a1b153be7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs deleted file mode 100644 index 315e477..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class ParallelCoordHandler : MainComponentHandler<ParallelCoord> - { - private Dictionary<int, double> m_SerieDimMin = new Dictionary<int, double>(); - private Dictionary<int, double> m_SerieDimMax = new Dictionary<int, double>(); - private double m_LastInterval; - private int m_LastSplitNumber; - - public override void InitComponent() - { - var grid = component; - grid.painter = chart.painter; - grid.refreshComponent = delegate() - { - grid.UpdateRuntimeData(chart.chartX, chart.chartY, chart.chartWidth, chart.chartHeight); - chart.OnCoordinateChanged(); - }; - grid.refreshComponent(); - } - - public override void CheckComponent(StringBuilder sb) - { - var grid = component; - if (grid.left >= chart.chartWidth) - sb.Append("warning:grid->left > chartWidth\n"); - if (grid.right >= chart.chartWidth) - sb.Append("warning:grid->right > chartWidth\n"); - if (grid.top >= chart.chartHeight) - sb.Append("warning:grid->top > chartHeight\n"); - if (grid.bottom >= chart.chartHeight) - sb.Append("warning:grid->bottom > chartHeight\n"); - if (grid.left + grid.right >= chart.chartWidth) - sb.Append("warning:grid.left + grid.right > chartWidth\n"); - if (grid.top + grid.bottom >= chart.chartHeight) - sb.Append("warning:grid.top + grid.bottom > chartHeight\n"); - } - - public override void Update() - { - UpdatePointerEnter(); - UpdateParallelAxisMinMaxValue(); - } - - public override void DrawBase(VertexHelper vh) - { - if (!SeriesHelper.IsAnyClipSerie(chart.series)) - { - DrawCoord(vh); - } - } - public override void DrawTop(VertexHelper vh) - { - if (SeriesHelper.IsAnyClipSerie(chart.series)) - { - DrawCoord(vh); - } - } - - private void DrawCoord(VertexHelper vh) - { - var grid = component; - if (grid.show && !ChartHelper.IsClearColor(grid.backgroundColor)) - { - var p1 = new Vector2(grid.context.x, grid.context.y); - var p2 = new Vector2(grid.context.x, grid.context.y + grid.context.height); - var p3 = new Vector2(grid.context.x + grid.context.width, grid.context.y + grid.context.height); - var p4 = new Vector2(grid.context.x + grid.context.width, grid.context.y); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, grid.backgroundColor); - } - } - - private void UpdatePointerEnter() - { - if (chart.isPointerInChart) - component.context.runtimeIsPointerEnter = component.Contains(chart.pointerPos); - else - component.context.runtimeIsPointerEnter = false; - } - - private void UpdateParallelAxisMinMaxValue() - { - var list = chart.GetChartComponents<ParallelAxis>(); - if (list.Count != component.context.parallelAxes.Count) - { - component.context.parallelAxes.Clear(); - foreach (var com in chart.GetChartComponents<ParallelAxis>()) - { - var axis = com as ParallelAxis; - if (axis.parallelIndex == component.index) - component.context.parallelAxes.Add(axis); - } - } - m_SerieDimMin.Clear(); - m_SerieDimMax.Clear(); - foreach (var serie in chart.series) - { - if ((serie is Parallel) && serie.parallelIndex == component.index) - { - foreach (var serieData in serie.data) - { - for (int i = 0; i < serieData.data.Count; i++) - { - var value = serieData.data[i]; - if (!m_SerieDimMin.ContainsKey(i)) - m_SerieDimMin[i] = value; - else if (m_SerieDimMin[i] > value) - m_SerieDimMin[i] = value; - - if (!m_SerieDimMax.ContainsKey(i)) - m_SerieDimMax[i] = value; - else if (m_SerieDimMax[i] < value) - m_SerieDimMax[i] = value; - } - } - } - } - for (int i = 0; i < component.context.parallelAxes.Count; i++) - { - var axis = component.context.parallelAxes[i]; - if (axis.IsCategory()) - { - m_SerieDimMax[i] = axis.data.Count > 0 ? axis.data.Count - 1 : 0; - m_SerieDimMin[i] = 0; - } - else if (axis.minMaxType == Axis.AxisMinMaxType.Custom) - { - m_SerieDimMin[i] = axis.min; - m_SerieDimMax[i] = axis.max; - } - else if (m_SerieDimMax.ContainsKey(i)) - { - - var tempMinValue = m_SerieDimMin[i]; - var tempMaxValue = m_SerieDimMax[i]; - AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); - m_SerieDimMin[i] = tempMinValue; - m_SerieDimMax[i] = tempMaxValue; - } - } - for (int i = 0; i < component.context.parallelAxes.Count; i++) - { - if (m_SerieDimMax.ContainsKey(i)) - { - var axis = component.context.parallelAxes[i]; - var tempMinValue = m_SerieDimMin[i]; - var tempMaxValue = m_SerieDimMax[i]; - - if (tempMinValue != axis.context.minValue || - tempMaxValue != axis.context.maxValue || - m_LastInterval != axis.interval || - m_LastSplitNumber != axis.splitNumber) - { - m_LastSplitNumber = axis.splitNumber; - m_LastInterval = axis.interval; - - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.offset = 0; - axis.context.lastCheckInverse = axis.inverse; - - AxisHandler<ParallelAxis>.UpdateAxisTickValueList(axis); - (axis.handler as ParallelAxisHander).UpdateAxisLabelText(axis); - chart.RefreshChart(); - } - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs.meta b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs.meta deleted file mode 100644 index e7ee712..0000000 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: eb7323519e00e4916a9c42c5faa36a38 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Polar.meta b/Assets/XCharts/Runtime/Coord/Polar.meta deleted file mode 100644 index d1b31bf..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 43b3734481ac34ff89708f2edfa473ca -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs b/Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs deleted file mode 100644 index b251c93..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Polar coordinate can be used in scatter and line chart. Every polar coordinate has an angleAxis and a radiusAxis. - /// |极坐标系组件。 - /// 极坐标系,可以用于散点图和折线图。每个极坐标系拥有一个角度轴和一个半径轴。 - /// </summary> - [Serializable] - [ComponentHandler(typeof(PolarCoordHandler), true)] - public class PolarCoord : CoordSystem, ISerieContainer - { - [SerializeField] private bool m_Show = true; - [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.45f }; - [SerializeField] private float m_Radius = 0.35f; - [SerializeField] private Color m_BackgroundColor; - - public PolarCoordContext context = new PolarCoordContext(); - - /// <summary> - /// Whether to show the polor component. - /// |是否显示极坐标。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); } - } - /// <summary> - /// The center of ploar. The center[0] is the x-coordinate, and the center[1] is the y-coordinate. - /// When value between 0 and 1 represents a percentage relative to the chart. - /// |极坐标的中心点。数组的第一项是横坐标,第二项是纵坐标。 - /// 当值为0-1之间时表示百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。 - /// </summary> - public float[] center - { - get { return m_Center; } - set { if (value != null) { m_Center = value; SetAllDirty(); } } - } - /// <summary> - /// the radius of polar. - /// |极坐标的半径。 - /// </summary> - public float radius - { - get { return m_Radius; } - set { if (PropertyUtil.SetStruct(ref m_Radius, value)) SetAllDirty(); } - } - /// <summary> - /// Background color of polar, which is transparent by default. - /// |极坐标的背景色,默认透明。 - /// </summary> - public Color backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_BackgroundColor, value)) SetVerticesDirty(); } - } - - public bool IsPointerEnter() - { - return context.isPointerEnter; - } - - public bool Contains(Vector3 pos) - { - return Vector3.Distance(pos, context.center) < context.radius; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs.meta b/Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs.meta deleted file mode 100644 index 03d8791..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ec567fac460994411a8aadcb5e0f9b68 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs b/Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs deleted file mode 100644 index 035c2ca..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class PolarCoordContext : MainComponentContext - { - /// <summary> - /// the center position of polar in container. - /// |极坐标在容器中的具体中心点。 - /// </summary> - public Vector3 center; - /// <summary> - /// the true radius of polar. - /// |极坐标的运行时实际半径。 - /// </summary> - public float radius; - public bool isPointerEnter; - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs.meta b/Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs.meta deleted file mode 100644 index e448702..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2eaaaa315fbae4fc3a9976f51a1396b3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs b/Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs deleted file mode 100644 index 7c176a8..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class PolarCoordHandler : MainComponentHandler<PolarCoord> - { - public override void Update() - { - PolarHelper.UpdatePolarCenter(component, chart.chartPosition, chart.chartWidth, chart.chartHeight); - - if (chart.isPointerInChart) - component.context.isPointerEnter = component.Contains(chart.pointerPos); - else - component.context.isPointerEnter = false; - } - - public override void DrawBase(VertexHelper vh) - { - DrawPolar(vh, component); - } - - private void DrawPolar(VertexHelper vh, PolarCoord polar) - { - PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight); - if (!ChartHelper.IsClearColor(polar.backgroundColor)) - { - UGL.DrawCricle(vh, polar.context.center, polar.context.radius, polar.backgroundColor); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs.meta b/Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs.meta deleted file mode 100644 index d3e4351..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarCoordHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: af4b941946def4928b416260dec7ac9b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs b/Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs deleted file mode 100644 index fa51a52..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - internal static class PolarHelper - { - public static void UpdatePolarCenter(PolarCoord polar, Vector3 chartPosition, float chartWidth, float chartHeight) - { - if (polar.center.Length < 2) return; - var centerX = polar.center[0] <= 1 ? chartWidth * polar.center[0] : polar.center[0]; - var centerY = polar.center[1] <= 1 ? chartHeight * polar.center[1] : polar.center[1]; - polar.context.center = chartPosition + new Vector3(centerX, centerY); - if (polar.radius <= 0) - { - polar.context.radius = 0; - } - else if (polar.radius <= 1) - { - polar.context.radius = Mathf.Min(chartWidth, chartHeight) * polar.radius; - } - else - { - polar.context.radius = polar.radius; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs.meta b/Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs.meta deleted file mode 100644 index 8ec1778..0000000 --- a/Assets/XCharts/Runtime/Coord/Polar/PolarHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: feb363cc2ae0846b89612143ce4535ae -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/SingleAxis.meta b/Assets/XCharts/Runtime/Coord/SingleAxis.meta deleted file mode 100644 index a460d59..0000000 --- a/Assets/XCharts/Runtime/Coord/SingleAxis.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 102d61482a6f946cc82f228c88369dfd -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs b/Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs deleted file mode 100644 index 990ebe3..0000000 --- a/Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [Serializable] - [ComponentHandler(null)] - public class SingleAxisCoord : CoordSystem - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs.meta b/Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs.meta deleted file mode 100644 index 84b8cde..0000000 --- a/Assets/XCharts/Runtime/Coord/SingleAxis/SingleAxisCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e3e972d6eb5bc45e1ba7b2c5740474fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Helper.meta b/Assets/XCharts/Runtime/Helper.meta deleted file mode 100644 index f8b14dc..0000000 --- a/Assets/XCharts/Runtime/Helper.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 58d150a402b5e4bfcbec6a28cba7ed44 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Helper/CheckHelper.cs b/Assets/XCharts/Runtime/Helper/CheckHelper.cs deleted file mode 100644 index 8ccd886..0000000 --- a/Assets/XCharts/Runtime/Helper/CheckHelper.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System.Text; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class CheckHelper - { - private static bool IsColorAlphaZero(Color color) - { - return !ChartHelper.IsClearColor(color) && color.a == 0; - } - - public static string CheckChart(BaseGraph chart) - { - if (chart is BaseChart) return CheckChart((BaseChart) chart); - else return string.Empty; - } - - public static string CheckChart(BaseChart chart) - { - var sb = ChartHelper.sb; - sb.Length = 0; - CheckName(chart, sb); - CheckSize(chart, sb); - CheckTheme(chart, sb); - CheckTitle(chart, sb); - CheckLegend(chart, sb); - CheckGrid(chart, sb); - CheckSerie(chart, sb); - return sb.ToString(); - } - - private static void CheckName(BaseChart chart, StringBuilder sb) - { - if (string.IsNullOrEmpty(chart.chartName)) return; - var list = XChartsMgr.GetCharts(chart.chartName); - if (list.Count > 1) - { - sb.AppendFormat("warning:chart name is repeated: {0}\n", chart.chartName); - } - } - - private static void CheckSize(BaseChart chart, StringBuilder sb) - { - if (chart.chartWidth == 0 || chart.chartHeight == 0) - { - sb.Append("warning:chart width or height is 0\n"); - } - } - - private static void CheckTheme(BaseChart chart, StringBuilder sb) - { - var theme = chart.theme; - theme.CheckWarning(sb); - } - - private static void CheckTitle(BaseChart chart, StringBuilder sb) - { - // foreach (var title in chart.titles) - // { - // if (!title.show) return; - // if (string.IsNullOrEmpty(title.text)) sb.AppendFormat("warning:title{0}->text is null\n", title.index); - // if (IsColorAlphaZero(title.textStyle.color)) - // sb.AppendFormat("warning:title{0}->textStyle->color alpha is 0\n", title.index); - // if (IsColorAlphaZero(title.subTextStyle.color)) - // sb.AppendFormat("warning:title{0}->subTextStyle->color alpha is 0\n", title.index); - // } - } - - private static void CheckLegend(BaseChart chart, StringBuilder sb) - { } - - private static void CheckGrid(BaseChart chart, StringBuilder sb) - { } - - private static void CheckSerie(BaseChart chart, StringBuilder sb) - { - var allDataIsEmpty = true; - var allDataIsZero = true; - var allSerieIsHide = true; - foreach (var serie in chart.series) - { - if (serie.show) allSerieIsHide = false; - if (serie.dataCount > 0) - { - allDataIsEmpty = false; - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.GetSerieData(i); - for (int j = 1; j < serieData.data.Count; j++) - { - if (serieData.GetData(j) != 0) - { - allDataIsZero = false; - break; - } - } - } - var dataCount = serie.GetSerieData(0).data.Count; - if (serie.showDataDimension > 1 && serie.showDataDimension != dataCount) - { - sb.AppendFormat("warning:serie {0} serieData.data.count[{1}] not match showDataDimension[{2}]\n", serie.index, dataCount, serie.showDataDimension); - } - } - else - { - sb.AppendFormat("warning:serie {0} no data\n", serie.index); - } - if (IsColorAlphaZero(serie.itemStyle.color)) - sb.AppendFormat("warning:serie {0} itemStyle->color alpha is 0\n", serie.index); - if (serie.itemStyle.opacity == 0) - sb.AppendFormat("warning:serie {0} itemStyle->opacity is 0\n", serie.index); - if (serie.itemStyle.borderWidth != 0 && IsColorAlphaZero(serie.itemStyle.borderColor)) - sb.AppendFormat("warning:serie {0} itemStyle->borderColor alpha is 0\n", serie.index); - if (serie is Line) - { - if (serie.lineStyle.opacity == 0) - sb.AppendFormat("warning:serie {0} lineStyle->opacity is 0\n", serie.index); - if (IsColorAlphaZero(serie.lineStyle.color)) - sb.AppendFormat("warning:serie {0} lineStyle->color alpha is 0\n", serie.index); - } - else if (serie is Pie) - { - if (serie.radius.Length >= 2 && serie.radius[1] == 0) - sb.AppendFormat("warning:serie {0} radius[1] is 0\n", serie.index); - } - else if (serie is Scatter || serie is EffectScatter) - { - if (!serie.symbol.show) - sb.AppendFormat("warning:serie {0} symbol type is None\n", serie.index); - } - } - if (allDataIsEmpty) sb.Append("warning:all serie data is empty\n"); - if (!allDataIsEmpty && allDataIsZero) sb.Append("warning:all serie data is 0\n"); - if (allSerieIsHide) sb.Append("warning:all serie is hide\n"); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Helper/CheckHelper.cs.meta b/Assets/XCharts/Runtime/Helper/CheckHelper.cs.meta deleted file mode 100644 index 56e1a2f..0000000 --- a/Assets/XCharts/Runtime/Helper/CheckHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 09a50ff0a7fdb4174b4dc2d28fc08b6a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Helper/FormatterHelper.cs b/Assets/XCharts/Runtime/Helper/FormatterHelper.cs deleted file mode 100644 index 06490eb..0000000 --- a/Assets/XCharts/Runtime/Helper/FormatterHelper.cs +++ /dev/null @@ -1,277 +0,0 @@ -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class FormatterHelper - { - public const string PH_NN = "\n"; - private static Regex s_Regex = new Regex(@"{([a-g|.]\d*)(:\d+(-\d+)?)?(:[c-g|x|p|r]\d*|:0\.#*)?}", RegexOptions.IgnoreCase); - private static Regex s_RegexSub = new Regex(@"(0\.#*)|(\d+-\d+)|(\w+)|(\.)", RegexOptions.IgnoreCase); - private static Regex s_RegexN = new Regex(@"^\d+", RegexOptions.IgnoreCase); - private static Regex s_RegexN_N = new Regex(@"\d+-\d+", RegexOptions.IgnoreCase); - private static Regex s_RegexFn = new Regex(@"[c-g|x|p|r]\d*|0\.#*", RegexOptions.IgnoreCase); - private static Regex s_RegexNewLine = new Regex(@"[\\|/]+n|</br>|<br>|<br/>", RegexOptions.IgnoreCase); - private static Regex s_RegexForAxisLabel = new Regex(@"{value(:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); - private static Regex s_RegexSubForAxisLabel = new Regex(@"(value)|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); - private static Regex s_RegexForSerieLabel = new Regex(@"{[a-g|\.](:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); - private static Regex s_RegexSubForSerieLabel = new Regex(@"(\.)|([a-g])|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); - - public static bool NeedFormat(string content) - { - return content.IndexOf('{') >= 0; - } - - /// <summary> - /// 替换字符串中的通配符,支持的通配符有{.}、{a}、{b}、{c}、{d}、{e}、{f}、{g}。 - /// </summary> - /// <param name="content">要替换的字符串</param> - /// <param name="dataIndex">选中的数据项serieData索引</param> - /// <param name="numericFormatter">默认的数字格式化</param> - /// <param name="serie">选中的serie</param> - /// <param name="series">所有serie</param> - /// <param name="theme">用来获取指定index的颜色</param> - /// <param name="category">选中的类目,一般用在折线图和柱状图</param> - /// <param name="dataZoom">dataZoom</param> - /// <returns></returns> - public static bool ReplaceContent(ref string content, int dataIndex, string numericFormatter, Serie serie, - BaseChart chart, DataZoom dataZoom = null) - { - var foundDot = false; - var mc = s_Regex.Matches(content); - foreach (var m in mc) - { - var old = m.ToString(); - var args = s_RegexSub.Matches(m.ToString()); - var argsCount = args.Count; - if (argsCount <= 0) continue; - int targetIndex = 0; - char p = GetSerieIndex(args[0].ToString(), ref targetIndex); - if (targetIndex >= 0) - { - serie = chart.GetSerie(targetIndex); - if (serie == null) continue; - } - else if (serie != null) - { - targetIndex = serie.index; - } - else - { - serie = chart.GetSerie(0); - targetIndex = 0; - } - if (serie == null) continue; - if (p == '.') - { - var bIndex = targetIndex; - if (argsCount >= 2) - { - var args1Str = args[1].ToString(); - if (s_RegexN.IsMatch(args1Str)) bIndex = int.Parse(args1Str); - } - content = content.Replace(old, ChartCached.ColorToDotStr(chart.theme.GetColor(bIndex))); - foundDot = true; - } - else if (p == 'a' || p == 'A') - { - if (argsCount == 1) - { - content = content.Replace(old, serie.serieName); - } - } - else if (p == 'b' || p == 'B' || p == 'e' || p == 'E') - { - var bIndex = dataIndex; - if (argsCount >= 2) - { - var args1Str = args[1].ToString(); - if (s_RegexN.IsMatch(args1Str)) bIndex = int.Parse(args1Str); - } - var needCategory = (p != 'e' && p != 'E') && (serie is Line || serie is Bar); - if (needCategory) - { - var category = chart.GetTooltipCategory(dataIndex, serie, dataZoom); - content = content.Replace(old, category); - } - else - { - var serieData = serie.GetSerieData(bIndex, dataZoom); - content = content.Replace(old, serieData.name); - } - } - else if (p == 'g' || p == 'G') - { - content = content.Replace(old, ChartCached.NumberToStr(serie.dataCount, "")); - } - else if (p == 'c' || p == 'C' || p == 'd' || p == 'D' || p == 'f' || p == 'f') - { - var isPercent = p == 'd' || p == 'D'; - var isTotal = p == 'f' || p == 'f'; - var bIndex = dataIndex; - var dimensionIndex = -1; - if (argsCount >= 2) - { - var args1Str = args[1].ToString(); - if (s_RegexFn.IsMatch(args1Str)) - { - numericFormatter = args1Str; - } - else if (s_RegexN_N.IsMatch(args1Str)) - { - var temp = args1Str.Split('-'); - bIndex = int.Parse(temp[0]); - dimensionIndex = int.Parse(temp[1]); - } - else if (s_RegexN.IsMatch(args1Str)) - { - dimensionIndex = int.Parse(args1Str); - } - else - { - Debug.LogError("unmatch:" + args1Str); - continue; - } - } - if (argsCount >= 3) - { - numericFormatter = args[2].ToString(); - } - if (dimensionIndex == -1) dimensionIndex = 1; - if (numericFormatter == string.Empty) - { - numericFormatter = SerieHelper.GetNumericFormatter(serie, serie.GetSerieData(bIndex), ""); - } - var value = serie.GetData(bIndex, dimensionIndex, dataZoom); - if (isPercent) - { - var total = serie.GetDataTotal(dimensionIndex, serie.GetSerieData(bIndex)); - var percent = total == 0 ? 0 : value / serie.yTotal * 100; - content = content.Replace(old, ChartCached.FloatToStr(percent, numericFormatter)); - } - else if (isTotal) - { - var total = serie.GetDataTotal(dimensionIndex, serie.GetSerieData(bIndex)); - content = content.Replace(old, ChartCached.FloatToStr(total, numericFormatter)); - } - else - { - content = content.Replace(old, ChartCached.FloatToStr(value, numericFormatter)); - } - } - } - content = s_RegexNewLine.Replace(content, PH_NN); - return foundDot; - } - - public static void ReplaceSerieLabelContent(ref string content, string numericFormatter, int dataCount, double value, double total, - string serieName, string category, string dataName, Color color) - { - var mc = s_RegexForSerieLabel.Matches(content); - foreach (var m in mc) - { - var old = m.ToString(); - var args = s_RegexSubForSerieLabel.Matches(old); - var argsCount = args.Count; - if (argsCount <= 0) continue; - var p = args[0].ToString().ElementAt(0); - if (argsCount >= 2) - { - numericFormatter = args[1].ToString(); - } - if (p == '.') - { - content = content.Replace(old, ChartCached.ColorToDotStr(color)); - } - else if (p == 'a' || p == 'A') - { - content = content.Replace(old, serieName); - } - else if (p == 'b' || p == 'B') - { - content = content.Replace(old, category); - } - else if (p == 'e' || p == 'E') - { - content = content.Replace(old, dataName); - } - else if (p == 'd' || p == 'D') - { - var rate = total == 0 ? 0 : value / total * 100; - content = content.Replace(old, ChartCached.NumberToStr(rate, numericFormatter)); - } - else if (p == 'c' || p == 'C') - { - content = content.Replace(old, ChartCached.NumberToStr(value, numericFormatter)); - } - else if (p == 'f' || p == 'f') - { - content = content.Replace(old, ChartCached.NumberToStr(total, numericFormatter)); - } - else if (p == 'g' || p == 'G') - { - content = content.Replace(old, ChartCached.NumberToStr(dataCount, numericFormatter)); - } - } - content = TrimAndReplaceLine(content); - } - - private static char GetSerieIndex(string strType, ref int index) - { - index = -1; - if (strType.Length > 1) - { - if (!int.TryParse(strType.Substring(1), out index)) - { - index = -1; - } - } - return strType.ElementAt(0); - } - - public static string TrimAndReplaceLine(StringBuilder sb) - { - return TrimAndReplaceLine(sb.ToString()); - } - - public static string TrimAndReplaceLine(string content) - { - return s_RegexNewLine.Replace(content.Trim(), PH_NN); - } - - public static void ReplaceAxisLabelContent(ref string content, string numericFormatter, double value) - { - var mc = s_RegexForAxisLabel.Matches(content); - foreach (var m in mc) - { - var old = m.ToString(); - var args = s_RegexSubForAxisLabel.Matches(m.ToString()); - var argsCount = args.Count; - if (argsCount <= 0) continue; - if (argsCount >= 2) - { - numericFormatter = args[1].ToString(); - } - content = content.Replace(old, ChartCached.FloatToStr(value, numericFormatter)); - } - content = TrimAndReplaceLine(content); - } - - public static void ReplaceAxisLabelContent(ref string content, string value) - { - var mc = s_RegexForAxisLabel.Matches(content); - foreach (var m in mc) - { - var old = m.ToString(); - var args = s_RegexSubForAxisLabel.Matches(m.ToString()); - var argsCount = args.Count; - if (argsCount <= 0) continue; - content = content.Replace(old, value); - } - content = TrimAndReplaceLine(content); - } - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Helper/FormatterHelper.cs.meta b/Assets/XCharts/Runtime/Helper/FormatterHelper.cs.meta deleted file mode 100644 index 6c2e5d3..0000000 --- a/Assets/XCharts/Runtime/Helper/FormatterHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0fddcb81df44148ed86496564b120261 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Helper/SerieHelper.cs b/Assets/XCharts/Runtime/Helper/SerieHelper.cs deleted file mode 100644 index 2000726..0000000 --- a/Assets/XCharts/Runtime/Helper/SerieHelper.cs +++ /dev/null @@ -1,783 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static partial class SerieHelper - { - public static double GetMinData(Serie serie, int dimension = 1, DataZoom dataZoom = null) - { - double min = double.MaxValue; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (value < min && !serie.IsIgnoreValue(value)) min = value; - } - } - return min == double.MaxValue ? 0 : min; - } - public static SerieData GetMinSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null) - { - double min = double.MaxValue; - SerieData minData = null; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (value < min && !serie.IsIgnoreValue(value)) - { - min = value; - minData = serieData; - } - } - } - return minData; - } - public static double GetMaxData(Serie serie, int dimension = 1, DataZoom dataZoom = null) - { - double max = double.MinValue; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (value > max && !serie.IsIgnoreValue(value)) max = value; - } - } - return max == double.MinValue ? 0 : max; - } - public static SerieData GetMaxSerieData(Serie serie, int dimension = 1, DataZoom dataZoom = null) - { - double max = double.MinValue; - SerieData maxData = null; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (value > max && !serie.IsIgnoreValue(value)) - { - max = value; - maxData = serieData; - } - } - } - return maxData; - } - - public static double GetAverageData(Serie serie, int dimension = 1, DataZoom dataZoom = null) - { - double total = 0; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (!serie.IsIgnoreValue(value)) - total += value; - } - } - return total != 0 ? total / dataList.Count : 0; - } - - private static List<double> s_TempList = new List<double>(); - public static double GetMedianData(Serie serie, int dimension = 1, DataZoom dataZoom = null) - { - s_TempList.Clear(); - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (!serie.IsIgnoreValue(value)) - s_TempList.Add(value); - } - } - s_TempList.Sort(); - var n = s_TempList.Count; - if (n % 2 == 0) return (s_TempList[n / 2] + s_TempList[n / 2 - 1]) / 2; - else return s_TempList[n / 2]; - } - - /// <summary> - /// Gets the maximum and minimum values of the specified dimension of a serie. - /// |获得系列指定维数的最大最小值。 - /// </summary> - /// <param name="serie">指定系列</param> - /// <param name="dimension">指定维数</param> - /// <param name="min">最小值</param> - /// <param name="max">最大值</param> - /// <param name="dataZoom">缩放组件,默认null</param> - public static void GetMinMaxData(Serie serie, int dimension, out double min, out double max, - DataZoom dataZoom = null) - { - max = double.MinValue; - min = double.MaxValue; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show && serieData.data.Count > dimension) - { - var value = serieData.data[dimension]; - if (!serie.IsIgnoreValue(value)) - { - if (value > max) max = value; - if (value < min) min = value; - } - } - } - } - - /// <summary> - /// Gets the maximum and minimum values of all data in the serie. - /// |获得系列所有数据的最大最小值。 - /// </summary> - /// <param name="serie"></param> - /// <param name="min"></param> - /// <param name="max"></param> - /// <param name="dataZoom"></param> - public static void GetMinMaxData(Serie serie, out double min, out double max, DataZoom dataZoom = null, int dimension = 0) - { - max = double.MinValue; - min = double.MaxValue; - var dataList = serie.GetDataList(dataZoom); - for (int i = 0; i < dataList.Count; i++) - { - var serieData = dataList[i]; - if (serieData.show) - { - var count = 0; - if (dimension > 0) count = dimension; - else count = serie.showDataDimension > serieData.data.Count ? - serieData.data.Count : - serie.showDataDimension; - for (int j = 0; j < count; j++) - { - var value = serieData.data[j]; - if (!serie.IsIgnoreValue(value)) - { - if (value > max) max = value; - if (value < min) min = value; - } - } - } - } - } - - /// <summary> - /// Whether the data for the specified dimension of serie are all 0. - /// |系列指定维数的数据是否全部为0。 - /// </summary> - /// <param name="serie">系列</param> - /// <param name="dimension">指定维数</param> - /// <returns></returns> - public static bool IsAllZeroValue(Serie serie, int dimension = 1) - { - foreach (var serieData in serie.data) - { - if (serieData.GetData(dimension) != 0) return false; - } - return true; - } - - /// <summary> - /// 更新运行时中心点和半径 - /// </summary> - /// <param name="chartWidth"></param> - /// <param name="chartHeight"></param> - public static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight) - { - if (serie.center.Length < 2) return; - var centerX = serie.center[0] <= 1 ? chartWidth * serie.center[0] : serie.center[0]; - var centerY = serie.center[1] <= 1 ? chartHeight * serie.center[1] : serie.center[1]; - serie.context.center = chartPosition + new Vector3(centerX, centerY); - var minWidth = Mathf.Min(chartWidth, chartHeight); - serie.context.insideRadius = serie.radius[0] <= 1 ? minWidth * serie.radius[0] : serie.radius[0]; - serie.context.outsideRadius = serie.radius[1] <= 1 ? minWidth * serie.radius[1] : serie.radius[1]; - } - - public static void UpdateRect(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight) - { - if (serie.left != 0 || serie.right != 0 || serie.top != 0 || serie.bottom != 0) - { - var runtimeLeft = serie.left <= 1 ? serie.left * chartWidth : serie.left; - var runtimeBottom = serie.bottom <= 1 ? serie.bottom * chartHeight : serie.bottom; - var runtimeTop = serie.top <= 1 ? serie.top * chartHeight : serie.top; - var runtimeRight = serie.right <= 1 ? serie.right * chartWidth : serie.right; - - serie.context.x = chartPosition.x + runtimeLeft; - serie.context.y = chartPosition.y + runtimeBottom; - serie.context.width = chartWidth - runtimeLeft - runtimeRight; - serie.context.height = chartHeight - runtimeTop - runtimeBottom; - serie.context.center = new Vector3(serie.context.x + serie.context.width / 2, - serie.context.y + serie.context.height / 2); - serie.context.rect = new Rect(serie.context.x, serie.context.y, serie.context.width, serie.context.height); - } - else - { - serie.context.x = chartPosition.x; - serie.context.y = chartPosition.y; - serie.context.width = chartWidth; - serie.context.height = chartHeight; - serie.context.center = chartPosition + new Vector3(chartWidth / 2, chartHeight / 2); - serie.context.rect = new Rect(serie.context.x, serie.context.y, serie.context.width, serie.context.height); - } - } - - public static Color32 GetItemBackgroundColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, - bool highlight, bool useDefault = true) - { - var color = ChartConst.clearColor32; - if (highlight) - { - var itemStyleEmphasis = GetItemStyleEmphasis(serie, serieData); - if (itemStyleEmphasis != null && !ChartHelper.IsClearColor(itemStyleEmphasis.backgroundColor)) - { - color = itemStyleEmphasis.backgroundColor; - ChartHelper.SetColorOpacity(ref color, itemStyleEmphasis.opacity); - return color; - } - } - var itemStyle = GetItemStyle(serie, serieData); - if (!ChartHelper.IsClearColor(itemStyle.backgroundColor)) - { - color = itemStyle.backgroundColor; - if (highlight) color = ChartHelper.GetHighlightColor(color); - ChartHelper.SetColorOpacity(ref color, itemStyle.opacity); - return color; - } - else if (useDefault) - { - color = theme.GetColor(index); - if (highlight) color = ChartHelper.GetHighlightColor(color); - color.a = 50; - return color; - } - return color; - } - - public static Color32 GetItemColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true) - { - if (serie == null) - return ChartConst.clearColor32; - - ItemStyle itemStyle = null; - if (highlight) - itemStyle = GetItemStyleEmphasis(serie, serieData); - if (itemStyle == null) - itemStyle = GetItemStyle(serie, serieData); - - var color = ChartHelper.IsClearColor(itemStyle.color) ? - theme.GetColor(index) : - itemStyle.color; - - if (highlight) - color = ChartHelper.GetHighlightColor(color); - if (opacity) - ChartHelper.SetColorOpacity(ref color, itemStyle.opacity); - return color; - } - public static Color32 GetItemColor0(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, Color32 defaultColor) - { - if (serie == null) - return ChartConst.clearColor32; - - ItemStyle itemStyle = null; - if (highlight) - itemStyle = GetItemStyleEmphasis(serie, serieData); - if (itemStyle == null) - itemStyle = GetItemStyle(serie, serieData); - - var color = ChartHelper.IsClearColor(itemStyle.color0) ? - defaultColor : - itemStyle.color0; - - if (highlight) - color = ChartHelper.GetHighlightColor(color); - - ChartHelper.SetColorOpacity(ref color, itemStyle.opacity); - return color; - } - - public static Color32 GetItemToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight, bool opacity = true) - { - if (serie == null) - return ChartConst.clearColor32; - - ItemStyle itemStyle = null; - if (highlight) - itemStyle = GetItemStyleEmphasis(serie, serieData); - if (itemStyle == null) - itemStyle = GetItemStyle(serie, serieData); - - var color = itemStyle.toColor; - if (ChartHelper.IsClearColor(color)) - { - color = ChartHelper.IsClearColor(itemStyle.color) ? - theme.GetColor(index) : - itemStyle.color; - } - - if (highlight) - color = ChartHelper.GetHighlightColor(color); - - if (opacity) - ChartHelper.SetColorOpacity(ref color, itemStyle.opacity); - return color; - } - - public static bool IsDownPoint(Serie serie, int index) - { - var dataPoints = serie.context.dataPoints; - if (dataPoints.Count < 2) return false; - else if (index > 0 && index < dataPoints.Count - 1) - { - var lp = dataPoints[index - 1]; - var np = dataPoints[index + 1]; - var cp = dataPoints[index]; - var dot = Vector3.Cross(np - lp, cp - np); - return dot.z < 0; - } - else if (index == 0) - { - return dataPoints[0].y < dataPoints[1].y; - } - else if (index == dataPoints.Count - 1) - { - return dataPoints[index].y < dataPoints[index - 1].y; - } - else - { - return false; - } - } - - public static ItemStyle GetItemStyle(Serie serie, SerieData serieData, bool highlight = false) - { - if (highlight) - { - var style = GetItemStyleEmphasis(serie, serieData); - if (style == null) return GetItemStyle(serie, serieData, false); - else return style; - } - else if (serie.IsPerformanceMode()) return serie.itemStyle; - else if (serieData != null && serieData.itemStyle != null) return serieData.itemStyle; - else return serie.itemStyle; - } - - public static ItemStyle GetItemStyleEmphasis(Serie serie, SerieData serieData) - { - if (!serie.IsPerformanceMode() && serieData != null && serieData.emphasisItemStyle != null && serieData.emphasisItemStyle.show) - return serieData.emphasisItemStyle; - else if (serie.emphasisItemStyle != null && serie.emphasisItemStyle.show) return serie.emphasisItemStyle; - else return null; - } - - public static LabelStyle GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false) - { - if (serieData == null) return serie.label; - if (highlight) - { - if (!serie.IsPerformanceMode() && serieData.emphasisLabel != null && serieData.emphasisLabel.show) - return serieData.emphasisLabel; - else if (serie.emphasisLabel != null && serie.emphasisLabel.show) return serie.emphasisLabel; - else return serie.label; - } - else - { - if (!serie.IsPerformanceMode() && serieData.labelStyle != null) return serieData.labelStyle; - else return serie.label; - } - } - - public static LabelStyle GetSerieEmphasisLabel(Serie serie, SerieData serieData) - { - if (!serie.IsPerformanceMode() && serieData.emphasisLabel != null && serieData.emphasisLabel.show) - return serieData.emphasisLabel; - else if (serie.emphasisLabel != null && serie.emphasisLabel.show) return serie.emphasisLabel; - else return null; - } - - public static LabelLine GetSerieLabelLine(Serie serie, SerieData serieData, bool highlight = false) - { - if (highlight) - { - if (!serie.IsPerformanceMode() && serieData.emphasisLabelLine != null && serieData.emphasisLabelLine.show) - return serieData.emphasisLabelLine; - else if (serie.emphasisLabelLine != null && serie.emphasisLabelLine.show) return serie.emphasisLabelLine; - else return serie.labelLine; - } - else - { - if (!serie.IsPerformanceMode() && serieData.labelLine != null) return serieData.labelLine; - else return serie.labelLine; - } - } - - public static SerieSymbol GetSerieSymbol(Serie serie, SerieData serieData) - { - if (!serie.IsPerformanceMode() && serieData.symbol != null) return serieData.symbol; - else return serie.symbol; - } - - public static LineStyle GetLineStyle(Serie serie, SerieData serieData) - { - if (serieData != null && serieData.lineStyle != null) return serieData.lineStyle; - else return serie.lineStyle; - } - - public static AreaStyle GetAreaStyle(Serie serie, SerieData serieData) - { - if (serieData != null && serieData.areaStyle != null) return serieData.areaStyle; - else return serie.areaStyle; - } - - public static TitleStyle GetTitleStyle(Serie serie, SerieData serieData) - { - if (serieData != null && serieData.titleStyle != null) return serieData.titleStyle; - else return serie.titleStyle; - } - - public static Color32 GetAreaColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight) - { - Color32 color = ChartConst.clearColor32; - var areaStyle = GetAreaStyle(serie, serieData); - if (areaStyle == null || !areaStyle.show) - return color; - if (!ChartHelper.IsClearColor(areaStyle.color)) color = areaStyle.color; - else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.color; - else color = theme.GetColor(index); - ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); - if (highlight) - { - if (!ChartHelper.IsClearColor(areaStyle.highlightColor)) - color = areaStyle.highlightColor; - else - color = ChartHelper.GetHighlightColor(color); - } - return color; - } - - public static Color32 GetAreaToColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight) - { - Color32 color = ChartConst.clearColor32; - var areaStyle = GetAreaStyle(serie, serieData); - if (areaStyle == null || !areaStyle.show) - return color; - if (!ChartHelper.IsClearColor(areaStyle.toColor)) color = areaStyle.toColor; - else if (!ChartHelper.IsClearColor(serie.itemStyle.toColor)) color = serie.itemStyle.toColor; - else color = theme.GetColor(index); - ChartHelper.SetColorOpacity(ref color, areaStyle.opacity); - if (highlight) - { - if (!ChartHelper.IsClearColor(areaStyle.highlightToColor)) - color = areaStyle.highlightToColor; - else - color = ChartHelper.GetHighlightColor(color); - } - return color; - } - - public static Color32 GetLineColor(Serie serie, SerieData serieData, ThemeStyle theme, int index, bool highlight) - { - Color32 color = ChartConst.clearColor32; - var lineStyle = GetLineStyle(serie, serieData); - if (highlight) - { - var itemStyleEmphasis = GetItemStyleEmphasis(serie, null); - if (itemStyleEmphasis != null && !ChartHelper.IsClearColor(itemStyleEmphasis.color)) - { - color = itemStyleEmphasis.color; - ChartHelper.SetColorOpacity(ref color, itemStyleEmphasis.opacity); - return color; - } - } - if (!ChartHelper.IsClearColor(lineStyle.color)) color = lineStyle.color; - else if (!ChartHelper.IsClearColor(serie.itemStyle.color)) color = serie.itemStyle.GetColor(); - if (ChartHelper.IsClearColor(color)) color = theme.GetColor(index); - ChartHelper.SetColorOpacity(ref color, lineStyle.opacity); - if (highlight) color = ChartHelper.GetHighlightColor(color); - return color; - } - - public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight) - { - var itemStyle = GetItemStyle(serie, serieData, highlight); - if (itemStyle != null && itemStyle.borderWidth != 0) return itemStyle.borderWidth; - else return serie.lineStyle.GetWidth(theme.serie.lineWidth) * 2; - } - - public static Color32 GetSymbolBorderColor(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight) - { - var itemStyle = GetItemStyle(serie, serieData, highlight); - if (itemStyle != null && !ChartHelper.IsClearColor(itemStyle.borderColor)) return itemStyle.borderColor; - else return serie.itemStyle.borderColor; - } - - public static float GetSymbolBorder(Serie serie, SerieData serieData, ThemeStyle theme, bool highlight, float defaultWidth) - { - var itemStyle = GetItemStyle(serie, serieData, highlight); - if (itemStyle != null && itemStyle.borderWidth != 0) return itemStyle.borderWidth; - else return defaultWidth; - } - - public static float[] GetSymbolCornerRadius(Serie serie, SerieData serieData, bool highlight) - { - var itemStyle = GetItemStyle(serie, serieData, highlight); - if (itemStyle != null) return itemStyle.cornerRadius; - else return null; - } - - public static string GetNumericFormatter(Serie serie, SerieData serieData, string defaultFormatter = null) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - if (!string.IsNullOrEmpty(itemStyle.numericFormatter)) return itemStyle.numericFormatter; - else return defaultFormatter; - } - - public static string GetItemFormatter(Serie serie, SerieData serieData, string defaultFormatter = null) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - if (!string.IsNullOrEmpty(itemStyle.itemFormatter)) return itemStyle.itemFormatter; - else return defaultFormatter; - } - - public static string GetItemMarker(Serie serie, SerieData serieData, string defaultMarker = null) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - if (!string.IsNullOrEmpty(itemStyle.itemMarker)) return itemStyle.itemMarker; - else return defaultMarker; - } - - /// <summary> - /// 获得指定维数的最大最小值 - /// </summary> - /// <param name="dimension"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public static void UpdateMinMaxData(Serie serie, int dimension, int ceilRate = 0, DataZoom dataZoom = null) - { - double min = 0, max = 0; - GetMinMaxData(serie, dimension, out min, out max, dataZoom); - if (ceilRate < 0) - { - serie.context.dataMin = min; - serie.context.dataMax = max; - } - else - { - serie.context.dataMin = ChartHelper.GetMinDivisibleValue(min, ceilRate); - serie.context.dataMax = ChartHelper.GetMaxDivisibleValue(max, ceilRate); - } - } - - public static void GetAllMinMaxData(Serie serie, int ceilRate = 0, DataZoom dataZoom = null) - { - double min = 0, max = 0; - GetMinMaxData(serie, out min, out max, dataZoom); - if (ceilRate < 0) - { - serie.context.dataMin = min; - serie.context.dataMax = max; - } - else - { - serie.context.dataMin = ChartHelper.GetMinDivisibleValue(min, ceilRate); - serie.context.dataMax = ChartHelper.GetMaxDivisibleValue(max, ceilRate); - } - } - - private static List<SerieData> emptyFilter = new List<SerieData>(); - /// <summary> - /// 根据dataZoom更新数据列表缓存 - /// </summary> - /// <param name="dataZoom"></param> - public static void UpdateFilterData(Serie serie, DataZoom dataZoom) - { - if (dataZoom == null || !dataZoom.enable) return; - if (dataZoom.IsContainsXAxis(serie.xAxisIndex)) - { - if (dataZoom.IsXAxisIndexValue(serie.xAxisIndex)) - { - double min = 0, max = 0; - dataZoom.GetXAxisIndexValue(serie.xAxisIndex, out min, out max); - UpdateFilterData_XAxisValue(serie, dataZoom, 0, min, max); - } - else - { - UpdateFilterData_Category(serie, dataZoom); - } - } - else if (dataZoom.IsContainsYAxis(serie.yAxisIndex)) - { - if (dataZoom.IsYAxisIndexValue(serie.yAxisIndex)) - { - double min = 0, max = 0; - dataZoom.GetYAxisIndexValue(serie.yAxisIndex, out min, out max); - UpdateFilterData_XAxisValue(serie, dataZoom, 0, min, max); - } - else - { - UpdateFilterData_Category(serie, dataZoom); - } - } - } - - private static void UpdateFilterData_XAxisValue(Serie serie, DataZoom dataZoom, int dimension, double min, double max) - { - var data = serie.data; - var startValue = min + (max - min) * dataZoom.start / 100; - var endValue = min + (max - min) * dataZoom.end / 100; - if (endValue < startValue) endValue = startValue; - - if (startValue != serie.m_FilterStartValue || endValue != serie.m_FilterEndValue || - dataZoom.minShowNum != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData) - { - serie.m_FilterStartValue = startValue; - serie.m_FilterEndValue = endValue; - serie.m_FilterMinShow = dataZoom.minShowNum; - serie.m_NeedUpdateFilterData = false; - - serie.m_FilterData.Clear(); - foreach (var serieData in data) - { - var value = serieData.GetData(dimension); - if (value >= startValue && value <= endValue) - { - serie.m_FilterData.Add(serieData); - } - } - } - else if (endValue == 0) - { - serie.m_FilterData = emptyFilter; - } - } - - private static void UpdateFilterData_Category(Serie serie, DataZoom dataZoom) - { - var data = serie.data; - var range = Mathf.RoundToInt(data.Count * (dataZoom.end - dataZoom.start) / 100); - if (range <= 0) range = 1; - int start = 0, end = 0; - if (dataZoom.context.invert) - { - end = Mathf.CeilToInt(data.Count * dataZoom.end / 100); - start = end - range; - if (start < 0) start = 0; - } - else - { - start = Mathf.FloorToInt(data.Count * dataZoom.start / 100); - end = start + range; - if (end > data.Count) end = data.Count; - } - if (start != serie.m_FilterStart || end != serie.m_FilterEnd || - dataZoom.minShowNum != serie.m_FilterMinShow || serie.m_NeedUpdateFilterData) - { - serie.m_FilterStart = start; - serie.m_FilterEnd = end; - serie.m_FilterMinShow = dataZoom.minShowNum; - serie.m_NeedUpdateFilterData = false; - if (data.Count > 0) - { - if (range < dataZoom.minShowNum) - { - if (dataZoom.minShowNum > data.Count) range = data.Count; - else range = dataZoom.minShowNum; - } - if (range > data.Count - start - 1) - start = data.Count - range - 1; - if (start >= 0) - serie.m_FilterData = data.GetRange(start, range); - else - serie.m_FilterData = data; - } - else - { - serie.m_FilterData = data; - } - } - else if (end == 0) - { - serie.m_FilterData = emptyFilter; - } - } - - public static void UpdateSerieRuntimeFilterData(Serie serie, bool filterInvisible = true) - { - serie.context.sortedData.Clear(); - foreach (var serieData in serie.data) - { - if (!filterInvisible || (filterInvisible && serieData.show)) - serie.context.sortedData.Add(serieData); - } - switch (serie.dataSortType) - { - case SerieDataSortType.Ascending: - serie.context.sortedData.Sort(delegate(SerieData data1, SerieData data2) - { - var value1 = data1.GetData(1); - var value2 = data2.GetData(1); - if (value1 == value2) return 0; - else if (value1 > value2) return 1; - else return -1; - }); - break; - case SerieDataSortType.Descending: - serie.context.sortedData.Sort(delegate(SerieData data1, SerieData data2) - { - var value1 = data1.GetData(1); - var value2 = data2.GetData(1); - if (value1 == value2) return 0; - else if (value1 > value2) return -1; - else return 1; - }); - break; - case SerieDataSortType.None: - break; - } - } - - public static T CloneSerie<T>(Serie serie) where T : Serie - { - var newSerie = Activator.CreateInstance<T>(); - SerieHelper.CopySerie(serie, newSerie); - return newSerie; - } - - public static void CopySerie(Serie oldSerie, Serie newSerie) - { - var fields = typeof(Serie).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - foreach (var field in fields) - { - if (field.IsDefined(typeof(SerializeField), false)) - { - var filedValue = field.GetValue(oldSerie); - if (filedValue == null) continue; - var filedType = filedValue.GetType(); - if (filedType.IsClass) - field.SetValue(newSerie, ReflectionUtil.DeepCloneSerializeField(filedValue)); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Helper/SerieHelper.cs.meta b/Assets/XCharts/Runtime/Helper/SerieHelper.cs.meta deleted file mode 100644 index a2ba9d1..0000000 --- a/Assets/XCharts/Runtime/Helper/SerieHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8c031417514104eebb5bbd60dd1f90fd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs b/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs deleted file mode 100644 index fc189a1..0000000 --- a/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class SerieLabelHelper - { - - public static Color GetLabelColor(Serie serie, ThemeStyle theme, int index) - { - if (serie.label != null && !ChartHelper.IsClearColor(serie.label.textStyle.color)) - { - return serie.label.textStyle.color; - } - else - { - return theme.GetColor(index); - } - } - - public static void ResetLabel(ChartText labelObject, LabelStyle label, ThemeStyle theme, - Color textColor, float rotate) - { - if (labelObject == null) return; - labelObject.SetColor(textColor); - labelObject.SetLocalEulerAngles(new Vector3(0, 0, rotate)); - labelObject.SetFontSize(label.textStyle.GetFontSize(theme.common)); - labelObject.SetFontStyle(label.textStyle.fontStyle); - } - - public static bool CanShowLabel(Serie serie, SerieData serieData, LabelStyle label, int dimesion) - { - return serie.show && serieData.context.canShowLabel && !serie.IsIgnoreValue(serieData, dimesion); - } - - public static string GetFormatterContent(Serie serie, SerieData serieData, - double dataValue, double dataTotal, LabelStyle serieLabel, Color color) - { - if (serieLabel == null) - { - serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - } - var numericFormatter = serieLabel == null ? "" : serieLabel.numericFormatter; - var serieName = serie.serieName; - var dataName = serieData != null ? serieData.name : null; - if (serieLabel.formatterFunction != null) - { - return serieLabel.formatterFunction(serieData.index, dataValue, null); - } - if (string.IsNullOrEmpty(serieLabel.formatter)) - return ChartCached.NumberToStr(dataValue, numericFormatter); - else - { - var content = serieLabel.formatter; - FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, serie.dataCount, dataValue, - dataTotal, serieName, dataName, dataName, color); - return content; - } - } - - public static void SetGaugeLabelText(Serie serie) - { - var serieData = serie.GetSerieData(0); - if (serieData == null) return; - if (serieData.labelObject == null) return; - var label = SerieHelper.GetSerieLabel(serie, serieData); - if (label == null) return; - var value = serieData.GetData(1); - var total = serie.max; - var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear); - serieData.labelObject.SetText(content); - serieData.labelObject.SetPosition(serie.context.center + label.offset); - if (!ChartHelper.IsClearColor(label.textStyle.color)) - { - serieData.labelObject.text.SetColor(label.textStyle.color); - } - } - - public static void UpdatePieLabelPosition(Serie serie, SerieData serieData) - { - if (serieData.labelObject == null) return; - var startAngle = serie.context.startAngle; - var currAngle = serieData.context.halfAngle; - var currRad = currAngle * Mathf.Deg2Rad; - var offsetRadius = serieData.context.offsetRadius; - var insideRadius = serieData.context.insideRadius; - var outsideRadius = serieData.context.outsideRadius; - var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); - switch (serieLabel.position) - { - case LabelStyle.Position.Center: - serieData.context.labelPosition = serie.context.center; - break; - case LabelStyle.Position.Inside: - var labelRadius = offsetRadius + insideRadius + (outsideRadius - insideRadius) / 2 + serieLabel.distance; - var labelCenter = new Vector2(serie.context.center.x + labelRadius * Mathf.Sin(currRad), - serie.context.center.y + labelRadius * Mathf.Cos(currRad)); - serieData.context.labelPosition = labelCenter; - break; - default: - //LabelStyle.Position.Outside - if (labelLine != null && labelLine.lineType == LabelLine.LineType.HorizontalLine) - { - var radius1 = serie.context.outsideRadius; - var radius3 = insideRadius + (outsideRadius - insideRadius) / 2; - var currSin = Mathf.Sin(currRad); - var currCos = Mathf.Cos(currRad); - var pos0 = new Vector3(serie.context.center.x + radius3 * currSin, serie.context.center.y + radius3 * currCos); - if ((currAngle - startAngle) % 360 > 180) - { - currSin = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad); - currCos = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad); - } - var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3; - r4 += labelLine.lineLength1 + labelLine.lineWidth * 4; - r4 += serieData.labelObject.text.GetPreferredWidth() / 2; - serieData.context.labelPosition = pos0 + ((currAngle - startAngle) % 360 > 180 ? Vector3.left : Vector3.right) * r4; - } - else - { - labelRadius = serie.context.outsideRadius + (labelLine == null ? 0 : labelLine.lineLength1); - labelCenter = new Vector2(serie.context.center.x + labelRadius * Mathf.Sin(currRad), - serie.context.center.y + labelRadius * Mathf.Cos(currRad)); - serieData.context.labelPosition = labelCenter; - } - break; - } - } - - public static void AvoidLabelOverlap(Serie serie, ComponentTheme theme) - { - if (!serie.avoidLabelOverlap) return; - var lastCheckPos = Vector3.zero; - var data = serie.data; - var splitCount = 0; - for (int n = 0; n < data.Count; n++) - { - var serieData = data[n]; - if (serieData.context.labelPosition.x != 0 && serieData.context.labelPosition.x < serie.context.center.x) - { - splitCount = n; - break; - } - } - for (int n = 0; n < splitCount; n++) - { - CheckSerieDataLabel(serie, data[n], false, theme, ref lastCheckPos); - } - lastCheckPos = Vector3.zero; - for (int n = data.Count - 1; n >= splitCount; n--) - { - CheckSerieDataLabel(serie, data[n], true, theme, ref lastCheckPos); - } - } - - private static void CheckSerieDataLabel(Serie serie, SerieData serieData, bool isLeft, ComponentTheme theme, - ref Vector3 lastCheckPos) - { - if (!serieData.context.canShowLabel) - { - serieData.SetLabelActive(false); - return; - } - if (!serieData.show) return; - var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); - var fontSize = serieLabel.textStyle.GetFontSize(theme); - var isOutside = serieLabel.position == LabelStyle.Position.Outside || - serieLabel.position == LabelStyle.Position.Default; - if (!serieLabel.show) return; - if (!isOutside) return; - if (lastCheckPos == Vector3.zero) - { - lastCheckPos = serieData.context.labelPosition; - } - else if (serieData.context.labelPosition.x != 0) - { - if (lastCheckPos.y - serieData.context.labelPosition.y < fontSize) - { - var labelRadius = serie.context.outsideRadius + labelLine.lineLength1; - var y1 = lastCheckPos.y - fontSize; - var cy = serie.context.center.y; - var diff = Mathf.Abs(y1 - cy); - var diffX = labelRadius * labelRadius - diff * diff; - diffX = diffX <= 0 ? 0 : diffX; - var x1 = serie.context.center.x + Mathf.Sqrt(diffX) * (isLeft ? -1 : 1); - serieData.context.labelPosition = new Vector3(x1, y1); - } - lastCheckPos = serieData.context.labelPosition; - serieData.labelObject.SetPosition(SerieLabelHelper.GetRealLabelPosition(serie, serieData, serieLabel, labelLine)); - } - } - - public static Vector3 GetRealLabelPosition(Serie serie, SerieData serieData, LabelStyle label, LabelLine labelLine) - { - if (label == null || labelLine == null) - return serieData.context.labelPosition; - var isOutside = label.position == LabelStyle.Position.Outside || - label.position == LabelStyle.Position.Default; - if (isOutside && labelLine.lineType != LabelLine.LineType.HorizontalLine) - { - var currAngle = serieData.context.halfAngle; - var offset = labelLine.lineLength2 + serieData.labelObject.GetTextWidth() / 2; - if ((currAngle - serie.context.startAngle) % 360 > 180) - return serieData.context.labelPosition + new Vector3(-offset, 0, 0); - else - return serieData.context.labelPosition + new Vector3(offset, 0, 0); - } - else - { - return serieData.context.labelPosition; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs.meta b/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs.meta deleted file mode 100644 index 5b4a31f..0000000 --- a/Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0b81cddd3452545748563f9c6ea9be69 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Helper/SeriesHelper.cs b/Assets/XCharts/Runtime/Helper/SeriesHelper.cs deleted file mode 100644 index 09be09c..0000000 --- a/Assets/XCharts/Runtime/Helper/SeriesHelper.cs +++ /dev/null @@ -1,452 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class SeriesHelper - { - - public static bool IsLegalLegendName(string name) - { - int numName = -1; - if (int.TryParse(name, out numName)) - { - if (numName >= 0 && numName < 100) return false; - } - return true; - } - - public static List<string> GetLegalSerieNameList(List<Serie> series) - { - var list = new List<string>(); - for (int n = 0; n < series.Count; n++) - { - var serie = series[n]; - if (serie.placeHolder) continue; - if (serie.useDataNameForColor) - { - for (int i = 0; i < serie.data.Count; i++) - { - var dataName = serie.data[i].name; - if (!string.IsNullOrEmpty(dataName) && IsLegalLegendName(dataName) && !list.Contains(dataName)) - list.Add(dataName); - } - } - else - { - if (!string.IsNullOrEmpty(serie.serieName) && !list.Contains(serie.serieName) && IsLegalLegendName(serie.serieName)) - list.Add(serie.serieName); - } - } - return list; - } - - /// <summary> - /// 获得所有系列名,不包含空名字。 - /// </summary> - /// <returns></returns> - public static void UpdateSerieNameList(BaseChart chart, ref List<string> serieNameList) - { - serieNameList.Clear(); - for (int n = 0; n < chart.series.Count; n++) - { - var serie = chart.series[n]; - if (serie.placeHolder) continue; - if (serie.useDataNameForColor) - { - for (int i = 0; i < serie.data.Count; i++) - { - var serieData = serie.data[i]; - if (serie is Pie && serie.IsIgnoreValue(serieData)) continue; - if (string.IsNullOrEmpty(serieData.name)) - serieNameList.Add(ChartCached.IntToStr(i)); - else if (!serieNameList.Contains(serieData.name)) - serieNameList.Add(serieData.name); - } - } - else - { - if (string.IsNullOrEmpty(serie.serieName)) - serieNameList.Add(ChartCached.IntToStr(n)); - else if (!serieNameList.Contains(serie.serieName)) - serieNameList.Add(serie.serieName); - } - } - } - - public static Color GetNameColor(BaseChart chart, int index, string name) - { - Serie destSerie = null; - SerieData destSerieData = null; - var series = chart.series; - for (int n = 0; n < series.Count; n++) - { - var serie = series[n]; - if (serie.placeHolder) continue; - if (serie.useDataNameForColor) - { - bool found = false; - for (int i = 0; i < serie.data.Count; i++) - { - if (name.Equals(serie.data[i].name)) - { - destSerie = serie; - destSerieData = serie.data[i]; - found = true; - break; - } - } - if (found) break; - } - if (name.Equals(serie.serieName)) - { - destSerie = serie; - destSerieData = null; - break; - } - } - return SerieHelper.GetItemColor(destSerie, destSerieData, chart.theme, index, false); - } - - /// <summary> - /// 是否有需裁剪的serie。 - /// </summary> - /// <returns></returns> - public static bool IsAnyClipSerie(List<Serie> series) - { - foreach (var serie in series) - { - if (serie.clip) return true; - } - return false; - } - - /// <summary> - /// 获得上一个同堆叠且显示的serie。 - /// </summary> - /// <param name="serie"></param> - /// <returns></returns> - public static Serie GetLastStackSerie(List<Serie> series, Serie serie) - { - if (serie == null || string.IsNullOrEmpty(serie.stack)) return null; - for (int i = serie.index - 1; i >= 0; i--) - { - var temp = series[i]; - if (temp.show && serie.stack.Equals(temp.stack)) return temp; - } - return null; - } - - public static Serie GetSerieByVesselIndex(List<Serie> series, int vesselIndex) - { - foreach (var serie in series) - { - if (serie.vesselIndex == vesselIndex) return serie; - } - return null; - } - - private static HashSet<string> _setForStack = new HashSet<string>(); - /// <summary> - /// 是否由数据堆叠 - /// </summary> - /// <returns></returns> - public static bool IsStack(List<Serie> series) - { - _setForStack.Clear(); - foreach (var serie in series) - { - if (string.IsNullOrEmpty(serie.stack)) continue; - if (_setForStack.Contains(serie.stack)) return true; - _setForStack.Add(serie.stack); - } - return false; - } - - /// <summary> - /// 是否堆叠 - /// </summary> - /// <param name="stackName"></param> - /// <param name="type"></param> - /// <returns></returns> - public static bool IsStack<T>(List<Serie> series, string stackName) where T : Serie - { - if (string.IsNullOrEmpty(stackName)) return false; - int count = 0; - foreach (var serie in series) - { - if (serie.show && serie is T) - { - if (stackName.Equals(serie.stack)) count++; - if (count >= 2) return true; - } - } - return false; - } - - /// <summary> - /// 是否时百分比堆叠 - /// </summary> - /// <param name="type"></param> - /// <returns></returns> - public static bool IsPercentStack<T>(List<Serie> series) where T : Serie - { - int count = 0; - bool isPercentStack = false; - foreach (var serie in series) - { - if (serie.show && serie is T) - { - if (!string.IsNullOrEmpty(serie.stack)) - { - count++; - if (serie.barPercentStack) isPercentStack = true; - } - if (count >= 2 && isPercentStack) return true; - } - } - return false; - } - - /// <summary> - /// 是否时百分比堆叠 - /// </summary> - /// <param name="stackName"></param> - /// <param name="type"></param> - /// <returns></returns> - public static bool IsPercentStack<T>(List<Serie> series, string stackName) where T : Serie - { - if (string.IsNullOrEmpty(stackName)) return false; - int count = 0; - bool isPercentStack = false; - foreach (var serie in series) - { - if (serie.show && serie is T) - { - if (stackName.Equals(serie.stack)) - { - count++; - if (serie.barPercentStack) isPercentStack = true; - } - if (count >= 2 && isPercentStack) return true; - } - } - return false; - } - - private static Dictionary<string, int> sets = new Dictionary<string, int>(); - /// <summary> - /// 获得堆叠系列列表 - /// </summary> - /// <param name="Dictionary<int"></param> - /// <param name="stackSeries"></param> - public static void GetStackSeries(List<Serie> series, ref Dictionary<int, List<Serie>> stackSeries) - { - int count = 0; - var serieCount = series.Count; - sets.Clear(); - if (stackSeries == null) - { - stackSeries = new Dictionary<int, List<Serie>>(serieCount); - } - else - { - foreach (var kv in stackSeries) - { - kv.Value.Clear(); - } - } - for (int i = 0; i < serieCount; i++) - { - var serie = series[i]; - serie.index = i; - if (string.IsNullOrEmpty(serie.stack)) - { - if (!stackSeries.ContainsKey(count)) - stackSeries[count] = new List<Serie>(serieCount); - stackSeries[count].Add(serie); - count++; - } - else - { - if (!sets.ContainsKey(serie.stack)) - { - sets.Add(serie.stack, count); - if (!stackSeries.ContainsKey(count)) - stackSeries[count] = new List<Serie>(serieCount); - stackSeries[count].Add(serie); - count++; - } - else - { - int stackIndex = sets[serie.stack]; - stackSeries[stackIndex].Add(serie); - } - } - } - } - - public static void UpdateStackDataList(List<Serie> series, Serie currSerie, DataZoom dataZoom, List<List<SerieData>> dataList) - { - dataList.Clear(); - for (int i = 0; i <= currSerie.index; i++) - { - var serie = series[i]; - if (serie.GetType() == currSerie.GetType() && ChartHelper.IsValueEqualsString(serie.stack, currSerie.stack)) - { - dataList.Add(serie.GetDataList(dataZoom)); - } - } - } - - /// <summary> - /// 获得维度X的最大最小值 - /// </summary> - /// <param name="dataZoom"></param> - /// <param name="axisIndex"></param> - /// <param name="minVaule"></param> - /// <param name="maxValue"></param> - public static void GetXMinMaxValue(List<Serie> series, DataZoom dataZoom, int axisIndex, bool isValueAxis, - bool inverse, out double minVaule, out double maxValue, bool isPolar = false) - { - GetMinMaxValue(series, dataZoom, axisIndex, isValueAxis, inverse, false, out minVaule, out maxValue, isPolar); - } - - /// <summary> - /// 获得维度Y的最大最小值 - /// </summary> - /// <param name="dataZoom"></param> - /// <param name="axisIndex"></param> - /// <param name="minVaule"></param> - /// <param name="maxValue"></param> - public static void GetYMinMaxValue(List<Serie> series, DataZoom dataZoom, int axisIndex, bool isValueAxis, - bool inverse, out double minVaule, out double maxValue, bool isPolar = false) - { - GetMinMaxValue(series, dataZoom, axisIndex, isValueAxis, inverse, true, out minVaule, out maxValue, isPolar); - } - - private static Dictionary<int, List<Serie>> _stackSeriesForMinMax = new Dictionary<int, List<Serie>>(); - private static Dictionary<int, double> _serieTotalValueForMinMax = new Dictionary<int, double>(); - public static void GetMinMaxValue(List<Serie> series, DataZoom dataZoom, int axisIndex, bool isValueAxis, - bool inverse, bool yValue, out double minVaule, out double maxValue, bool isPolar = false) - { - double min = double.MaxValue; - double max = double.MinValue; - var isPercentStack = SeriesHelper.IsPercentStack<Bar>(series); - if (!SeriesHelper.IsStack(series) || (isValueAxis && !yValue)) - { - for (int i = 0; i < series.Count; i++) - { - var serie = series[i]; - if ((isPolar && serie.polarIndex != axisIndex) || - (!isPolar && serie.yAxisIndex != axisIndex) || - !serie.show) continue; - var updateDuration = serie.animation.enable?serie.animation.dataChangeDuration : 0; - if (isPercentStack && SeriesHelper.IsPercentStack<Bar>(series, serie.serieName)) - { - if (100 > max) max = 100; - if (0 < min) min = 0; - } - else - { - var showData = serie.GetDataList(dataZoom); - foreach (var data in showData) - { - - if (serie is Candlestick) - { - var dataMin = data.GetMinData(inverse); - var dataMax = data.GetMaxData(inverse); - if (dataMax > max) max = dataMax; - if (dataMin < min) min = dataMin; - } - else - { - //var currData = data.GetData(yValue ? 1 : 0, inverse); - var currData = data.GetCurrData(yValue ? 1 : 0, updateDuration, inverse); - if (!serie.IsIgnoreValue(currData)) - { - if (currData > max) max = currData; - if (currData < min) min = currData; - } - } - } - } - } - } - else - { - SeriesHelper.GetStackSeries(series, ref _stackSeriesForMinMax); - foreach (var ss in _stackSeriesForMinMax) - { - _serieTotalValueForMinMax.Clear(); - for (int i = 0; i < ss.Value.Count; i++) - { - var serie = ss.Value[i]; - if ((isPolar && serie.polarIndex != axisIndex) || - (!isPolar && serie.yAxisIndex != axisIndex) || - !serie.show) continue; - var showData = serie.GetDataList(dataZoom); - if (SeriesHelper.IsPercentStack<Bar>(series, serie.stack)) - { - for (int j = 0; j < showData.Count; j++) - { - _serieTotalValueForMinMax[j] = 100; - } - } - else - { - for (int j = 0; j < showData.Count; j++) - { - if (!_serieTotalValueForMinMax.ContainsKey(j)) - _serieTotalValueForMinMax[j] = 0; - double currData = 0; - if (serie is Candlestick) - { - currData = showData[j].GetMaxData(false); - } - else - { - currData = yValue ? showData[j].GetData(1) : showData[j].GetData(0); - } - if (inverse) currData = -currData; - if (!serie.IsIgnoreValue(currData)) - _serieTotalValueForMinMax[j] = _serieTotalValueForMinMax[j] + currData; - } - } - } - double tmax = double.MinValue; - double tmin = double.MaxValue; - foreach (var tt in _serieTotalValueForMinMax) - { - if (tt.Value > tmax) tmax = tt.Value; - if (tt.Value < tmin) tmin = tt.Value; - } - if (tmax > max) max = tmax; - if (tmin < min) min = tmin; - } - } - if (max == double.MinValue && min == double.MaxValue) - { - minVaule = 0; - maxValue = 0; - } - else - { - minVaule = min > 1 ? Math.Floor(min) : min; - maxValue = max > 1 ? Math.Ceiling(max) : max; - } - } - - public static int GetMaxSerieDataCount(List<Serie> series) - { - int max = 0; - foreach (var serie in series) - { - if (serie.dataCount > max) max = serie.dataCount; - } - return max; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Helper/SeriesHelper.cs.meta b/Assets/XCharts/Runtime/Helper/SeriesHelper.cs.meta deleted file mode 100644 index bda31ea..0000000 --- a/Assets/XCharts/Runtime/Helper/SeriesHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 96a06a5949772464da15c44ae2ad400d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/I18n.meta b/Assets/XCharts/Runtime/I18n.meta deleted file mode 100644 index 3486925..0000000 --- a/Assets/XCharts/Runtime/I18n.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3091670d5958a4fbaa9024b5cda31f1d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/I18n/Lang.cs b/Assets/XCharts/Runtime/I18n/Lang.cs deleted file mode 100644 index eb62484..0000000 --- a/Assets/XCharts/Runtime/I18n/Lang.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Language. - /// |国际化语言表。 - /// </summary> - [Serializable] - [CreateAssetMenu(menuName = "XCharts/Export Lang")] - public class Lang : ScriptableObject - { - public string langName = "EN"; - public LangTime time = new LangTime(); - public LangCandlestick candlestick = new LangCandlestick(); - - public string GetMonthAbbr(int month) - { - if (month < 1 && month > 12) return month.ToString(); - else return time.monthAbbr[month - 1]; - } - - public string GetDay(int day) - { - day = day - 1; - if (day >= 0 && day < time.dayOfMonth.Count - 1) - return time.dayOfMonth[day]; - else - return day.ToString(); - } - - public string GetCandlestickDimensionName(int i) - { - if (i >= 0 && i < candlestick.dimensionNames.Count) - return candlestick.dimensionNames[i]; - else - return string.Empty; - } - } - - [Serializable] - public class LangTime - { - public List<string> months = new List<string>() - { - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December" - }; - public List<string> monthAbbr = new List<string>() - { - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - }; - public List<string> dayOfMonth = new List<string>() - { - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "14", - "15", - "16", - "17", - "18", - "19", - "20", - "21", - "22", - "23", - "24", - "25", - "26", - "27", - "28", - "29", - "30", - "31" - }; - public List<string> dayOfWeek = new List<string>() - { - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday" - }; - public List<string> dayOfWeekAbbr = new List<string>() - { - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat" - }; - } - - [Serializable] - public class LangCandlestick - { - public List<string> dimensionNames = new List<string>() { "open", "close", "lowest", "highest" }; - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/I18n/Lang.cs.meta b/Assets/XCharts/Runtime/I18n/Lang.cs.meta deleted file mode 100644 index 1f35cfa..0000000 --- a/Assets/XCharts/Runtime/I18n/Lang.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b65fc8b25febc4b9e8acb500d16770b2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal.meta b/Assets/XCharts/Runtime/Internal.meta deleted file mode 100644 index 791d17b..0000000 --- a/Assets/XCharts/Runtime/Internal.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 750348e0c6842d74e872391f6ea942da -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes.meta b/Assets/XCharts/Runtime/Internal/Attributes.meta deleted file mode 100644 index d27d0ee..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: aa2d903c5b18c41f78b61bd01f1512f3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs deleted file mode 100644 index 5827d57..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class ComponentHandlerAttribute : Attribute - { - public readonly Type handler; - public readonly bool allowMultiple = true; - - public ComponentHandlerAttribute(Type handler) - { - this.handler = handler; - this.allowMultiple = true; - } - - public ComponentHandlerAttribute(Type handler, bool allowMultiple) - { - this.handler = handler; - this.allowMultiple = allowMultiple; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs.meta deleted file mode 100644 index 0cabefc..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ComponentHandlerAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 396f8e713effb49fa8757d45944e7d30 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs deleted file mode 100644 index b1040ca..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class CoordOptionsAttribute : Attribute - { - public readonly Type type0; - public readonly Type type1; - public readonly Type type2; - public readonly Type type3; - - public CoordOptionsAttribute(Type coord) - { - type0 = coord; - } - public CoordOptionsAttribute(Type coord, Type coord2) - { - type0 = coord; - type1 = coord2; - } - public CoordOptionsAttribute(Type coord, Type coord2, Type coord3) - { - type0 = coord; - type1 = coord2; - type2 = coord3; - } - public CoordOptionsAttribute(Type coord, Type coord2, Type coord3, Type coord4) - { - type0 = coord; - type1 = coord2; - type2 = coord3; - type3 = coord4; - } - - public bool Contains<T>() where T : CoordSystem - { - var type = typeof(T); - return (type == type0 || type == type1 || type == type2 || type == type3); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs.meta deleted file mode 100644 index faba950..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/CoordOptionsAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8c03247521a944507bcdb1bcfbbc6006 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs deleted file mode 100644 index d680761..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class DefaultAnimationAttribute : Attribute - { - public readonly AnimationType type; - - public DefaultAnimationAttribute(AnimationType handler) - { - this.type = handler; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs.meta deleted file mode 100644 index 8b15da5..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/DefaultAnimationAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b25b7b1d8388945d4bf78e54f094470f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs deleted file mode 100644 index dbbc307..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - public class IgnoreDoc : Attribute - { - public IgnoreDoc() - { - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs.meta deleted file mode 100644 index aab5242..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/IgnoreDocAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd89bf9e568d34de089f71258f2bd211 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs deleted file mode 100644 index 0a96ce6..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - public class ListFor : Attribute - { - public readonly Type type; - - public ListFor(Type type) - { - this.type = type; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs.meta deleted file mode 100644 index d4d2d6e..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ListForAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 34edd91ec3857490fa2f04c620e44299 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs deleted file mode 100644 index 52a9881..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - public sealed class ListForComponent : ListFor - { - public ListForComponent(Type type) : base(type) - { } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs.meta deleted file mode 100644 index dca1752..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ListForComponentAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 529bcbd6bb69b4aac905c44451077ca5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs deleted file mode 100644 index 07bcf23..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - public sealed class ListForSerie : ListFor - { - public ListForSerie(Type type) : base(type) - { } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs.meta deleted file mode 100644 index f5a2afd..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/ListForSerieAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2723e22555ab04116892a8c7d5c75fbd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs deleted file mode 100644 index 551bb9a..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class RequireChartComponentAttribute : Attribute - { - public readonly Type type0; - public readonly Type type1; - public readonly Type type2; - - public RequireChartComponentAttribute(Type requiredComponent) - { - type0 = requiredComponent; - } - public RequireChartComponentAttribute(Type requiredComponent, Type requiredComponent2) - { - type0 = requiredComponent; - type1 = requiredComponent2; - } - public RequireChartComponentAttribute(Type requiredComponent, Type requiredComponent2, Type requiredComponent3) - { - type0 = requiredComponent; - type1 = requiredComponent2; - type2 = requiredComponent3; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs.meta deleted file mode 100644 index 3ad3719..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/RequireChartComponentAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1f27bf434cb8045a6b5d02930f8df479 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs deleted file mode 100644 index 1586119..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - /// <summary> - /// What serie can convert to me - /// </summary> - public sealed class SerieConvertAttribute : Attribute - { - public readonly Type type0; - public readonly Type type1; - public readonly Type type2; - public readonly Type type3; - - public SerieConvertAttribute(Type serie) - { - type0 = serie; - } - public SerieConvertAttribute(Type serie, Type serie2) - { - type0 = serie; - type1 = serie2; - } - public SerieConvertAttribute(Type serie, Type serie2, Type serie3) - { - type0 = serie; - type1 = serie2; - type2 = serie3; - } - public SerieConvertAttribute(Type serie, Type serie2, Type serie3, Type serie4) - { - type0 = serie; - type1 = serie2; - type2 = serie3; - type3 = serie4; - } - - public bool Contains<T>() where T : Serie - { - return Contains(typeof(T)); - } - - public bool Contains(Type type) - { - return (type == type0 || type == type1 || type == type2 || type == type3); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs.meta deleted file mode 100644 index b4de61a..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieConvertAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 74af4595d38cb43ca8f11348cc979137 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs deleted file mode 100644 index cd16379..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class SerieDataExtraComponentAttribute : Attribute - { - public readonly List<Type> types = new List<Type>(); - - public SerieDataExtraComponentAttribute() - { } - public SerieDataExtraComponentAttribute(Type type1) - { - AddType(type1); - } - public SerieDataExtraComponentAttribute(Type type1, Type type2) - { - AddType(type1); - AddType(type2); - } - public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3) - { - AddType(type1); - AddType(type2); - AddType(type3); - } - public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - } - public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - AddType(type5); - } - public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - AddType(type5); - AddType(type6); - } - public SerieDataExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - AddType(type5); - AddType(type6); - AddType(type7); - } - - private void AddType(Type type) - { - if (!SerieData.extraComponentMap.ContainsKey(type)) - throw new ArgumentException("SerieData not support extra component:" + type); - types.Add(type); - } - - public bool Contains<T>() where T : ISerieExtraComponent - { - return Contains(typeof(T)); - } - - public bool Contains(Type type) - { - return types.Contains(type); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs.meta deleted file mode 100644 index 43120ee..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraComponentAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a77e2e342c09c4c6b95a0094ad0fcffc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs deleted file mode 100644 index 12e2c3f..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class SerieDataExtraFieldAttribute : Attribute - { - public readonly List<string> fields = new List<string>(); - - public SerieDataExtraFieldAttribute() - { } - public SerieDataExtraFieldAttribute(string field1) - { - AddFiled(field1); - } - public SerieDataExtraFieldAttribute(string field1, string field2) - { - AddFiled(field1); - AddFiled(field2); - } - public SerieDataExtraFieldAttribute(string field1, string field2, string field3) - { - AddFiled(field1); - AddFiled(field2); - AddFiled(field3); - } - public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4) - { - AddFiled(field1); - AddFiled(field2); - AddFiled(field3); - AddFiled(field4); - } - public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5) - { - AddFiled(field1); - AddFiled(field2); - AddFiled(field3); - AddFiled(field4); - AddFiled(field5); - } - public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5, string field6) - { - AddFiled(field1); - AddFiled(field2); - AddFiled(field3); - AddFiled(field4); - AddFiled(field5); - AddFiled(field6); - } - public SerieDataExtraFieldAttribute(string field1, string field2, string field3, string field4, string field5, string field6, string field7) - { - AddFiled(field1); - AddFiled(field2); - AddFiled(field3); - AddFiled(field4); - AddFiled(field5); - AddFiled(field6); - AddFiled(field7); - } - - private void AddFiled(string field) - { - if (!SerieData.extraFieldList.Contains(field)) - throw new ArgumentException("SerieData not support field:" + field); - fields.Add(field); - } - - public bool Contains(string field) - { - return fields.Contains(field); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs.meta deleted file mode 100644 index 216bf90..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieDataExtraFieldAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c8b0cc5a1c11e497abb7e32c7d14b25f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs deleted file mode 100644 index f4cb9ce..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class SerieExtraComponentAttribute : Attribute - { - public readonly List<Type> types = new List<Type>(); - - public SerieExtraComponentAttribute() - { } - public SerieExtraComponentAttribute(Type type1) - { - AddType(type1); - } - public SerieExtraComponentAttribute(Type type1, Type type2) - { - AddType(type1); - AddType(type2); - } - public SerieExtraComponentAttribute(Type type1, Type type2, Type type3) - { - AddType(type1); - AddType(type2); - AddType(type3); - } - public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - } - public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - AddType(type5); - } - public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - AddType(type5); - AddType(type6); - } - public SerieExtraComponentAttribute(Type type1, Type type2, Type type3, Type type4, Type type5, Type type6, Type type7) - { - AddType(type1); - AddType(type2); - AddType(type3); - AddType(type4); - AddType(type5); - AddType(type6); - AddType(type7); - } - - private void AddType(Type type) - { - if (!Serie.extraComponentMap.ContainsKey(type)) - throw new ArgumentException("Serie not support extra component:" + type); - types.Add(type); - } - - public bool Contains<T>() where T : ISerieExtraComponent - { - return Contains(typeof(T)); - } - - public bool Contains(Type type) - { - return types.Contains(type); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs.meta deleted file mode 100644 index 99dd27c..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieExtraComponentAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7d61861a0f45f43af8915ae23cc326e9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs b/Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs deleted file mode 100644 index 1bd21e7..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] - public sealed class SerieHandlerAttribute : Attribute - { - public readonly Type handler; - public readonly bool allowMultiple = true; - - public SerieHandlerAttribute(Type handler) - { - this.handler = handler; - this.allowMultiple = true; - } - public SerieHandlerAttribute(Type handler, bool allowMultiple) - { - this.handler = handler; - this.allowMultiple = allowMultiple; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs.meta b/Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs.meta deleted file mode 100644 index 2dfda00..0000000 --- a/Assets/XCharts/Runtime/Internal/Attributes/SerieHandlerAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 810e22da460074d639f56dd860d9f5d1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.API.cs b/Assets/XCharts/Runtime/Internal/BaseChart.API.cs deleted file mode 100644 index 230af44..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.API.cs +++ /dev/null @@ -1,542 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// The base class of all charts. - /// |所有Chart的基类。 - /// </summary> - public partial class BaseChart - { - /// <summary> - /// The name of chart. - /// |</summary> - public string chartName - { - get { return m_ChartName; } - set - { - if (!string.IsNullOrEmpty(value) && XChartsMgr.ContainsChart(value)) - { - Debug.LogError("chartName repeated:" + value); - } - else - { - m_ChartName = value; - } - } - } - /// <summary> - /// The theme. - /// |</summary> - public ThemeStyle theme { get { return m_Theme; } set { m_Theme = value; } } - /// <summary> - /// Global parameter setting component. - /// |全局设置组件。 - /// </summary> - public Settings settings { get { return m_Settings; } } - /// <summary> - /// The x of chart. - /// |图表的X - /// </summary> - public float chartX { get { return m_ChartX; } } - /// <summary> - /// The y of chart. - /// |图表的Y - /// </summary> - public float chartY { get { return m_ChartY; } } - /// <summary> - /// The width of chart. - /// |图表的宽 - /// </summary> - public float chartWidth { get { return m_ChartWidth; } } - /// <summary> - /// The height of chart. - /// |图表的高 - /// </summary> - public float chartHeight { get { return m_ChartHeight; } } - public Vector2 chartMinAnchor { get { return m_ChartMinAnchor; } } - public Vector2 chartMaxAnchor { get { return m_ChartMaxAnchor; } } - public Vector2 chartPivot { get { return m_ChartPivot; } } - public Vector2 chartSizeDelta { get { return m_ChartSizeDelta; } } - /// <summary> - /// The position of chart. - /// |图表的左下角起始坐标。 - /// </summary> - public Vector3 chartPosition { get { return m_ChartPosition; } } - public Rect chartRect { get { return m_ChartRect; } } - public Action onInit { set { m_OnInit = value; } } - public Action onUpdate { set { m_OnUpdate = value; } } - /// <summary> - /// 自定义绘制回调。在绘制Serie前调用。 - /// </summary> - public Action<VertexHelper> onDraw { set { m_OnDrawBase = value; } } - /// <summary> - /// 自定义Serie绘制回调。在每个Serie绘制完前调用。 - /// </summary> - public Action<VertexHelper, Serie> onDrawBeforeSerie { set { m_OnDrawSerieBefore = value; } } - /// <summary> - /// 自定义Serie绘制回调。在每个Serie绘制完后调用。 - /// </summary> - public Action<VertexHelper, Serie> onDrawAfterSerie { set { m_OnDrawSerieAfter = value; } } - /// <summary> - /// 自定义Top绘制回调。在绘制Tooltip前调用。 - /// </summary> - public Action<VertexHelper> onDrawTop { set { m_OnDrawTop = value; } } - /// <summary> - /// 自定义仪表盘指针绘制委托。 - /// </summary> - public CustomDrawGaugePointerFunction customDrawGaugePointerFunction { set { m_CustomDrawGaugePointerFunction = value; } get { return m_CustomDrawGaugePointerFunction; } } - /// <summary> - /// the callback function of click pie area. - /// |点击饼图区域回调。参数:PointerEventData,SerieIndex,SerieDataIndex - /// </summary> - public Action<PointerEventData, int, int> onPointerClickPie { set { m_OnPointerClickPie = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerClickPie; } } - /// <summary> - /// the callback function of click bar. - /// |点击柱形图柱条回调。参数:eventData, dataIndex - /// </summary> - public Action<PointerEventData, int> onPointerClickBar { set { m_OnPointerClickBar = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerClickBar; } } - /// <summary> - /// 坐标轴变更数据索引时回调。参数:axis, dataIndex/dataValue - /// </summary> - public Action<Axis, double> onAxisPointerValueChanged { set { m_OnAxisPointerValueChanged = value; } get { return m_OnAxisPointerValueChanged; } } - /// <summary> - /// the callback function of click legend. - /// |点击图例按钮回调。参数:legendIndex, legendName, show - /// </summary> - public Action<Legend, int, string, bool> onLegendClick { set { m_OnLegendClick = value; } internal get { return m_OnLegendClick; } } - /// <summary> - /// the callback function of enter legend. - /// |鼠标进入图例回调。参数:legendIndex, legendName - /// </summary> - public Action<Legend, int, string> onLegendEnter { set { m_OnLegendEnter = value; } internal get { return m_OnLegendEnter; } } - /// <summary> - /// the callback function of exit legend. - /// |鼠标退出图例回调。参数:legendIndex, legendName - /// </summary> - public Action<Legend, int, string> onLegendExit { set { m_OnLegendExit = value; } internal get { return m_OnLegendExit; } } - public void Init(bool defaultChart = true) - { - if (defaultChart) - { - OnInit(); - DefaultChart(); - } - else - { - OnBeforeSerialize(); - } - } - /// <summary> - /// Redraw chart in next frame. - /// |在下一帧刷新整个图表。 - /// </summary> - public void RefreshChart() - { - foreach (var serie in m_Series) - serie.ResetInteract(); - m_RefreshChart = true; - if (m_Painter) m_Painter.Refresh(); - foreach (var painter in m_PainterList) painter.Refresh(); - if (m_PainterTop) m_PainterTop.Refresh(); - } - - /// <summary> - /// Redraw chart serie in next frame. - /// |在下一帧刷新图表的指定serie。 - /// </summary> - public void RefreshChart(int serieIndex) - { - RefreshPainter(GetSerie(serieIndex)); - } - - /// <summary> - /// Redraw chart serie in next frame. - /// |在下一帧刷新图表的指定serie。 - /// </summary> - public void RefreshChart(Serie serie) - { - if (serie == null) return; - serie.ResetInteract(); - RefreshPainter(serie); - } - - /// <summary> - /// Remove all series and legend data. - /// |It just emptying all of serie's data without emptying the list of series. - /// |清除所有数据,系列中只是移除数据,列表会保留。 - /// </summary> - public virtual void ClearData() - { - foreach (var serie in m_Series) - serie.ClearData(); - foreach (var component in m_Components) - component.ClearData(); - m_CheckAnimation = false; - RefreshChart(); - } - - /// <summary> - /// Remove all data from series and legend. - /// |The series list is also cleared. - /// |清除所有系列和图例数据,系列的列表也会被清除。 - /// </summary> - public virtual void RemoveData() - { - foreach (var component in m_Components) - component.ClearData(); - m_Series.Clear(); - m_SerieHandlers.Clear(); - m_CheckAnimation = false; - RefreshChart(); - } - - /// <summary> - /// Remove legend and serie by name. - /// |清除指定系列名称的数据。 - /// </summary> - /// <param name="serieName">the name of serie</param> - public virtual void RemoveData(string serieName) - { - RemoveSerie(serieName); - foreach (var component in m_Components) - { - if (component is Legend) - { - var legend = component as Legend; - legend.RemoveData(serieName); - } - } - RefreshChart(); - } - - public virtual void UpdateLegendColor(string legendName, bool active) - { - var legendIndex = m_LegendRealShowName.IndexOf(legendName); - if (legendIndex >= 0) - { - foreach (var component in m_Components) - { - if (component is Legend) - { - var legend = component as Legend; - var iconColor = LegendHelper.GetIconColor(this, legend, legendIndex, legendName, active); - var contentColor = LegendHelper.GetContentColor(this, legendIndex, legendName, legend, m_Theme, active); - legend.UpdateButtonColor(legendName, iconColor); - legend.UpdateContentColor(legendName, contentColor); - } - } - } - } - - /// <summary> - /// Whether serie is activated. - /// |获得指定图例名字的系列是否显示。 - /// </summary> - /// <param name="legendName"></param> - /// <returns></returns> - public virtual bool IsActiveByLegend(string legendName) - { - foreach (var serie in m_Series) - { - if (serie.show && legendName.Equals(serie.serieName)) - { - return true; - } - else - { - foreach (var serieData in serie.data) - { - if (serieData.show && legendName.Equals(serieData.name)) - { - return true; - } - } - } - - } - return false; - } - - /// <summary> - /// Update chart theme. - /// |切换内置主题。 - /// </summary> - /// <param name="theme">theme</param> - public bool UpdateTheme(ThemeType theme) - { - if (theme == ThemeType.Custom) - { - Debug.LogError("UpdateTheme: not support switch to Custom theme."); - return false; - } - if (m_Theme.sharedTheme == null) - m_Theme.sharedTheme = XCThemeMgr.GetTheme(ThemeType.Default); - m_Theme.sharedTheme.CopyTheme(theme); - return true; - } - - /// <summary> - /// Update chart theme info. - /// |切换图表主题。 - /// </summary> - /// <param name="theme">theme</param> - public void UpdateTheme(Theme theme) - { - m_Theme.sharedTheme = theme; - SetAllComponentDirty(); -#if UNITY_EDITOR - UnityEditor.EditorUtility.SetDirty(this); -#endif - } - - /// <summary> - /// Whether series animation enabel. - /// |启用或关闭起始动画。 - /// </summary> - /// <param name="flag"></param> - public void AnimationEnable(bool flag) - { - foreach (var serie in m_Series) serie.AnimationEnable(flag); - } - - /// <summary> - /// fadeIn animation. - /// |开始渐入动画。 - /// </summary> - public void AnimationFadeIn() - { - foreach (var serie in m_Series) serie.AnimationFadeIn(); - } - - /// <summary> - /// fadeIn animation. - /// |开始渐出动画。 - /// </summary> - public void AnimationFadeOut() - { - foreach (var serie in m_Series) serie.AnimationFadeOut(); - } - - /// <summary> - /// Pause animation. - /// |暂停动画。 - /// </summary> - public void AnimationPause() - { - foreach (var serie in m_Series) serie.AnimationPause(); - } - - /// <summary> - /// Stop play animation. - /// |继续动画。 - /// </summary> - public void AnimationResume() - { - foreach (var serie in m_Series) serie.AnimationResume(); - } - - /// <summary> - /// Reset animation. - /// |重置动画。 - /// </summary> - public void AnimationReset() - { - foreach (var serie in m_Series) serie.AnimationReset(); - } - - /// <summary> - /// 点击图例按钮 - /// </summary> - /// <param name="legendIndex">图例按钮索引</param> - /// <param name="legendName">图例按钮名称</param> - /// <param name="show">显示还是隐藏</param> - public void ClickLegendButton(int legendIndex, string legendName, bool show) - { - OnLegendButtonClick(legendIndex, legendName, show); - RefreshChart(); - } - - /// <summary> - /// 坐标是否在图表范围内 - /// </summary> - /// <param name="local"></param> - /// <returns></returns> - public bool IsInChart(Vector2 local) - { - return IsInChart(local.x, local.y); - } - - public bool IsInChart(float x, float y) - { - if (x < m_ChartX || x > m_ChartX + m_ChartWidth || - y < m_ChartY || y > m_ChartY + m_ChartHeight) - { - return false; - } - return true; - } - - public void ClampInChart(ref Vector3 pos) - { - if (!IsInChart(pos.x, pos.y)) - { - if (pos.x < m_ChartX) pos.x = m_ChartX; - if (pos.x > m_ChartX + m_ChartWidth) pos.x = m_ChartX + m_ChartWidth; - if (pos.y < m_ChartY) pos.y = m_ChartY; - if (pos.y > m_ChartY + m_ChartHeight) pos.y = m_ChartY + m_ChartHeight; - } - } - - public Vector3 ClampInGrid(GridCoord grid, Vector3 pos) - { - if (grid.Contains(pos)) return pos; - else - { - // var pos = new Vector3(pos.x, pos.y); - if (pos.x < grid.context.x) pos.x = grid.context.x; - if (pos.x > grid.context.x + grid.context.width) pos.x = grid.context.x + grid.context.width; - if (pos.y < grid.context.y) pos.y = grid.context.y; - if (pos.y > grid.context.y + grid.context.height) pos.y = grid.context.y + grid.context.height; - return pos; - } - } - - /// <summary> - /// 转换X轴和Y轴的配置 - /// </summary> - /// <param name="index">坐标轴索引,0或1</param> - public void CovertXYAxis(int index) - { - List<MainComponent> m_XAxes; - List<MainComponent> m_YAxes; - m_ComponentMaps.TryGetValue(typeof(XAxis), out m_XAxes); - m_ComponentMaps.TryGetValue(typeof(YAxis), out m_YAxes); - if (index >= 0 && index <= 1) - { - var xAxis = m_XAxes[index] as XAxis; - var yAxis = m_YAxes[index] as YAxis; - var tempX = xAxis.Clone(); - xAxis.Copy(yAxis); - yAxis.Copy(tempX); - xAxis.context.offset = 0; - yAxis.context.offset = 0; - xAxis.context.minValue = 0; - xAxis.context.maxValue = 0; - yAxis.context.minValue = 0; - yAxis.context.maxValue = 0; - RefreshChart(); - } - } - - /// <summary> - /// 在下一帧刷新DataZoom - /// </summary> - public void RefreshDataZoom() - { - foreach (var handler in m_ComponentHandlers) - { - if (handler is DataZoomHandler) - { - (handler as DataZoomHandler).RefreshDataZoomLabel(); - } - } - } - - /// <summary> - /// 设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。 - /// </summary> - public void SetMaxCache(int maxCache) - { - foreach (var serie in m_Series) - serie.maxCache = maxCache; - foreach (var component in m_Components) - { - if (component is Axis) - { - (component as Axis).maxCache = maxCache; - } - } - } - - public Vector3 GetTitlePosition(Title title) - { - return chartPosition + title.location.GetPosition(chartWidth, chartHeight); - } - - public int GetLegendRealShowNameIndex(string name) - { - return m_LegendRealShowName.IndexOf(name); - } - - public Color32 GetLegendRealShowNameColor(string name) - { - var index = GetLegendRealShowNameIndex(name); - return theme.GetColor(index); - } - - /// <summary> - /// 设置Base Painter的材质球 - /// </summary> - /// <param name="material"></param> - public void SetBasePainterMaterial(Material material) - { - settings.basePainterMaterial = material; - if (m_Painter != null) - { - m_Painter.material = material; - } - } - - /// <summary> - /// 设置Serie Painter的材质球 - /// </summary> - /// <param name="material"></param> - public void SetSeriePainterMaterial(Material material) - { - settings.basePainterMaterial = material; - if (m_PainterList != null) - { - foreach (var painter in m_PainterList) - painter.material = material; - } - } - - /// <summary> - /// 设置Top Painter的材质球 - /// </summary> - /// <param name="material"></param> - public void SetTopPainterMaterial(Material material) - { - settings.topPainterMaterial = material; - if (m_PainterTop != null) - { - m_PainterTop.material = material; - } - } - - public Color32 GetChartBackgroundColor() - { - var background = GetChartComponent<Background>(); - return theme.GetBackgroundColor(background); - } - - public Color32 GetItemColor(Serie serie, SerieData serieData, bool highlight = false) - { - var colorIndex = serieData == null || !serie.useDataNameForColor ? - GetLegendRealShowNameIndex(serie.legendName) : - GetLegendRealShowNameIndex(serieData.legendName); - return SerieHelper.GetItemColor(serie, serieData, m_Theme, colorIndex, highlight); - } - - public Color32 GetItemColor(Serie serie, bool highlight = false) - { - return SerieHelper.GetItemColor(serie, null, m_Theme, serie.context.colorIndex, highlight); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.API.cs.meta b/Assets/XCharts/Runtime/Internal/BaseChart.API.cs.meta deleted file mode 100644 index fcc2101..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.API.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 62d2f81e569a4477aab2091dc0b8dba7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Component.cs b/Assets/XCharts/Runtime/Internal/BaseChart.Component.cs deleted file mode 100644 index e7ef7b3..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Component.cs +++ /dev/null @@ -1,427 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public partial class BaseChart - { - public bool TryAddChartComponent<T>() where T : MainComponent - { - return TryAddChartComponent(typeof(T)); - } - - public bool TryAddChartComponent(Type type) - { - if (CanAddChartComponent(type)) - { - AddChartComponent(type); - return true; - } - else - { - return false; - } - } - - public bool TryAddChartComponent<T>(out T component) where T : MainComponent - { - var type = typeof(T); - if (CanAddChartComponent(type)) - { - component = AddChartComponent(type) as T; - return true; - } - else - { - component = null; - return false; - } - } - - public T AddChartComponent<T>() where T : MainComponent - { - return (T) AddChartComponent(typeof(T)); - } - - public T AddChartComponentWhenNoExist<T>() where T : MainComponent - { - if (HasChartComponent<T>()) return null; - return AddChartComponent<T>(); - } - - public MainComponent AddChartComponent(Type type) - { - if (!CanAddChartComponent(type)) - { - Debug.LogError("XCharts ERROR: CanAddChartComponent:" + type.Name); - return null; - } - CheckAddRequireChartComponent(type); - var component = Activator.CreateInstance(type) as MainComponent; - if (component == null) - { - Debug.LogError("XCharts ERROR: CanAddChartComponent:" + type.Name); - return null; - } - component.SetDefaultValue(); - if (component is IUpdateRuntimeData) - (component as IUpdateRuntimeData).UpdateRuntimeData(chartX, chartY, chartWidth, chartHeight); - AddComponent(component); - m_Components.Sort(); - CreateComponentHandler(component); -#if UNITY_EDITOR && UNITY_2019_1_OR_NEWER - UnityEditor.EditorUtility.SetDirty(this); -#endif - return component; - } - - private void AddComponent(MainComponent component) - { - var type = component.GetType(); - m_Components.Add(component); - List<MainComponent> list; - if (!m_ComponentMaps.TryGetValue(type, out list)) - { - list = new List<MainComponent>(); - m_ComponentMaps[type] = list; - } - component.index = list.Count; - list.Add(component); - } - - private void CheckAddRequireChartComponent(Type type) - { - if (Attribute.IsDefined(type, typeof(RequireChartComponentAttribute))) - { - foreach (var obj in type.GetCustomAttributes(typeof(RequireChartComponentAttribute), false)) - { - var attribute = obj as RequireChartComponentAttribute; - if (attribute.type0 != null && !HasChartComponent(attribute.type0)) - AddChartComponent(attribute.type0); - if (attribute.type1 != null && !HasChartComponent(attribute.type1)) - AddChartComponent(attribute.type1); - if (attribute.type2 != null && !HasChartComponent(attribute.type2)) - AddChartComponent(attribute.type2); - } - } - } - - private void CreateComponentHandler(MainComponent component) - { - if (!component.GetType().IsDefined(typeof(ComponentHandlerAttribute), false)) - { - Debug.LogError("MainComponent no Handler:" + component.GetType()); - return; - } - var attrubte = component.GetType().GetAttribute<ComponentHandlerAttribute>(); - if (attrubte.handler == null) - return; - - var handler = (MainComponentHandler) Activator.CreateInstance(attrubte.handler); - handler.attribute = attrubte; - handler.chart = this; - handler.SetComponent(component); - component.handler = handler; - m_ComponentHandlers.Add(handler); - } - - public bool RemoveChartComponent<T>(int index = 0) - where T : MainComponent - { - return RemoveChartComponent(typeof(T), index); - } - - public int RemoveChartComponents<T>() - where T : MainComponent - { - return RemoveChartComponents(typeof(T)); - } - - public void RemoveAllChartComponent() - { - m_Components.Clear(); - InitComponentHandlers(); - } - - public bool RemoveChartComponent(Type type, int index = 0) - { - MainComponent toRemove = null; - for (int i = 0; i < m_Components.Count; i++) - { - if (m_Components[i].GetType() == type && m_Components[i].index == index) - { - toRemove = m_Components[i]; - break; - } - } - return RemoveChartComponent(toRemove); - } - - public int RemoveChartComponents(Type type) - { - int count = 0; - for (int i = m_Components.Count - 1; i > 0; i--) - { - if (m_Components[i].GetType() == type) - { - RemoveChartComponent(m_Components[i]); - count++; - } - } - return count; - } - - public bool RemoveChartComponent(MainComponent component) - { - if (component == null) return false; - if (m_Components.Remove(component)) - { - if (component.gameObject != null) - ChartHelper.SetActive(component.gameObject, false); - InitComponentHandlers(); - RefreshChart(); - return true; - } - return false; - } - - public bool CanAddChartComponent(Type type) - { - if (!type.IsSubclassOf(typeof(MainComponent))) return false; - if (!m_TypeListForComponent.ContainsKey(type)) return false; - if (CanMultipleComponent(type)) return !HasChartComponent(type); - else return true; - } - - public bool HasChartComponent<T>() - where T : MainComponent - { - return HasChartComponent(typeof(T)); - } - - public bool HasChartComponent(Type type) - { - foreach (var component in m_Components) - { - if (component == null) continue; - if (component.GetType() == type) - return true; - } - return false; - } - - public bool CanMultipleComponent(Type type) - { - return Attribute.IsDefined(type, typeof(DisallowMultipleComponent)); - } - - public int GetChartComponentNum<T>() where T : MainComponent - { - return GetChartComponentNum(typeof(T)); - } - - public int GetChartComponentNum(Type type) - { - List<MainComponent> list; - if (m_ComponentMaps.TryGetValue(type, out list)) - return list.Count; - else - return 0; - } - - public T GetChartComponent<T>(int index = 0) where T : MainComponent - { - foreach (var component in m_Components) - { - if (component is T && component.index == index) - return component as T; - } - return null; - } - - public List<MainComponent> GetChartComponents<T>() where T : MainComponent - { - return m_ComponentMaps[typeof(T)]; - } - - public T GetOrAddChartComponent<T>() where T : MainComponent - { - var component = GetChartComponent<T>(); - if (component == null) - return AddChartComponent<T>(); - else - return component; - } - - public bool TryGetChartComponent<T>(out T component, int index = 0) - where T : MainComponent - { - component = null; - foreach (var com in m_Components) - { - if (com is T && com.index == index) - { - component = (T) com; - return true; - } - } - return false; - } - public GridCoord GetGrid(Vector2 local) - { - List<MainComponent> list; - if (m_ComponentMaps.TryGetValue(typeof(GridCoord), out list)) - { - foreach (var component in list) - { - var grid = component as GridCoord; - if (grid.Contains(local)) return grid; - } - } - return null; - } - - public GridCoord GetGridOfDataZoom(DataZoom dataZoom) - { - GridCoord grid = null; - if (dataZoom.xAxisIndexs != null && dataZoom.xAxisIndexs.Count > 0) - { - var xAxis = GetChartComponent<XAxis>(dataZoom.xAxisIndexs[0]); - grid = GetChartComponent<GridCoord>(xAxis.gridIndex); - } - else if (dataZoom.yAxisIndexs != null && dataZoom.yAxisIndexs.Count > 0) - { - var yAxis = GetChartComponent<YAxis>(dataZoom.yAxisIndexs[0]); - grid = GetChartComponent<GridCoord>(yAxis.gridIndex); - } - if (grid == null) return GetChartComponent<GridCoord>(); - else return grid; - } - - public DataZoom GetDataZoomOfAxis(Axis axis) - { - foreach (var component in m_Components) - { - if (component is DataZoom) - { - var dataZoom = component as DataZoom; - if (!dataZoom.enable) continue; - if (dataZoom.IsContainsAxis(axis)) return dataZoom; - } - } - return null; - } - - public VisualMap GetVisualMapOfSerie(Serie serie) - { - foreach (var component in m_Components) - { - if (component is VisualMap) - { - var visualMap = component as VisualMap; - if (visualMap.serieIndex == serie.index) return visualMap; - } - } - return null; - } - - public void GetDataZoomOfSerie(Serie serie, out DataZoom xDataZoom, out DataZoom yDataZoom) - { - xDataZoom = null; - yDataZoom = null; - if (serie == null) return; - foreach (var component in m_Components) - { - if (component is DataZoom) - { - var dataZoom = component as DataZoom; - if (!dataZoom.enable) continue; - if (dataZoom.IsContainsXAxis(serie.xAxisIndex)) - { - xDataZoom = dataZoom; - } - if (dataZoom.IsContainsYAxis(serie.yAxisIndex)) - { - yDataZoom = dataZoom; - } - } - } - } - - /// <summary> - /// reutrn true when all the show axis is `Value` type. - /// |纯数值坐标轴(数值轴或对数轴)。 - /// </summary> - public bool IsAllAxisValue() - { - foreach (var component in m_Components) - { - if (component is Axis) - { - var axis = component as Axis; - if (axis.show && !axis.IsValue() && !axis.IsLog() && !axis.IsTime()) return false; - } - } - return true; - } - - /// <summary> - /// 纯类目轴。 - /// </summary> - public bool IsAllAxisCategory() - { - foreach (var component in m_Components) - { - if (component is Axis) - { - var axis = component as Axis; - if (axis.show && !axis.IsCategory()) return false; - } - } - return true; - } - - public bool IsInAnyGrid(Vector2 local) - { - List<MainComponent> list; - if (m_ComponentMaps.TryGetValue(typeof(GridCoord), out list)) - { - foreach (var grid in list) - { - if ((grid as GridCoord).Contains(local)) return true; - } - } - return false; - } - - internal string GetTooltipCategory(int dataIndex, DataZoom dataZoom = null) - { - var xAxis = GetChartComponent<XAxis>(); - var yAxis = GetChartComponent<YAxis>(); - if (yAxis.IsCategory()) - { - return yAxis.GetData((int) yAxis.context.pointerValue, dataZoom); - } - else if (xAxis.IsCategory()) - { - return xAxis.GetData((int) xAxis.context.pointerValue, dataZoom); - } - return null; - } - internal string GetTooltipCategory(int dataIndex, Serie serie, DataZoom dataZoom = null) - { - var xAxis = GetChartComponent<XAxis>(serie.xAxisIndex); - var yAxis = GetChartComponent<YAxis>(serie.yAxisIndex); - if (yAxis.IsCategory()) - { - return yAxis.GetData((int) yAxis.context.pointerValue, dataZoom); - } - else if (xAxis.IsCategory()) - { - return xAxis.GetData((int) xAxis.context.pointerValue, dataZoom); - } - return null; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Component.cs.meta b/Assets/XCharts/Runtime/Internal/BaseChart.Component.cs.meta deleted file mode 100644 index 430d2a9..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Component.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: abbf9c9160e2c45c4a873a7da09672be -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs b/Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs deleted file mode 100644 index cbd04da..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public partial class BaseChart - { - public virtual void InitAxisRuntimeData(Axis axis) - { } - - public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue) - { - if (IsAllAxisValue()) - { - if (axis is XAxis) - { - SeriesHelper.GetXMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); - } - else - { - SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); - } - } - else - { - SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, false, axis.inverse, out tempMinValue, out tempMaxValue); - } - AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs.meta b/Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs.meta deleted file mode 100644 index 4d9b1cc..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Custom.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ae62083fadc854bcc8c8312f84c6d166 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs b/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs deleted file mode 100644 index f23303b..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs +++ /dev/null @@ -1,134 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - public partial class BaseChart - { - public void DrawClipPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, - Color32 color, bool clip, GridCoord grid) - { - DrawClipPolygon(vh, p1, p2, p3, p4, color, color, clip, grid); - } - - public void DrawClipPolygon(VertexHelper vh, Vector3 p, float radius, Color32 color, - bool clip, bool vertical, GridCoord grid) - { - if (!IsInChart(p)) return; - if (!clip || (clip && (grid.Contains(p)))) - UGL.DrawSquare(vh, p, radius, color); - } - - public void DrawClipPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, - Color32 startColor, Color32 toColor, bool clip, GridCoord grid) - { - ClampInChart(ref p1); - ClampInChart(ref p2); - ClampInChart(ref p3); - ClampInChart(ref p4); - if (clip) - { - p1 = ClampInGrid(grid, p1); - p2 = ClampInGrid(grid, p2); - p3 = ClampInGrid(grid, p3); - p4 = ClampInGrid(grid, p4); - } - if (!clip || (clip && (grid.Contains(p1) && grid.Contains(p2) && grid.Contains(p3) && - grid.Contains(p4)))) - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, startColor, toColor); - } - - public void DrawClipPolygon(VertexHelper vh, ref Vector3 p1, ref Vector3 p2, ref Vector3 p3, ref Vector3 p4, - Color32 startColor, Color32 toColor, bool clip, GridCoord grid) - { - ClampInChart(ref p1); - ClampInChart(ref p2); - ClampInChart(ref p3); - ClampInChart(ref p4); - if (clip) - { - p1 = ClampInGrid(grid, p1); - p2 = ClampInGrid(grid, p2); - p3 = ClampInGrid(grid, p3); - p4 = ClampInGrid(grid, p4); - } - if (!clip || - (clip && (grid.Contains(p1) && grid.Contains(p2) && grid.Contains(p3) && - grid.Contains(p4)))) - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, startColor, toColor); - } - - public void DrawClipTriangle(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Color32 color, - bool clip, GridCoord grid) - { - DrawClipTriangle(vh, p1, p2, p3, color, color, color, clip, grid); - } - - public void DrawClipTriangle(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Color32 color, - Color32 color2, Color32 color3, bool clip, GridCoord grid) - { - if (!IsInChart(p1) || !IsInChart(p2) || !IsInChart(p3)) return; - if (!clip || (clip && (grid.Contains(p1) || grid.Contains(p2) || grid.Contains(p3)))) - UGL.DrawTriangle(vh, p1, p2, p3, color, color2, color3); - } - - public void DrawClipLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, Color32 color, - bool clip, GridCoord grid) - { - if (!IsInChart(p1) || !IsInChart(p2)) return; - if (!clip || (clip && (grid.Contains(p1) || grid.Contains(p2)))) - UGL.DrawLine(vh, p1, p2, size, color); - } - - public void DrawClipSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness, - Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, Color32 borderColor, float gap, - bool clip, float[] cornerRadius, GridCoord grid, Vector3 startPos) - { - if (!IsInChart(pos)) return; - if (!clip || (clip && (grid.Contains(pos)))) - DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, emptyColor, borderColor, - gap, cornerRadius, startPos); - } - - public void DrawClipZebraLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, float zebraWidth, - float zebraGap, Color32 color, Color32 toColor, bool clip, GridCoord grid, float maxDistance) - { - ClampInChart(ref p1); - ClampInChart(ref p2); - UGL.DrawZebraLine(vh, p1, p2, size, zebraWidth, zebraGap, color, toColor, maxDistance); - } - - public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness, - Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, Color32 borderColor, - float gap, float[] cornerRadius) - { - DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, emptyColor, borderColor, - gap, cornerRadius, Vector3.zero); - } - - public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness, - Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, Color32 borderColor, - float gap, float[] cornerRadius, Vector3 startPos) - { - var backgroundColor = GetChartBackgroundColor(); - if (ChartHelper.IsClearColor(emptyColor)) - emptyColor = backgroundColor; - var smoothness = settings.cicleSmoothness; - ChartDrawer.DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, - cornerRadius, emptyColor, backgroundColor, borderColor, smoothness, startPos); - } - - public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid) - { - if (ChartHelper.IsValueEqualsColor(areaColor, areaToColor)) return areaColor; - return Color32.Lerp(areaToColor, areaColor, (pos.y - grid.context.y) / grid.context.height); - } - - public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid) - { - if (ChartHelper.IsValueEqualsColor(areaColor, areaToColor)) return areaColor; - return Color32.Lerp(areaToColor, areaColor, (pos.x - grid.context.x) / grid.context.width); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs.meta b/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs.meta deleted file mode 100644 index 26dffb0..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 781bfba23eace44fcbbf9ee6924da32b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs b/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs deleted file mode 100644 index d5c28b8..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs +++ /dev/null @@ -1,985 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEngine; - -namespace XCharts.Runtime -{ - public partial class BaseChart - { - public T AddSerie<T>(string serieName = null, bool show = true, bool addToHead = false) where T : Serie - { - if (!CanAddSerie<T>()) return null; - var index = -1; - var serie = InsertSerie(index, typeof(T), serieName, show, addToHead) as T; - CreateSerieHandler(serie); - return serie; - } - - public T InsertSerie<T>(int index, string serieName = null, bool show = true) where T : Serie - { - if (!CanAddSerie<T>()) return null; - return InsertSerie(index, typeof(T), serieName, show) as T; - } - - public void InsertSerie(Serie serie, int index = -1, bool addToHead = false) - { - serie.AnimationRestart(); - AnimationStyleHelper.UpdateSerieAnimation(serie); - if (addToHead) m_Series.Insert(0, serie); - else if (index >= 0) m_Series.Insert(index, serie); - else m_Series.Add(serie); - ResetSeriesIndex(); - SeriesHelper.UpdateSerieNameList(this, ref m_LegendRealShowName); - } - - public bool MoveUpSerie(int serieIndex) - { - if (serieIndex < 0 || serieIndex > m_Series.Count - 1) return false; - if (serieIndex == 0) return false; - var up = GetSerie(serieIndex - 1); - var temp = GetSerie(serieIndex); - m_Series[serieIndex - 1] = temp; - m_Series[serieIndex] = up; - ResetSeriesIndex(); - InitSerieHandlers(); - RefreshChart(); - return true; - } - - public bool MoveDownSerie(int serieIndex) - { - if (serieIndex < 0 || serieIndex > m_Series.Count - 1) return false; - if (serieIndex == m_Series.Count - 1) return false; - var down = GetSerie(serieIndex + 1); - var temp = GetSerie(serieIndex); - m_Series[serieIndex + 1] = temp; - m_Series[serieIndex] = down; - ResetSeriesIndex(); - InitSerieHandlers(); - RefreshChart(); - return true; - } - - public bool CanAddSerie<T>() where T : Serie - { - return CanAddSerie(typeof(T)); - } - - public bool CanAddSerie(Type type) - { - return m_TypeListForSerie.ContainsKey(type); - } - - public bool HasSerie<T>() where T : Serie - { - return HasSerie(typeof(T)); - } - - public bool HasSerie(Type type) - { - if (!type.IsSubclassOf(typeof(Serie))) return false; - foreach (var serie in m_Series) - { - if (serie.GetType() == type) - return true; - } - return false; - } - - public T GetSerie<T>() where T : Serie - { - foreach (var serie in m_Series) - { - if (serie is T) return serie as T; - } - return null; - } - - public Serie GetSerie(string serieName) - { - foreach (var serie in m_Series) - { - if (serie.serieName.Equals(serieName)) return serie; - } - return null; - } - - public Serie GetSerie(int serieIndex) - { - if (serieIndex < 0 || serieIndex > m_Series.Count - 1) return null; - return m_Series[serieIndex]; - } - - public T GetSerie<T>(int serieIndex) where T : Serie - { - if (serieIndex < 0 || serieIndex > m_Series.Count - 1) return null; - return m_Series[serieIndex] as T; - } - - public void RemoveSerie(string serieName) - { - for (int i = m_Series.Count - 1; i >= 0; i--) - { - var serie = m_Series[i]; - if (string.IsNullOrEmpty(serie.serieName) && serie.serieName.Equals(serieName)) - RemoveSerie(serie); - } - } - - public void RemoveSerie(int serieIndex) - { - if (serieIndex < 0 || serieIndex > m_Series.Count - 1) return; - RemoveSerie(m_Series[serieIndex]); - } - - public void RemoveSerie<T>() where T : Serie - { - for (int i = m_Series.Count - 1; i >= 0; i--) - { - var serie = m_Series[i]; - if (serie is T) - RemoveSerie(serie); - } - } - - public void RemoveSerie(Serie serie) - { - serie.OnRemove(); - m_SerieHandlers.Remove(serie.handler); - m_Series.Remove(serie); - RefreshChart(); - } - - public bool CovertSerie<T>(Serie serie) where T : Serie - { - return CovertSerie(serie, typeof(T)); - } - - public bool CovertSerie(Serie serie, Type type) - { - try - { - var newSerie = type.InvokeMember("CovertSerie", - BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, - new object[] { serie }) as Serie; - return ReplaceSerie(serie, newSerie); - } - catch - { - Debug.LogError(string.Format("CovertSerie Failed: can't found {0}.CovertSerie(Serie serie)", type.Name)); - return false; - } - } - - public bool ReplaceSerie(Serie oldSerie, Serie newSerie) - { - if (oldSerie == null || newSerie == null) - return false; - - var index = m_Series.IndexOf(oldSerie); - if (index < 0) - return false; - AnimationStyleHelper.UpdateSerieAnimation(newSerie); - oldSerie.OnRemove(); - m_Series.RemoveAt(index); - m_Series.Insert(index, newSerie); - ResetSeriesIndex(); - InitSerieHandlers(); - RefreshAllComponent(); - RefreshChart(); - return true; - } - - /// <summary> - /// Add a data to serie. - /// |If serieName doesn't exist in legend,will be add to legend. - /// |添加一个数据到指定的系列中。 - /// </summary> - /// <param name="serieName">the name of serie</param> - /// <param name="data">the data to add</param> - /// <param name="dataName">the name of data</param> - /// <param name="dataId">the unique id of data</param> - /// <returns>Returns True on success</returns> - public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieName); - if (serie != null) - { - var serieData = serie.AddYData(data, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - - /// <summary> - /// Add a data to serie. - /// |添加一个数据到指定的系列中。 - /// </summary> - /// <param name="serieIndex">the index of serie</param> - /// <param name="data">the data to add</param> - /// <param name="dataName">the name of data</param> - /// <param name="dataId">the unique id of data</param> - /// <returns>Returns True on success</returns> - public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - var serieData = serie.AddYData(data, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - - /// <summary> - /// Add an arbitray dimension data to serie,such as (x,y,z,...). - /// |添加多维数据(x,y,z...)到指定的系列中。 - /// </summary> - /// <param name="serieName">the name of serie</param> - /// <param name="multidimensionalData">the (x,y,z,...) data</param> - /// <param name="dataName">the name of data</param> - /// <param name="dataId">the unique id of data</param> - /// <returns>Returns True on success</returns> - public SerieData AddData(string serieName, List<double> multidimensionalData, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieName); - if (serie != null) - { - var serieData = serie.AddData(multidimensionalData, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - - /// <summary> - /// Add an arbitray dimension data to serie,such as (x,y,z,...). - /// |添加多维数据(x,y,z...)到指定的系列中。 - /// </summary> - /// <param name="serieIndex">the index of serie,index starts at 0</param> - /// <param name="multidimensionalData">the (x,y,z,...) data</param> - /// <param name="dataName">the name of data</param> - /// <param name="dataId">the unique id of data</param> - /// <returns>Returns True on success</returns> - public SerieData AddData(int serieIndex, List<double> multidimensionalData, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - var serieData = serie.AddData(multidimensionalData, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - - /// <summary> - /// Add a (x,y) data to serie. - /// |添加(x,y)数据到指定系列中。 - /// </summary> - /// <param name="serieName">the name of serie</param> - /// <param name="xValue">x data</param> - /// <param name="yValue">y data</param> - /// <param name="dataName">the name of data</param> - /// <param name="dataId">the unique id of data</param> - /// <returns>Returns True on success</returns> - public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieName); - if (serie != null) - { - var serieData = serie.AddXYData(xValue, yValue, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - - /// <summary> - /// Add a (x,y) data to serie. - /// |添加(x,y)数据到指定系列中。 - /// </summary> - /// <param name="serieIndex">the index of serie</param> - /// <param name="xValue">x data</param> - /// <param name="yValue">y data</param> - /// <param name="dataName">the name of data</param> - /// <param name="dataId">the unique id of data</param> - /// <returns>Returns True on success</returns> - public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - var serieData = serie.AddXYData(xValue, yValue, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - /// <summary> - /// Add a (time,y) data to serie. - /// |添加(time,y)数据到指定的系列中。 - /// </summary> - /// <param name="serieName"></param> - /// <param name="time"></param> - /// <param name="yValue"></param> - /// <param name="dataName"></param> - /// <param name="dataId"></param> - /// <returns></returns> - public SerieData AddData(string serieName, DateTime time, double yValue, string dataName = null, string dataId = null) - { - var xValue = DateTimeUtil.GetTimestamp(time); - return AddData(serieName, xValue, yValue, dataName, dataId); - } - - /// <summary> - /// Add a (time,y) data to serie. - /// |添加(time,y)数据到指定的系列中。 - /// </summary> - /// <param name="serieIndex"></param> - /// <param name="time"></param> - /// <param name="yValue"></param> - /// <param name="dataName"></param> - /// <param name="dataId"></param> - /// <returns></returns> - public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null) - { - var xValue = DateTimeUtil.GetTimestamp(time); - return AddData(serieIndex, xValue, yValue, dataName, dataId); - } - - public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - var serieData = serie.AddData(open, close, lowest, heighest, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) - { - var serie = GetSerie(serieName); - if (serie != null) - { - var serieData = serie.AddData(open, close, lowest, heighest, dataName, dataId); - RefreshPainter(serie.painter); - return serieData; - } - return null; - } - - /// <summary> - /// Update serie data by serie name. - /// |更新指定系列中的指定索引数据。 - /// </summary> - /// <param name="serieName">the name of serie</param> - /// <param name="dataIndex">the index of data</param> - /// <param name="value">the data will be update</param> - public bool UpdateData(string serieName, int dataIndex, double value) - { - var serie = GetSerie(serieName); - if (serie != null) - { - serie.UpdateYData(dataIndex, value); - RefreshPainter(serie); - return true; - } - return false; - } - - /// <summary> - /// Update serie data by serie index. - /// |更新指定系列中的指定索引数据。 - /// </summary> - /// <param name="serieIndex">the index of serie</param> - /// <param name="dataIndex">the index of data</param> - /// <param name="value">the data will be update</param> - public bool UpdateData(int serieIndex, int dataIndex, double value) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - serie.UpdateYData(dataIndex, value); - RefreshPainter(serie); - return true; - } - return false; - } - - /// <summary> - /// 更新指定系列指定索引的数据项的多维数据。 - /// </summary> - /// <param name="serieName"></param> - /// <param name="dataIndex"></param> - /// <param name="multidimensionalData">一个数据项的多维数据列表,而不是多个数据项的数据</param> - public bool UpdateData(string serieName, int dataIndex, List<double> multidimensionalData) - { - var serie = GetSerie(serieName); - if (serie != null) - { - serie.UpdateData(dataIndex, multidimensionalData); - RefreshPainter(serie); - return true; - } - return false; - } - - /// <summary> - /// 更新指定系列指定索引的数据项的多维数据。 - /// </summary> - /// <param name="serieIndex"></param> - /// <param name="dataIndex"></param> - /// <param name="multidimensionalData">一个数据项的多维数据列表,而不是多个数据项的数据</param> - public bool UpdateData(int serieIndex, int dataIndex, List<double> multidimensionalData) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - serie.UpdateData(dataIndex, multidimensionalData); - RefreshPainter(serie); - return true; - } - return false; - } - - /// <summary> - /// 更新指定系列指定索引指定维数的数据。维数从0开始。 - /// </summary> - /// <param name="serieName"></param> - /// <param name="dataIndex"></param> - /// <param name="dimension">指定维数,从0开始</param> - /// <param name="value"></param> - public bool UpdateData(string serieName, int dataIndex, int dimension, double value) - { - var serie = GetSerie(serieName); - if (serie != null) - { - serie.UpdateData(dataIndex, dimension, value); - RefreshPainter(serie); - return true; - } - return false; - } - - /// <summary> - /// 更新指定系列指定索引指定维数的数据。维数从0开始。 - /// </summary> - /// <param name="serieIndex"></param> - /// <param name="dataIndex"></param> - /// <param name="dimension">指定维数,从0开始</param> - /// <param name="value"></param> - public bool UpdateData(int serieIndex, int dataIndex, int dimension, double value) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - serie.UpdateData(dataIndex, dimension, value); - RefreshPainter(serie); - return true; - } - return false; - } - - /// <summary> - /// Update serie data name. - /// |更新指定系列中的指定索引数据名称。 - /// </summary> - /// <param name="serieName"></param> - /// <param name="dataIndex"></param> - /// <param name="dataName"></param> - public bool UpdateDataName(string serieName, int dataIndex, string dataName) - { - var serie = GetSerie(serieName); - if (serie != null) - { - serie.UpdateDataName(dataIndex, dataName); - return true; - } - return false; - } - - /// <summary> - /// Update serie data name. - /// |更新指定系列中的指定索引数据名称。 - /// </summary> - /// <param name="serieIndex"></param> - /// <param name="dataName"></param> - /// <param name="dataIndex"></param> - public bool UpdateDataName(int serieIndex, int dataIndex, string dataName) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - serie.UpdateDataName(dataIndex, dataName); - return true; - } - return false; - } - - public double GetData(string serieName, int dataIndex, int dimension = 1) - { - var serie = GetSerie(serieName); - if (serie != null) - { - return serie.GetData(dataIndex, dimension); - } - return 0; - } - - public double GetData(int serieIndex, int dataIndex, int dimension = 1) - { - var serie = GetSerie(serieIndex); - if (serie != null) - { - return serie.GetData(dataIndex, dimension); - } - return 0; - } - - public int GetAllSerieDataCount() - { - var total = 0; - foreach (var serie in m_Series) - total += serie.dataCount; - return total; - } - - /// <summary> - /// Whether to show serie. - /// |设置指定系列是否显示。 - /// </summary> - /// <param name="serieName">the name of serie</param> - /// <param name="active">Active or not</param> - public void SetSerieActive(string serieName, bool active) - { - var serie = GetSerie(serieName); - if (serie != null) - SetSerieActive(serie, active); - } - - /// <summary> - /// Whether to show serie. - /// |设置指定系列是否显示。 - /// </summary> - /// <param name="serieIndex">the index of serie</param> - /// <param name="active">Active or not</param> - public void SetSerieActive(int serieIndex, bool active) - { - var serie = GetSerie(serieIndex); - if (serie != null) - SetSerieActive(serie, active); - } - - public void SetSerieActive(Serie serie, bool active) - { - serie.show = active; - serie.AnimationReset(); - if (active) serie.AnimationFadeIn(); - UpdateLegendColor(serie.serieName, active); - } - - /// <summary> - /// Add a category data to xAxis. - /// |添加一个类目数据到指定的x轴。 - /// </summary> - /// <param name="category">the category data</param> - /// <param name="xAxisIndex">which xAxis should category add to</param> - public void AddXAxisData(string category, int xAxisIndex = 0) - { - var xAxis = GetChartComponent<XAxis>(xAxisIndex); - if (xAxis != null) - { - xAxis.AddData(category); - } - } - - /// <summary> - /// Update category data. - /// |更新X轴类目数据。 - /// </summary> - /// <param name="index">the index of category data</param> - /// <param name="category"></param> - /// <param name="xAxisIndex">which xAxis index to update to</param> - public void UpdateXAxisData(int index, string category, int xAxisIndex = 0) - { - var xAxis = GetChartComponent<XAxis>(xAxisIndex); - if (xAxis != null) - { - xAxis.UpdateData(index, category); - } - } - - /// <summary> - /// Add an icon to xAxis. - /// |添加一个图标到指定的x轴。 - /// </summary> - /// <param name="icon"></param> - /// <param name="xAxisIndex"></param> - public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0) - { - var xAxis = GetChartComponent<XAxis>(xAxisIndex); - if (xAxis != null) - { - xAxis.AddIcon(icon); - } - } - - /// <summary> - /// Update xAxis icon. - /// |更新X轴图标。 - /// </summary> - /// <param name="index"></param> - /// <param name="icon"></param> - /// <param name="xAxisIndex"></param> - public void UdpateXAxisIcon(int index, Sprite icon, int xAxisIndex = 0) - { - var xAxis = GetChartComponent<XAxis>(xAxisIndex); - if (xAxis != null) - { - xAxis.UpdateIcon(index, icon); - } - } - - /// <summary> - /// Add a category data to yAxis. - /// |添加一个类目数据到指定的y轴。 - /// </summary> - /// <param name="category">the category data</param> - /// <param name="yAxisIndex">which yAxis should category add to</param> - public void AddYAxisData(string category, int yAxisIndex = 0) - { - var yAxis = GetChartComponent<YAxis>(yAxisIndex); - if (yAxis != null) - { - yAxis.AddData(category); - } - } - - /// <summary> - /// Update category data. - /// |更新Y轴类目数据。 - /// </summary> - /// <param name="index">the index of category data</param> - /// <param name="category"></param> - /// <param name="yAxisIndex">which yAxis index to update to</param> - public void UpdateYAxisData(int index, string category, int yAxisIndex = 0) - { - var yAxis = GetChartComponent<YAxis>(yAxisIndex); - if (yAxis != null) - { - yAxis.UpdateData(index, category); - } - } - - /// <summary> - /// Add an icon to yAxis. - /// |添加一个图标到指定的y轴。 - /// </summary> - /// <param name="icon"></param> - /// <param name="yAxisIndex"></param> - public void AddYAxisIcon(Sprite icon, int yAxisIndex = 0) - { - var yAxis = GetChartComponent<YAxis>(yAxisIndex); - if (yAxis != null) - { - yAxis.AddIcon(icon); - } - } - - /// <summary> - /// 更新Y轴图标。 - /// </summary> - /// <param name="index"></param> - /// <param name="icon"></param> - /// <param name="yAxisIndex"></param> - public void UpdateYAxisIcon(int index, Sprite icon, int yAxisIndex = 0) - { - var yAxis = GetChartComponent<YAxis>(yAxisIndex); - if (yAxis != null) - { - yAxis.UpdateIcon(index, icon); - } - } - - public float GetSerieBarGap<T>() where T : Serie - { - float gap = 0f; - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - if (serie is T) - { - if (serie.barGap != 0) - { - gap = serie.barGap; - } - } - } - return gap; - } - - public double GetSerieSameStackTotalValue<T>(string stack, int dataIndex) where T : Serie - { - if (string.IsNullOrEmpty(stack)) return 0; - double total = 0; - foreach (var serie in m_Series) - { - if (serie is T) - { - if (stack.Equals(serie.stack)) - { - total += serie.data[dataIndex].data[1]; - } - } - } - return total; - } - - public int GetSerieBarRealCount<T>() where T : Serie - { - var count = 0; - barStackSet.Clear(); - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - if (!serie.show) continue; - if (serie is T) - { - if (!string.IsNullOrEmpty(serie.stack)) - { - if (barStackSet.Contains(serie.stack)) continue; - barStackSet.Add(serie.stack); - } - count++; - - } - } - return count; - } - - private HashSet<string> barStackSet = new HashSet<string>(); - public float GetSerieTotalWidth<T>(float categoryWidth, float gap, int realBarCount) where T : Serie - { - float total = 0; - float lastGap = 0; - barStackSet.Clear(); - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - if (!serie.show) continue; - if (serie is T) - { - if (!string.IsNullOrEmpty(serie.stack)) - { - if (barStackSet.Contains(serie.stack)) continue; - barStackSet.Add(serie.stack); - } - var width = GetStackBarWidth<T>(categoryWidth, serie, realBarCount); - if (gap == -1) - { - if (width > total) total = width; - } - else - { - lastGap = ChartHelper.GetActualValue(gap, width); - total += width; - total += lastGap; - } - } - } - if (total > 0 && gap != -1) total -= lastGap; - return total; - } - - public float GetSerieTotalGap<T>(float categoryWidth, float gap, int index) where T : Serie - { - if (index <= 0) return 0; - var total = 0f; - var count = 0; - var totalRealBarCount = GetSerieBarRealCount<T>(); - barStackSet.Clear(); - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - if (!serie.show) continue; - if (serie is T) - { - if (!string.IsNullOrEmpty(serie.stack)) - { - if (barStackSet.Contains(serie.stack)) continue; - barStackSet.Add(serie.stack); - } - var width = GetStackBarWidth<T>(categoryWidth, serie, totalRealBarCount); - if (gap == -1) - { - if (width > total) total = width; - } - else - { - total += width + ChartHelper.GetActualValue(gap, width); - } - if (count + 1 >= index) - break; - else - count++; - } - } - return total; - } - - private float GetStackBarWidth<T>(float categoryWidth, Serie now, int realBarCount) where T : Serie - { - if (string.IsNullOrEmpty(now.stack)) return now.GetBarWidth(categoryWidth, realBarCount); - float barWidth = 0; - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - if ((serie is T) && - serie.show && now.stack.Equals(serie.stack)) - { - if (serie.barWidth > barWidth) barWidth = serie.barWidth; - } - } - if (barWidth == 0) - { - var width = ChartHelper.GetActualValue(0.6f, categoryWidth); - if (realBarCount == 0) - return width < 1 ? categoryWidth : width; - else - return width / realBarCount; - } - else - return ChartHelper.GetActualValue(barWidth, categoryWidth); - } - - private List<string> tempList = new List<string>(); - public int GetSerieIndexIfStack<T>(Serie currSerie) where T : Serie - { - tempList.Clear(); - int index = 0; - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - if (!(serie is T)) continue; - if (string.IsNullOrEmpty(serie.stack)) - { - if (serie.index == currSerie.index) return index; - tempList.Add(string.Empty); - index++; - } - else - { - if (!tempList.Contains(serie.stack)) - { - if (serie.index == currSerie.index) return index; - tempList.Add(serie.stack); - index++; - } - else - { - if (serie.index == currSerie.index) return tempList.IndexOf(serie.stack); - } - } - } - return 0; - } - - internal void InitSerieHandlers() - { - m_SerieHandlers.Clear(); - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - serie.index = i; - CreateSerieHandler(serie); - } - } - - private void CreateSerieHandler(Serie serie) - { - if (serie == null) - throw new ArgumentNullException("serie is null"); - - if (!serie.GetType().IsDefined(typeof(SerieHandlerAttribute), false)) - { - Debug.LogError("Serie no Handler:" + serie.GetType()); - return; - } - var attribute = serie.GetType().GetAttribute<SerieHandlerAttribute>(); - var handler = (SerieHandler) Activator.CreateInstance(attribute.handler); - handler.attribute = attribute; - handler.chart = this; - handler.defaultDimension = 1; - handler.SetSerie(serie); - serie.handler = handler; - m_SerieHandlers.Add(handler); - } - - private Serie InsertSerie(int index, Type type, string serieName, bool show = true, bool addToHead = false) - { - CheckAddRequireChartComponent(type); - var serie = Activator.CreateInstance(type) as Serie; - serie.show = show; - serie.serieName = serieName; - serie.serieType = type.Name; - serie.index = m_Series.Count; - - if (type == typeof(Scatter)) - { - serie.symbol.show = true; - serie.symbol.type = SymbolType.Circle; - } - else if (type == typeof(Line)) - { - serie.symbol.show = true; - serie.symbol.type = SymbolType.EmptyCircle; - } - else - { - serie.symbol.show = false; - } - InsertSerie(serie, index, addToHead); - return serie; - } - - private void ResetSeriesIndex() - { -#if UNITY_EDITOR && UNITY_2019_1_OR_NEWER - UnityEditor.EditorUtility.SetDirty(this); -#endif - for (int i = 0; i < m_Series.Count; i++) - { - m_Series[i].index = i; - } - } - - private void AddSerieAfterDeserialize(Serie serie) - { - serie.OnAfterDeserialize(); - m_Series.Add(serie); - } - - public string GenerateDefaultSerieName() - { - return "serie" + m_Series.Count; - } - - public bool IsSerieName(string name) - { - if (string.IsNullOrEmpty(name)) - return false; - foreach (var serie in m_Series) - { - if (name.Equals(serie.serieName)) - return true; - } - return false; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs.meta b/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs.meta deleted file mode 100644 index 841dd30..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Serie.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 70fab7deef662441eaaee4d6ddd43295 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.cs b/Assets/XCharts/Runtime/Internal/BaseChart.cs deleted file mode 100644 index 50b44db..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.cs +++ /dev/null @@ -1,698 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [AddComponentMenu("XCharts/EmptyChart", 10)] - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public partial class BaseChart : BaseGraph, ISerializationCallbackReceiver - { - [SerializeField] protected string m_ChartName; - [SerializeField] protected ThemeStyle m_Theme = new ThemeStyle(); - [SerializeField] protected Settings m_Settings; - -#pragma warning disable 0414 - [SerializeField][ListForComponent(typeof(AngleAxis))] private List<AngleAxis> m_AngleAxes = new List<AngleAxis>(); - [SerializeField][ListForComponent(typeof(Background))] private List<Background> m_Backgrounds = new List<Background>(); - [SerializeField][ListForComponent(typeof(DataZoom))] private List<DataZoom> m_DataZooms = new List<DataZoom>(); - [SerializeField][ListForComponent(typeof(GridCoord))] private List<GridCoord> m_Grids = new List<GridCoord>(); - [SerializeField][ListForComponent(typeof(Legend))] private List<Legend> m_Legends = new List<Legend>(); - [SerializeField][ListForComponent(typeof(MarkLine))] private List<MarkLine> m_MarkLines = new List<MarkLine>(); - [SerializeField][ListForComponent(typeof(MarkArea))] private List<MarkArea> m_MarkAreas = new List<MarkArea>(); - [SerializeField][ListForComponent(typeof(PolarCoord))] private List<PolarCoord> m_Polars = new List<PolarCoord>(); - [SerializeField][ListForComponent(typeof(RadarCoord))] private List<RadarCoord> m_Radars = new List<RadarCoord>(); - [SerializeField][ListForComponent(typeof(RadiusAxis))] private List<RadiusAxis> m_RadiusAxes = new List<RadiusAxis>(); - [SerializeField][ListForComponent(typeof(Title))] private List<Title> m_Titles = new List<Title>(); - [SerializeField][ListForComponent(typeof(Tooltip))] private List<Tooltip> m_Tooltips = new List<Tooltip>(); - [SerializeField][ListForComponent(typeof(VisualMap))] private List<VisualMap> m_VisualMaps = new List<VisualMap>(); - [SerializeField][ListForComponent(typeof(XAxis))] private List<XAxis> m_XAxes = new List<XAxis>(); - [SerializeField][ListForComponent(typeof(YAxis))] private List<YAxis> m_YAxes = new List<YAxis>(); - [SerializeField][ListForComponent(typeof(SingleAxis))] private List<SingleAxis> m_SingleAxes = new List<SingleAxis>(); - [SerializeField][ListForComponent(typeof(ParallelCoord))] private List<ParallelCoord> m_Parallels = new List<ParallelCoord>(); - [SerializeField][ListForComponent(typeof(ParallelAxis))] private List<ParallelAxis> m_ParallelAxes = new List<ParallelAxis>(); - [SerializeField][ListForComponent(typeof(Comment))] private List<Comment> m_Comments = new List<Comment>(); - - [SerializeField][ListForSerie(typeof(Bar))] private List<Bar> m_SerieBars = new List<Bar>(); - [SerializeField][ListForSerie(typeof(Candlestick))] private List<Candlestick> m_SerieCandlesticks = new List<Candlestick>(); - [SerializeField][ListForSerie(typeof(EffectScatter))] private List<EffectScatter> m_SerieEffectScatters = new List<EffectScatter>(); - [SerializeField][ListForSerie(typeof(Heatmap))] private List<Heatmap> m_SerieHeatmaps = new List<Heatmap>(); - [SerializeField][ListForSerie(typeof(Line))] private List<Line> m_SerieLines = new List<Line>(); - [SerializeField][ListForSerie(typeof(Pie))] private List<Pie> m_SeriePies = new List<Pie>(); - [SerializeField][ListForSerie(typeof(Radar))] private List<Radar> m_SerieRadars = new List<Radar>(); - [SerializeField][ListForSerie(typeof(Ring))] private List<Ring> m_SerieRings = new List<Ring>(); - [SerializeField][ListForSerie(typeof(Scatter))] private List<Scatter> m_SerieScatters = new List<Scatter>(); - [SerializeField][ListForSerie(typeof(Parallel))] private List<Parallel> m_SerieParallels = new List<Parallel>(); - [SerializeField][ListForSerie(typeof(SimplifiedLine))] private List<SimplifiedLine> m_SerieSimplifiedLines = new List<SimplifiedLine>(); - [SerializeField][ListForSerie(typeof(SimplifiedBar))] private List<SimplifiedBar> m_SerieSimplifiedBars = new List<SimplifiedBar>(); - [SerializeField][ListForSerie(typeof(SimplifiedCandlestick))] private List<SimplifiedCandlestick> m_SerieSimplifiedCandlesticks = new List<SimplifiedCandlestick>(); -#pragma warning restore 0414 - protected List<Serie> m_Series = new List<Serie>(); - protected List<MainComponent> m_Components = new List<MainComponent>(); - - protected Dictionary<Type, FieldInfo> m_TypeListForComponent = new Dictionary<Type, FieldInfo>(); - protected Dictionary<Type, FieldInfo> m_TypeListForSerie = new Dictionary<Type, FieldInfo>(); - - protected Dictionary<Type, List<MainComponent>> m_ComponentMaps = new Dictionary<Type, List<MainComponent>>(); - - public Dictionary<Type, FieldInfo> typeListForComponent { get { return m_TypeListForComponent; } } - public Dictionary<Type, FieldInfo> typeListForSerie { get { return m_TypeListForSerie; } } - public List<MainComponent> components { get { return m_Components; } } - - public List<Serie> series { get { return m_Series; } } - - protected float m_ChartWidth; - protected float m_ChartHeight; - protected float m_ChartX; - protected float m_ChartY; - protected Vector3 m_ChartPosition = Vector3.zero; - protected Vector2 m_ChartMinAnchor; - protected Vector2 m_ChartMaxAnchor; - protected Vector2 m_ChartPivot; - protected Vector2 m_ChartSizeDelta; - - protected Rect m_ChartRect = new Rect(0, 0, 0, 0); - protected Action m_OnInit; - protected Action m_OnUpdate; - protected Action<VertexHelper> m_OnDrawBase; - protected Action<VertexHelper> m_OnDrawTop; - protected Action<VertexHelper, Serie> m_OnDrawSerieBefore; - protected Action<VertexHelper, Serie> m_OnDrawSerieAfter; - protected Action<PointerEventData, int, int> m_OnPointerClickPie; - protected Action<PointerEventData, int> m_OnPointerClickBar; - protected Action<Axis, double> m_OnAxisPointerValueChanged; - protected Action<Legend, int, string, bool> m_OnLegendClick; - protected Action<Legend, int, string> m_OnLegendEnter; - protected Action<Legend, int, string> m_OnLegendExit; - - protected CustomDrawGaugePointerFunction m_CustomDrawGaugePointerFunction; - - internal bool m_CheckAnimation = false; - internal protected List<string> m_LegendRealShowName = new List<string>(); - protected List<Painter> m_PainterList = new List<Painter>(); - internal Painter m_PainterTop; - internal int m_BasePainterVertCount; - internal int m_TopPainterVertCount; - - private ThemeType m_CheckTheme = 0; - protected List<MainComponentHandler> m_ComponentHandlers = new List<MainComponentHandler>(); - protected List<SerieHandler> m_SerieHandlers = new List<SerieHandler>(); - - protected virtual void DefaultChart() { } - - protected override void InitComponent() - { - base.InitComponent(); - SeriesHelper.UpdateSerieNameList(this, ref m_LegendRealShowName); - foreach (var handler in m_ComponentHandlers) - handler.InitComponent(); - foreach (var handler in m_SerieHandlers) - handler.InitComponent(); - m_DebugInfo.Init(this); - } - - protected override void Awake() - { - if (m_Settings == null) - m_Settings = Settings.DefaultSettings; - CheckTheme(); - base.Awake(); - InitComponentHandlers(); - InitSerieHandlers(); - AnimationReset(); - AnimationFadeIn(); - XChartsMgr.AddChart(this); - } - - protected void OnInit() - { - RemoveAllChartComponent(); - OnBeforeSerialize(); - AddChartComponentWhenNoExist<Title>(); - AddChartComponentWhenNoExist<Tooltip>(); - - GetChartComponent<Title>().text = GetType().Name; - - if (m_Theme.sharedTheme != null) - m_Theme.sharedTheme.CopyTheme(ThemeType.Default); - else - m_Theme.sharedTheme = XCThemeMgr.GetTheme(ThemeType.Default); - - var sizeDelta = rectTransform.sizeDelta; - if (sizeDelta.x < 580 && sizeDelta.y < 300) - { - rectTransform.sizeDelta = new Vector2(580, 300); - } - ChartHelper.HideAllObject(transform); - if (m_OnInit != null) - m_OnInit(); - } - -#if UNITY_EDITOR - protected override void Reset() - { - base.Reset(); - OnInit(); - DefaultChart(); - Awake(); - } -#endif - - protected override void Start() - { - RefreshChart(); - } - - protected override void Update() - { - CheckTheme(); - base.Update(); - CheckPainter(); - CheckRefreshChart(); - Internal_CheckAnimation(); - foreach (var handler in m_SerieHandlers) handler.Update(); - foreach (var handler in m_ComponentHandlers) handler.Update(); - m_DebugInfo.Update(); - if (m_OnUpdate != null) - m_OnUpdate(); - } - - public Painter GetPainter(int index) - { - if (index >= 0 && index < m_PainterList.Count) - { - return m_PainterList[index]; - } - return null; - } - - public void RefreshBasePainter() - { - m_Painter.Refresh(); - } - public void RefreshTopPainter() - { - m_PainterTop.Refresh(); - } - - public void RefreshPainter(int index) - { - var painter = GetPainter(index); - RefreshPainter(painter); - } - - public void RefreshPainter(Serie serie) - { - if (serie == null) return; - RefreshPainter(GetPainterIndexBySerie(serie)); - } - - internal override void RefreshPainter(Painter painter) - { - base.RefreshPainter(painter); - if (painter != null && painter.type == Painter.Type.Serie) - { - m_PainterTop.Refresh(); - } - } - - public void SetPainterActive(int index, bool flag) - { - var painter = GetPainter(index); - if (painter == null) return; - painter.SetActive(flag, m_DebugInfo.showAllChartObject); - } - - protected virtual void CheckTheme() - { - if (m_Theme.sharedTheme == null) - { - m_Theme.sharedTheme = XCThemeMgr.GetTheme(ThemeType.Default); - } - if (m_Theme.sharedTheme != null && m_CheckTheme != m_Theme.themeType) - { - m_CheckTheme = m_Theme.themeType; - m_Theme.sharedTheme.CopyTheme(m_CheckTheme); -#if UNITY_EDITOR - UnityEditor.EditorUtility.SetDirty(this); -#endif - SetAllComponentDirty(); - OnThemeChanged(); - } - } - protected override void CheckComponent() - { - base.CheckComponent(); - if (m_Theme.anyDirty) - { - if (m_Theme.componentDirty) - { - SetAllComponentDirty(); - } - if (m_Theme.vertsDirty) RefreshChart(); - m_Theme.ClearDirty(); - } - foreach (var com in m_Components) - CheckComponentDirty(com); - } - - protected void CheckComponentDirty(MainComponent component) - { - if (component == null) return; - if (component.anyDirty) - { - if (component.componentDirty && component.refreshComponent != null) - { - component.refreshComponent.Invoke(); - } - if (component.vertsDirty) - { - if (component.painter != null) - { - RefreshPainter(component.painter); - } - } - component.ClearDirty(); - } - } - - protected override void SetAllComponentDirty() - { - base.SetAllComponentDirty(); - m_Theme.SetAllDirty(); - foreach (var com in m_Components) com.SetAllDirty(); - m_RefreshChart = true; - } - - protected override void OnDestroy() - { - for (int i = transform.childCount - 1; i >= 0; i--) - { - DestroyImmediate(transform.GetChild(i).gameObject); - } - } - - protected virtual void CheckPainter() - { - for (int i = 0; i < m_Series.Count; i++) - { - var serie = m_Series[i]; - serie.index = i; - SetPainterActive(i, true); - } - } - - protected override void InitPainter() - { - base.InitPainter(); - if (settings == null) return; - m_Painter.material = settings.basePainterMaterial; - m_PainterList.Clear(); - var sizeDelta = new Vector2(m_GraphWidth, m_GraphHeight); - for (int i = 0; i < settings.maxPainter; i++) - { - var index = settings.reversePainter ? settings.maxPainter - 1 - i : i; - var painter = ChartHelper.AddPainterObject("painter_" + index, transform, m_GraphMinAnchor, - m_GraphMaxAnchor, m_GraphPivot, sizeDelta, chartHideFlags, 2 + index); - painter.index = m_PainterList.Count; - painter.type = Painter.Type.Serie; - painter.onPopulateMesh = OnDrawPainterSerie; - painter.SetActive(false, m_DebugInfo.showAllChartObject); - painter.material = settings.seriePainterMaterial; - painter.transform.SetSiblingIndex(index + 1); - m_PainterList.Add(painter); - } - m_PainterTop = ChartHelper.AddPainterObject("painter_t", transform, m_GraphMinAnchor, - m_GraphMaxAnchor, m_GraphPivot, sizeDelta, chartHideFlags, 2 + settings.maxPainter); - m_PainterTop.type = Painter.Type.Top; - m_PainterTop.onPopulateMesh = OnDrawPainterTop; - m_PainterTop.SetActive(true, m_DebugInfo.showAllChartObject); - m_PainterTop.material = settings.topPainterMaterial; - m_PainterTop.transform.SetSiblingIndex(settings.maxPainter + 1); - } - - internal void InitComponentHandlers() - { - m_ComponentHandlers.Clear(); - m_Components.Sort(); - m_ComponentMaps.Clear(); - foreach (var component in m_Components) - { - var type = component.GetType(); - List<MainComponent> list; - if (!m_ComponentMaps.TryGetValue(type, out list)) - { - list = new List<MainComponent>(); - m_ComponentMaps[type] = list; - } - component.index = list.Count; - list.Add(component); - CreateComponentHandler(component); - } - } - - protected override void CheckRefreshChart() - { - if (m_Painter == null) return; - if (m_RefreshChart) - { - CheckRefreshPainter(); - m_RefreshChart = false; - } - } - - protected override void CheckRefreshPainter() - { - if (m_Painter == null) return; - m_Painter.CheckRefresh(); - foreach (var painter in m_PainterList) painter.CheckRefresh(); - if (m_PainterTop != null) m_PainterTop.CheckRefresh(); - } - - public void Internal_CheckAnimation() - { - if (!m_CheckAnimation) - { - m_CheckAnimation = true; - AnimationFadeIn(); - } - } - - protected override void OnSizeChanged() - { - base.OnSizeChanged(); - m_ChartWidth = m_GraphWidth; - m_ChartHeight = m_GraphHeight; - m_ChartX = m_GraphX; - m_ChartY = m_GraphY; - m_ChartPosition = m_GraphPosition; - m_ChartMinAnchor = m_GraphMinAnchor; - m_ChartMaxAnchor = m_GraphMaxAnchor; - m_ChartPivot = m_GraphPivot; - m_ChartSizeDelta = m_GraphSizeDelta; - m_ChartRect = m_GraphRect; - SetAllComponentDirty(); - OnCoordinateChanged(); - RefreshChart(); - } - - internal virtual void OnSerieDataUpdate(int serieIndex) - { - foreach (var handler in m_ComponentHandlers) handler.OnSerieDataUpdate(serieIndex); - } - - internal virtual void OnCoordinateChanged() - { - foreach (var component in m_Components) - { - if (component is Axis) - component.SetAllDirty(); - if (component is IUpdateRuntimeData) - (component as IUpdateRuntimeData).UpdateRuntimeData(m_ChartX, m_ChartY, m_ChartWidth, m_ChartHeight); - } - } - - protected override void OnLocalPositionChanged() - { - Background background; - if (TryGetChartComponent<Background>(out background)) - background.SetAllDirty(); - } - - protected virtual void OnThemeChanged() { } - - public virtual void OnDataZoomRangeChanged(DataZoom dataZoom) - { - foreach (var index in dataZoom.xAxisIndexs) - { - var axis = GetChartComponent<XAxis>(index); - if (axis != null && axis.show) axis.SetAllDirty(); - } - foreach (var index in dataZoom.yAxisIndexs) - { - var axis = GetChartComponent<YAxis>(index); - if (axis != null && axis.show) axis.SetAllDirty(); - } - } - - public override void OnPointerClick(PointerEventData eventData) - { - m_DebugInfo.clickChartCount++; - base.OnPointerClick(eventData); - foreach (var handler in m_SerieHandlers) handler.OnPointerClick(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnPointerClick(eventData); - } - - public override void OnPointerDown(PointerEventData eventData) - { - base.OnPointerDown(eventData); - foreach (var handler in m_SerieHandlers) handler.OnPointerDown(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnPointerDown(eventData); - } - - public override void OnPointerUp(PointerEventData eventData) - { - base.OnPointerUp(eventData); - foreach (var handler in m_SerieHandlers) handler.OnPointerUp(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnPointerUp(eventData); - } - - public override void OnPointerEnter(PointerEventData eventData) - { - base.OnPointerEnter(eventData); - foreach (var handler in m_SerieHandlers) handler.OnPointerEnter(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnPointerEnter(eventData); - } - - public override void OnPointerExit(PointerEventData eventData) - { - base.OnPointerExit(eventData); - foreach (var handler in m_SerieHandlers) handler.OnPointerExit(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnPointerExit(eventData); - } - - public override void OnBeginDrag(PointerEventData eventData) - { - base.OnBeginDrag(eventData); - foreach (var handler in m_SerieHandlers) handler.OnBeginDrag(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnBeginDrag(eventData); - } - - public override void OnDrag(PointerEventData eventData) - { - base.OnDrag(eventData); - foreach (var handler in m_SerieHandlers) handler.OnDrag(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnDrag(eventData); - } - - public override void OnEndDrag(PointerEventData eventData) - { - base.OnEndDrag(eventData); - foreach (var handler in m_SerieHandlers) handler.OnEndDrag(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnEndDrag(eventData); - } - - public override void OnScroll(PointerEventData eventData) - { - base.OnScroll(eventData); - foreach (var handler in m_SerieHandlers) handler.OnScroll(eventData); - foreach (var handler in m_ComponentHandlers) handler.OnScroll(eventData); - } - - public virtual void OnLegendButtonClick(int index, string legendName, bool show) - { - foreach (var handler in m_SerieHandlers) - handler.OnLegendButtonClick(index, legendName, show); - } - - public virtual void OnLegendButtonEnter(int index, string legendName) - { - foreach (var handler in m_SerieHandlers) - handler.OnLegendButtonEnter(index, legendName); - } - - public virtual void OnLegendButtonExit(int index, string legendName) - { - foreach (var handler in m_SerieHandlers) - handler.OnLegendButtonExit(index, legendName); - } - - protected override void OnDrawPainterBase(VertexHelper vh, Painter painter) - { - vh.Clear(); - DrawBackground(vh); - DrawPainterBase(vh); - foreach (var handler in m_ComponentHandlers) handler.DrawBase(vh); - foreach (var handler in m_SerieHandlers) handler.DrawBase(vh); - if (m_OnDrawBase != null) - { - m_OnDrawBase(vh); - } - m_BasePainterVertCount = vh.currentVertCount; - } - - protected virtual void OnDrawPainterSerie(VertexHelper vh, Painter painter) - { - vh.Clear(); - var maxPainter = settings.maxPainter; - var maxSeries = m_Series.Count; - var rate = Mathf.CeilToInt(maxSeries * 1.0f / maxPainter); - m_PainterTop.Refresh(); - m_DebugInfo.refreshCount++; - for (int i = painter.index * rate; i < (painter.index + 1) * rate && i < maxSeries; i++) - { - var serie = m_Series[i]; - serie.context.colorIndex = GetLegendRealShowNameIndex(serie.legendName); - serie.context.dataPoints.Clear(); - serie.context.dataIgnores.Clear(); - serie.animation.context.isAllItemAnimationEnd = true; - if (!serie.context.pointerEnter) - serie.ResetInteract(); - - if (m_OnDrawSerieBefore != null) - { - m_OnDrawSerieBefore.Invoke(vh, serie); - } - DrawPainterSerie(vh, serie); - if (i >= 0 && i < m_SerieHandlers.Count) - { - var handler = m_SerieHandlers[i]; - handler.DrawSerie(vh); - handler.RefreshLabelNextFrame(); - } - if (m_OnDrawSerieAfter != null) - { - m_OnDrawSerieAfter(vh, serie); - } - serie.context.vertCount = vh.currentVertCount; - } - } - - protected virtual void OnDrawPainterTop(VertexHelper vh, Painter painter) - { - vh.Clear(); - DrawPainterTop(vh); - foreach (var draw in m_ComponentHandlers) draw.DrawTop(vh); - if (m_OnDrawTop != null) - { - m_OnDrawTop(vh); - } - m_TopPainterVertCount = vh.currentVertCount; - } - - protected virtual void DrawPainterSerie(VertexHelper vh, Serie serie) { } - - protected virtual void DrawPainterTop(VertexHelper vh) - { - foreach (var handler in m_SerieHandlers) - handler.DrawTop(vh); - } - - protected virtual void DrawBackground(VertexHelper vh) - { - var background = GetChartComponent<Background>(); - if (background != null && background.show) - return; - Vector3 p1 = new Vector3(chartX, chartY + chartHeight); - Vector3 p2 = new Vector3(chartX + chartWidth, chartY + chartHeight); - Vector3 p3 = new Vector3(chartX + chartWidth, chartY); - Vector3 p4 = new Vector3(chartX, chartY); - UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, theme.backgroundColor); - } - - protected int GetPainterIndexBySerie(Serie serie) - { - var maxPainter = settings.maxPainter; - var maxSeries = m_Series.Count; - if (maxPainter >= maxSeries) return serie.index; - else - { - var rate = Mathf.CeilToInt(maxSeries * 1.0f / maxPainter); - return serie.index / rate; - } - } - - private void InitListForFieldInfos() - { - if (m_TypeListForSerie.Count != 0) return; - m_TypeListForComponent.Clear(); - m_TypeListForSerie.Clear(); - var fileds1 = GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); - var fileds2 = GetType().BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance); - var list = ListPool<FieldInfo>.Get(); - list.AddRange(fileds1); - list.AddRange(fileds2); - foreach (var field in list) - { - var attribute1 = field.GetAttribute<ListForSerie>(false); - if (attribute1 != null) - m_TypeListForSerie.Add(attribute1.type, field); - - var attribute2 = field.GetAttribute<ListForComponent>(false); - if (attribute2 != null) - m_TypeListForComponent.Add(attribute2.type, field); - } - ListPool<FieldInfo>.Release(list); - } - - public void OnBeforeSerialize() - { -#if UNITY_EDITOR && UNITY_2019_1_OR_NEWER - if (!UnityEditor.EditorUtility.IsDirty(this)) - return; - UnityEditor.EditorUtility.ClearDirty(this); -#endif - InitListForFieldInfos(); - foreach (var kv in m_TypeListForSerie) - { - ReflectionUtil.InvokeListClear(this, kv.Value); - } - foreach (var kv in m_TypeListForComponent) - { - ReflectionUtil.InvokeListClear(this, kv.Value); - } - foreach (var component in m_Components) - { - FieldInfo field; - if (m_TypeListForComponent.TryGetValue(component.GetType(), out field)) - ReflectionUtil.InvokeListAdd(this, field, component); - else - Debug.LogError("No ListForComponent:" + component.GetType()); - } - foreach (var serie in m_Series) - { - FieldInfo field; - serie.OnBeforeSerialize(); - if (m_TypeListForSerie.TryGetValue(serie.GetType(), out field)) - ReflectionUtil.InvokeListAdd(this, field, serie); - else - Debug.LogError("No ListForSerie:" + serie.GetType()); - } - } - - public void OnAfterDeserialize() - { - InitListForFieldInfos(); - m_Components.Clear(); - m_Series.Clear(); - foreach (var kv in m_TypeListForComponent) - { - ReflectionUtil.InvokeListAddTo<MainComponent>(this, kv.Value, AddComponent); - } - foreach (var kv in m_TypeListForSerie) - { - ReflectionUtil.InvokeListAddTo<Serie>(this, kv.Value, AddSerieAfterDeserialize); - } - m_Series.Sort(); - m_Components.Sort(); - InitComponentHandlers(); - InitSerieHandlers(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.cs.meta b/Assets/XCharts/Runtime/Internal/BaseChart.cs.meta deleted file mode 100644 index 25be7da..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseChart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d5053a63a1ebdfe4f8972f194156c3d3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseGraph.API.cs b/Assets/XCharts/Runtime/Internal/BaseGraph.API.cs deleted file mode 100644 index a929022..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseGraph.API.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.EventSystems; - -namespace XCharts.Runtime -{ - /// <summary> - /// The base class of all graphs or components. - /// |所有图形的基类。 - /// </summary> - public partial class BaseGraph - { - /// <summary> - /// The x of graph. - /// |图形的X - /// </summary> - public float graphX { get { return m_GraphX; } } - /// <summary> - /// The y of graph. - /// |图形的Y - /// </summary> - public float graphY { get { return m_GraphY; } } - /// <summary> - /// The width of graph. - /// |图形的宽 - /// </summary> - public float graphWidth { get { return m_GraphWidth; } } - /// <summary> - /// The height of graph. - /// |图形的高 - /// </summary> - public float graphHeight { get { return m_GraphHeight; } } - /// <summary> - /// The position of graph. - /// |图形的左下角起始坐标。 - /// </summary> - public Vector3 graphPosition { get { return m_GraphPosition; } } - public Rect graphRect { get { return m_GraphRect; } } - /// <summary> - /// The postion of pointer. - /// |鼠标位置。 - /// </summary> - public Vector2 pointerPos { get; protected set; } - /// <summary> - /// Whether the mouse pointer is in the chart. - /// |鼠标是否在图表内。 - /// </summary> - public bool isPointerInChart { get; protected set; } - /// <summary> - /// 警告信息。 - /// </summary> - public string warningInfo { get; protected set; } - /// <summary> - /// 强制开启鼠标事件检测。 - /// </summary> - public bool forceOpenRaycastTarget { get { return m_ForceOpenRaycastTarget; } set { m_ForceOpenRaycastTarget = value; } } - /// <summary> - /// 鼠标点击回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onPointerClick { set { m_OnPointerClick = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标按下回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onPointerDown { set { m_OnPointerDown = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标弹起回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onPointerUp { set { m_OnPointerUp = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标进入回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onPointerEnter { set { m_OnPointerEnter = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标退出回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onPointerExit { set { m_OnPointerExit = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标开始拖拽回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onBeginDrag { set { m_OnBeginDrag = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标拖拽回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onDrag { set { m_OnDrag = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标结束拖拽回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onEndDrag { set { m_OnEndDrag = value; m_ForceOpenRaycastTarget = true; } } - /// <summary> - /// 鼠标滚动回调。 - /// </summary> - public Action<PointerEventData, BaseGraph> onScroll { set { m_OnScroll = value; m_ForceOpenRaycastTarget = true; } } - - /// <summary> - /// 设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform) - /// </summary> - /// <param name="width"></param> - /// <param name="height"></param> - public virtual void SetSize(float width, float height) - { - if (LayerHelper.IsFixedWidthHeight(rectTransform)) - { - rectTransform.sizeDelta = new Vector2(width, height); - } - else - { - Debug.LogError("Can't set size on stretch pivot,you need to modify rectTransform by yourself."); - } - } - - /// <summary> - /// 重新初始化Painter - /// </summary> - public void SetPainterDirty() - { - m_PainerDirty = true; - } - - /// <summary> - /// Redraw graph in next frame. - /// |在下一帧刷新图形。 - /// </summary> - public void RefreshGraph() - { - m_RefreshChart = true; - } - - public void RefreshAllComponent() - { - SetAllComponentDirty(); - RefreshGraph(); - } - - /// <summary> - /// 检测警告信息。 - /// </summary> - /// <returns></returns> - public string CheckWarning() - { - warningInfo = CheckHelper.CheckChart(this); - return warningInfo; - } - - /// <summary> - /// 移除并重新创建所有图表的Object。 - /// </summary> - public void RebuildChartObject() - { - ChartHelper.DestroyAllChildren(transform); - SetAllComponentDirty(); - } - - public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint) - { -#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX - var relative = Display.RelativeMouseAt(screenPoint); - if (relative != Vector3.zero) - screenPoint = relative; -#endif - var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - screenPoint, cam, out chartPoint)) - { - return false; - } - return true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseGraph.API.cs.meta b/Assets/XCharts/Runtime/Internal/BaseGraph.API.cs.meta deleted file mode 100644 index 26a83ab..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseGraph.API.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 46b27d174989044f3b63eaf0c3b21fcd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/BaseGraph.cs b/Assets/XCharts/Runtime/Internal/BaseGraph.cs deleted file mode 100644 index 28b212d..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseGraph.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [RequireComponent(typeof(CanvasRenderer))] - public partial class BaseGraph : MaskableGraphic, IPointerDownHandler, IPointerUpHandler, - IPointerEnterHandler, IPointerExitHandler, IBeginDragHandler, IPointerClickHandler, - IDragHandler, IEndDragHandler, IScrollHandler - { - - [SerializeField] protected bool m_EnableTextMeshPro = false; - [SerializeField] protected DebugInfo m_DebugInfo = new DebugInfo(); - - protected Painter m_Painter; - protected int m_SiblingIndex; - - protected float m_GraphWidth; - protected float m_GraphHeight; - protected float m_GraphX; - protected float m_GraphY; - protected Vector3 m_GraphPosition = Vector3.zero; - protected Vector2 m_GraphMinAnchor; - protected Vector2 m_GraphMaxAnchor; - protected Vector2 m_GraphPivot; - protected Vector2 m_GraphSizeDelta; - protected Vector2 m_GraphAnchoredPosition; - protected Rect m_GraphRect = new Rect(0, 0, 0, 0); - protected bool m_RefreshChart = false; - protected bool m_ForceOpenRaycastTarget; - protected bool m_IsControlledByLayout = false; - protected bool m_PainerDirty = false; - protected bool m_IsOnValidate = false; - protected Vector3 m_LastLocalPosition; - - protected Action<PointerEventData, BaseGraph> m_OnPointerClick; - protected Action<PointerEventData, BaseGraph> m_OnPointerDown; - protected Action<PointerEventData, BaseGraph> m_OnPointerUp; - protected Action<PointerEventData, BaseGraph> m_OnPointerEnter; - protected Action<PointerEventData, BaseGraph> m_OnPointerExit; - protected Action<PointerEventData, BaseGraph> m_OnBeginDrag; - protected Action<PointerEventData, BaseGraph> m_OnDrag; - protected Action<PointerEventData, BaseGraph> m_OnEndDrag; - protected Action<PointerEventData, BaseGraph> m_OnScroll; - - protected Vector2 graphAnchorMax { get { return m_GraphMinAnchor; } } - protected Vector2 graphAnchorMin { get { return m_GraphMaxAnchor; } } - protected Vector2 graphPivot { get { return m_GraphPivot; } } - public HideFlags chartHideFlags { get { return m_DebugInfo.showAllChartObject ? HideFlags.None : HideFlags.HideInHierarchy; } } - public DebugInfo debug { get { return m_DebugInfo; } } - private ScrollRect m_ScrollRect; - - public Painter painter { get { return m_Painter; } } - - protected virtual void InitComponent() - { - InitPainter(); - } - - protected override void Awake() - { - CheckTextMeshPro(); - m_SiblingIndex = 0; - m_LastLocalPosition = transform.localPosition; - UpdateSize(); - InitComponent(); - CheckIsInScrollRect(); - } - - protected override void Start() - { - m_RefreshChart = true; - } - - protected virtual void Update() - { - CheckSize(); - if (m_IsOnValidate) - { - m_IsOnValidate = false; - m_RefreshChart = true; - CheckTextMeshPro(); - InitComponent(); - } - else - { - CheckComponent(); - } - CheckPointerPos(); - CheckRefreshChart(); - CheckRefreshPainter(); - } - - protected virtual void SetAllComponentDirty() - { -#if UNITY_EDITOR - if (!Application.isPlaying) - { - m_IsOnValidate = true; - } -#endif - m_PainerDirty = true; - } - - protected virtual void CheckComponent() - { - if (m_PainerDirty) - { - InitPainter(); - m_PainerDirty = false; - } - } - - private void CheckTextMeshPro() - { -#if dUI_TextMeshPro - var enableTextMeshPro = true; -#else - var enableTextMeshPro = false; -#endif - if (m_EnableTextMeshPro != enableTextMeshPro) - { - m_EnableTextMeshPro = enableTextMeshPro; - RebuildChartObject(); - } - } - -#if UNITY_EDITOR - protected override void Reset() - { } - - protected override void OnValidate() - { - m_IsOnValidate = true; - } -#endif - - protected override void OnDestroy() - { - for (int i = transform.childCount - 1; i >= 0; i--) - { - DestroyImmediate(transform.GetChild(i).gameObject); - } - } - - protected override void OnPopulateMesh(VertexHelper vh) - { - vh.Clear(); - } - - protected virtual void InitPainter() - { - m_Painter = ChartHelper.AddPainterObject("painter_b", transform, m_GraphMinAnchor, - m_GraphMaxAnchor, m_GraphPivot, new Vector2(m_GraphWidth, m_GraphHeight), chartHideFlags, 1); - m_Painter.type = Painter.Type.Base; - m_Painter.onPopulateMesh = OnDrawPainterBase; - m_Painter.transform.SetSiblingIndex(0); - } - - private void CheckSize() - { - var currWidth = rectTransform.rect.width; - var currHeight = rectTransform.rect.height; - - if (m_GraphWidth == 0 && m_GraphHeight == 0 && (currWidth != 0 || currHeight != 0)) - { - Awake(); - } - - if (m_GraphWidth != currWidth || - m_GraphHeight != currHeight || - m_GraphMinAnchor != rectTransform.anchorMin || - m_GraphMaxAnchor != rectTransform.anchorMax || - m_GraphAnchoredPosition != rectTransform.anchoredPosition) - { - UpdateSize(); - } - if (!ChartHelper.IsValueEqualsVector3(m_LastLocalPosition, transform.localPosition)) - { - m_LastLocalPosition = transform.localPosition; - OnLocalPositionChanged(); - } - } - - protected void UpdateSize() - { - m_GraphWidth = rectTransform.rect.width; - m_GraphHeight = rectTransform.rect.height; - - m_GraphMaxAnchor = rectTransform.anchorMax; - m_GraphMinAnchor = rectTransform.anchorMin; - m_GraphSizeDelta = rectTransform.sizeDelta; - m_GraphAnchoredPosition = rectTransform.anchoredPosition; - - rectTransform.pivot = LayerHelper.ResetChartPositionAndPivot(m_GraphMinAnchor, m_GraphMaxAnchor, - m_GraphWidth, m_GraphHeight, ref m_GraphX, ref m_GraphY); - m_GraphPivot = rectTransform.pivot; - - m_GraphRect.x = m_GraphX; - m_GraphRect.y = m_GraphY; - m_GraphRect.width = m_GraphWidth; - m_GraphRect.height = m_GraphHeight; - m_GraphPosition.x = m_GraphX; - m_GraphPosition.y = m_GraphY; - - OnSizeChanged(); - } - - private void CheckPointerPos() - { - if (!isPointerInChart) return; - if (canvas == null) return; - Vector2 local; - if (!ScreenPointToChartPoint(Input.mousePosition, out local)) - { - pointerPos = Vector2.zero; - } - else - { - pointerPos = local; - } - } - - protected virtual void CheckIsInScrollRect() - { - m_ScrollRect = GetComponentInParent<ScrollRect>(); - } - - protected virtual void CheckRefreshChart() - { - if (m_RefreshChart) - { - m_Painter.Refresh(); - m_RefreshChart = false; - } - } - - protected virtual void CheckRefreshPainter() - { - m_Painter.CheckRefresh(); - } - - internal virtual void RefreshPainter(Painter painter) - { - if (painter == null) return; - painter.Refresh(); - } - - protected virtual void OnSizeChanged() - { - m_RefreshChart = true; - } - - protected virtual void OnLocalPositionChanged() - { } - - protected virtual void OnDrawPainterBase(VertexHelper vh, Painter painter) - { - DrawPainterBase(vh); - } - - protected virtual void DrawPainterBase(VertexHelper vh) - { } - - public virtual void OnPointerClick(PointerEventData eventData) - { - if (m_OnPointerClick != null) m_OnPointerClick(eventData, this); - } - - public virtual void OnPointerDown(PointerEventData eventData) - { - if (m_OnPointerDown != null) m_OnPointerDown(eventData, this); - } - - public virtual void OnPointerUp(PointerEventData eventData) - { - if (m_OnPointerUp != null) m_OnPointerUp(eventData, this); - } - - public virtual void OnPointerEnter(PointerEventData eventData) - { - isPointerInChart = true; - if (m_OnPointerEnter != null) m_OnPointerEnter(eventData, this); - } - - public virtual void OnPointerExit(PointerEventData eventData) - { - isPointerInChart = false; - if (m_OnPointerExit != null) m_OnPointerExit(eventData, this); - } - - public virtual void OnBeginDrag(PointerEventData eventData) - { - if (m_ScrollRect != null) m_ScrollRect.OnBeginDrag(eventData); - if (m_OnBeginDrag != null) m_OnBeginDrag(eventData, this); - } - - public virtual void OnEndDrag(PointerEventData eventData) - { - if (m_ScrollRect != null) m_ScrollRect.OnEndDrag(eventData); - if (m_OnEndDrag != null) m_OnEndDrag(eventData, this); - } - - public virtual void OnDrag(PointerEventData eventData) - { - if (m_ScrollRect != null) m_ScrollRect.OnDrag(eventData); - if (m_OnDrag != null) m_OnDrag(eventData, this); - } - - public virtual void OnScroll(PointerEventData eventData) - { - if (m_ScrollRect != null) m_ScrollRect.OnScroll(eventData); - if (m_OnScroll != null) m_OnScroll(eventData, this); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/BaseGraph.cs.meta b/Assets/XCharts/Runtime/Internal/BaseGraph.cs.meta deleted file mode 100644 index fb3c60e..0000000 --- a/Assets/XCharts/Runtime/Internal/BaseGraph.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4f059825ead3b4a7da7f1fbcebbf545e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Basic.meta b/Assets/XCharts/Runtime/Internal/Basic.meta deleted file mode 100644 index e554ca9..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 31e8b0503e55d41f0bf3baab818d0dfa -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs b/Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs deleted file mode 100644 index 57c992a..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public abstract class BaseSerie - { - public virtual bool vertsDirty { get { return m_VertsDirty; } } - public virtual bool componentDirty { get { return m_ComponentDirty; } } - public virtual bool useDataNameForColor { get { return false; } } - public virtual bool titleJustForSerie { get { return false; } } - public virtual bool useSortData { get { return false; } } - public virtual bool multiDimensionLabel { get { return false; } } - public bool anyDirty { get { return vertsDirty || componentDirty; } } - public Painter painter { get { return m_Painter; } set { m_Painter = value; } } - public Action refreshComponent { get; set; } - public GameObject gameObject { get; set; } - - [NonSerialized] protected bool m_VertsDirty; - [NonSerialized] protected bool m_ComponentDirty; - [NonSerialized] protected Painter m_Painter; - [NonSerialized] public SerieContext context = new SerieContext(); - [NonSerialized] public InteractData interact = new InteractData(); - - public SerieHandler handler { get; set; } - - public virtual void SetVerticesDirty() - { - m_VertsDirty = true; - } - - public virtual void ClearVerticesDirty() - { - m_VertsDirty = false; - } - - public virtual void SetComponentDirty() - { - m_ComponentDirty = true; - } - - public virtual void ClearComponentDirty() - { - m_ComponentDirty = false; - } - - public virtual void ClearData() - { } - - public virtual void ClearDirty() - { - ClearVerticesDirty(); - ClearComponentDirty(); - } - - public virtual void SetAllDirty() - { - SetVerticesDirty(); - SetComponentDirty(); - } - - public virtual void OnRemove() - { - if (handler != null) - handler.RemoveComponent(); - } - - public virtual void OnDataUpdate() - { } - - public virtual void OnBeforeSerialize() - { } - - public virtual void OnAfterDeserialize() - { - OnDataUpdate(); - } - - public void RefreshLabel() - { - if (handler != null) - handler.RefreshLabelNextFrame(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs.meta b/Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs.meta deleted file mode 100644 index 7280559..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/BaseSerie.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 28d00b46c33234f0ab88a5756f63679b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs b/Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs deleted file mode 100644 index 90bca35..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class ChildComponent - { - public virtual int index { get; set; } - - [NonSerialized] protected bool m_VertsDirty; - [NonSerialized] protected bool m_ComponentDirty; - [NonSerialized] protected Painter m_Painter; - - /// <summary> - /// 图表重绘标记。 - /// </summary> - public virtual bool vertsDirty { get { return m_VertsDirty; } } - /// <summary> - /// 组件重新初始化标记。 - /// </summary> - public virtual bool componentDirty { get { return m_ComponentDirty; } } - /// <summary> - /// 需要重绘图表或重新初始化组件。 - /// </summary> - public bool anyDirty { get { return vertsDirty || componentDirty; } } - public Painter painter { get { return m_Painter; } set { m_Painter = value; } } - public Action refreshComponent { get; set; } - public GameObject gameObject { get; set; } - - public virtual void SetVerticesDirty() - { - m_VertsDirty = true; - } - - public virtual void ClearVerticesDirty() - { - m_VertsDirty = false; - } - - public virtual void SetComponentDirty() - { - m_ComponentDirty = true; - } - - public virtual void ClearComponentDirty() - { - m_ComponentDirty = false; - } - - public virtual void ClearDirty() - { - ClearVerticesDirty(); - ClearComponentDirty(); - } - - public virtual void SetAllDirty() - { - SetVerticesDirty(); - SetComponentDirty(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs.meta b/Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs.meta deleted file mode 100644 index 8ffda00..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/ChildComponent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 358324a6b44cb4b35b4393ecf2458993 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs b/Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs deleted file mode 100644 index 6b66f70..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - /// <summary> - /// Coordinate system component. - /// | - /// 坐标系系统。 - /// </summary> - [Serializable] - public abstract class CoordSystem : MainComponent - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs.meta b/Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs.meta deleted file mode 100644 index c74fa3d..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/CoordSystem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 60a0ecce780d64885aa5875dae39aa03 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs b/Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs deleted file mode 100644 index a0834de..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.Text; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class MainComponent : IComparable - { - public int instanceId { get; internal set; } - public int index { get; internal set; } - protected bool m_VertsDirty; - protected bool m_ComponentDirty; - protected Painter m_Painter; - - /// <summary> - /// 图表重绘标记。 - /// </summary> - public virtual bool vertsDirty { get { return m_VertsDirty; } } - /// <summary> - /// 组件重新初始化标记。 - /// </summary> - public virtual bool componentDirty { get { return m_ComponentDirty; } } - /// <summary> - /// 需要重绘图表或重新初始化组件。 - /// </summary> - public bool anyDirty { get { return vertsDirty || componentDirty; } } - public Painter painter { get { return m_Painter; } set { m_Painter = value; } } - public Action refreshComponent { get; set; } - public GameObject gameObject { get; set; } - internal MainComponentHandler handler { get; set; } - - public virtual void SetVerticesDirty() - { - m_VertsDirty = true; - } - - public virtual void ClearVerticesDirty() - { - m_VertsDirty = false; - } - - public virtual void SetComponentDirty() - { - m_ComponentDirty = true; - } - - public virtual void ClearComponentDirty() - { - m_ComponentDirty = false; - } - - public virtual void Reset() { } - - public virtual void ClearData() { } - - public virtual void ClearDirty() - { - ClearVerticesDirty(); - ClearComponentDirty(); - } - - public virtual void SetAllDirty() - { - SetVerticesDirty(); - SetComponentDirty(); - } - - public virtual void SetDefaultValue() { } - - public virtual void OnRemove() - { - if (handler != null) - handler.RemoveComponent(); - } - - public int CompareTo(object obj) - { - var flag = GetType().Name.CompareTo(obj.GetType().Name); - if (flag == 0) - return index.CompareTo((obj as MainComponent).index); - else - return flag; - } - } - - public abstract class MainComponentHandler - { - public BaseChart chart { get; internal set; } - public ComponentHandlerAttribute attribute { get; internal set; } - - public virtual void InitComponent() { } - public virtual void RemoveComponent() { } - public virtual void CheckComponent(StringBuilder sb) { } - public virtual void Update() { } - public virtual void DrawBase(VertexHelper vh) { } - public virtual void DrawTop(VertexHelper vh) { } - public virtual void OnSerieDataUpdate(int serieIndex) { } - public virtual void OnPointerClick(PointerEventData eventData) { } - public virtual void OnPointerDown(PointerEventData eventData) { } - public virtual void OnPointerUp(PointerEventData eventData) { } - public virtual void OnPointerEnter(PointerEventData eventData) { } - public virtual void OnPointerExit(PointerEventData eventData) { } - public virtual void OnDrag(PointerEventData eventData) { } - public virtual void OnBeginDrag(PointerEventData eventData) { } - public virtual void OnEndDrag(PointerEventData eventData) { } - public virtual void OnScroll(PointerEventData eventData) { } - internal abstract void SetComponent(MainComponent component); - } - - public abstract class MainComponentHandler<T> : MainComponentHandler - where T : MainComponent - { - public T component { get; internal set; } - - internal override void SetComponent(MainComponent component) - { - this.component = (T) component; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs.meta b/Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs.meta deleted file mode 100644 index 7bd0ad6..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/MainComponent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 45df06cc65b1844bab6fe52ef5d782e8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs b/Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs deleted file mode 100644 index 02e10f7..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace XCharts.Runtime -{ - public class MainComponentContext - { - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs.meta b/Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs.meta deleted file mode 100644 index d4f9308..0000000 --- a/Assets/XCharts/Runtime/Internal/Basic/MainComponentContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2f85d9a16a84b474993b84d0e705bbcf -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc.meta b/Assets/XCharts/Runtime/Internal/Misc.meta deleted file mode 100644 index 89f5d7b..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 7c3110bdc66d84fd6b59aa8c6843f5e3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs b/Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs deleted file mode 100644 index 3843ca2..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// The delegate function for LabelStyle‘s formatter. - /// |SerieLabel的formatter自定义委托。 - /// </summary> - /// <param name="dataIndex">数据索引</param> - /// <param name="value">数值</param> - /// <returns>最终显示的文本内容</returns> - public delegate string LabelFormatterFunction(int dataIndex, double value, string category); - public delegate float AnimationDelayFunction(int dataIndex); - public delegate float AnimationDurationFunction(int dataIndex); - /// <summary> - /// 获取标记大小的回调。 - /// </summary> - /// <param name="data"></param> - /// <returns></returns> - public delegate float SymbolSizeFunction(List<double> data); - public delegate void CustomDrawGaugePointerFunction(VertexHelper vh, int serieIndex, int dataIndex, float currentAngle); -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs.meta deleted file mode 100644 index 27b82fb..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/DelegateFunction.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8d9ec774e2e5b4d9ba407a27f60b6d71 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/Enums.cs b/Assets/XCharts/Runtime/Internal/Misc/Enums.cs deleted file mode 100644 index f19d2d6..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/Enums.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace XCharts.Runtime -{ - /// <summary> - /// the layout is horizontal or vertical. - /// |垂直还是水平布局方式。 - /// </summary> - public enum Orient - { - /// <summary> - /// 水平 - /// </summary> - Horizonal, - /// <summary> - /// 垂直 - /// </summary> - Vertical - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/Enums.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/Enums.cs.meta deleted file mode 100644 index e27ae4c..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/Enums.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 124ff8824480945229e367921154d13a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs b/Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs deleted file mode 100644 index c979d5d..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public interface INeedSerieContainer - { - int containerIndex { get; } - int containterInstanceId { get; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs.meta deleted file mode 100644 index f2dd8fc..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/INeedSerieContainer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 69c33f4520abf483585632a17268a9a9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs b/Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs deleted file mode 100644 index 34f2e35..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace XCharts.Runtime -{ - /// <summary> - /// 属性变更接口 - /// </summary> - public interface IPropertyChanged - { - void OnChanged(); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs.meta deleted file mode 100644 index 6521200..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/IPropertyChanged.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 24f32e2d632f08245ae885545f14a2a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs b/Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs deleted file mode 100644 index 5e09dc4..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace XCharts.Runtime -{ - public interface ISerieContainer - { - //bool runtimeIsPointerEnter { get; } - int index { get; } - bool IsPointerEnter(); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs.meta deleted file mode 100644 index 2a7b0d5..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISerieContainer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9d02195c119c14384903aa94daf21a1a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs b/Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs deleted file mode 100644 index 0187300..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public interface ISerieDataComponent - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs.meta deleted file mode 100644 index 6e31f40..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISerieDataComponent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 34105fa92849e42abab6320ce3ea540f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs b/Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs deleted file mode 100644 index dda88d4..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public interface ISerieExtraComponent - { - bool show { get; set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs.meta deleted file mode 100644 index d9d9a3c..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISerieExtraComponent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 20d76dbb8ca234b439951f6e72826c43 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs b/Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs deleted file mode 100644 index 20afab9..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs +++ /dev/null @@ -1,9 +0,0 @@ -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public interface ISimplifiedSerie - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs.meta deleted file mode 100644 index 81f5854..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ISimplifiedSerie.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cd917380f26ed4fb393092a4017f9907 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs b/Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs deleted file mode 100644 index e69de29..0000000 diff --git a/Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs.meta deleted file mode 100644 index fecfc56..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/ITooltipView.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f5ec8a82e2f9043c5b2e0b880fb024b6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs b/Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs deleted file mode 100644 index c1d7f0f..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public interface IUpdateRuntimeData - { - void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs.meta b/Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs.meta deleted file mode 100644 index 15b89d6..0000000 --- a/Assets/XCharts/Runtime/Internal/Misc/IUpdateRuntimeData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 07abc4a18196a426a96d1ed14cbc7bf0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Object.meta b/Assets/XCharts/Runtime/Internal/Object.meta deleted file mode 100644 index 011588c..0000000 --- a/Assets/XCharts/Runtime/Internal/Object.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 3d225ec4fe992405d91714722649cc93 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs b/Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs deleted file mode 100644 index 746e17f..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs +++ /dev/null @@ -1,340 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public class ChartLabel : Image - { - [SerializeField] private ChartText m_LabelText; - - private bool m_HideIconIfTextEmpty = false; - private bool m_AutoSize = true; - private float m_PaddingLeft = 0; - private float m_PaddingRight = 0; - private float m_PaddingTop = 0; - private float m_PaddingBottom = 0; - private float m_Width = 0; - private float m_Height = 0; - private RectTransform m_TextRect; - private RectTransform m_IconRect; - private RectTransform m_ObjectRect; - private Vector3 m_IconOffest; - private Align m_Align = Align.Left; - private Image m_IconImage; - - public Image icon - { - get { return m_IconImage; } - set { SetIcon(value); } - } - public ChartText text - { - get { return m_LabelText; } - set - { - m_LabelText = value; - if (value != null) m_TextRect = m_LabelText.gameObject.GetComponent<RectTransform>(); - } - } - - public bool hideIconIfTextEmpty { set { m_HideIconIfTextEmpty = value; } } - public bool isIconActive { get; private set; } - public bool isAnimationEnd { get; internal set; } - - internal RectTransform objectRect - { - get - { - if (m_ObjectRect == null) - m_ObjectRect = gameObject.GetComponent<RectTransform>(); - return m_ObjectRect; - } - } - - protected override void Awake() - { - raycastTarget = false; - } - - public void SetTextPadding(TextPadding padding) - { - m_PaddingLeft = padding.left; - m_PaddingRight = padding.right; - m_PaddingTop = padding.top; - m_PaddingBottom = padding.bottom; - UpdatePadding(); - } - public void SetPadding(float[] padding) - { - if (padding.Length >= 4) - { - m_PaddingLeft = padding[3]; - m_PaddingRight = padding[1]; - m_PaddingTop = padding[0]; - m_PaddingBottom = padding[2]; - } - else if (padding.Length >= 2) - { - m_PaddingLeft = padding[1]; - m_PaddingRight = padding[1]; - m_PaddingTop = padding[0]; - m_PaddingBottom = padding[0]; - } - else if (padding.Length == 1) - { - m_PaddingLeft = padding[0]; - m_PaddingRight = padding[0]; - m_PaddingTop = padding[0]; - m_PaddingBottom = padding[0]; - } - UpdatePadding(); - } - - public void SetIcon(Image image) - { - m_IconImage = image; - if (image != null) - { - m_IconRect = m_IconImage.GetComponent<RectTransform>(); - } - } - - public float GetWidth() - { - return m_Width; - } - - public float GetHeight() - { - return m_Height; - } - - public void SetSize(float width, float height) - { - this.m_Width = width; - this.m_Height = height; - m_AutoSize = width == 0 && height == 0; - objectRect.sizeDelta = new Vector2(width, height); - } - - public void SetIconSprite(Sprite sprite) - { - if (m_IconImage != null) m_IconImage.sprite = sprite; - } - - public void SetIconSize(float width, float height) - { - if (m_IconRect != null) m_IconRect.sizeDelta = new Vector3(width, height); - } - - public void UpdateIcon(IconStyle iconStyle, Sprite sprite = null) - { - if (m_IconImage == null || iconStyle == null) - return; - - SetIconActive(iconStyle.show); - if (iconStyle.show) - { - m_IconImage.sprite = sprite == null ? iconStyle.sprite : sprite; - m_IconImage.color = iconStyle.color; - m_IconImage.type = iconStyle.type; - m_IconRect.sizeDelta = new Vector2(iconStyle.width, iconStyle.height); - m_IconOffest = iconStyle.offset; - m_Align = iconStyle.align; - m_HideIconIfTextEmpty = iconStyle.autoHideWhenLabelEmpty; - AdjustIconPos(); - if (iconStyle.layer == IconStyle.Layer.UnderText) - m_IconRect.SetSiblingIndex(0); - else - m_IconRect.SetSiblingIndex(transform.childCount - 1); - } - } - - public float GetTextWidth() - { - if (m_TextRect) return m_TextRect.sizeDelta.x; - else return 0; - } - - public float GetTextHeight() - { - if (m_TextRect) return m_TextRect.sizeDelta.y; - return 0; - } - - public void SetTextColor(Color color) - { - if (m_LabelText != null) m_LabelText.SetColor(color); - } - - public void SetTextRotate(float rotate) - { - if (m_LabelText != null) m_LabelText.SetLocalEulerAngles(new Vector3(0, 0, rotate)); - } - - public void SetPosition(Vector3 position) - { - transform.localPosition = position; - } - - public void SetRectPosition(Vector3 position) - { - objectRect.anchoredPosition3D = position; - } - - public Vector3 GetPosition() - { - return transform.localPosition; - } - - public void SetActive(bool flag) - { - ChartHelper.SetActive(gameObject, flag); - } - public void SetTextActive(bool flag) - { - if (m_LabelText != null) m_LabelText.SetActive(flag); - } - public void SetIconActive(bool flag) - { - isIconActive = flag; - if (m_IconImage) ChartHelper.SetActive(m_IconImage, flag); - } - - public bool SetText(string text) - { - if (m_TextRect == null || m_LabelText == null) - return false; - - if (text == null) - text = ""; - if (!m_LabelText.GetText().Equals(text)) - { - m_LabelText.SetText(text); - if (m_AutoSize) - { - var newSize = string.IsNullOrEmpty(text) ? Vector2.zero : - new Vector2(m_LabelText.GetPreferredWidth(), - m_LabelText.GetPreferredHeight()); - var sizeChange = newSize.x != m_TextRect.sizeDelta.x || newSize.y != m_TextRect.sizeDelta.y; - this.m_Width = newSize.x; - this.m_Height = newSize.y; - if (sizeChange) - { - m_TextRect.sizeDelta = newSize; - UpdateSize(); - UpdatePadding(); - AdjustIconPos(); - } - return sizeChange; - } - AdjustIconPos(); - if (m_HideIconIfTextEmpty && isIconActive) - { - ChartHelper.SetActive(m_IconImage.gameObject, !string.IsNullOrEmpty(text)); - } - } - return false; - } - - private void UpdateSize() - { - if (m_AutoSize) - { - var sizeDelta = m_TextRect.sizeDelta; - m_Width = sizeDelta.x + m_PaddingLeft + m_PaddingRight; - m_Height = sizeDelta.y + m_PaddingTop + m_PaddingBottom; - objectRect.sizeDelta = new Vector2(m_Width, m_Height); - } - } - - private void UpdatePadding() - { - if (m_TextRect == null) return; - switch (text.alignment) - { - case TextAnchor.LowerLeft: - m_TextRect.anchoredPosition = new Vector2(m_PaddingLeft, m_PaddingBottom); - break; - case TextAnchor.UpperLeft: - m_TextRect.anchoredPosition = new Vector2(m_PaddingLeft, -m_PaddingTop); - break; - case TextAnchor.MiddleLeft: - m_TextRect.anchoredPosition = new Vector2(m_PaddingLeft, m_Height / 2 - m_PaddingTop - m_TextRect.sizeDelta.y / 2); - break; - case TextAnchor.LowerRight: - m_TextRect.anchoredPosition = new Vector2(-m_PaddingRight, m_PaddingBottom); - break; - case TextAnchor.UpperRight: - m_TextRect.anchoredPosition = new Vector2(-m_PaddingRight, -m_PaddingTop); - break; - case TextAnchor.MiddleRight: - m_TextRect.anchoredPosition = new Vector2(-m_PaddingRight, m_Height / 2 - m_PaddingTop - m_TextRect.sizeDelta.y / 2); - break; - case TextAnchor.LowerCenter: - m_TextRect.anchoredPosition = new Vector2(-(m_Width / 2 - m_PaddingLeft - m_TextRect.sizeDelta.x / 2), m_PaddingBottom); - break; - case TextAnchor.UpperCenter: - m_TextRect.anchoredPosition = new Vector2(-(m_Width / 2 - m_PaddingLeft - m_TextRect.sizeDelta.x / 2), -m_PaddingTop); - break; - case TextAnchor.MiddleCenter: - m_TextRect.anchoredPosition = new Vector2(-(m_Width / 2 - m_PaddingLeft - m_TextRect.sizeDelta.x / 2), m_Height / 2 - m_PaddingTop - m_TextRect.sizeDelta.y / 2); - break; - default: - break; - } - } - - private void AdjustIconPos() - { - if (m_IconImage && m_IconRect && m_LabelText != null && m_TextRect != null) - { - var iconX = 0f; - switch (m_Align) - { - case Align.Left: - switch (m_LabelText.alignment) - { - case TextAnchor.LowerLeft: - case TextAnchor.UpperLeft: - case TextAnchor.MiddleLeft: - iconX = -m_TextRect.sizeDelta.x / 2 - m_IconRect.sizeDelta.x / 2; - break; - case TextAnchor.LowerRight: - case TextAnchor.UpperRight: - case TextAnchor.MiddleRight: - iconX = m_TextRect.sizeDelta.x / 2 - m_LabelText.GetPreferredWidth() - m_IconRect.sizeDelta.x / 2; - break; - case TextAnchor.LowerCenter: - case TextAnchor.UpperCenter: - case TextAnchor.MiddleCenter: - iconX = -m_LabelText.GetPreferredWidth() / 2 - m_IconRect.sizeDelta.x / 2; - break; - } - break; - case Align.Right: - switch (m_LabelText.alignment) - { - case TextAnchor.LowerLeft: - case TextAnchor.UpperLeft: - case TextAnchor.MiddleLeft: - iconX = m_TextRect.sizeDelta.x / 2 + m_IconRect.sizeDelta.x / 2; - break; - case TextAnchor.LowerRight: - case TextAnchor.UpperRight: - case TextAnchor.MiddleRight: - iconX = m_IconRect.sizeDelta.x / 2; - break; - case TextAnchor.LowerCenter: - case TextAnchor.UpperCenter: - case TextAnchor.MiddleCenter: - iconX = m_LabelText.GetPreferredWidth() / 2 + m_IconRect.sizeDelta.x / 2; - break; - } - break; - } - m_IconRect.anchoredPosition = m_IconOffest + new Vector3(iconX, 0); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs.meta b/Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs.meta deleted file mode 100644 index d673cbb..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/ChartLabel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 61287841bdc4142caba8e77985cd8715 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Object/ChartObject.cs b/Assets/XCharts/Runtime/Internal/Object/ChartObject.cs deleted file mode 100644 index 143e120..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/ChartObject.cs +++ /dev/null @@ -1,14 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - public class ChartObject - { - protected GameObject m_GameObject; - - public virtual void Destroy() - { - GameObject.Destroy(m_GameObject); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Object/ChartObject.cs.meta b/Assets/XCharts/Runtime/Internal/Object/ChartObject.cs.meta deleted file mode 100644 index 183b9e7..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/ChartObject.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0fe3102b0eea042938d30af910ca86d6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Object/ChartText.cs b/Assets/XCharts/Runtime/Internal/Object/ChartText.cs deleted file mode 100644 index c01b68a..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/ChartText.cs +++ /dev/null @@ -1,319 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - [System.Serializable] - public class ChartText - { - private Text m_Text; - private TextAnchor m_TextAlignment; - public Text text - { - get { return m_Text; } - set { m_Text = value; } - } -#if dUI_TextMeshPro - private TextMeshProUGUI m_TMPText; - public TextMeshProUGUI tmpText { get { return m_TMPText; } set { m_TMPText = value; } } -#endif - public GameObject gameObject - { - get - { -#if dUI_TextMeshPro - if (m_TMPText != null) return m_TMPText.gameObject; -#else - if (m_Text != null) return m_Text.gameObject; -#endif - return null; - } - } - - public TextAnchor alignment - { - get - { - return m_TextAlignment; - } - set - { - SetAlignment(alignment); - } - } - - public ChartText() - { } - - public ChartText(GameObject textParent) - { -#if dUI_TextMeshPro - m_TMPText = textParent.GetComponentInChildren<TextMeshProUGUI>(); - if (m_TMPText == null) - { - Debug.LogError("can't find TextMeshProUGUI component:" + textParent); - } -#else - m_Text = textParent.GetComponentInChildren<Text>(); - if (m_Text == null) - { - Debug.LogError("can't find Text component:" + textParent); - } -#endif - } - - public void SetFontSize(float fontSize) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.fontSize = fontSize; -#else - if (m_Text != null) m_Text.fontSize = (int) fontSize; -#endif - } - - public void SetText(string text) - { - if (text == null) text = string.Empty; - else text = text.Replace("\\n", "\n"); -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.text = text; -#else - if (m_Text != null) m_Text.text = text; -#endif - } - - public string GetText() - { -#if dUI_TextMeshPro - if (m_TMPText != null) return m_TMPText.text; -#else - if (m_Text != null) return m_Text.text; -#endif - return string.Empty; - } - - public void SetColor(Color color) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.color = color; -#else - if (m_Text != null) m_Text.color = color; -#endif - } - - public void SetLineSpacing(float lineSpacing) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.lineSpacing = lineSpacing; -#else - if (m_Text != null) m_Text.lineSpacing = lineSpacing; -#endif - } - - public void SetActive(bool flag) - { -#if dUI_TextMeshPro - //m_TMPText.gameObject.SetActive(flag); - if (m_TMPText != null) ChartHelper.SetActive(m_TMPText.gameObject, flag); -#else - //m_Text.gameObject.SetActive(flag); - if (m_Text != null) ChartHelper.SetActive(m_Text.gameObject, flag); -#endif - } - - public void SetLocalPosition(Vector3 position) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.transform.localPosition = position; -#else - if (m_Text != null) m_Text.transform.localPosition = position; -#endif - } - - public void SetRectPosition(Vector3 position) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.GetComponent<RectTransform>().anchoredPosition3D = position; -#else - if (m_Text != null) m_Text.GetComponent<RectTransform>().anchoredPosition3D = position; -#endif - } - - public void SetSizeDelta(Vector2 sizeDelta) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.GetComponent<RectTransform>().sizeDelta = sizeDelta; -#else - if (m_Text != null) m_Text.GetComponent<RectTransform>().sizeDelta = sizeDelta; -#endif - } - - public void SetLocalEulerAngles(Vector3 position) - { -#if dUI_TextMeshPro - if (m_TMPText != null) m_TMPText.transform.localEulerAngles = position; -#else - if (m_Text != null) m_Text.transform.localEulerAngles = position; -#endif - } - - public void SetAlignment(TextAnchor alignment) - { - m_TextAlignment = alignment; -#if dUI_TextMeshPro - if (m_TMPText == null) return; - switch (alignment) - { - case TextAnchor.LowerCenter: - m_TMPText.alignment = TextAlignmentOptions.Bottom; - break; - case TextAnchor.LowerLeft: - m_TMPText.alignment = TextAlignmentOptions.BottomLeft; - break; - case TextAnchor.LowerRight: - m_TMPText.alignment = TextAlignmentOptions.BottomRight; - break; - case TextAnchor.MiddleCenter: - m_TMPText.alignment = TextAlignmentOptions.Center; - break; - case TextAnchor.MiddleLeft: - m_TMPText.alignment = TextAlignmentOptions.Left; - break; - case TextAnchor.MiddleRight: - m_TMPText.alignment = TextAlignmentOptions.Right; - break; - case TextAnchor.UpperCenter: - m_TMPText.alignment = TextAlignmentOptions.Top; - break; - case TextAnchor.UpperLeft: - m_TMPText.alignment = TextAlignmentOptions.TopLeft; - break; - case TextAnchor.UpperRight: - m_TMPText.alignment = TextAlignmentOptions.TopRight; - break; - default: - m_TMPText.alignment = TextAlignmentOptions.Center; - m_TextAlignment = TextAnchor.MiddleCenter; - break; - } -#else - if (m_Text != null) m_Text.alignment = alignment; -#endif - } - - public void SetFont(Font font) - { - if (m_Text) m_Text.font = font; - } - - public void SetFontStyle(FontStyle fontStyle) - { -#if dUI_TextMeshPro - if (m_TMPText == null) return; - switch (fontStyle) - { - case FontStyle.Normal: - m_TMPText.fontStyle = FontStyles.Normal; - break; - case FontStyle.Bold: - m_TMPText.fontStyle = FontStyles.Bold; - break; - case FontStyle.BoldAndItalic: - m_TMPText.fontStyle = FontStyles.Bold | FontStyles.Italic; - break; - case FontStyle.Italic: - m_TMPText.fontStyle = FontStyles.Italic; - break; - } -#else - if (m_Text != null) m_Text.fontStyle = fontStyle; -#endif - } - - public void SetFontAndSizeAndStyle(TextStyle textStyle, ComponentTheme theme) - { -#if dUI_TextMeshPro - if (m_TMPText == null) return; - m_TMPText.font = textStyle.tmpFont == null ? theme.tmpFont : textStyle.tmpFont; - m_TMPText.fontSize = textStyle.fontSize == 0 ? theme.fontSize : textStyle.fontSize; - m_TMPText.fontStyle = textStyle.tmpFontStyle; -#else - if (m_Text != null) - { - m_Text.font = textStyle.font == null ? theme.font : textStyle.font; - m_Text.fontSize = textStyle.fontSize == 0 ? theme.fontSize : textStyle.fontSize; - m_Text.fontStyle = textStyle.fontStyle; - } -#endif - } - - public float GetPreferredWidth(string content) - { -#if dUI_TextMeshPro - if (m_TMPText != null) return 0; // TODO: -#else - if (m_Text != null) - { - var tg = m_Text.cachedTextGeneratorForLayout; - var setting = m_Text.GetGenerationSettings(Vector2.zero); - return tg.GetPreferredWidth(content, setting) / m_Text.pixelsPerUnit; - } -#endif - return 0; - } - - public float GetPreferredWidth() - { -#if dUI_TextMeshPro - if (m_TMPText != null) return m_TMPText.preferredWidth; -#else - if (m_Text != null) return m_Text.preferredWidth; -#endif - return 0; - } - public float GetPreferredHeight() - { -#if dUI_TextMeshPro - if (m_TMPText != null) return m_TMPText.preferredHeight; -#else - if (m_Text != null) return m_Text.preferredHeight; -#endif - return 0; - } - - public string GetPreferredText(string content, string suffix, float maxWidth) - { -#if dUI_TextMeshPro - if (m_TMPText != null) return content; // TODO: -#else - if (m_Text != null) - { - var sourWid = GetPreferredWidth(content); - if (sourWid < maxWidth) return content; - var suffixWid = GetPreferredWidth(suffix); - var textWid = maxWidth - 1.3f * suffixWid; - for (int i = content.Length; i > 0; i--) - { - var temp = content.Substring(0, i); - if (GetPreferredWidth(temp) < textWid) - { - return temp + suffix; - } - } - } -#endif - return string.Empty; - } - -#if dUI_TextMeshPro - - public void SetFont(TMP_FontAsset font) - { - if (m_TMPText != null) m_TMPText.font = font; - } -#endif - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Object/ChartText.cs.meta b/Assets/XCharts/Runtime/Internal/Object/ChartText.cs.meta deleted file mode 100644 index 6b1b33d..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/ChartText.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4e2466c1fe5874bea8373b071405a930 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Object/LegendItem.cs b/Assets/XCharts/Runtime/Internal/Object/LegendItem.cs deleted file mode 100644 index 9a6f754..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/LegendItem.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public class LegendItem - { - private int m_Index; - private string m_Name; - private string m_LegendName; - private GameObject m_GameObject; - private Button m_Button; - private Image m_Icon; - private ChartText m_Text; - private Image m_TextBackground; - private RectTransform m_Rect; - private RectTransform m_IconRect; - private RectTransform m_TextRect; - private RectTransform m_TextBackgroundRect; - private float m_Gap = 0f; - private float m_LabelPaddingLeftRight = 0f; - private float m_LabelPaddingTopBottom = 0f; - private bool m_LabelAutoSize = true; - - public int index { get { return m_Index; } set { m_Index = value; } } - public string name { get { return m_Name; } set { m_Name = value; } } - public string legendName { get { return m_LegendName; } set { m_LegendName = value; } } - public GameObject gameObject { get { return m_GameObject; } } - public Button button { get { return m_Button; } } - public float width - { - get - { - if (m_IconRect && m_TextBackgroundRect) - { - return m_IconRect.sizeDelta.x + m_Gap + m_TextBackgroundRect.sizeDelta.x; - } - else - { - return 0; - } - } - } - - public float height - { - get - { - if (m_IconRect && m_TextBackgroundRect) - { - return Mathf.Max(m_IconRect.sizeDelta.y, m_TextBackgroundRect.sizeDelta.y); - } - else - { - return 0; - } - } - } - - public void SetObject(GameObject obj) - { - m_GameObject = obj; - m_Button = obj.GetComponent<Button>(); - m_Rect = obj.GetComponent<RectTransform>(); - m_Icon = obj.transform.Find("icon").gameObject.GetComponent<Image>(); - m_TextBackground = obj.transform.Find("content").gameObject.GetComponent<Image>(); - m_Text = new ChartText(obj); - m_IconRect = m_Icon.gameObject.GetComponent<RectTransform>(); - m_TextRect = m_Text.gameObject.GetComponent<RectTransform>(); - m_TextBackgroundRect = m_TextBackground.gameObject.GetComponent<RectTransform>(); - } - - public void SetButton(Button button) - { - m_Button = button; - } - - public void SetIcon(Image icon) - { - m_Icon = icon; - } - - public void SetText(ChartText text) - { - m_Text = text; - } - - public void SetTextBackground(Image image) - { - m_TextBackground = image; - } - - public void SetIconSize(float width, float height) - { - if (m_IconRect) - { - m_IconRect.sizeDelta = new Vector2(width, height); - } - } - - public Rect GetIconRect() - { - if (m_GameObject && m_IconRect) - { - var pos = m_GameObject.transform.localPosition; - var sizeDelta = m_IconRect.sizeDelta; - var y = pos.y - (m_Rect.sizeDelta.y - sizeDelta.y) / 2 - sizeDelta.y; - return new Rect(pos.x, y, m_IconRect.sizeDelta.x, m_IconRect.sizeDelta.y); - } - else - { - return Rect.zero; - } - } - - public Color GetIconColor() - { - if (m_Icon) return m_Icon.color; - else return Color.clear; - } - - public void SetIconColor(Color color) - { - if (m_Icon) - { - m_Icon.color = color; - } - } - - public void SetIconImage(Sprite image) - { - if (m_Icon) - { - m_Icon.sprite = image; - } - } - - public void SetIconActive(bool active) - { - if (m_Icon) - { - m_Icon.gameObject.SetActive(active); - } - } - - public void SetContentColor(Color color) - { - if (m_Text != null) - { - m_Text.SetColor(color); - } - } - - public void SetContentBackgroundColor(Color color) - { - if (m_TextBackground) - { - m_TextBackground.color = color; - } - } - - public void SetContentPosition(Vector3 offset) - { - m_Gap = offset.x; - if (m_TextBackgroundRect) - { - var posX = m_IconRect.sizeDelta.x + offset.x; - m_TextBackgroundRect.anchoredPosition3D = new Vector3(posX, offset.y, 0); - } - } - - public bool SetContent(string content) - { - if (m_Text != null && !m_Text.GetText().Equals(content)) - { - m_Text.SetText(content); - if (m_LabelAutoSize) - { - var newSize = string.IsNullOrEmpty(content) ? Vector2.zero : - new Vector2(m_Text.GetPreferredWidth(), m_Text.GetPreferredHeight()); - var sizeChange = newSize.x != m_TextRect.sizeDelta.x || newSize.y != m_TextRect.sizeDelta.y; - if (sizeChange) - { - m_TextRect.sizeDelta = newSize; - m_TextRect.anchoredPosition3D = new Vector3(m_LabelPaddingLeftRight, 0); - m_TextBackgroundRect.sizeDelta = new Vector2(m_Text.GetPreferredWidth() + m_LabelPaddingLeftRight * 2, - m_Text.GetPreferredHeight() + m_LabelPaddingTopBottom * 2 - 4); - m_Rect.sizeDelta = new Vector3(width, height); - } - return sizeChange; - } - } - return false; - } - - public void SetPosition(Vector3 position) - { - if (m_GameObject) - { - m_GameObject.transform.localPosition = position; - } - } - - public void SetActive(bool active) - { - if (m_GameObject) - { - m_GameObject.SetActive(active); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Object/LegendItem.cs.meta b/Assets/XCharts/Runtime/Internal/Object/LegendItem.cs.meta deleted file mode 100644 index e7a5204..0000000 --- a/Assets/XCharts/Runtime/Internal/Object/LegendItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3e5abcb8f339f41f5b3680ecdab67509 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Painter.cs b/Assets/XCharts/Runtime/Internal/Painter.cs deleted file mode 100644 index c60041a..0000000 --- a/Assets/XCharts/Runtime/Internal/Painter.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [RequireComponent(typeof(CanvasRenderer))] - public class Painter : MaskableGraphic - { - public enum Type - { - Base, - Serie, - Top - } - protected int m_Index = -1; - protected Type m_Type = Type.Base; - protected bool m_Refresh; - protected Action<VertexHelper, Painter> m_OnPopulateMesh; - - public Action<VertexHelper, Painter> onPopulateMesh { set { m_OnPopulateMesh = value; } } - public int index { get { return m_Index; } set { m_Index = value; } } - public Type type { get { return m_Type; } set { m_Type = value; } } - public void Refresh() - { - if (gameObject == null) return; - if (!gameObject.activeSelf) return; - m_Refresh = true; - } - - public void Init() - { - raycastTarget = false; - } - - public void SetActive(bool flag, bool isDebugMode = false) - { - if (gameObject.activeInHierarchy != flag) - { - gameObject.SetActive(flag); - } - var hideFlags = flag && isDebugMode ? HideFlags.None : HideFlags.HideInHierarchy; - if (gameObject.hideFlags != hideFlags) - { - gameObject.hideFlags = hideFlags; - } - } - - protected override void Awake() - { - Init(); - } - - internal void CheckRefresh() - { - if (m_Refresh && gameObject.activeSelf) - { - m_Refresh = false; - SetVerticesDirty(); - } - } - - protected override void OnPopulateMesh(VertexHelper vh) - { - vh.Clear(); - if (m_OnPopulateMesh != null) - { - m_OnPopulateMesh(vh, this); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Painter.cs.meta b/Assets/XCharts/Runtime/Internal/Painter.cs.meta deleted file mode 100644 index 60597fa..0000000 --- a/Assets/XCharts/Runtime/Internal/Painter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 01c85cd323a9f4dfb803470695bd0944 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Pools.meta b/Assets/XCharts/Runtime/Internal/Pools.meta deleted file mode 100644 index 49e7df6..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 576ce681815d348d0a2abbbadf3dd9f7 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Pools/ListPool.cs b/Assets/XCharts/Runtime/Internal/Pools/ListPool.cs deleted file mode 100644 index 8210fde..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/ListPool.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - internal static class ListPool<T> - { - private static readonly ObjectPool<List<T>> s_ListPool = new ObjectPool<List<T>>(OnGet, OnClear); - static void OnGet(List<T> l) - { - if (l.Capacity < 50) - { - l.Capacity = 50; - } - } - static void OnClear(List<T> l) - { - l.Clear(); - } - - public static List<T> Get() - { - return s_ListPool.Get(); - } - - public static void Release(List<T> toRelease) - { - s_ListPool.Release(toRelease); - } - - public static void ClearAll() - { - s_ListPool.ClearAll(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Pools/ListPool.cs.meta b/Assets/XCharts/Runtime/Internal/Pools/ListPool.cs.meta deleted file mode 100644 index 7807cc9..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/ListPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 02c30457469c746dc96f00f24cb6e1c6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs b/Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs deleted file mode 100644 index 9dfb045..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.Events; - -namespace XCharts.Runtime -{ - public class ObjectPool<T> where T : new() - { - private readonly bool m_NewIfEmpty = true; - private readonly Stack<T> m_Stack = new Stack<T>(); - private readonly UnityAction<T> m_ActionOnGet; - private readonly UnityAction<T> m_ActionOnRelease; - - public int countAll { get; private set; } - public int countActive { get { return countAll - countInactive; } } - public int countInactive { get { return m_Stack.Count; } } - - public ObjectPool(UnityAction<T> actionOnGet, UnityAction<T> actionOnRelease, bool newIfEmpty = true) - { - m_NewIfEmpty = newIfEmpty; - m_ActionOnGet = actionOnGet; - m_ActionOnRelease = actionOnRelease; - } - - public T Get() - { - T element; - if (m_Stack.Count == 0) - { - if (!m_NewIfEmpty) return default(T); - element = new T(); - countAll++; - } - else - { - element = m_Stack.Pop(); - } - if (m_ActionOnGet != null) - m_ActionOnGet(element); - return element; - } - - public void Release(T element) - { - if (m_Stack.Count > 0 && ReferenceEquals(m_Stack.Peek(), element)) - Debug.LogError("Internal error. Trying to destroy object that is already released to pool."); - if (m_ActionOnRelease != null) - m_ActionOnRelease(element); - m_Stack.Push(element); - } - - public void ClearAll() - { - m_Stack.Clear(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs.meta b/Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs.meta deleted file mode 100644 index 58927ca..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/ObjectPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 09e67988253cb4f568b82d52b4113797 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs b/Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs deleted file mode 100644 index 9380580..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs +++ /dev/null @@ -1,26 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - internal static class SerieDataPool - { - private static readonly ObjectPool<SerieData> s_ListPool = new ObjectPool<SerieData>(null, OnClear); - - static void OnGet(SerieData serieData) { } - - static void OnClear(SerieData serieData) - { - serieData.Reset(); - } - - public static SerieData Get() - { - return s_ListPool.Get(); - } - - public static void Release(SerieData toRelease) - { - s_ListPool.Release(toRelease); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs.meta b/Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs.meta deleted file mode 100644 index 5bd4740..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/SerieDataPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: faf4da15b01d74648bd13f73125e27bd -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs b/Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs deleted file mode 100644 index 321d894..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class SerieLabelPool - { - private static readonly Stack<GameObject> m_Stack = new Stack<GameObject>(200); - private static Dictionary<int, bool> m_ReleaseDic = new Dictionary<int, bool>(1000); - - public static GameObject Get(string name, Transform parent, LabelStyle label, Color color, - float iconWidth, float iconHeight, ThemeStyle theme) - { - GameObject element; - if (m_Stack.Count == 0 || !Application.isPlaying) - { - element = CreateSerieLabel(name, parent, label, color, iconWidth, iconHeight, theme); - } - else - { - element = m_Stack.Pop(); - if (element == null) - { - element = CreateSerieLabel(name, parent, label, color, iconWidth, iconHeight, theme); - } - m_ReleaseDic.Remove(element.GetInstanceID()); - element.name = name; - element.transform.SetParent(parent); - var text = new ChartText(element); - text.SetColor(color); - text.SetFontAndSizeAndStyle(label.textStyle, theme.common); - ChartHelper.SetActive(element, true); - } - element.transform.localEulerAngles = new Vector3(0, 0, label.rotate); - return element; - } - - public static void Release(GameObject element) - { - if (element == null) return; - ChartHelper.SetActive(element, false); - if (!Application.isPlaying) return; - if (!m_ReleaseDic.ContainsKey(element.GetInstanceID())) - { - m_Stack.Push(element); - m_ReleaseDic.Add(element.GetInstanceID(), true); - } - } - - public static void ReleaseAll(Transform parent) - { - int count = parent.childCount; - for (int i = 0; i < count; i++) - { - Release(parent.GetChild(i).gameObject); - } - } - - public static void ClearAll() - { - m_Stack.Clear(); - m_ReleaseDic.Clear(); - } - - private static GameObject CreateSerieLabel(string name, Transform parent, LabelStyle labelStyle, Color color, - float iconWidth, float iconHeight, ThemeStyle theme) - { - var label = ChartHelper.AddChartLabel(name, parent, labelStyle, theme.common, - "", color, TextAnchor.MiddleCenter); - label.SetActive(labelStyle.show); - return label.gameObject; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs.meta b/Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs.meta deleted file mode 100644 index 8d5c752..0000000 --- a/Assets/XCharts/Runtime/Internal/Pools/SerieLabelPool.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e960aeb14c09844e3bdcdc4138af0761 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities.meta b/Assets/XCharts/Runtime/Internal/Utilities.meta deleted file mode 100644 index 6ceb052..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: dd10f45b4e7714b7687abf5f2f016993 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs b/Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs deleted file mode 100644 index 59a505b..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class ChartCached - { - private const string NUMERIC_FORMATTER_D = "D"; - private const string NUMERIC_FORMATTER_d = "d"; - private const string NUMERIC_FORMATTER_X = "X"; - private const string NUMERIC_FORMATTER_x = "x"; - private static readonly string s_DefaultAxis = "axis_"; - private static CultureInfo ci = new CultureInfo("en-us"); // "en-us", "zh-cn", "ar-iq", "de-de" - private static Dictionary<Color, string> s_ColorToStr = new Dictionary<Color, string>(100); - private static Dictionary<int, string> s_SerieLabelName = new Dictionary<int, string>(1000); - private static Dictionary<Color, string> s_ColorDotStr = new Dictionary<Color, string>(100); - private static Dictionary<Type, Dictionary<int, string>> s_ComponentObjectName = new Dictionary<Type, Dictionary<int, string>>(); - private static Dictionary<int, string> s_AxisLabelName = new Dictionary<int, string>(); - private static Dictionary<Type, string> s_TypeName = new Dictionary<Type, string>(); - - private static Dictionary<double, Dictionary<string, string>> s_NumberToStr = new Dictionary<double, Dictionary<string, string>>(); - private static Dictionary<int, Dictionary<string, string>> s_PrecisionToStr = new Dictionary<int, Dictionary<string, string>>(); - - public static string FloatToStr(double value, string numericFormatter = "F", int precision = 0) - { - if (precision > 0 && numericFormatter.Length == 1) - { - if (!s_PrecisionToStr.ContainsKey(precision)) - { - s_PrecisionToStr[precision] = new Dictionary<string, string>(); - } - if (!s_PrecisionToStr[precision].ContainsKey(numericFormatter)) - { - s_PrecisionToStr[precision][numericFormatter] = numericFormatter + precision; - } - return NumberToStr(value, s_PrecisionToStr[precision][numericFormatter]); - } - else - { - return NumberToStr(value, numericFormatter); - } - } - - public static string NumberToStr(double value, string formatter) - { - if (!s_NumberToStr.ContainsKey(value)) - { - s_NumberToStr[value] = new Dictionary<string, string>(); - } - if (!s_NumberToStr[value].ContainsKey(formatter)) - { - if (string.IsNullOrEmpty(formatter)) - { - if (value - (int) value == 0) - s_NumberToStr[value][formatter] = ((int) value).ToString(); - else - s_NumberToStr[value][formatter] = value.ToString(); - } - else if (formatter.StartsWith(NUMERIC_FORMATTER_D) || - formatter.StartsWith(NUMERIC_FORMATTER_d) || - formatter.StartsWith(NUMERIC_FORMATTER_X) || - formatter.StartsWith(NUMERIC_FORMATTER_x) - ) - { - s_NumberToStr[value][formatter] = ((int) value).ToString(formatter, ci); - } - else - { - s_NumberToStr[value][formatter] = value.ToString(formatter, ci); - } - } - return s_NumberToStr[value][formatter]; - } - - public static string IntToStr(int value, string numericFormatter = "") - { - return NumberToStr(value, numericFormatter); - } - - public static string ColorToStr(Color color) - { - if (s_ColorToStr.ContainsKey(color)) - { - return s_ColorToStr[color]; - } - else - { - s_ColorToStr[color] = ColorUtility.ToHtmlStringRGBA(color); - return s_ColorToStr[color]; - } - } - - public static string ColorToDotStr(Color color) - { - if (!s_ColorDotStr.ContainsKey(color)) - { - s_ColorDotStr[color] = "<color=#" + ColorToStr(color) + ">● </color>"; - } - return s_ColorDotStr[color]; - } - - public static string GetSerieLabelName(string prefix, int i, int j) - { - int key = i * 10000000 + j; - if (s_SerieLabelName.ContainsKey(key)) - { - return s_SerieLabelName[key]; - } - else - { - string name = prefix + "_" + i + "_" + j; - s_SerieLabelName[key] = name; - return name; - } - } - - internal static string GetComponentObjectName(MainComponent component) - { - Dictionary<int, string> dict; - var type = component.GetType(); - if (s_ComponentObjectName.TryGetValue(type, out dict)) - { - string name; - if (!dict.TryGetValue(component.index, out name)) - { - name = GetTypeName(type) + component.index; - dict[component.index] = name; - } - return name; - } - else - { - var name = GetTypeName(type) + component.index; - dict = new Dictionary<int, string>(); - dict.Add(component.index, name); - s_ComponentObjectName[type] = dict; - return name; - } - } - - internal static string GetAxisLabelName(int index) - { - string name; - if (!s_AxisLabelName.TryGetValue(index, out name)) - { - name = s_DefaultAxis + index; - s_AxisLabelName[index] = name; - return name; - } - else - { - return name; - } - } - - internal static string GetTypeName<T>() - { - return GetTypeName(typeof(T)); - } - - internal static string GetTypeName(Type type) - { - if (s_TypeName.ContainsKey(type)) return s_TypeName[type]; - else - { - var name = type.Name; - s_TypeName[type] = name; - return name; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs.meta deleted file mode 100644 index 7d4496e..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartCached.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 403191b8caeb44430b89d9f3260c4a76 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs b/Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs deleted file mode 100644 index 2b0eeb6..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs +++ /dev/null @@ -1,11 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class ChartConst - { - public static readonly Color32 clearColor32 = new Color32(0, 0, 0, 0); - public static readonly Color32 greyColor32 = new Color32(128, 128, 128, 255); - public static readonly Color clearColor = Color.clear; - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs.meta deleted file mode 100644 index f932d45..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartConst.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e19d8fc0680be46b5ac9babf7dd9fe27 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs b/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs deleted file mode 100644 index 69b7e2c..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - public static class ChartDrawer - { - public static void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness, - Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius, - Color32 emptyColor, Color32 backgroundColor, Color32 borderColor, float smoothness, Vector3 startPos) - { - switch (type) - { - case SymbolType.None: - break; - case SymbolType.Circle: - if (gap > 0) - { - UGL.DrawDoughnut(vh, pos, symbolSize, symbolSize + gap, backgroundColor, backgroundColor, color, smoothness); - } - else - { - if (tickness > 0) - UGL.DrawDoughnut(vh, pos, symbolSize, symbolSize + tickness, borderColor, borderColor, color, smoothness); - else - UGL.DrawCricle(vh, pos, symbolSize, color, toColor, smoothness); - } - break; - case SymbolType.EmptyCircle: - if (gap > 0) - { - UGL.DrawCricle(vh, pos, symbolSize + gap, backgroundColor, smoothness); - UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, emptyColor, smoothness); - } - else - { - UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, emptyColor, smoothness); - } - break; - case SymbolType.Rect: - if (gap > 0) - { - UGL.DrawSquare(vh, pos, symbolSize + gap, backgroundColor); - UGL.DrawSquare(vh, pos, symbolSize, color, toColor); - } - else - { - if (tickness > 0) - { - UGL.DrawRoundRectangle(vh, pos, symbolSize, symbolSize, color, color, 0, cornerRadius, true); - UGL.DrawBorder(vh, pos, symbolSize, symbolSize, tickness, borderColor, 0, cornerRadius); - } - else - UGL.DrawRoundRectangle(vh, pos, symbolSize, symbolSize, color, color, 0, cornerRadius, true); - } - break; - case SymbolType.EmptyRect: - if (gap > 0) - { - UGL.DrawSquare(vh, pos, symbolSize + gap, backgroundColor); - UGL.DrawBorder(vh, pos, symbolSize / 2, symbolSize / 2, tickness, color); - } - else - { - UGL.DrawBorder(vh, pos, symbolSize / 2, symbolSize / 2, tickness, color); - } - break; - case SymbolType.Triangle: - if (gap > 0) - { - UGL.DrawTriangle(vh, pos, symbolSize + gap, backgroundColor); - UGL.DrawTriangle(vh, pos, symbolSize, color, toColor); - } - else - { - UGL.DrawTriangle(vh, pos, symbolSize, color, toColor); - } - break; - case SymbolType.Diamond: - if (gap > 0) - { - UGL.DrawDiamond(vh, pos, symbolSize + gap, backgroundColor); - UGL.DrawDiamond(vh, pos, symbolSize, color, toColor); - } - else - { - UGL.DrawDiamond(vh, pos, symbolSize, color, toColor); - } - break; - case SymbolType.Arrow: - var arrowWidth = symbolSize * 2; - var arrowHeight = arrowWidth * 1.5f; - var arrowOffset = 0; - var arrowDent = arrowWidth / 3.3f; - UGL.DrawArrow(vh, startPos, pos, arrowWidth, arrowHeight, - arrowOffset, arrowDent, color); - break; - } - } - - public static void DrawLineStyle(VertexHelper vh, LineStyle lineStyle, Vector3 startPos, Vector3 endPos, - Color32 defaultColor, float themeWidth, LineStyle.Type themeType) - { - var type = lineStyle.GetType(themeType); - var width = lineStyle.GetWidth(themeWidth); - var color = lineStyle.GetColor(defaultColor); - DrawLineStyle(vh, type, width, startPos, endPos, color, color); - } - - public static void DrawLineStyle(VertexHelper vh, LineStyle lineStyle, Vector3 startPos, Vector3 endPos, - float themeWidth, LineStyle.Type themeType, Color32 defaultColor, Color32 defaultToColor) - { - var type = lineStyle.GetType(themeType); - var width = lineStyle.GetWidth(themeWidth); - var color = lineStyle.GetColor(defaultColor); - var toColor = ChartHelper.IsClearColor(defaultToColor) ? color : defaultToColor; - DrawLineStyle(vh, type, width, startPos, endPos, color, toColor); - } - - public static void DrawLineStyle(VertexHelper vh, LineStyle.Type lineType, float lineWidth, - Vector3 startPos, Vector3 endPos, Color32 color) - { - DrawLineStyle(vh, lineType, lineWidth, startPos, endPos, color, color); - } - - public static void DrawLineStyle(VertexHelper vh, LineStyle.Type lineType, float lineWidth, - Vector3 startPos, Vector3 endPos, Color32 color, Color32 toColor) - { - switch (lineType) - { - case LineStyle.Type.Dashed: - UGL.DrawDashLine(vh, startPos, endPos, lineWidth, color, toColor); - break; - case LineStyle.Type.Dotted: - UGL.DrawDotLine(vh, startPos, endPos, lineWidth, color, toColor); - break; - case LineStyle.Type.Solid: - UGL.DrawLine(vh, startPos, endPos, lineWidth, color, toColor); - break; - case LineStyle.Type.DashDot: - UGL.DrawDashDotLine(vh, startPos, endPos, lineWidth, color); - break; - case LineStyle.Type.DashDotDot: - UGL.DrawDashDotDotLine(vh, startPos, endPos, lineWidth, color); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs.meta deleted file mode 100644 index 64d094a..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 712f08d71f1bf4ab6a1785526bcd5c30 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs deleted file mode 100644 index c254007..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs +++ /dev/null @@ -1,883 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -#if dUI_TextMeshPro -using TMPro; -#endif -#if UNITY_EDITOR -using UnityEditor; -#endif - -namespace XCharts.Runtime -{ - public static class ChartHelper - { - private static StringBuilder s_Builder = new StringBuilder(); - private static Vector3 s_DefaultIngoreDataVector3 = Vector3.zero; - - public static StringBuilder sb { get { return s_Builder; } } - public static Vector3 ignoreVector3 { get { return s_DefaultIngoreDataVector3; } } - - public static bool IsIngore(Vector3 pos) - { - return pos == s_DefaultIngoreDataVector3; - } - public static string Cancat(string str1, string str2) - { - s_Builder.Length = 0; - s_Builder.Append(str1).Append(str2); - return s_Builder.ToString(); - } - - public static string Cancat(string str1, int i) - { - s_Builder.Length = 0; - s_Builder.Append(str1).Append(ChartCached.IntToStr(i)); - return s_Builder.ToString(); - } - - public static void SetActive(GameObject gameObject, bool active) - { - if (gameObject == null) return; - SetActive(gameObject.transform, active); - } - - public static void SetActive(Image image, bool active) - { - if (image == null) return; - SetActive(image.gameObject, active); - } - - public static void SetActive(Text text, bool active) - { - if (text == null) return; - SetActive(text.gameObject, active); - } - - /// <summary> - /// 通过设置scale实现是否显示,优化性能,减少GC - /// </summary> - /// <param name="transform"></param> - /// <param name="active"></param> - public static void SetActive(Transform transform, bool active) - { - if (transform == null) return; - if (active) transform.localScale = Vector3.one; - else transform.localScale = Vector3.zero; - } - public static void HideAllObject(GameObject obj, string match = null) - { - if (obj == null) return; - HideAllObject(obj.transform, match); - } - - public static void HideAllObject(Transform parent, string match = null) - { - if (parent == null) return; - ActiveAllObject(parent, false, match); - } - - public static void ActiveAllObject(Transform parent, bool active, string match = null) - { - if (parent == null) return; - for (int i = 0; i < parent.childCount; i++) - { - if (match == null) - SetActive(parent.GetChild(i), active); - else - { - var go = parent.GetChild(i); - if (go.name.StartsWith(match)) - { - SetActive(go, active); - } - } - } - } - - public static void DestroyAllChildren(Transform parent) - { - if (parent == null) return; - var childCount = parent.childCount; - for (int i = childCount - 1; i >= 0; i--) - { - var go = parent.GetChild(i); - if (go != null) - { - GameObject.DestroyImmediate(go.gameObject, true); - } - } - } - - public static void DestoryGameObject(Transform parent, string childName) - { - if (parent == null) return; - var go = parent.Find(childName); - if (go != null) - { - GameObject.DestroyImmediate(go.gameObject, true); - } - } - public static void DestoryGameObjectByMatch(Transform parent, string match) - { - if (parent == null) return; - var childCount = parent.childCount; - for (int i = childCount - 1; i >= 0; i--) - { - var go = parent.GetChild(i); - if (go != null && go.name.StartsWith(match)) - { - GameObject.DestroyImmediate(go.gameObject, true); - } - } - } - - public static void DestoryGameObject(GameObject go) - { - if (go != null) GameObject.DestroyImmediate(go, true); - } - - public static string GetFullName(Transform transform) - { - string name = transform.name; - Transform obj = transform; - while (obj.transform.parent) - { - name = obj.transform.parent.name + "/" + name; - obj = obj.transform.parent; - } - return name; - } - - public static void RemoveComponent<T>(GameObject gameObject) - { - var component = gameObject.GetComponent<T>(); - if (component != null) - { -#if UNITY_EDITOR - if (!Application.isPlaying) - GameObject.DestroyImmediate(component as GameObject, true); - else - GameObject.Destroy(component as GameObject); -#else - GameObject.Destroy(component as GameObject); -#endif - } - } - public static T GetOrAddComponent<T>(Transform transform) where T : Component - { - return GetOrAddComponent<T>(transform.gameObject); - } - - public static T GetOrAddComponent<T>(GameObject gameObject) where T : Component - { - if (gameObject.GetComponent<T>() == null) - { - return gameObject.AddComponent<T>(); - } - else - { - return gameObject.GetComponent<T>(); - } - } - - public static GameObject AddObject(string name, Transform parent, Vector2 anchorMin, - Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta, int replaceIndex = -1) - { - GameObject obj; - if (parent.Find(name)) - { - obj = parent.Find(name).gameObject; - SetActive(obj, true); - obj.transform.localPosition = Vector3.zero; - obj.transform.localScale = Vector3.one; - } - else if (replaceIndex >= 0 && replaceIndex < parent.childCount) - { - obj = parent.GetChild(replaceIndex).gameObject; - if (!obj.name.Equals(name)) obj.name = name; - SetActive(obj, true); - } - else - { - obj = new GameObject(); - obj.name = name; - obj.transform.SetParent(parent); - obj.transform.localScale = Vector3.one; - obj.transform.localPosition = Vector3.zero; - } - RectTransform rect = GetOrAddComponent<RectTransform>(obj); - rect.localPosition = Vector3.zero; - rect.sizeDelta = sizeDelta; - rect.anchorMin = anchorMin; - rect.anchorMax = anchorMax; - rect.pivot = pivot; - rect.anchoredPosition3D = Vector3.zero; - return obj; - } - - public static void UpdateRectTransform(GameObject obj, Vector2 anchorMin, - Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta) - { - if (obj == null) return; - RectTransform rect = GetOrAddComponent<RectTransform>(obj); - rect.sizeDelta = sizeDelta; - rect.anchorMin = anchorMin; - rect.anchorMax = anchorMax; - rect.pivot = pivot; - } - - public static ChartText AddTextObject(string objectName, Transform parent, Vector2 anchorMin, Vector2 anchorMax, - Vector2 pivot, Vector2 sizeDelta, TextStyle textStyle, ComponentTheme theme, Color autoColor, - TextAnchor autoAlignment, ChartText chartText = null) - { - GameObject txtObj = AddObject(objectName, parent, anchorMin, anchorMax, pivot, sizeDelta); - txtObj.transform.localEulerAngles = new Vector3(0, 0, textStyle.rotate); - if (chartText == null) - chartText = new ChartText(); -#if dUI_TextMeshPro - RemoveComponent<Text>(txtObj); - chartText.tmpText = GetOrAddComponent<TextMeshProUGUI>(txtObj); - chartText.tmpText.font = textStyle.tmpFont == null ? theme.tmpFont : textStyle.tmpFont; - chartText.tmpText.fontStyle = textStyle.tmpFontStyle; - chartText.tmpText.richText = true; - chartText.tmpText.raycastTarget = false; - chartText.tmpText.enableWordWrapping = textStyle.autoWrap; -#else - chartText.text = GetOrAddComponent<Text>(txtObj); - chartText.text.font = textStyle.font == null ? theme.font : textStyle.font; - chartText.text.fontStyle = textStyle.fontStyle; - chartText.text.horizontalOverflow = textStyle.autoWrap ? HorizontalWrapMode.Wrap : HorizontalWrapMode.Overflow; - chartText.text.verticalOverflow = VerticalWrapMode.Overflow; - chartText.text.supportRichText = true; - chartText.text.raycastTarget = false; -#endif - if (textStyle.autoColor && autoColor != Color.clear) - chartText.SetColor(autoColor); - else - chartText.SetColor(textStyle.GetColor(theme.textColor)); - - chartText.SetAlignment(textStyle.autoAlign ? autoAlignment : textStyle.alignment); - chartText.SetFontSize(textStyle.GetFontSize(theme)); - chartText.SetText("Text"); - chartText.SetLineSpacing(textStyle.lineSpacing); - chartText.SetActive(textStyle.show); - - RectTransform rect = GetOrAddComponent<RectTransform>(txtObj); - rect.localPosition = Vector3.zero; - rect.sizeDelta = sizeDelta; - rect.anchorMin = anchorMin; - rect.anchorMax = anchorMax; - rect.pivot = pivot; - return chartText; - } - - internal static Painter AddPainterObject(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, - Vector2 pivot, Vector2 sizeDelta, HideFlags hideFlags, int siblingIndex) - { - var painterObj = ChartHelper.AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta); - painterObj.hideFlags = hideFlags; - painterObj.transform.SetSiblingIndex(siblingIndex); - return ChartHelper.GetOrAddComponent<Painter>(painterObj); - } - - public static Image AddIcon(string name, Transform parent, IconStyle iconStyle) - { - return AddIcon(name, parent, iconStyle.width, iconStyle.height, iconStyle.sprite, iconStyle.type); - } - - public static Image AddIcon(string name, Transform parent, float width, float height, Sprite sprite = null, - Image.Type type = Image.Type.Simple) - { - var anchorMax = new Vector2(0.5f, 0.5f); - var anchorMin = new Vector2(0.5f, 0.5f); - var pivot = new Vector2(0.5f, 0.5f); - var sizeDelta = new Vector2(width, height); - GameObject iconObj = AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta); - var img = GetOrAddComponent<Image>(iconObj); - if (img.raycastTarget != false) - img.raycastTarget = false; - if (img.type != type) - img.type = type; - if (sprite != null && img.sprite != sprite) - { - img.sprite = sprite; - if (width == 0 || height == 0) - { - img.SetNativeSize(); - } - } - return img; - } - - public static ChartLabel AddAxisLabelObject(int total, int index, string name, Transform parent, - Vector2 sizeDelta, Axis axis, ComponentTheme theme, - string content, Color autoColor, TextAnchor autoAlignment = TextAnchor.MiddleCenter) - { - var textStyle = axis.axisLabel.textStyle; - var label = AddChartLabel(name, parent, axis.axisLabel, theme, content, autoColor, autoAlignment); - var labelShow = axis.axisLabel.show && (axis.axisLabel.interval == 0 || index % (axis.axisLabel.interval + 1) == 0); - if (labelShow) - { - if (!axis.axisLabel.showStartLabel && index == 0) labelShow = false; - else if (!axis.axisLabel.showEndLabel && index == total - 1) labelShow = false; - } - label.UpdateIcon(axis.axisLabel.icon, axis.GetIcon(index)); - label.text.SetActive(labelShow); - return label; - } - - public static ChartLabel AddChartLabel(string name, Transform parent, LabelStyle labelStyle, - ComponentTheme theme, string content, Color autoColor, TextAnchor autoAlignment = TextAnchor.MiddleCenter) - { - Vector2 anchorMin, anchorMax, pivot; - var sizeDelta = new Vector2(labelStyle.width, labelStyle.height); - var textStyle = labelStyle.textStyle; - var alignment = textStyle.GetAlignment(autoAlignment); - UpdateAnchorAndPivotByTextAlignment(alignment, out anchorMin, out anchorMax, out pivot); - var labelObj = AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta); - // TODO: 为了兼容旧版本,这里后面版本可以去掉 - #region temp code - var oldText = labelObj.GetComponent<Text>(); - if (oldText != null) - { - GameObject.DestroyImmediate(oldText); - } - var oldImage = labelObj.GetComponent<Image>(); - if (oldImage != null) - { - GameObject.DestroyImmediate(oldImage); - } - #endregion - - var label = GetOrAddComponent<ChartLabel>(labelObj); - label.text = AddTextObject("Text", label.gameObject.transform, anchorMin, anchorMax, pivot, - sizeDelta, textStyle, theme, autoColor, autoAlignment, label.text); - label.icon = ChartHelper.AddIcon("Icon", label.gameObject.transform, labelStyle.icon); - label.SetSize(labelStyle.width, labelStyle.height); - label.SetTextPadding(labelStyle.textPadding); - label.SetText(content); - label.UpdateIcon(labelStyle.icon); - if (labelStyle.background.show) - { - label.color = (!labelStyle.background.autoColor || autoColor == Color.clear) ? - labelStyle.background.color : autoColor; - label.sprite = labelStyle.background.sprite; - label.type = labelStyle.background.type; - } - else - { - label.color = Color.clear; - label.sprite = null; - } - label.transform.localEulerAngles = new Vector3(0, 0, labelStyle.rotate); - label.transform.localPosition = labelStyle.offset; - return label; - } - - private static void UpdateAnchorAndPivotByTextAlignment(TextAnchor alignment, out Vector2 anchorMin, out Vector2 anchorMax, - out Vector2 pivot) - { - switch (alignment) - { - case TextAnchor.LowerLeft: - anchorMin = new Vector2(0f, 0f); - anchorMax = new Vector2(0f, 0f); - pivot = new Vector2(0f, 0f); - break; - case TextAnchor.UpperLeft: - anchorMin = new Vector2(0f, 1f); - anchorMax = new Vector2(0f, 1f); - pivot = new Vector2(0f, 1f); - break; - case TextAnchor.MiddleLeft: - anchorMin = new Vector2(0f, 0.5f); - anchorMax = new Vector2(0f, 0.5f); - pivot = new Vector2(0f, 0.5f); - break; - case TextAnchor.LowerRight: - anchorMin = new Vector2(1f, 0f); - anchorMax = new Vector2(1f, 0f); - pivot = new Vector2(1f, 0f); - break; - case TextAnchor.UpperRight: - anchorMin = new Vector2(1f, 1f); - anchorMax = new Vector2(1f, 1f); - pivot = new Vector2(1f, 1f); - break; - case TextAnchor.MiddleRight: - anchorMin = new Vector2(1, 0.5f); - anchorMax = new Vector2(1, 0.5f); - pivot = new Vector2(1, 0.5f); - break; - case TextAnchor.LowerCenter: - anchorMin = new Vector2(0.5f, 0f); - anchorMax = new Vector2(0.5f, 0f); - pivot = new Vector2(0.5f, 0f); - break; - case TextAnchor.UpperCenter: - anchorMin = new Vector2(0.5f, 1f); - anchorMax = new Vector2(0.5f, 1f); - pivot = new Vector2(0.5f, 1f); - break; - case TextAnchor.MiddleCenter: - anchorMin = new Vector2(0.5f, 0.5f); - anchorMax = new Vector2(0.5f, 0.5f); - pivot = new Vector2(0.5f, 0.5f); - break; - default: - anchorMin = new Vector2(0.5f, 0.5f); - anchorMax = new Vector2(0.5f, 0.5f); - pivot = new Vector2(0.5f, 0.5f); - break; - } - } - - internal static ChartLabel AddTooltipIndicatorLabel(Tooltip tooltip, string name, Transform parent, - ThemeStyle theme, TextAnchor alignment) - { - var label = ChartHelper.AddChartLabel(name, parent, tooltip.indicatorLabelStyle, theme.tooltip, - "", Color.clear, alignment); - label.SetActive(tooltip.show && tooltip.indicatorLabelStyle.show); - return label; - } - - public static void GetPointList(ref List<Vector3> posList, Vector3 sp, Vector3 ep, float k = 30f) - { - Vector3 dir = (ep - sp).normalized; - float dist = Vector3.Distance(sp, ep); - int segment = (int) (dist / k); - posList.Clear(); - posList.Add(sp); - for (int i = 1; i < segment; i++) - { - posList.Add(sp + dir * dist * i / segment); - } - posList.Add(ep); - } - - public static bool IsValueEqualsColor(Color32 color1, Color32 color2) - { - return color1.a == color2.a && - color1.b == color2.b && - color1.g == color2.g && - color1.r == color2.r; - } - - public static bool IsValueEqualsColor(Color color1, Color color2) - { - return color1.a == color2.a && - color1.b == color2.b && - color1.g == color2.g && - color1.r == color2.r; - } - - public static bool IsValueEqualsString(string str1, string str2) - { - if (str1 == null && str2 == null) return true; - else if (str1 != null && str2 != null) return str1.Equals(str2); - else return false; - } - - public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2) - { - return v1.x == v2.x && v1.y == v2.y; - } - - public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2) - { - return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; - } - - public static bool IsValueEqualsList<T>(List<T> list1, List<T> list2) - { - if (list1 == null || list2 == null) return false; - if (list1.Count != list2.Count) return false; - for (int i = 0; i < list1.Count; i++) - { - if (list1[i] == null && list2[i] == null) { } - else - { - if (list1[i] != null) - { - if (!list1[i].Equals(list2[i])) return false; - } - else - { - if (!list2[i].Equals(list1[i])) return false; - } - } - } - return true; - } - - public static bool IsEquals(double d1, double d2) - { - return Math.Abs(d1 - d2) < 0.000001d; - } - - public static bool IsEquals(float d1, float d2) - { - return Math.Abs(d1 - d2) < 0.000001f; - } - - public static bool IsClearColor(Color32 color) - { - return color.a == 0 && color.b == 0 && color.g == 0 && color.r == 0; - } - - public static bool IsClearColor(Color color) - { - return color.a == 0 && color.b == 0 && color.g == 0 && color.r == 0; - } - - public static bool IsZeroVector(Vector3 pos) - { - return pos.x == 0 && pos.y == 0 && pos.z == 0; - } - - public static bool CopyList<T>(List<T> toList, List<T> fromList) - { - if (toList == null || fromList == null) return false; - toList.Clear(); - foreach (var item in fromList) toList.Add(item); - return true; - } - public static bool CopyArray<T>(T[] toList, T[] fromList) - { - if (toList == null || fromList == null) return false; - if (toList.Length != fromList.Length) - { - toList = new T[fromList.Length]; - } - for (int i = 0; i < fromList.Length; i++) toList[i] = fromList[i]; - return true; - } - - public static List<float> ParseFloatFromString(string jsonData) - { - List<float> list = new List<float>(); - if (string.IsNullOrEmpty(jsonData)) return list; - int startIndex = jsonData.IndexOf("["); - int endIndex = jsonData.IndexOf("]"); - string temp = jsonData.Substring(startIndex + 1, endIndex - startIndex - 1); - if (temp.IndexOf("],") > -1 || temp.IndexOf("] ,") > -1) - { - string[] datas = temp.Split(new string[] { "],", "] ," }, StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < datas.Length; i++) - { - temp = datas[i]; - } - return list; - } - else - { - string[] datas = temp.Split(','); - for (int i = 0; i < datas.Length; i++) - { - list.Add(float.Parse(datas[i].Trim())); - } - return list; - } - } - - public static List<string> ParseStringFromString(string jsonData) - { - List<string> list = new List<string>(); - if (string.IsNullOrEmpty(jsonData)) return list; - string pattern = "[\"'](.*?)[\"']"; - if (Regex.IsMatch(jsonData, pattern)) - { - MatchCollection m = Regex.Matches(jsonData, pattern); - foreach (Match match in m) - { - list.Add(match.Groups[1].Value); - } - } - return list; - } - - public static Color32 GetColor(string hexColorStr) - { - Color color; - ColorUtility.TryParseHtmlString(hexColorStr, out color); - return (Color32) color; - } - - public static double GetMaxDivisibleValue(double max, int ceilRate) - { - if (max == 0) return 0; - if (max > -1 && max < 1) - { - int count = 1; - int intvalue = (int) (max * Mathf.Pow(10, count)); - while (intvalue == 0 && count < 12) - { - count++; - intvalue = (int) (max * Mathf.Pow(10, count)); - } - var pow = Mathf.Pow(10, count); - if (max > 0) return (int) ((max * pow + 1)) / pow; - else return (int) ((max * pow - 1)) / pow; - } - if (ceilRate == 0) - { - var bigger = Math.Ceiling(Math.Abs(max)); - int n = 1; - while (bigger / (Mathf.Pow(10, n)) > 10) - { - n++; - } - double mm = bigger; - if (mm > 10 && n < 38) - { - mm = bigger - bigger % (Mathf.Pow(10, n)); - mm += max > 0 ? Mathf.Pow(10, n) : -Mathf.Pow(10, n); - } - var mmm = mm - Mathf.Pow(10, n) / 2; - if (max < 0) return -Math.Ceiling(mmm > -max ? mmm : mm); - else return Math.Ceiling(mmm > max ? mmm : mm); - } - else - { - var mod = max % ceilRate; - int rate = (int) (max / ceilRate); - return mod == 0 ? max : (max < 0 ? rate : rate + 1) * ceilRate; - } - } - - public static double GetMinDivisibleValue(double min, int ceilRate) - { - if (min == 0) return 0; - if (min > -1 && min < 1) - { - int count = 1; - int intvalue = (int) (min * Mathf.Pow(10, count)); - while (intvalue == 0 && count < 12) - { - count++; - intvalue = (int) (min * Mathf.Pow(10, count)); - } - var pow = Mathf.Pow(10, count); - if (min > 0) return (int) ((min * pow + 1)) / pow; - else return (int) ((min * pow - 1)) / pow; - } - if (ceilRate == 0) - { - var bigger = Math.Floor(Math.Abs(min)); - int n = 1; - while (bigger / (Mathf.Pow(10, n)) > 10) - { - n++; - } - double mm = bigger; - if (mm > 10 && n < 38) - { - mm = bigger - bigger % (Mathf.Pow(10, n)); - mm += min < 0 ? Mathf.Pow(10, n) : -Mathf.Pow(10, n); - } - if (min < 0) return -Math.Floor(mm); - else return Math.Floor(mm); - } - else - { - var mod = min % ceilRate; - int rate = (int) (min / ceilRate); - return mod == 0 ? min : (min < 0 ? rate - 1 : rate) * ceilRate; - } - } - - public static double GetMaxLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber) - { - splitNumber = 0; - if (value <= 0) return 0; - double max = 0; - while (max < value) - { - if (isLogBaseE) - { - max = Math.Exp(splitNumber); - } - else - { - max = Math.Pow(logBase, splitNumber); - } - splitNumber++; - } - return max; - } - - public static double GetMinLogValue(double value, float logBase, bool isLogBaseE, out int splitNumber) - { - splitNumber = 0; - if (value > 1) return 1; - double min = 1; - while (min > value) - { - if (isLogBaseE) - { - min = Math.Exp(-splitNumber); - } - else - { - min = Math.Pow(logBase, -splitNumber); - } - splitNumber++; - } - return min; - } - - public static int GetFloatAccuracy(double value) - { - if (value > 1 || value < -1) return 0; - int count = 1; - int intvalue = (int) (value * Mathf.Pow(10, count)); - while (intvalue == 0 && count < 38) - { - count++; - intvalue = (int) (value * Mathf.Pow(10, count)); - } - if (count == 38 && (value == 0 || value == 1)) return 1; - else return count; - } - - public static void AddEventListener(GameObject obj, EventTriggerType type, - UnityEngine.Events.UnityAction<BaseEventData> call) - { - EventTrigger trigger = GetOrAddComponent<EventTrigger>(obj.gameObject); - EventTrigger.Entry entry = new EventTrigger.Entry(); - entry.eventID = type; - entry.callback = new EventTrigger.TriggerEvent(); - entry.callback.AddListener(call); - trigger.triggers.Add(entry); - } - - public static void ClearEventListener(GameObject obj) - { - EventTrigger trigger = obj.GetComponent<EventTrigger>(); - if (trigger != null) - { - trigger.triggers.Clear(); - } - } - - public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle) - { - Vector3 point = Quaternion.AngleAxis(angle, axis) * (position - center); - Vector3 resultVec3 = center + point; - return resultVec3; - } - - public static Vector3 GetPosition(Vector3 center, float angle, float radius) - { - var rad = angle * Mathf.Deg2Rad; - var px = Mathf.Sin(rad) * radius; - var py = Mathf.Cos(rad) * radius; - return center + new Vector3(px, py); - } - - /// <summary> - /// 获得0-360的角度(12点钟方向为0度) - /// </summary> - /// <param name="from"></param> - /// <param name="to"></param> - /// <returns></returns> - public static float GetAngle360(Vector2 from, Vector2 to) - { - float angle; - - Vector3 cross = Vector3.Cross(from, to); - angle = Vector2.Angle(from, to); - angle = cross.z > 0 ? -angle : angle; - angle = (angle + 360) % 360; - return angle; - } - - public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false) - { - angle = isDegree ? angle * Mathf.Deg2Rad : angle; - return new Vector3(center.x + radius * Mathf.Sin(angle), center.y + radius * Mathf.Cos(angle)); - } - - public static Vector3 GetDire(float angle, bool isDegree = false) - { - angle = isDegree ? angle * Mathf.Deg2Rad : angle; - return new Vector3(Mathf.Sin(angle), Mathf.Cos(angle)); - } - - public static Vector3 GetVertialDire(Vector3 dire) - { - if (dire.x == 0) - { - return new Vector3(-1, 0, 0); - } - if (dire.y == 0) - { - return new Vector3(0, -1, 0); - } - else - { - return new Vector3(-dire.y / dire.x, 1, 0).normalized; - } - } - - public static Vector3 GetLastValue(List<Vector3> list) - { - if (list.Count <= 0) return Vector3.zero; - else return list[list.Count - 1]; - } - - public static void SetColorOpacity(ref Color32 color, float opacity) - { - if (color.a != 0 && opacity != 1) - { - color.a = (byte) (color.a * opacity); - } - } - - public static Color32 GetHighlightColor(Color32 color, float rate = 0.8f) - { - var newColor = color; - newColor.r = (byte) (color.r * rate); - newColor.g = (byte) (color.g * rate); - newColor.b = (byte) (color.b * rate); - return newColor; - } - - public static bool IsPointInQuadrilateral(Vector3 P, Vector3 A, Vector3 B, Vector3 C, Vector3 D) - { - Vector3 v0 = Vector3.Cross(A - D, P - D); - Vector3 v1 = Vector3.Cross(B - A, P - A); - Vector3 v2 = Vector3.Cross(C - B, P - B); - Vector3 v3 = Vector3.Cross(D - C, P - C); - if (Vector3.Dot(v0, v1) < 0 || Vector3.Dot(v0, v2) < 0 || Vector3.Dot(v0, v3) < 0) - { - return false; - } - else - { - return true; - } - } - - public static bool IsInRect(Vector3 pos, float xMin, float xMax, float yMin, float yMax) - { - return pos.x >= xMin && pos.x <= xMax && pos.y <= yMax && pos.y >= yMin; - } - - public static bool IsColorAlphaZero(Color color) - { - return !ChartHelper.IsClearColor(color) && color.a == 0; - } - - public static float GetActualValue(float valueOrRate, float total, float maxRate = 1.5f) - { - if (valueOrRate >= -maxRate && valueOrRate <= maxRate) return valueOrRate * total; - else return valueOrRate; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs.meta deleted file mode 100644 index 2e6abc8..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 47cfa7bd879be4069bd187e46346d73d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs deleted file mode 100644 index f59a703..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - public static class ComponentHelper - { - public static AngleAxis GetAngleAxis(List<MainComponent> components, int polarIndex) - { - foreach (var component in components) - { - if (component is AngleAxis) - { - var axis = component as AngleAxis; - if (axis.polarIndex == polarIndex) return axis; - } - } - return null; - } - - public static RadiusAxis GetRadiusAxis(List<MainComponent> components, int polarIndex) - { - foreach (var component in components) - { - if (component is RadiusAxis) - { - var axis = component as RadiusAxis; - if (axis.polarIndex == polarIndex) return axis; - } - } - return null; - } - - public static float GetXAxisOnZeroOffset(List<MainComponent> components, XAxis axis) - { - if (!axis.axisLine.onZero) return 0; - foreach (var component in components) - { - if (component is YAxis) - { - var yAxis = component as YAxis; - if (yAxis.IsValue() && yAxis.gridIndex == axis.gridIndex) return yAxis.context.offset; - } - } - return 0; - } - - public static float GetYAxisOnZeroOffset(List<MainComponent> components, YAxis axis) - { - if (!axis.axisLine.onZero) return 0; - foreach (var component in components) - { - if (component is XAxis) - { - var xAxis = component as XAxis; - if (xAxis.IsValue() && xAxis.gridIndex == axis.gridIndex) return xAxis.context.offset; - } - } - return 0; - } - - public static bool IsAnyCategoryOfYAxis(List<MainComponent> components) - { - foreach (var component in components) - { - if (component is YAxis) - { - var yAxis = component as YAxis; - if (yAxis.type == Axis.AxisType.Category) - return true; - } - } - return false; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs.meta deleted file mode 100644 index df48974..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1b7af706293fe4e63b4d079dbe5c0ea2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs deleted file mode 100644 index ee555ad..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - internal static class DataHelper - { - public static double DataAverage(ref List<SerieData> showData, SampleType sampleType, - int minCount, int maxCount, int rate) - { - double totalAverage = 0; - if (rate > 1 && sampleType == SampleType.Peak) - { - double total = 0; - for (int i = minCount; i < maxCount; i++) - { - total += showData[i].data[1]; - } - totalAverage = total / (maxCount - minCount); - } - return totalAverage; - } - - public static double SampleValue(ref List<SerieData> showData, SampleType sampleType, int rate, - int minCount, int maxCount, double totalAverage, int index, float dataChangeDuration, - ref bool dataChanging, Axis axis) - { - var inverse = axis.inverse; - var minValue = axis.context.minValue; - var maxValue = axis.context.maxValue; - if (rate <= 1 || index == minCount) - { - if (showData[index].IsDataChanged()) - dataChanging = true; - - return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); - } - switch (sampleType) - { - case SampleType.Sum: - case SampleType.Average: - double total = 0; - var count = 0; - for (int i = index; i > index - rate; i--) - { - count++; - total += showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); - if (showData[i].IsDataChanged()) - dataChanging = true; - } - if (sampleType == SampleType.Average) - return total / rate; - else - return total; - - case SampleType.Max: - double max = double.MinValue; - for (int i = index; i > index - rate; i--) - { - var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); - if (value > max) - max = value; - - if (showData[i].IsDataChanged()) - dataChanging = true; - } - return max; - - case SampleType.Min: - double min = double.MaxValue; - for (int i = index; i > index - rate; i--) - { - var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); - if (value < min) - min = value; - - if (showData[i].IsDataChanged()) - dataChanging = true; - } - return min; - - case SampleType.Peak: - max = double.MinValue; - min = double.MaxValue; - total = 0; - for (int i = index; i > index - rate; i--) - { - var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); - total += value; - if (value < min) - min = value; - if (value > max) - max = value; - - if (showData[i].IsDataChanged()) - dataChanging = true; - } - var average = total / rate; - if (average >= totalAverage) - return max; - else - return min; - } - if (showData[index].IsDataChanged()) - dataChanging = true; - - return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs.meta deleted file mode 100644 index da77e53..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c982f1be15b204c9190197803101f2db -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs deleted file mode 100644 index 6b128f8..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs +++ /dev/null @@ -1,226 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class LayerHelper - { - private static Vector2 s_Vector0And0 = new Vector2(0, 0); - private static Vector2 s_Vector0And0Dot5 = new Vector2(0, 0.5f); - private static Vector2 s_Vector0And1 = new Vector2(0, 1f); - private static Vector2 s_Vector0Dot5And1 = new Vector2(0.5f, 1f); - private static Vector2 s_Vector0Dot5And0Dot5 = new Vector2(0.5f, 0.5f); - private static Vector2 s_Vector0Dot5And0 = new Vector2(0.5f, 0f); - private static Vector2 s_Vector1And1 = new Vector2(1f, 1f); - private static Vector2 s_Vector1And0Dot5 = new Vector2(1f, 0.5f); - private static Vector2 s_Vector1And0 = new Vector2(1f, 0); - - internal static Vector2 ResetChartPositionAndPivot(Vector2 minAnchor, Vector2 maxAnchor, float width, - float height, ref float chartX, ref float chartY) - { - if (IsLeftTop(minAnchor, maxAnchor)) - { - chartX = 0; - chartY = -height; - return s_Vector0And1; - } - else if (IsLeftCenter(minAnchor, maxAnchor)) - { - chartX = 0; - chartY = -height / 2; - return s_Vector0And0Dot5; - } - else if (IsLeftBottom(minAnchor, maxAnchor)) - { - chartX = 0; - chartY = 0; - return s_Vector0And0; - } - else if (IsCenterTop(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = -height; - return s_Vector0Dot5And1; - } - else if (IsCenterCenter(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = -height / 2; - return s_Vector0Dot5And0Dot5; - } - else if (IsCenterBottom(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = 0; - return s_Vector0Dot5And0; - } - else if (IsRightTop(minAnchor, maxAnchor)) - { - chartX = -width; - chartY = -height; - return s_Vector1And1; - } - else if (IsRightCenter(minAnchor, maxAnchor)) - { - chartX = -width; - chartY = -height / 2; - return s_Vector1And0Dot5; - } - else if (IsRightBottom(minAnchor, maxAnchor)) - { - chartX = -width; - chartY = 0; - return s_Vector1And0; - } - else if (IsStretchTop(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = -height; - return s_Vector0Dot5And1; - } - else if (IsStretchMiddle(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = -height / 2; - return s_Vector0Dot5And0Dot5; - } - else if (IsStretchBottom(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = 0; - return s_Vector0Dot5And0; - } - else if (IsStretchLeft(minAnchor, maxAnchor)) - { - chartX = 0; - chartY = -height / 2; - return s_Vector0And0Dot5; - } - else if (IsStretchCenter(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = -height / 2; - return s_Vector0Dot5And0Dot5; - } - else if (IsStretchRight(minAnchor, maxAnchor)) - { - chartX = -width; - chartY = -height / 2; - return s_Vector1And0Dot5; - } - else if (IsStretchStrech(minAnchor, maxAnchor)) - { - chartX = -width / 2; - chartY = -height / 2; - return s_Vector0Dot5And0Dot5; - } - chartX = 0; - chartY = 0; - return Vector2.zero; - } - - private static bool IsLeftTop(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And1 && maxAnchor == s_Vector0And1; - } - - private static bool IsLeftCenter(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And0Dot5 && maxAnchor == s_Vector0And0Dot5; - } - - private static bool IsLeftBottom(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == Vector2.zero && maxAnchor == Vector2.zero; - } - - private static bool IsCenterTop(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0Dot5And1 && maxAnchor == s_Vector0Dot5And1; - } - - private static bool IsCenterCenter(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0Dot5And0Dot5 && maxAnchor == s_Vector0Dot5And0Dot5; - } - - private static bool IsCenterBottom(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0Dot5And0 && maxAnchor == s_Vector0Dot5And0; - } - - private static bool IsRightTop(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector1And1 && maxAnchor == s_Vector1And1; - } - - private static bool IsRightCenter(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector1And0Dot5 && maxAnchor == s_Vector1And0Dot5; - } - - private static bool IsRightBottom(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector1And0 && maxAnchor == s_Vector1And0; - } - - private static bool IsStretchTop(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And1 && maxAnchor == s_Vector1And1; - } - - private static bool IsStretchMiddle(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And0Dot5 && maxAnchor == s_Vector1And0Dot5; - } - - private static bool IsStretchBottom(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And0 && maxAnchor == s_Vector1And0; - } - - private static bool IsStretchLeft(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And0 && maxAnchor == s_Vector0And1; - } - - private static bool IsStretchCenter(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0Dot5And0 && maxAnchor == s_Vector0Dot5And1; - } - - private static bool IsStretchRight(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector1And0 && maxAnchor == s_Vector1And1; - } - - private static bool IsStretchStrech(Vector2 minAnchor, Vector2 maxAnchor) - { - return minAnchor == s_Vector0And0 && maxAnchor == s_Vector1And1; - } - - public static bool IsStretchPivot(RectTransform rt) - { - return IsStretchTop(rt.anchorMin, rt.anchorMax) || - IsStretchMiddle(rt.anchorMin, rt.anchorMax) || - IsStretchBottom(rt.anchorMin, rt.anchorMax) || - IsStretchLeft(rt.anchorMin, rt.anchorMax) || - IsStretchCenter(rt.anchorMin, rt.anchorMax) || - IsStretchRight(rt.anchorMin, rt.anchorMax) || - IsStretchStrech(rt.anchorMin, rt.anchorMax); - } - - public static bool IsFixedWidthHeight(RectTransform rt) - { - return IsLeftTop(rt.anchorMin, rt.anchorMax) || - IsLeftCenter(rt.anchorMin, rt.anchorMax) || - IsLeftBottom(rt.anchorMin, rt.anchorMax) || - IsCenterTop(rt.anchorMin, rt.anchorMax) || - IsCenterCenter(rt.anchorMin, rt.anchorMax) || - IsCenterBottom(rt.anchorMin, rt.anchorMax) || - IsRightTop(rt.anchorMin, rt.anchorMax) || - IsRightCenter(rt.anchorMin, rt.anchorMax) || - IsRightBottom(rt.anchorMin, rt.anchorMax); - } - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs.meta deleted file mode 100644 index f9d31b8..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/LayoutHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8d6eeea6fc2824cc891fec0674bf2d71 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs b/Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs deleted file mode 100644 index 2103a5f..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public static class MathUtil - { - public static double Abs(double d) - { - return d > 0 ? d : -d; - } - - public static double Clamp(double d, double min, double max) - { - if (d >= min && d <= max) return d; - else if (d < min) return min; - else return max; - } - - public static bool Approximately(double a, double b) - { - return Math.Abs(b - a) < Math.Max(0.000001f * Math.Max(Math.Abs(a), Math.Abs(b)), Mathf.Epsilon * 8); - } - - public static double Clamp01(double value) - { - if (value < 0F) - return 0F; - else if (value > 1F) - return 1F; - else - return value; - } - - public static double Lerp(double a, double b, double t) - { - return a + (b - a) * Clamp01(t); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs.meta b/Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs.meta deleted file mode 100644 index 0c3d017..0000000 --- a/Assets/XCharts/Runtime/Internal/Utilities/MathUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 094dc7b90e3a049b48f15f990c050db1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs b/Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs deleted file mode 100644 index f8f252d..0000000 --- a/Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs +++ /dev/null @@ -1,168 +0,0 @@ -#if UNITY_EDITOR - -using System; -using System.IO; -using UnityEditor; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - public class XCResourcesImporter - { - bool m_EssentialResourcesImported; - - public XCResourcesImporter() { } - - public void OnDestroy() { } - - public void OnGUI() - { - m_EssentialResourcesImported = Resources.Load<XCSettings>("XCSettings") != null; - - GUILayout.BeginVertical(); - { - GUILayout.BeginVertical(EditorStyles.helpBox); - { - GUILayout.Label("XCharts Essentials", EditorStyles.boldLabel); - GUILayout.Label("This appears to be the first time you access XCharts, as such we need to add resources to your project that are essential for using XCharts. These new resources will be placed at the root of your project in the \"XCharts\" folder.", new GUIStyle(EditorStyles.label) { wordWrap = true }); - GUILayout.Space(5f); - - GUI.enabled = !m_EssentialResourcesImported; - GUI.enabled = true; - if (GUILayout.Button("Import XCharts Essentials")) - { - string packageFullPath = XChartsMgr.GetPackageFullPath(); - if (packageFullPath != null) - { - var sourPath = Path.Combine(packageFullPath, "Resources"); - var destPath = Path.Combine(Application.dataPath, "XCharts/Resources"); - if (CopyFolder(sourPath, destPath)) - { - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - } - } - GUILayout.Space(5f); - GUI.enabled = true; - } - GUILayout.EndVertical(); - } - GUILayout.EndVertical(); - GUILayout.Space(5f); - } - - private static bool CopyFolder(string sourPath, string destPath) - { - try - { - if (!Directory.Exists(destPath)) - { - Directory.CreateDirectory(destPath); - } - var files = Directory.GetFiles(sourPath); - foreach (var file in files) - { - var name = Path.GetFileName(file); - var path = Path.Combine(destPath, name); - File.Copy(file, path); - } - var folders = Directory.GetDirectories(sourPath); - foreach (var folder in folders) - { - var name = Path.GetFileName(folder); - var path = Path.Combine(destPath, name); - CopyFolder(folder, path); - } - return true; - } - catch (Exception e) - { - Debug.LogError("CopyFolder:" + e.Message); - return false; - } - } - - internal void RegisterResourceImportCallback() - { - AssetDatabase.importPackageCompleted += ImportCallback; - } - - /// <summary> - /// - /// </summary> - /// <param name="packageName"></param> - void ImportCallback(string packageName) - { - if (packageName == "XCharts Essential Resources") - { - m_EssentialResourcesImported = true; -#if UNITY_2018_3_OR_NEWER - SettingsService.NotifySettingsProviderChanged(); -#endif - } - Debug.Log("[" + packageName + "] have been imported."); - - AssetDatabase.importPackageCompleted -= ImportCallback; - } - } - - public class XCResourceImporterWindow : UnityEditor.EditorWindow - { - [SerializeField] XCResourcesImporter m_ResourceImporter; - - static XCResourceImporterWindow m_ImporterWindow; - - public static void ShowPackageImporterWindow() - { - var packagePath = XChartsMgr.GetPackageFullPath(); - if (packagePath != null) - { - if (m_ImporterWindow == null) - { - m_ImporterWindow = GetWindow<XCResourceImporterWindow>(); - m_ImporterWindow.titleContent = new GUIContent("XCharts Importer"); - } - m_ImporterWindow.Focus(); - } - } - - void OnEnable() - { - SetEditorWindowSize(); - - if (m_ResourceImporter == null) - m_ResourceImporter = new XCResourcesImporter(); - } - - void OnDestroy() - { - m_ResourceImporter.OnDestroy(); - } - - void OnGUI() - { - m_ResourceImporter.OnGUI(); - } - - void OnInspectorUpdate() - { - Repaint(); - } - - /// <summary> - /// Limits the minimum size of the editor window. - /// |</summary> - void SetEditorWindowSize() - { - EditorWindow editorWindow = this; - - Vector2 windowSize = new Vector2(640, 210); - editorWindow.minSize = windowSize; - editorWindow.maxSize = windowSize; - } - } -} - -#endif \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs.meta b/Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs.meta deleted file mode 100644 index 2fd06d7..0000000 --- a/Assets/XCharts/Runtime/Internal/XCResourcesImporter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fee2f9747b8914ddba13895caa2aa236 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/XCSettings.cs b/Assets/XCharts/Runtime/Internal/XCSettings.cs deleted file mode 100644 index d1617bc..0000000 --- a/Assets/XCharts/Runtime/Internal/XCSettings.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif -#if UNITY_EDITOR -using UnityEditor; -#endif - -namespace XCharts.Runtime -{ - [Serializable] -#if UNITY_2018_3 - - [ExcludeFromPresetAttribute] -#endif - public class XCSettings : ScriptableObject - { - public readonly static string THEME_ASSET_NAME_PREFIX = "XCTheme-"; - public readonly static string THEME_ASSET_FOLDER = "Assets/XCharts/Resources"; - - [SerializeField] private Lang m_Lang = null; - [SerializeField] private Font m_Font = null; -#if dUI_TextMeshPro - [SerializeField] private TMP_FontAsset m_TMPFont = null; -#endif - [SerializeField][Range(1, 200)] private int m_FontSizeLv1 = 28; - [SerializeField][Range(1, 200)] private int m_FontSizeLv2 = 24; - [SerializeField][Range(1, 200)] private int m_FontSizeLv3 = 20; - [SerializeField][Range(1, 200)] private int m_FontSizeLv4 = 18; - [SerializeField] private LineStyle.Type m_AxisLineType = LineStyle.Type.Solid; - [SerializeField][Range(0, 20)] private float m_AxisLineWidth = 0.8f; - [SerializeField] private LineStyle.Type m_AxisSplitLineType = LineStyle.Type.Solid; - [SerializeField][Range(0, 20)] private float m_AxisSplitLineWidth = 0.8f; - [SerializeField][Range(0, 20)] private float m_AxisTickWidth = 0.8f; - [SerializeField][Range(0, 20)] private float m_AxisTickLength = 5f; - [SerializeField][Range(0, 200)] private float m_GaugeAxisLineWidth = 15f; - [SerializeField][Range(0, 20)] private float m_GaugeAxisSplitLineWidth = 0.8f; - [SerializeField][Range(0, 20)] private float m_GaugeAxisSplitLineLength = 15f; - [SerializeField][Range(0, 20)] private float m_GaugeAxisTickWidth = 0.8f; - [SerializeField][Range(0, 20)] private float m_GaugeAxisTickLength = 5f; - [SerializeField][Range(0, 20)] private float m_TootipLineWidth = 0.8f; - [SerializeField][Range(0, 20)] private float m_DataZoomBorderWidth = 0.5f; - [SerializeField][Range(0, 20)] private float m_DataZoomDataLineWidth = 0.5f; - [SerializeField][Range(0, 20)] private float m_VisualMapBorderWidth = 0f; - - [SerializeField][Range(0, 20)] private float m_SerieLineWidth = 1.8f; - [SerializeField][Range(0, 200)] private float m_SerieLineSymbolSize = 5f; - [SerializeField][Range(0, 200)] private float m_SerieScatterSymbolSize = 20f; - [SerializeField][Range(0, 200)] private float m_SerieSelectedRate = 1.3f; - [SerializeField][Range(0, 10)] private float m_SerieCandlestickBorderWidth = 1f; - - [SerializeField] private bool m_EditorShowAllListData = false; - - [SerializeField][Range(1, 20)] protected int m_MaxPainter = 10; - [SerializeField][Range(1, 10)] protected float m_LineSmoothStyle = 3f; - [SerializeField][Range(1f, 20)] protected float m_LineSmoothness = 2f; - [SerializeField][Range(1f, 20)] protected float m_LineSegmentDistance = 3f; - [SerializeField][Range(1, 10)] protected float m_CicleSmoothness = 2f; - [SerializeField][Range(10, 50)] protected float m_VisualMapTriangeLen = 20f; - [SerializeField][Range(1, 20)] protected float m_PieTooltipExtraRadius = 8f; - [SerializeField][Range(1, 20)] protected float m_PieSelectedOffset = 8f; - [SerializeField] protected List<Theme> m_CustomThemes = new List<Theme>(); - - public static Lang lang { get { return Instance.m_Lang; } } - public static Font font { get { return Instance.m_Font; } } -#if dUI_TextMeshPro - public static TMP_FontAsset tmpFont { get { return Instance.m_TMPFont; } } -#endif - /// <summary> - /// 一级字体大小。 - /// </summary> - public static int fontSizeLv1 { get { return Instance.m_FontSizeLv1; } } - public static int fontSizeLv2 { get { return Instance.m_FontSizeLv2; } } - public static int fontSizeLv3 { get { return Instance.m_FontSizeLv3; } } - public static int fontSizeLv4 { get { return Instance.m_FontSizeLv4; } } - public static LineStyle.Type axisLineType { get { return Instance.m_AxisLineType; } } - public static float axisLineWidth { get { return Instance.m_AxisLineWidth; } } - public static LineStyle.Type axisSplitLineType { get { return Instance.m_AxisSplitLineType; } } - public static float axisSplitLineWidth { get { return Instance.m_AxisSplitLineWidth; } } - public static float axisTickWidth { get { return Instance.m_AxisTickWidth; } } - public static float axisTickLength { get { return Instance.m_AxisTickLength; } } - public static float gaugeAxisLineWidth { get { return Instance.m_GaugeAxisLineWidth; } } - public static float gaugeAxisSplitLineWidth { get { return Instance.m_GaugeAxisSplitLineWidth; } } - public static float gaugeAxisSplitLineLength { get { return Instance.m_GaugeAxisSplitLineLength; } } - public static float gaugeAxisTickWidth { get { return Instance.m_GaugeAxisTickWidth; } } - public static float gaugeAxisTickLength { get { return Instance.m_GaugeAxisTickLength; } } - - public static float tootipLineWidth { get { return Instance.m_TootipLineWidth; } } - public static float dataZoomBorderWidth { get { return Instance.m_DataZoomBorderWidth; } } - public static float dataZoomDataLineWidth { get { return Instance.m_DataZoomDataLineWidth; } } - public static float visualMapBorderWidth { get { return Instance.m_VisualMapBorderWidth; } } - - #region serie - public static float serieLineWidth { get { return Instance.m_SerieLineWidth; } } - public static float serieLineSymbolSize { get { return Instance.m_SerieLineSymbolSize; } } - public static float serieScatterSymbolSize { get { return Instance.m_SerieScatterSymbolSize; } } - public static float serieSelectedRate { get { return Instance.m_SerieSelectedRate; } } - public static float serieCandlestickBorderWidth { get { return Instance.m_SerieCandlestickBorderWidth; } } - #endregion - - #region editor - public static bool editorShowAllListData { get { return Instance.m_EditorShowAllListData; } } - #endregion - - #region graphic - public static int maxPainter { get { return Instance.m_MaxPainter; } } - public static float lineSmoothStyle { get { return Instance.m_LineSmoothStyle; } } - public static float lineSmoothness { get { return Instance.m_LineSmoothness; } } - public static float lineSegmentDistance { get { return Instance.m_LineSegmentDistance; } } - public static float cicleSmoothness { get { return Instance.m_CicleSmoothness; } } - public static float visualMapTriangeLen { get { return Instance.m_VisualMapTriangeLen; } } - public static float pieTooltipExtraRadius { get { return Instance.m_PieTooltipExtraRadius; } } - public static float pieSelectedOffset { get { return Instance.m_PieSelectedOffset; } } - #endregion - - public static List<Theme> customThemes { get { return Instance.m_CustomThemes; } } - - private static XCSettings s_Instance; - public static XCSettings Instance - { - get - { - if (s_Instance == null) - { - s_Instance = Resources.Load<XCSettings>("XCSettings"); -#if UNITY_EDITOR - if (s_Instance == null) - { - var assetPath = GetSettingAssetPath(); - if (string.IsNullOrEmpty(assetPath)) - XCResourceImporterWindow.ShowPackageImporterWindow(); - else - s_Instance = AssetDatabase.LoadAssetAtPath<XCSettings>(assetPath); - } - else - { - if (s_Instance.m_Lang == null) - s_Instance.m_Lang = Resources.Load<Lang>("XCLang-EN"); - if (s_Instance.m_Lang == null) - s_Instance.m_Lang = ScriptableObject.CreateInstance<Lang>(); - if (s_Instance.m_Font == null) - s_Instance.m_Font = Resources.GetBuiltinResource<Font>("Arial.ttf"); -#if dUI_TextMeshPro - if (s_Instance.m_TMPFont == null) - s_Instance.m_TMPFont = Resources.Load<TMP_FontAsset>("LiberationSans SDF"); -#endif - } -#endif - } - return s_Instance; - } - } - -#if UNITY_EDITOR - public static bool ExistAssetFile() - { - return System.IO.File.Exists("Assets/XCharts/Resources/XCSettings.asset"); - } - - public static string GetSettingAssetPath() - { - var path = "Assets/XCharts/Resources/XCSettings.asset"; - if (File.Exists(path)) return path; - var dir = Application.dataPath; - string[] matchingPaths = Directory.GetDirectories(dir); - foreach (var match in matchingPaths) - { - if (match.Contains("XCharts")) - { - var jsonPath = string.Format("{0}/package.json", match); - if (File.Exists(jsonPath)) - { - var jsonText = File.ReadAllText(jsonPath); - if (jsonText.Contains("\"displayName\": \"XCharts\"")) - { - path = string.Format("{0}/Resources/XCSettings.asset", match.Replace('\\', '/')); - if (File.Exists(path)) - return path.Substring(path.IndexOf("/Assets/") + 1); - } - } - } - } - return null; - } -#endif - - public static bool AddCustomTheme(Theme theme) - { - if (theme == null) return false; - if (Instance == null || Instance.m_CustomThemes == null) return false; - if (!Instance.m_CustomThemes.Contains(theme)) - { - Instance.m_CustomThemes.Add(theme); -#if UNITY_EDITOR - EditorUtility.SetDirty(Instance); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); -#endif - return true; - } - return false; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/XCSettings.cs.meta b/Assets/XCharts/Runtime/Internal/XCSettings.cs.meta deleted file mode 100644 index 4fc72f2..0000000 --- a/Assets/XCharts/Runtime/Internal/XCSettings.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3694d869548264b718bdfc6c8009dcf1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/XCThemeMgr.cs b/Assets/XCharts/Runtime/Internal/XCThemeMgr.cs deleted file mode 100644 index 86c239c..0000000 --- a/Assets/XCharts/Runtime/Internal/XCThemeMgr.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using UnityEngine; -#if UNITY_EDITOR -using UnityEditor; -#endif -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - public static class XCThemeMgr - { - /// <summary> - /// 重新加载主题列表 - /// </summary> - public static void ReloadThemeList() - { - XChartsMgr.themes.Clear(); - XChartsMgr.themeNames.Clear(); - AddTheme(LoadTheme(ThemeType.Default)); - AddTheme(LoadTheme(ThemeType.Dark)); - if (XCSettings.Instance != null) - { - foreach (var theme in XCSettings.customThemes) - { - AddTheme(theme); - } - } - } - - public static void CheckReloadTheme() - { - if (XChartsMgr.themeNames.Count < 0) - ReloadThemeList(); - } - - public static void AddTheme(Theme theme) - { - if (theme == null) return; - if (!XChartsMgr.themes.ContainsKey(theme.themeName)) - { - XChartsMgr.themes.Add(theme.themeName, theme); - XChartsMgr.themeNames.Add(theme.themeName); - XChartsMgr.themeNames.Sort(); - } - } - - public static Theme GetTheme(ThemeType type) - { - return GetTheme(type.ToString()); - } - - public static Theme GetTheme(string themeName) - { - if (!XChartsMgr.themes.ContainsKey(themeName)) - { - return null; - } - return XChartsMgr.themes[themeName]; - } - - public static Theme LoadTheme(ThemeType type) - { - return LoadTheme(type.ToString()); - } - - public static Theme LoadTheme(string themeName) - { - var theme = Resources.Load<Theme>(XCSettings.THEME_ASSET_NAME_PREFIX + themeName); - if (theme == null) - theme = Resources.Load<Theme>(themeName); - return theme; - } - - public static List<string> GetAllThemeNames() - { - return XChartsMgr.themeNames; - } - - public static List<Theme> GetThemeList() - { - var list = new List<Theme>(); - foreach (var theme in XChartsMgr.themes.Values) - { - list.Add(theme); - } - return list; - } - - public static bool ContainsTheme(string themeName) - { - return XChartsMgr.themeNames.Contains(themeName); - } - - public static void SwitchTheme(BaseChart chart, string themeName) - { -#if UNITY_EDITOR - if (XChartsMgr.themes.Count == 0) - { - ReloadThemeList(); - } -#endif - if (!XChartsMgr.themes.ContainsKey(themeName)) - { - Debug.LogError("SwitchTheme ERROR: not exist theme:" + themeName); - return; - } - var target = XChartsMgr.themes[themeName]; - chart.UpdateTheme(target); - } - - public static bool ExportTheme(Theme theme, string themeNewName) - { -#if UNITY_EDITOR - var newtheme = Theme.EmptyTheme; - newtheme.CopyTheme(theme); - newtheme.themeType = ThemeType.Custom; - newtheme.themeName = themeNewName; - ExportTheme(newtheme); - return true; -#else - return false; -#endif - } - - public static bool ExportTheme(Theme theme) - { -#if UNITY_EDITOR - var themeAssetName = XCSettings.THEME_ASSET_NAME_PREFIX + theme.themeName; - var themeAssetPath = Application.dataPath + "/../" + XCSettings.THEME_ASSET_FOLDER; - if (!Directory.Exists(themeAssetPath)) - { - Directory.CreateDirectory(themeAssetPath); - } - var themeAssetFilePath = string.Format("{0}/{1}.asset", XCSettings.THEME_ASSET_FOLDER, themeAssetName); - AssetDatabase.CreateAsset(theme, themeAssetFilePath); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - return true; -#else - return false; -#endif - } - - public static string GetThemeAssetPath(string themeName) - { - return string.Format("{0}/{1}{2}.asset", XCSettings.THEME_ASSET_FOLDER, - XCSettings.THEME_ASSET_NAME_PREFIX, themeName); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/XCThemeMgr.cs.meta b/Assets/XCharts/Runtime/Internal/XCThemeMgr.cs.meta deleted file mode 100644 index 7ac9815..0000000 --- a/Assets/XCharts/Runtime/Internal/XCThemeMgr.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: faf4bcb5b4fa24f0782ab4737a448696 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Internal/XChartsMgr.cs b/Assets/XCharts/Runtime/Internal/XChartsMgr.cs deleted file mode 100644 index 69b9c21..0000000 --- a/Assets/XCharts/Runtime/Internal/XChartsMgr.cs +++ /dev/null @@ -1,317 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using UnityEngine; -using UnityEngine.SceneManagement; -#if UNITY_EDITOR -using UnityEditor; -#endif - -namespace XCharts.Runtime -{ - class XChartsVersion - { - public string version = ""; - public int date = 0; - public int checkdate = 0; - public string desc = ""; - public string homepage = ""; - } - - [ExecuteInEditMode] - public static class XChartsMgr - { - public static readonly string version = "3.0.1"; - public static readonly int versionDate = 20220616; - public static string fullVersion { get { return version + "-" + versionDate; } } - - internal static List<BaseChart> chartList = new List<BaseChart>(); - internal static Dictionary<string, Theme> themes = new Dictionary<string, Theme>(); - internal static List<string> themeNames = new List<string>(); - - static XChartsMgr() - { - SerieLabelPool.ClearAll(); - chartList.Clear(); - if (Resources.Load<XCSettings>("XCSettings")) - XCThemeMgr.ReloadThemeList(); - SceneManager.sceneUnloaded += OnSceneLoaded; - } - - static void OnSceneLoaded(Scene scene) - { - SerieLabelPool.ClearAll(); - } - - public static void AddChart(BaseChart chart) - { - var sameNameChart = GetChart(chart.chartName); - if (sameNameChart != null) - { - var path = ChartHelper.GetFullName(sameNameChart.transform); - Debug.LogError("A chart named `" + chart.chartName + "` already exists:" + path); - RemoveChart(chart.chartName); - } - if (!ContainsChart(chart)) - { - chartList.Add(chart); - } - } - - public static BaseChart GetChart(string chartName) - { - if (string.IsNullOrEmpty(chartName)) return null; - return chartList.Find(chart => chartName.Equals(chart.chartName)); - } - - public static List<BaseChart> GetCharts(string chartName) - { - if (string.IsNullOrEmpty(chartName)) return null; - return chartList.FindAll(chart => chartName.Equals(chart.chartName)); - } - - public static void RemoveChart(string chartName) - { - if (string.IsNullOrEmpty(chartName)) return; - chartList.RemoveAll(chart => chartName.Equals(chart.chartName)); - } - - public static bool ContainsChart(string chartName) - { - if (string.IsNullOrEmpty(chartName)) return false; - return GetCharts(chartName) != null; - } - - public static bool ContainsChart(BaseChart chart) - { - return chartList.Contains(chart); - } - - public static bool IsRepeatChartName(BaseChart chart, string chartName = null) - { - if (chartName == null) - chartName = chart.chartName; - if (string.IsNullOrEmpty(chartName)) - return false; - foreach (var temp in chartList) - { - if (temp != chart && chartName.Equals(temp.chartName)) - return true; - } - return false; - } - - public static string GetRepeatChartNameInfo(BaseChart chart, string chartName) - { - if (string.IsNullOrEmpty(chartName)) - return string.Empty; - string result = ""; - foreach (var temp in chartList) - { - if (temp != chart && chartName.Equals(temp.chartName)) - result += ChartHelper.GetFullName(temp.transform) + "\n"; - } - return result; - } - - public static void RemoveAllChartObject() - { - if (chartList.Count == 0) - { - return; - } - foreach (var chart in chartList) - { - if (chart != null) - chart.RebuildChartObject(); - } - } - -#if UNITY_EDITOR - public static string GetPackageFullPath() - { - string packagePath = Path.GetFullPath("Packages/com.monitor1394.xcharts"); - if (Directory.Exists(packagePath)) - { - return packagePath; - } - packagePath = Path.GetFullPath("Assets/.."); - if (Directory.Exists(packagePath)) - { - if (File.Exists(packagePath + "/Assets/Packages/XCharts/package.json")) - { - return packagePath + "/Assets/Packages/XCharts"; - } - - if (File.Exists(packagePath + "/Assets/XCharts/package.json")) - { - return packagePath + "/Assets/XCharts"; - } - - string[] matchingPaths = Directory.GetDirectories(packagePath, "XCharts", SearchOption.AllDirectories); - string path = ValidateLocation(matchingPaths, packagePath); - if (path != null) return Path.Combine(packagePath, path); - } - return null; - } - - private static string ValidateLocation(string[] paths, string projectPath) - { - for (int i = 0; i < paths.Length; i++) - { - if (File.Exists(paths[i] + "/package.json")) - { - string folderPath = paths[i].Replace(projectPath, ""); - folderPath = folderPath.TrimStart('\\', '/'); - return folderPath; - } - } - return null; - } - - [UnityEditor.Callbacks.DidReloadScripts] - static void OnEditorReload() - { - for (int i = chartList.Count - 1; i >= 0; i--) - { - var chart = chartList[i]; - if (chart == null) - { - chartList.RemoveAt(i); - } - else - { - chart.InitComponentHandlers(); - chart.InitSerieHandlers(); - } - } - } - - public static void EnableTextMeshPro() - { - DefineSymbolsUtil.AddGlobalDefine("dUI_TextMeshPro"); - RemoveAllChartObject(); - } - - public static void DisableTextMeshPro() - { - DefineSymbolsUtil.RemoveGlobalDefine("dUI_TextMeshPro"); - RemoveAllChartObject(); - } - - public static bool IsExistTMPAssembly() - { - -#if UNITY_2018_1_OR_NEWER - foreach (var assembly in UnityEditor.Compilation.CompilationPipeline.GetAssemblies(UnityEditor.Compilation.AssembliesType.Player)) - { - if (assembly.name.Equals("Unity.TextMeshPro")) return true; - } -#elif UNITY_2017_3_OR_NEWER - foreach (var assembly in UnityEditor.Compilation.CompilationPipeline.GetAssemblies()) - { - if (assembly.name.Equals("Unity.TextMeshPro")) return true; - } -#endif - return false; - } - - public static bool ModifyTMPRefence(bool removeTMP = false) - { - var packagePath = GetPackageFullPath(); - if (!ModifyTMPRefence(packagePath + "/Runtime/XCharts.Runtime.asmdef", removeTMP)) return false; - if (!ModifyTMPRefence(packagePath + "/Editor/XCharts.Editor.asmdef", removeTMP)) return false; - return true; - } - - private static bool ModifyTMPRefence(string asmdefPath, bool removeTMP = false) - { - if (!File.Exists(asmdefPath)) - { - Debug.LogError("AddTMPRefence ERROR: can't find: " + asmdefPath); - return false; - } - try - { - var dest = new List<string>(); - var refs = new List<string>(); - var lines = File.ReadAllLines(asmdefPath); - var referencesStart = false; - var addedTMP = false; - var removedTMP = false; - var tmpName = "\"Unity.TextMeshPro\""; - var refCount = 0; - foreach (var line in lines) - { - if (string.IsNullOrEmpty(line)) continue; - if (line.Contains("\"references\": [")) - { - dest.Add(line); - referencesStart = true; - } - else if (referencesStart) - { - if (line.Contains("],")) - { - referencesStart = false; - if (refCount > 0) - { - var old = dest[dest.Count - 1]; - if (old.EndsWith(",")) - dest[dest.Count - 1] = old.Substring(0, old.Length - 1); - } - if (!removeTMP && !refs.Contains(tmpName)) - { - if (refs.Count > 0) - dest[dest.Count - 1] = dest[dest.Count - 1] + ","; - dest.Add(" " + tmpName); - dest.Add(line); - addedTMP = true; - } - else - { - dest.Add(line); - } - } - else - { - if (removeTMP) - { - if (!line.Contains(tmpName)) - { - dest.Add(line); - refCount++; - } - else - { - removedTMP = true; - } - } - else - { - dest.Add(line); - refs.Add(line.Trim()); - } - } - } - else - { - dest.Add(line); - } - } - if (addedTMP || removedTMP) - { - File.WriteAllText(asmdefPath, string.Join("\n", dest.ToArray())); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - return true; - } - catch (System.Exception e) - { - Debug.LogError("AddTMPRefence ERROR:" + e.Message); - return false; - } - } -#endif - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Internal/XChartsMgr.cs.meta b/Assets/XCharts/Runtime/Internal/XChartsMgr.cs.meta deleted file mode 100644 index f86bdc6..0000000 --- a/Assets/XCharts/Runtime/Internal/XChartsMgr.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 953f0e846565c4086a4bcdc6bc14cf85 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie.meta b/Assets/XCharts/Runtime/Serie.meta deleted file mode 100644 index 01ece4f..0000000 --- a/Assets/XCharts/Runtime/Serie.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6db844a618e3c4634ac6c8afa60d4835 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Bar.meta b/Assets/XCharts/Runtime/Serie/Bar.meta deleted file mode 100644 index 924588f..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: db4db63725f6848e785146f5cf4bb657 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Bar/Bar.cs b/Assets/XCharts/Runtime/Serie/Bar/Bar.cs deleted file mode 100644 index 89ed702..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/Bar.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(BarHandler), true)] - [SerieConvert(typeof(Line), typeof(Pie))] - [RequireChartComponent(typeof(GridCoord))] - [DefaultAnimation(AnimationType.BottomToTop)] - [SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField("m_Ignore")] - public class Bar : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Bar>(serieName); - for (int i = 0; i < 5; i++) - { - chart.AddData(serie.index, UnityEngine.Random.Range(10, 90)); - } - return serie; - } - - public static Bar CovertSerie(Serie serie) - { - var newSerie = SerieHelper.CloneSerie<Bar>(serie); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Bar/Bar.cs.meta b/Assets/XCharts/Runtime/Serie/Bar/Bar.cs.meta deleted file mode 100644 index b13d9c4..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/Bar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cfb8051cfc49e4afabd94a11c5912c3e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs b/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs deleted file mode 100644 index d581809..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs +++ /dev/null @@ -1,436 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class BarHandler : SerieHandler<Bar> - { - List<List<SerieData>> m_StackSerieData = new List<List<SerieData>>(); - private GridCoord m_SerieGrid; - private float[] m_CapusleDefaultCornerRadius = new float[] { 1, 1, 1, 1 }; - - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category, - marker, itemFormatter, numericFormatter); - } - - public override void DrawSerie(VertexHelper vh) - { - DrawBarSerie(vh, serie, serie.context.colorIndex); - } - - public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) - { - switch (label.position) - { - case LabelStyle.Position.Bottom: - var center = serieData.context.rect.center; - return new Vector3(center.x, center.y - serieData.context.rect.height / 2); - case LabelStyle.Position.Center: - case LabelStyle.Position.Inside: - return serieData.context.rect.center; - default: - return serieData.context.position; - } - } - - public override void OnPointerDown(PointerEventData eventData) - { - if (!serie.context.pointerEnter) return; - if (serie.context.pointerItemDataIndex < 0) return; - if (chart.onPointerClickBar != null) - { - chart.onPointerClickBar(eventData, serie.context.pointerItemDataIndex); - } - } - - private void UpdateSerieContext() - { - if (m_SerieGrid == null) - return; - - var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter; - var needInteract = false; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - serieData.context.highlight = false; - serieData.interact.Reset(); - } - chart.RefreshPainter(serie); - } - return; - } - m_LastCheckContextFlag = needCheck; - if (m_LegendEnter) - { - serie.context.pointerEnter = true; - foreach (var serieData in serie.data) - { - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - } - else - { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - if (serie.context.pointerAxisDataIndexs.Contains(serieData.index) || - serieData.context.rect.Contains(chart.pointerPos)) - { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; - serieData.context.highlight = true; - - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - else - { - serieData.context.highlight = false; - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - } - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - private void DrawBarSerie(VertexHelper vh, Bar serie, int colorIndex) - { - if (!serie.show || serie.animation.HasFadeOut()) - return; - - var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); - - Axis axis; - Axis relativedAxis; - - if (isY) - { - axis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - relativedAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - } - else - { - axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - relativedAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - } - m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - - if (axis == null) - return; - if (relativedAxis == null) - return; - if (m_SerieGrid == null) - return; - var dataZoom = chart.GetDataZoomOfAxis(axis); - var showData = serie.GetDataList(dataZoom); - - if (showData.Count <= 0) - return; - - var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width; - var relativedAxisLength = isY ? m_SerieGrid.context.width : m_SerieGrid.context.height; - var axisXY = isY ? m_SerieGrid.context.y : m_SerieGrid.context.x; - - var isStack = SeriesHelper.IsStack<Bar>(chart.series, serie.stack); - if (isStack) - SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData); - - var barCount = chart.GetSerieBarRealCount<Bar>(); - float categoryWidth = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom); - float barGap = chart.GetSerieBarGap<Bar>(); - float totalBarWidth = chart.GetSerieTotalWidth<Bar>(categoryWidth, barGap, barCount); - float barWidth = serie.GetBarWidth(categoryWidth, barCount); - float offset = (categoryWidth - totalBarWidth) * 0.5f; - var serieReadIndex = chart.GetSerieIndexIfStack<Bar>(serie); - float gap = serie.barGap == -1 ? offset : offset + chart.GetSerieTotalGap<Bar>(categoryWidth, barGap, serieReadIndex); - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : - showData.Count; - var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series, serie.stack); - bool dataChanging = false; - float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double yMinValue = relativedAxis.context.minValue; - double yMaxValue = relativedAxis.context.maxValue; - - var areaColor = ColorUtil.clearColor32; - var areaToColor = ColorUtil.clearColor32; - var interacting = false; - - serie.containerIndex = m_SerieGrid.index; - serie.containterInstanceId = m_SerieGrid.instanceId; - serie.animation.InitProgress(axisXY, axisXY + axisLength); - for (int i = serie.minShow; i < maxCount; i++) - { - var serieData = showData[i]; - serieData.index = i; - if (!serieData.show || serie.IsIgnoreValue(serieData)) - { - serie.context.dataPoints.Add(Vector3.zero); - continue; - } - - if (serieData.IsDataChanged()) - dataChanging = true; - - var highlight = serieData.context.highlight || serie.highlight; - var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight); - var value = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse); - var relativedValue = serieData.GetCurrData(1, dataChangeDuration, relativedAxis.inverse, yMinValue, yMaxValue); - var borderWidth = relativedValue == 0 ? 0 : itemStyle.runtimeBorderWidth; - var borderGap = relativedValue == 0 ? 0 : itemStyle.borderGap; - var borderGapAndWidth = borderWidth + borderGap; - - if (!serieData.interact.TryGetColor(ref areaColor, ref areaToColor, ref interacting)) - { - areaColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, highlight); - areaToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, highlight); - serieData.interact.SetColor(ref interacting, areaColor, areaToColor); - } - - var pX = 0f; - var pY = 0f; - UpdateXYPosition(m_SerieGrid, isY, axis, relativedAxis, i, categoryWidth, barWidth, isStack, value, ref pX, ref pY); - var barHig = 0f; - if (isPercentStack) - { - var valueTotal = chart.GetSerieSameStackTotalValue<Bar>(serie.stack, i); - barHig = valueTotal != 0 ? (float) (relativedValue / valueTotal * relativedAxisLength) : 0; - } - else - { - barHig = AxisHelper.GetAxisValueLength(m_SerieGrid, relativedAxis, categoryWidth, relativedValue); - } - - float currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig); - Vector3 plb, plt, prt, prb, top; - UpdateRectPosition(m_SerieGrid, isY, relativedValue, pX, pY, gap, borderWidth, barWidth, currHig, - out plb, out plt, out prt, out prb, out top); - serieData.context.stackHeight = barHig; - serieData.context.position = top; - serieData.context.rect = Rect.MinMaxRect(plb.x + borderGapAndWidth, plb.y + borderGapAndWidth, - prt.x - borderGapAndWidth, prt.y - borderGapAndWidth); - serieData.context.backgroundRect = isY ? - Rect.MinMaxRect(m_SerieGrid.context.x, plb.y, m_SerieGrid.context.x + relativedAxisLength, prt.y) : - Rect.MinMaxRect(plb.x, m_SerieGrid.context.y, prb.x, m_SerieGrid.context.y + relativedAxisLength); - - if (!serie.clip || (serie.clip && m_SerieGrid.Contains(top))) - serie.context.dataPoints.Add(top); - else - continue; - - if (serie.show && currHig != 0 && !serie.placeHolder) - { - switch (serie.barType) - { - case BarType.Normal: - case BarType.Capsule: - DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, gap, barWidth, - pX, pY, plb, plt, prt, prb, isY, m_SerieGrid, axis, areaColor, areaToColor, relativedValue); - break; - case BarType.Zebra: - DrawZebraBar(vh, serie, serieData, itemStyle, colorIndex, highlight, gap, barWidth, - pX, pY, plb, plt, prt, prb, isY, m_SerieGrid, axis, areaColor, areaToColor); - break; - } - } - if (serie.animation.CheckDetailBreak(top, isY)) - { - break; - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - chart.RefreshPainter(serie); - } - if (dataChanging || interacting) - { - chart.RefreshPainter(serie); - } - } - - private void UpdateXYPosition(GridCoord grid, bool isY, Axis axis, Axis relativedAxis, int i, float categoryWidth, float barWidth, bool isStack, - double value, ref float pX, ref float pY) - { - if (isY) - { - if (axis.IsCategory()) - { - pY = grid.context.y + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f); - } - else - { - if (axis.context.minMaxRange <= 0) pY = grid.context.y; - else - { - var valueLen = (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * grid.context.height; - pY = grid.context.y + valueLen - categoryWidth * 0.5f; - } - } - pX = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0); - if (isStack) - { - for (int n = 0; n < m_StackSerieData.Count - 1; n++) - pX += m_StackSerieData[n][i].context.stackHeight; - } - } - else - { - if (axis.IsCategory()) - { - pX = grid.context.x + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f); - } - else - { - if (axis.context.minMaxRange <= 0) pX = grid.context.x; - else - { - var valueLen = (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * grid.context.width; - pX = grid.context.x + valueLen - categoryWidth * 0.5f; - } - } - pY = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0); - if (isStack) - { - for (int n = 0; n < m_StackSerieData.Count - 1; n++) - pY += m_StackSerieData[n][i].context.stackHeight; - } - } - } - - private void UpdateRectPosition(GridCoord grid, bool isY, double yValue, float pX, float pY, float gap, float borderWidth, - float barWidth, float currHig, - out Vector3 plb, out Vector3 plt, out Vector3 prt, out Vector3 prb, out Vector3 top) - { - if (isY) - { - if (yValue < 0) - { - plt = new Vector3(pX + currHig, pY + gap + barWidth); - prt = new Vector3(pX, pY + gap + barWidth); - prb = new Vector3(pX, pY + gap); - plb = new Vector3(pX + currHig, pY + gap); - } - else - { - plt = new Vector3(pX, pY + gap + barWidth); - prt = new Vector3(pX + currHig, pY + gap + barWidth); - prb = new Vector3(pX + currHig, pY + gap); - plb = new Vector3(pX, pY + gap); - } - top = new Vector3(pX + currHig, pY + gap + barWidth / 2); - } - else - { - if (yValue < 0) - { - plb = new Vector3(pX + gap, pY + currHig); - plt = new Vector3(pX + gap, pY); - prt = new Vector3(pX + gap + barWidth, pY); - prb = new Vector3(pX + gap + barWidth, pY + currHig); - } - else - { - plb = new Vector3(pX + gap, pY); - plt = new Vector3(pX + gap, pY + currHig); - prt = new Vector3(pX + gap + barWidth, pY + currHig); - prb = new Vector3(pX + gap + barWidth, pY); - } - top = new Vector3(pX + gap + barWidth / 2, pY + currHig); - } - if (serie.clip) - { - plb = chart.ClampInGrid(grid, plb); - plt = chart.ClampInGrid(grid, plt); - prt = chart.ClampInGrid(grid, prt); - prb = chart.ClampInGrid(grid, prb); - top = chart.ClampInGrid(grid, top); - } - } - - private void DrawNormalBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, - bool highlight, float gap, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt, - Vector3 prb, bool isYAxis, GridCoord grid, Axis axis, Color32 areaColor, Color32 areaToColor, double value) - { - var borderWidth = itemStyle.runtimeBorderWidth; - var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, colorIndex, highlight, false); - var cornerRadius = serie.barType == BarType.Capsule && !itemStyle.IsNeedCorner() ? - m_CapusleDefaultCornerRadius : - itemStyle.cornerRadius; - var invert = value < 0; - if (!ChartHelper.IsClearColor(backgroundColor)) - { - UGL.DrawRoundRectangle(vh, serieData.context.backgroundRect, backgroundColor, backgroundColor, 0, - cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert); - } - UGL.DrawRoundRectangle(vh, serieData.context.rect, areaColor, areaToColor, 0, - cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert); - if (serie.barType == BarType.Capsule) - { - UGL.DrawBorder(vh, serieData.context.backgroundRect, borderWidth, itemStyle.borderColor, - 0, cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert, -borderWidth); - } - else - { - UGL.DrawBorder(vh, serieData.context.rect, borderWidth, itemStyle.borderColor, - 0, cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert, itemStyle.borderGap); - } - } - - private void DrawZebraBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, - bool highlight, float gap, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt, - Vector3 prb, bool isYAxis, GridCoord grid, Axis axis, Color32 barColor, Color32 barToColor) - { - var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, colorIndex, highlight, false); - if (!ChartHelper.IsClearColor(backgroundColor)) - { - UGL.DrawRoundRectangle(vh, serieData.context.backgroundRect, backgroundColor, backgroundColor, 0, - null, isYAxis, chart.settings.cicleSmoothness, false); - } - if (isYAxis) - { - plt = (plb + plt) / 2; - prt = (prt + prb) / 2; - chart.DrawClipZebraLine(vh, plt, prt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap, - barColor, barToColor, serie.clip, grid, grid.context.width); - } - else - { - plb = (prb + plb) / 2; - plt = (plt + prt) / 2; - chart.DrawClipZebraLine(vh, plb, plt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap, - barColor, barToColor, serie.clip, grid, grid.context.height); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs.meta deleted file mode 100644 index 68b7310..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5bd8425bf4c1b4bf2adf8940be58ddec -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs b/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs deleted file mode 100644 index 3eed9ff..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - [SerieHandler(typeof(SimplifiedBarHandler), true)] - [SerieConvert(typeof(SimplifiedLine), typeof(Bar))] - [CoordOptions(typeof(GridCoord))] - [DefaultAnimation(AnimationType.LeftToRight)] - [SerieExtraComponent()] - [SerieDataExtraComponent()] - [SerieDataExtraField()] - public class SimplifiedBar : Serie, INeedSerieContainer, ISimplifiedSerie - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<SimplifiedBar>(serieName); - serie.symbol.show = false; - var lastValue = 0d; - for (int i = 0; i < 50; i++) - { - if (i < 20) - lastValue += UnityEngine.Random.Range(0, 5); - else - lastValue += UnityEngine.Random.Range(-3, 5); - chart.AddData(serie.index, lastValue); - } - return serie; - } - - public static SimplifiedBar CovertSerie(Serie serie) - { - var newSerie = serie.Clone<SimplifiedBar>(); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs.meta b/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs.meta deleted file mode 100644 index d6b3a10..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7fc754e0afd4d4f138389c19611aaedb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs b/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs deleted file mode 100644 index 3e4264d..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs +++ /dev/null @@ -1,368 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class SimplifiedBarHandler : SerieHandler<SimplifiedBar> - { - private GridCoord m_SerieGrid; - - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category, - marker, itemFormatter, numericFormatter); - } - - public override void DrawSerie(VertexHelper vh) - { - DrawBarSerie(vh, serie, serie.context.colorIndex); - } - - private void UpdateSerieContext() - { - if (m_SerieGrid == null) - return; - - var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter; - var needInteract = false; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - return; - } - m_LastCheckContextFlag = needCheck; - if (m_LegendEnter) - { - serie.context.pointerEnter = true; - foreach (var serieData in serie.data) - { - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - } - else - { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - if (serieData.context.rect.Contains(chart.pointerPos)) - { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; - serieData.context.highlight = true; - - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - else - { - serieData.context.highlight = false; - var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - serieData.interact.SetColor(ref needInteract, barColor, barToColor); - } - } - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - private void DrawBarSerie(VertexHelper vh, SimplifiedBar serie, int colorIndex) - { - if (!serie.show || serie.animation.HasFadeOut()) - return; - - var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); - - Axis axis; - Axis relativedAxis; - - if (isY) - { - axis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - relativedAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - } - else - { - axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - relativedAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - } - m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - - if (axis == null) - return; - if (relativedAxis == null) - return; - if (m_SerieGrid == null) - return; - - var dataZoom = chart.GetDataZoomOfAxis(axis); - var showData = serie.GetDataList(dataZoom); - - if (showData.Count <= 0) - return; - - var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width; - var axisXY = isY ? m_SerieGrid.context.y : m_SerieGrid.context.x; - - var barCount = chart.GetSerieBarRealCount<SimplifiedBar>(); - float categoryWidth = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom); - float barGap = chart.GetSerieBarGap<SimplifiedBar>(); - float totalBarWidth = chart.GetSerieTotalWidth<SimplifiedBar>(categoryWidth, barGap, barCount); - float barWidth = serie.GetBarWidth(categoryWidth, barCount); - float offset = (categoryWidth - totalBarWidth) * 0.5f; - float barGapWidth = barWidth + barWidth * barGap; - float gap = serie.barGap == -1 ? offset : offset + serie.index * barGapWidth; - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : - showData.Count; - - bool dataChanging = false; - float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double yMinValue = relativedAxis.context.minValue; - double yMaxValue = relativedAxis.context.maxValue; - - var areaColor = ColorUtil.clearColor32; - var areaToColor = ColorUtil.clearColor32; - var interacting = false; - - serie.containerIndex = m_SerieGrid.index; - serie.containterInstanceId = m_SerieGrid.instanceId; - serie.animation.InitProgress(axisXY, axisXY + axisLength); - for (int i = serie.minShow; i < maxCount; i++) - { - var serieData = showData[i]; - if (!serieData.show || serie.IsIgnoreValue(serieData)) - { - serie.context.dataPoints.Add(Vector3.zero); - continue; - } - - if (serieData.IsDataChanged()) - dataChanging = true; - - var highlight = serieData.context.highlight || serie.highlight; - var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight); - var value = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse); - var relativedValue = serieData.GetCurrData(1, dataChangeDuration, relativedAxis.inverse, yMinValue, yMaxValue); - var borderWidth = relativedValue == 0 ? 0 : itemStyle.runtimeBorderWidth; - - if (!serieData.interact.TryGetColor(ref areaColor, ref areaToColor, ref interacting)) - { - areaColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, highlight); - areaToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, highlight); - serieData.interact.SetColor(ref interacting, areaColor, areaToColor); - } - - var pX = 0f; - var pY = 0f; - UpdateXYPosition(m_SerieGrid, isY, axis, relativedAxis, i, categoryWidth, barWidth, value, ref pX, ref pY); - - var barHig = AxisHelper.GetAxisValueLength(m_SerieGrid, relativedAxis, categoryWidth, relativedValue); - var currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig); - - Vector3 plb, plt, prt, prb, top; - UpdateRectPosition(m_SerieGrid, isY, relativedValue, pX, pY, gap, borderWidth, barWidth, currHig, - out plb, out plt, out prt, out prb, out top); - serieData.context.stackHeight = barHig; - serieData.context.position = top; - serieData.context.rect = Rect.MinMaxRect(plb.x, plb.y, prb.x, prt.y); - serie.context.dataPoints.Add(top); - DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, gap, barWidth, - pX, pY, plb, plt, prt, prb, false, m_SerieGrid, areaColor, areaToColor); - - if (serie.animation.CheckDetailBreak(top, isY)) - { - break; - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - chart.RefreshPainter(serie); - } - if (dataChanging || interacting) - { - chart.RefreshPainter(serie); - } - } - - private void UpdateXYPosition(GridCoord grid, bool isY, Axis axis, Axis relativedAxis, int i, float categoryWidth, float barWidth, - double value, ref float pX, ref float pY) - { - if (isY) - { - if (axis.IsCategory()) - { - pY = grid.context.y + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f); - } - else - { - if (axis.context.minMaxRange <= 0) pY = grid.context.y; - else pY = grid.context.y + (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * (grid.context.height - barWidth); - } - pX = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0); - } - else - { - if (axis.IsCategory()) - { - pX = grid.context.x + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f); - } - else - { - if (axis.context.minMaxRange <= 0) pX = grid.context.x; - else pX = grid.context.x + (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * (grid.context.width - barWidth); - } - pY = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0); - } - } - - private void UpdateRectPosition(GridCoord grid, bool isY, double yValue, float pX, float pY, float gap, float borderWidth, - float barWidth, float currHig, - out Vector3 plb, out Vector3 plt, out Vector3 prt, out Vector3 prb, out Vector3 top) - { - if (isY) - { - if (yValue < 0) - { - plt = new Vector3(pX - borderWidth, pY + gap + barWidth - borderWidth); - prt = new Vector3(pX + currHig + borderWidth, pY + gap + barWidth - borderWidth); - prb = new Vector3(pX + currHig + borderWidth, pY + gap + borderWidth); - plb = new Vector3(pX - borderWidth, pY + gap + borderWidth); - } - else - { - plt = new Vector3(pX + borderWidth, pY + gap + barWidth - borderWidth); - prt = new Vector3(pX + currHig - borderWidth, pY + gap + barWidth - borderWidth); - prb = new Vector3(pX + currHig - borderWidth, pY + gap + borderWidth); - plb = new Vector3(pX + borderWidth, pY + gap + borderWidth); - } - top = new Vector3(pX + currHig - borderWidth, pY + gap + barWidth / 2); - } - else - { - if (yValue < 0) - { - plb = new Vector3(pX + gap + borderWidth, pY - borderWidth); - plt = new Vector3(pX + gap + borderWidth, pY + currHig + borderWidth); - prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig + borderWidth); - prb = new Vector3(pX + gap + barWidth - borderWidth, pY - borderWidth); - } - else - { - plb = new Vector3(pX + gap + borderWidth, pY + borderWidth); - plt = new Vector3(pX + gap + borderWidth, pY + currHig - borderWidth); - prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig - borderWidth); - prb = new Vector3(pX + gap + barWidth - borderWidth, pY + borderWidth); - } - top = new Vector3(pX + gap + barWidth / 2, pY + currHig - borderWidth); - } - if (serie.clip) - { - plb = chart.ClampInGrid(grid, plb); - plt = chart.ClampInGrid(grid, plt); - prt = chart.ClampInGrid(grid, prt); - prb = chart.ClampInGrid(grid, prb); - top = chart.ClampInGrid(grid, top); - } - } - - private void DrawNormalBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, - bool highlight, float gap, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt, - Vector3 prb, bool isYAxis, GridCoord grid, Color32 areaColor, Color32 areaToColor) - { - - var borderWidth = itemStyle.runtimeBorderWidth; - if (isYAxis) - { - if (serie.clip) - { - prb = chart.ClampInGrid(grid, prb); - plb = chart.ClampInGrid(grid, plb); - plt = chart.ClampInGrid(grid, plt); - prt = chart.ClampInGrid(grid, prt); - } - var itemWidth = Mathf.Abs(prb.x - plt.x); - var itemHeight = Mathf.Abs(prt.y - plb.y); - var center = new Vector3((plt.x + prb.x) / 2, (prt.y + plb.y) / 2); - if (itemWidth > 0 && itemHeight > 0) - { - var invert = center.x < plb.x; - if (itemStyle.IsNeedCorner()) - { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaToColor, 0, - itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert); - } - else - { - chart.DrawClipPolygon(vh, plb, plt, prt, prb, areaColor, areaToColor, serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor, - itemStyle.borderToColor, 0, itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert); - } - } - else - { - if (serie.clip) - { - prb = chart.ClampInGrid(grid, prb); - plb = chart.ClampInGrid(grid, plb); - plt = chart.ClampInGrid(grid, plt); - prt = chart.ClampInGrid(grid, prt); - } - var itemWidth = Mathf.Abs(prt.x - plb.x); - var itemHeight = Mathf.Abs(plt.y - prb.y); - var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2); - if (itemWidth > 0 && itemHeight > 0) - { - var invert = center.y < plb.y; - if (itemStyle.IsNeedCorner()) - { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaToColor, 0, - itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert); - } - else - { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaToColor, - serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor, - itemStyle.borderToColor, 0, itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs.meta deleted file mode 100644 index 86f252e..0000000 --- a/Assets/XCharts/Runtime/Serie/Bar/SimplifiedBarHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: afd7226ecff7f4b9fad297101bc33b8c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Candlestick.meta b/Assets/XCharts/Runtime/Serie/Candlestick.meta deleted file mode 100644 index 0cc9989..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 641a5dafd45e6455ca9ef9558efe1083 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs b/Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs deleted file mode 100644 index 6ac985e..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs +++ /dev/null @@ -1,30 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(CandlestickHandler), true)] - [DefaultAnimation(AnimationType.LeftToRight)] - [SerieExtraComponent()] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(EmphasisItemStyle))] - [SerieDataExtraField()] - public class Candlestick : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Candlestick>(serieName); - var defaultDataCount = 5; - for (int i = 0; i < defaultDataCount; i++) - { - var open = Random.Range(20, 60); - var close = Random.Range(40, 90); - var lowest = Random.Range(0, 50); - var heighest = Random.Range(50, 100); - chart.AddData(serie.index, open, close, lowest, heighest); - } - return serie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs.meta b/Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs.meta deleted file mode 100644 index 4c84a79..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/Candlestick.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c1fbb6247f54f4dd2a1f3e7f6bafb8c7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs deleted file mode 100644 index 7955f60..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class CandlestickHandler : SerieHandler<Candlestick> - { - public override void DrawSerie(VertexHelper vh) - { - DrawCandlestickSerie(vh, serie); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - if (dataIndex < 0) - dataIndex = serie.context.pointerItemDataIndex; - - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - title = category; - - var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - var newMarker = SerieHelper.GetItemMarker(serie, serieData, marker); - var newItemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - var newNumericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.category = category; - param.dimension = 1; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = 0; - param.total = 0; - param.color = color; - param.marker = newMarker; - param.itemFormatter = newItemFormatter; - param.numericFormatter = newNumericFormatter; - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(serie.serieName); - param.columns.Add(string.Empty); - - paramList.Add(param); - for (int i = 0; i < 4; i++) - { - param = new SerieParams(); - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.dimension = i; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = serieData.GetData(i); - param.total = SerieHelper.GetMaxData(serie, i); - param.color = color; - param.marker = newMarker; - param.itemFormatter = newItemFormatter; - param.numericFormatter = newNumericFormatter; - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i)); - param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); - - paramList.Add(param); - } - } - - private void DrawCandlestickSerie(VertexHelper vh, Candlestick serie) - { - if (!serie.show) return; - if (serie.animation.HasFadeOut()) return; - XAxis xAxis; - YAxis yAxis; - GridCoord grid; - if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) return; - if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) return; - if (!chart.TryGetChartComponent<GridCoord>(out grid, xAxis.gridIndex)) return; - var theme = chart.theme; - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - var showData = serie.GetDataList(dataZoom); - float categoryWidth = AxisHelper.GetDataWidth(xAxis, grid.context.width, showData.Count, dataZoom); - float barWidth = serie.GetBarWidth(categoryWidth); - float gap = (categoryWidth - barWidth) / 2; - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : - showData.Count; - - bool dataChanging = false; - float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double yMinValue = yAxis.context.minValue; - double yMaxValue = yAxis.context.maxValue; - var isYAxis = false; - serie.containerIndex = grid.index; - serie.containterInstanceId = grid.instanceId; - for (int i = serie.minShow; i < maxCount; i++) - { - var serieData = showData[i]; - if (serie.IsIgnoreValue(serieData)) - { - serie.context.dataPoints.Add(Vector3.zero); - continue; - } - var highlight = serie.data[i].context.highlight || serie.highlight; - var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight); - var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var isRise = yAxis.inverse ? close<open : close> open; - var borderWidth = open == 0 ? 0f : - (itemStyle.runtimeBorderWidth == 0 ? theme.serie.candlestickBorderWidth : - itemStyle.runtimeBorderWidth); - if (serieData.IsDataChanged()) dataChanging = true; - float pX = grid.context.x + i * categoryWidth; - float zeroY = grid.context.y + yAxis.context.offset; - if (!xAxis.boundaryGap) pX -= categoryWidth / 2; - float pY = zeroY; - var barHig = 0f; - double valueTotal = yMaxValue - yMinValue; - var minCut = (yMinValue > 0 ? yMinValue : 0); - if (valueTotal != 0) - { - barHig = (float) ((close - open) / valueTotal * grid.context.height); - pY += (float) ((open - minCut) / valueTotal * grid.context.height); - } - serieData.context.stackHeight = barHig; - float currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig); - Vector3 plb, plt, prt, prb, top; - - plb = new Vector3(pX + gap + borderWidth, pY + borderWidth); - plt = new Vector3(pX + gap + borderWidth, pY + currHig - borderWidth); - prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig - borderWidth); - prb = new Vector3(pX + gap + barWidth - borderWidth, pY + borderWidth); - top = new Vector3(pX + gap + barWidth / 2, pY + currHig - borderWidth); - if (serie.clip) - { - plb = chart.ClampInGrid(grid, plb); - plt = chart.ClampInGrid(grid, plt); - prt = chart.ClampInGrid(grid, prt); - prb = chart.ClampInGrid(grid, prb); - top = chart.ClampInGrid(grid, top); - } - serie.context.dataPoints.Add(top); - var areaColor = isRise ? - itemStyle.GetColor(theme.serie.candlestickColor) : - itemStyle.GetColor0(theme.serie.candlestickColor0); - var borderColor = isRise ? - itemStyle.GetBorderColor(theme.serie.candlestickBorderColor) : - itemStyle.GetBorderColor0(theme.serie.candlestickBorderColor0); - var itemWidth = Mathf.Abs(prt.x - plb.x); - var itemHeight = Mathf.Abs(plt.y - prb.y); - var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2); - var lowPos = new Vector3(center.x, zeroY + (float) ((lowest - minCut) / valueTotal * grid.context.height)); - var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height)); - var openCenterPos = new Vector3(center.x, prb.y); - var closeCenterPos = new Vector3(center.x, prt.y); - if (barWidth > 2f * borderWidth) - { - if (itemWidth > 0 && itemHeight > 0) - { - if (itemStyle.IsNeedCorner()) - { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - else - { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, - serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - } - else - { - UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); - } - if (isRise) - { - UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); - } - else - { - UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - } - if (dataChanging) - { - chart.RefreshPainter(serie); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs.meta deleted file mode 100644 index d9bbb9d..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6d530c536c5784f2593e9a7c5a57df16 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs b/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs deleted file mode 100644 index 820b00a..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs +++ /dev/null @@ -1,39 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(SimplifiedCandlestickHandler), true)] - [DefaultAnimation(AnimationType.LeftToRight)] - [SerieExtraComponent()] - [SerieDataExtraComponent()] - [SerieDataExtraField()] - public class SimplifiedCandlestick : Serie, INeedSerieContainer, ISimplifiedSerie - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<SimplifiedCandlestick>(serieName); - - var lastValue = 50d; - for (int i = 0; i < 50; i++) - { - lastValue += UnityEngine.Random.Range(-10, 20); - var open = lastValue + Random.Range(-10, 5); - var close = lastValue + Random.Range(-5, 10); - var lowest = lastValue + Random.Range(-15, -10); - var heighest = lastValue + Random.Range(10, 20); - chart.AddData(serie.index, open, close, lowest, heighest); - } - return serie; - } - - public static SimplifiedCandlestick CovertSerie(Serie serie) - { - var newSerie = serie.Clone<SimplifiedCandlestick>(); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs.meta b/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs.meta deleted file mode 100644 index 682a2ba..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestick.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1202f0da64c484488bb69b8382af9918 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs b/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs deleted file mode 100644 index 455f600..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class SimplifiedCandlestickHandler : SerieHandler<SimplifiedCandlestick> - { - public override void DrawSerie(VertexHelper vh) - { - DrawCandlestickSerie(vh, serie); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - if (dataIndex < 0) - dataIndex = serie.context.pointerItemDataIndex; - - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - title = category; - - var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - var newMarker = SerieHelper.GetItemMarker(serie, serieData, marker); - var newItemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - var newNumericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.category = category; - param.dimension = 1; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = 0; - param.total = 0; - param.color = color; - param.marker = newMarker; - param.itemFormatter = newItemFormatter; - param.numericFormatter = newNumericFormatter; - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(serie.serieName); - param.columns.Add(string.Empty); - - paramList.Add(param); - for (int i = 0; i < 4; i++) - { - param = new SerieParams(); - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.dimension = i; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = serieData.GetData(i); - param.total = SerieHelper.GetMaxData(serie, i); - param.color = color; - param.marker = newMarker; - param.itemFormatter = newItemFormatter; - param.numericFormatter = newNumericFormatter; - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i)); - param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); - - paramList.Add(param); - } - } - - private void DrawCandlestickSerie(VertexHelper vh, SimplifiedCandlestick serie) - { - if (!serie.show) return; - if (serie.animation.HasFadeOut()) return; - XAxis xAxis; - YAxis yAxis; - GridCoord grid; - if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) return; - if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) return; - if (!chart.TryGetChartComponent<GridCoord>(out grid, xAxis.gridIndex)) return; - var theme = chart.theme; - var dataZoom = chart.GetDataZoomOfAxis(xAxis); - var showData = serie.GetDataList(dataZoom); - float categoryWidth = AxisHelper.GetDataWidth(xAxis, grid.context.width, showData.Count, dataZoom); - float barWidth = serie.GetBarWidth(categoryWidth); - float gap = (categoryWidth - barWidth) / 2; - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : - showData.Count; - - bool dataChanging = false; - float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double yMinValue = yAxis.context.minValue; - double yMaxValue = yAxis.context.maxValue; - var isYAxis = false; - var itemStyle = serie.itemStyle; - serie.containerIndex = grid.index; - serie.containterInstanceId = grid.instanceId; - - for (int i = serie.minShow; i < maxCount; i++) - { - var serieData = showData[i]; - if (serie.IsIgnoreValue(serieData)) - { - serie.context.dataPoints.Add(Vector3.zero); - continue; - } - var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue); - var isRise = yAxis.inverse ? close<open : close> open; - var borderWidth = open == 0 ? 0f : - (itemStyle.runtimeBorderWidth == 0 ? theme.serie.candlestickBorderWidth : - itemStyle.runtimeBorderWidth); - if (serieData.IsDataChanged()) dataChanging = true; - float pX = grid.context.x + i * categoryWidth; - float zeroY = grid.context.y + yAxis.context.offset; - if (!xAxis.boundaryGap) pX -= categoryWidth / 2; - float pY = zeroY; - var barHig = 0f; - double valueTotal = yMaxValue - yMinValue; - var minCut = (yMinValue > 0 ? yMinValue : 0); - if (valueTotal != 0) - { - barHig = (float) ((close - open) / valueTotal * grid.context.height); - pY += (float) ((open - minCut) / valueTotal * grid.context.height); - } - serieData.context.stackHeight = barHig; - float currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig); - Vector3 plb, plt, prt, prb, top; - - plb = new Vector3(pX + gap + borderWidth, pY + borderWidth); - plt = new Vector3(pX + gap + borderWidth, pY + currHig - borderWidth); - prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig - borderWidth); - prb = new Vector3(pX + gap + barWidth - borderWidth, pY + borderWidth); - top = new Vector3(pX + gap + barWidth / 2, pY + currHig - borderWidth); - // if (serie.clip) - // { - // plb = chart.ClampInGrid(grid, plb); - // plt = chart.ClampInGrid(grid, plt); - // prt = chart.ClampInGrid(grid, prt); - // prb = chart.ClampInGrid(grid, prb); - // top = chart.ClampInGrid(grid, top); - // } - serie.context.dataPoints.Add(top); - var areaColor = isRise ? - itemStyle.GetColor(theme.serie.candlestickColor) : - itemStyle.GetColor0(theme.serie.candlestickColor0); - var borderColor = isRise ? - itemStyle.GetBorderColor(theme.serie.candlestickBorderColor) : - itemStyle.GetBorderColor0(theme.serie.candlestickBorderColor0); - var itemWidth = Mathf.Abs(prt.x - plb.x); - var itemHeight = Mathf.Abs(plt.y - prb.y); - var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2); - var lowPos = new Vector3(center.x, zeroY + (float) ((lowest - minCut) / valueTotal * grid.context.height)); - var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height)); - var openCenterPos = new Vector3(center.x, prb.y); - var closeCenterPos = new Vector3(center.x, prt.y); - if (barWidth > 2f * borderWidth) - { - if (itemWidth > 0 && itemHeight > 0) - { - if (itemStyle.IsNeedCorner()) - { - UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - else - { - chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor, - serie.clip, grid); - } - UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0, - itemStyle.cornerRadius, isYAxis, 0.5f); - } - if (isRise) - { - UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor); - } - else - { - UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor); - UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor); - } - } - else - { - UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor); - } - - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - } - if (dataChanging) - { - chart.RefreshPainter(serie); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs.meta deleted file mode 100644 index 998419c..0000000 --- a/Assets/XCharts/Runtime/Serie/Candlestick/SimplifiedCandlestickHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 42727a035319b4eab92ddf0742630115 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Heatmap.meta b/Assets/XCharts/Runtime/Serie/Heatmap.meta deleted file mode 100644 index ccda235..0000000 --- a/Assets/XCharts/Runtime/Serie/Heatmap.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 70535a50c140c47cc8cac1820dc03170 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs b/Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs deleted file mode 100644 index 9d71356..0000000 --- a/Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs +++ /dev/null @@ -1,30 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(HeatmapHandler), true)] - [DefaultAnimation(AnimationType.LeftToRight)] - [RequireChartComponent(typeof(VisualMap))] - [SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField()] - public class Heatmap : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Heatmap>(serieName); - serie.itemStyle.show = true; - serie.itemStyle.borderWidth = 1; - serie.itemStyle.borderColor = Color.clear; - - var emphasis = serie.AddExtraComponent<EmphasisItemStyle>(); - emphasis.show = true; - emphasis.borderWidth = 1; - emphasis.borderColor = Color.black; - return serie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs.meta b/Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs.meta deleted file mode 100644 index 1c06a6d..0000000 --- a/Assets/XCharts/Runtime/Serie/Heatmap/Heatmap.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2a9984972d3c74a01945c4064739a826 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs b/Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs deleted file mode 100644 index 517033f..0000000 --- a/Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class HeatmapHandler : SerieHandler<Heatmap> - { - private GridCoord m_SerieGrid; - - public override int defaultDimension { get { return 2; } } - - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void DrawSerie(VertexHelper vh) - { - DrawHeatmapSerie(vh, serie); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - dataIndex = serie.context.pointerItemDataIndex; - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - if (string.IsNullOrEmpty(category)) - { - var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - if (xAxis != null) - category = xAxis.GetData((int) serieData.GetData(0)); - } - - title = serie.serieName; - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.dimension = defaultDimension; - param.dataCount = serie.dataCount; - param.serieData = serieData; - param.color = serieData.context.color; - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(category); - param.columns.Add(ChartCached.NumberToStr(serieData.GetData(defaultDimension), param.numericFormatter)); - - paramList.Add(param); - } - - private void UpdateSerieContext() - { - if (m_SerieGrid == null) - return; - - var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter; - var needInteract = false; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - serieData.context.highlight = false; - } - chart.RefreshPainter(serie); - } - return; - } - m_LastCheckContextFlag = needCheck; - if (m_LegendEnter) - { - serie.context.pointerEnter = true; - foreach (var serieData in serie.data) - { - serieData.context.highlight = true; - } - } - else - { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - if (!needInteract && serieData.context.rect.Contains(chart.pointerPos)) - { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; - serieData.context.highlight = true; - needInteract = true; - } - else - { - serieData.context.highlight = false; - } - } - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie) - { - if (serie.animation.HasFadeOut()) return; - XAxis xAxis; - YAxis yAxis; - if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) return; - if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) return; - m_SerieGrid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex); - xAxis.boundaryGap = true; - yAxis.boundaryGap = true; - var visualMap = chart.GetVisualMapOfSerie(serie); - var emphasisItemStyle = serie.emphasisItemStyle; - var xCount = xAxis.data.Count; - var yCount = yAxis.data.Count; - var xWidth = m_SerieGrid.context.width / xCount; - var yWidth = m_SerieGrid.context.height / yCount; - - var zeroX = m_SerieGrid.context.x; - var zeroY = m_SerieGrid.context.y; - var rangeMin = visualMap.rangeMin; - var rangeMax = visualMap.rangeMax; - var color = chart.theme.GetColor(serie.index); - var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0; - var rectWid = xWidth - 2 * borderWidth; - var rectHig = yWidth - 2 * borderWidth; - - var borderColor = serie.itemStyle.opacity > 0 ? - serie.itemStyle.borderColor : - ChartConst.clearColor32; - borderColor.a = (byte) (borderColor.a * serie.itemStyle.opacity); - - var borderToColor = serie.itemStyle.opacity > 0 ? - serie.itemStyle.borderToColor : - ChartConst.clearColor32; - borderToColor.a = (byte) (borderToColor.a * serie.itemStyle.opacity); - - serie.context.dataPoints.Clear(); - serie.animation.InitProgress(0, xCount); - var animationIndex = serie.animation.GetCurrIndex(); - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var dataChanging = false; - serie.containerIndex = m_SerieGrid.index; - serie.containterInstanceId = m_SerieGrid.instanceId; - for (int n = 0; n < serie.dataCount; n++) - { - var serieData = serie.data[n]; - serieData.index = n; - var i = (int) serieData.GetData(0); - var j = (int) serieData.GetData(1); - var dimension = VisualMapHelper.GetDimension(visualMap, serieData.data.Count); - if (serie.IsIgnoreValue(serieData, dimension)) - { - serie.context.dataPoints.Add(Vector3.zero); - continue; - } - var value = serieData.GetCurrData(dimension, dataChangeDuration, yAxis.inverse, - yAxis.context.minValue, yAxis.context.maxValue); - if (serieData.IsDataChanged()) dataChanging = true; - var pos = new Vector3(zeroX + (i + (xAxis.boundaryGap ? 0.5f : 0)) * xWidth, - zeroY + (j + (yAxis.boundaryGap ? 0.5f : 0)) * yWidth); - serie.context.dataPoints.Add(pos); - serieData.context.position = pos; - - serieData.context.canShowLabel = false; - serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig); - if (value == 0) continue; - if ((value < rangeMin && rangeMin != visualMap.min) || - (value > rangeMax && rangeMax != visualMap.max)) - { - continue; - } - if (!visualMap.IsInSelectedValue(value)) continue; - if (animationIndex >= 0 && i > animationIndex) continue; - color = visualMap.GetColor(value); - if (serieData.context.highlight) - color = ChartHelper.GetHighlightColor(color); - - serieData.context.canShowLabel = true; - serieData.context.color = color; - - var highlight = (serieData.context.highlight) || - visualMap.context.pointerIndex > 0; - - //UGL.DrawRectangle(vh, pos, rectWid / 2, rectHig / 2, color); - UGL.DrawRectangle(vh, serieData.context.rect, color); - - if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor)) - { - UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor); - } - if (visualMap.hoverLink && highlight && emphasisItemStyle != null && - emphasisItemStyle.borderWidth > 0) - { - var emphasisBorderWidth = emphasisItemStyle.borderWidth; - var emphasisBorderColor = emphasisItemStyle.opacity > 0 ? - emphasisItemStyle.borderColor : ChartConst.clearColor32; - var emphasisBorderToColor = emphasisItemStyle.opacity > 0 ? - emphasisItemStyle.borderToColor : ChartConst.clearColor32; - UGL.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor, - emphasisBorderToColor); - } - - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(xCount); - chart.RefreshPainter(serie); - } - if (dataChanging) - { - chart.RefreshPainter(serie); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs.meta deleted file mode 100644 index 2a731f5..0000000 --- a/Assets/XCharts/Runtime/Serie/Heatmap/HeatmapHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a5cd70274da44d50b48fc04d8b52e21 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line.meta b/Assets/XCharts/Runtime/Serie/Line.meta deleted file mode 100644 index 2f308b9..0000000 --- a/Assets/XCharts/Runtime/Serie/Line.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 61f1a04d9920849e7861bebdfd070384 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/Line.cs b/Assets/XCharts/Runtime/Serie/Line/Line.cs deleted file mode 100644 index d504f13..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/Line.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [Serializable] - [SerieHandler(typeof(LineHandler), true)] - [SerieConvert(typeof(Bar), typeof(Pie))] - [CoordOptions(typeof(GridCoord), typeof(PolarCoord))] - [DefaultAnimation(AnimationType.LeftToRight)] - [SerieExtraComponent( - typeof(LabelStyle), - typeof(EndLabelStyle), - typeof(LineArrow), - typeof(AreaStyle), - typeof(EmphasisItemStyle), - typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent( - typeof(ItemStyle), - typeof(LabelStyle), - typeof(SerieSymbol), - typeof(EmphasisItemStyle), - typeof(EmphasisLabelStyle))] - [SerieDataExtraField("m_Ignore")] - public class Line : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Line>(serieName); - serie.symbol.show = true; - for (int i = 0; i < 5; i++) - { - chart.AddData(serie.index, UnityEngine.Random.Range(10, 90)); - } - return serie; - } - - public static Line CovertSerie(Serie serie) - { - var newSerie = serie.Clone<Line>(); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/Line.cs.meta b/Assets/XCharts/Runtime/Serie/Line/Line.cs.meta deleted file mode 100644 index b88d15c..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/Line.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 883eff3dc77e0439a80d257577790cbc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs deleted file mode 100644 index ff00839..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ /dev/null @@ -1,436 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - /// <summary> - /// For grid coord - /// </summary> - internal sealed partial class LineHandler : SerieHandler<Line> - { - List<List<SerieData>> m_StackSerieData = new List<List<SerieData>>(); - private GridCoord m_SerieGrid; - - public override Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label) - { - var invert = label.autoOffset && - SerieHelper.IsDownPoint(serie, serieData.index) && - (serie.areaStyle == null || !serie.areaStyle.show); - if (invert) - { - var offset = label.GetOffset(serie.context.insideRadius); - return new Vector3(offset.x, -offset.y, offset.z); - } - else - { - return label.GetOffset(serie.context.insideRadius); - } - } - - private void UpdateSerieGridContext() - { - if (m_SerieGrid == null) - return; - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - serie.highlight = false; - serie.ResetInteract(); - foreach (var serieData in serie.data) - serieData.context.highlight = false; - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - return; - } - m_LastCheckContextFlag = needCheck; - var themeSymbolSize = chart.theme.serie.lineSymbolSize; - var themeSymbolSelectedSize = chart.theme.serie.lineSymbolSelectedSize; - var needInteract = false; - if (m_LegendEnter) - { - serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - } - else if (serie.context.isTriggerByAxis) - { - serie.context.pointerEnter = true; - serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - - if (i == serie.context.pointerItemDataIndex) - { - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - else - { - serieData.context.highlight = false; - serieData.interact.SetValue(ref needInteract, symbolSize); - } - } - } - else - { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - serieData.index = i; - var dist = Vector3.Distance(chart.pointerPos, serieData.context.position); - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - if (dist <= symbolSelectedSize) - { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; - serie.interact.SetValue(ref needInteract, lineWidth, true); - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - else - { - serieData.context.highlight = false; - serieData.interact.SetValue(ref needInteract, symbolSize); - } - } - } - if (needInteract) - { - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - } - - private void DrawLinePoint(VertexHelper vh, Serie serie) - { - if (!serie.show || serie.IsPerformanceMode()) - return; - - if (m_SerieGrid == null) - return; - - var count = serie.context.dataPoints.Count; - var clip = SeriesHelper.IsAnyClipSerie(chart.series); - var theme = chart.theme; - var interacting = false; - var lineArrow = serie.lineArrow; - var visualMap = chart.GetVisualMapOfSerie(serie); - var isVisualMapGradient = VisualMapHelper.IsNeedLineGradient(visualMap); - var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); - - Axis axis; - Axis relativedAxis; - - if (isY) - { - axis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - relativedAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - } - else - { - axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - relativedAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - } - for (int i = 0; i < count; i++) - { - var serieData = serie.GetSerieData(i); - if (serieData == null) - continue; - if (serieData.context.isClip) - continue; - - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - - if (!symbol.show || !symbol.ShowSymbol(i, count)) - continue; - - var pos = serie.context.dataPoints[i]; - if (lineArrow != null && lineArrow.show) - { - if (lineArrow.position == LineArrow.Position.Start && i == 0) - continue; - if (lineArrow.position == LineArrow.Position.End && i == count - 1) - continue; - } - - if (ChartHelper.IsIngore(pos)) - continue; - - var highlight = serie.data[i].context.highlight || serie.highlight; - var symbolSize = highlight ? - theme.serie.lineSymbolSelectedSize : - theme.serie.lineSymbolSize; - if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting)) - { - symbolSize = highlight ? - symbol.GetSelectedSize(serieData.data, symbolSize) : - symbol.GetSize(serieData.data, symbolSize); - serieData.interact.SetValue(ref interacting, symbolSize); - symbolSize = serie.animation.GetSysmbolSize(symbolSize); - } - var symbolColor = SerieHelper.GetItemColor(serie, serieData, theme, serie.index, highlight); - var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, theme, serie.index, highlight); - var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, theme, serie.index, highlight, false); - - if (isVisualMapGradient) - { - symbolColor = VisualMapHelper.GetLineGradientColor(visualMap, pos, m_SerieGrid, axis, relativedAxis, symbolColor); - symbolToColor = symbolColor; - } - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, theme, highlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); - chart.DrawClipSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, - symbolColor, symbolToColor, symbolEmptyColor, borderColor, symbol.gap, clip, cornerRadius, m_SerieGrid, - i > 0 ? serie.context.dataPoints[i - 1] : m_SerieGrid.context.position); - } - if (interacting) - { - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - } - - private void DrawLineArrow(VertexHelper vh, Serie serie) - { - if (!serie.show || serie.lineArrow == null || !serie.lineArrow.show) - return; - - if (serie.context.dataPoints.Count < 2) - return; - - var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index, false); - var startPos = Vector3.zero; - var arrowPos = Vector3.zero; - var lineArrow = serie.lineArrow.arrow; - var dataPoints = serie.context.drawPoints; - switch (serie.lineArrow.position) - { - case LineArrow.Position.End: - if (dataPoints.Count < 3) - { - startPos = dataPoints[dataPoints.Count - 2].position; - arrowPos = dataPoints[dataPoints.Count - 1].position; - } - else - { - startPos = dataPoints[dataPoints.Count - 3].position; - arrowPos = dataPoints[dataPoints.Count - 2].position; - } - UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height, - lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor)); - - break; - - case LineArrow.Position.Start: - startPos = dataPoints[1].position; - arrowPos = dataPoints[0].position; - UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height, - lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor)); - - break; - } - } - - private void DrawLineSerie(VertexHelper vh, Line serie) - { - if (!serie.show) - return; - if (serie.animation.HasFadeOut()) - return; - - var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); - - Axis axis; - Axis relativedAxis; - - if (isY) - { - axis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - relativedAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - } - else - { - axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - relativedAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - } - - if (axis == null) - return; - if (relativedAxis == null) - return; - - m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - if (m_SerieGrid == null) - return; - if (m_EndLabel != null && !m_SerieGrid.context.endLabelList.Contains(m_EndLabel)) - { - m_SerieGrid.context.endLabelList.Add(m_EndLabel); - } - - var visualMap = chart.GetVisualMapOfSerie(serie); - var dataZoom = chart.GetDataZoomOfAxis(axis); - var showData = serie.GetDataList(dataZoom); - - if (showData.Count <= 0) - return; - - var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width; - var scaleWid = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom); - - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : - showData.Count; - int rate = LineHelper.GetDataAverageRate(serie, m_SerieGrid, maxCount, false); - var totalAverage = serie.sampleAverage > 0 ? - serie.sampleAverage : - DataHelper.DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate); - var dataChanging = false; - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - - var interacting = false; - var lineWidth = LineHelper.GetLineWidth(ref interacting, serie, chart.theme.serie.lineWidth); - - axis.context.scaleWidth = scaleWid; - serie.containerIndex = m_SerieGrid.index; - serie.containterInstanceId = m_SerieGrid.instanceId; - - Serie lastSerie = null; - var isStack = SeriesHelper.IsStack<Line>(chart.series, serie.stack); - if (isStack) - { - lastSerie = SeriesHelper.GetLastStackSerie(chart.series, serie); - SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData); - } - var lp = Vector3.zero; - for (int i = serie.minShow; i < maxCount; i += rate) - { - var serieData = showData[i]; - var isIgnore = serie.IsIgnoreValue(serieData); - if (isIgnore) - { - serieData.context.stackHeight = 0; - serieData.context.position = Vector3.zero; - if (serie.ignoreLineBreak && serie.context.dataIgnores.Count > 0) - { - serie.context.dataIgnores[serie.context.dataIgnores.Count - 1] = true; - } - } - else - { - var np = Vector3.zero; - var xValue = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse); - var relativedValue = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, - maxCount, totalAverage, i, dataChangeDuration, ref dataChanging, relativedAxis); - - serieData.context.stackHeight = GetDataPoint(isY, axis, relativedAxis, m_SerieGrid, xValue, relativedValue, - i, scaleWid, isStack, ref np); - serieData.context.isClip = false; - if (serie.clip && !m_SerieGrid.Contains(np)) - { - if (m_SerieGrid.BoundaryPoint(lp, np, ref np)) - { - serieData.context.isClip = true; - } - } - serie.context.dataIgnores.Add(false); - serieData.context.position = np; - serie.context.dataPoints.Add(np); - lp = np; - } - } - - if (dataChanging || interacting) - chart.RefreshPainter(serie); - - if (serie.context.dataPoints.Count <= 0) - return; - - serie.animation.InitProgress(serie.context.dataPoints, isY); - - VisualMapHelper.AutoSetLineMinMax(visualMap, serie, isY, axis, relativedAxis); - LineHelper.UpdateSerieDrawPoints(serie, chart.settings, chart.theme, visualMap, lineWidth, isY); - LineHelper.DrawSerieLineArea(vh, serie, lastSerie, chart.theme, visualMap, isY, axis, relativedAxis, m_SerieGrid); - LineHelper.DrawSerieLine(vh, chart.theme, serie, visualMap, m_SerieGrid, axis, relativedAxis, lineWidth); - - serie.context.vertCount = vh.currentVertCount; - - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize)); - chart.RefreshPainter(serie); - } - } - - private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord grid, double xValue, - double yValue, int i, float scaleWid, bool isStack, ref Vector3 np) - { - float xPos, yPos; - var gridXY = isY ? grid.context.x : grid.context.y; - var valueHig = 0f; - if (isY) - { - valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); - valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); - - xPos = gridXY + valueHig; - yPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue); - - if (isStack) - { - for (int n = 0; n < m_StackSerieData.Count - 1; n++) - xPos += m_StackSerieData[n][i].context.stackHeight; - } - } - else - { - - valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); - valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); - - yPos = gridXY + valueHig; - xPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue); - - if (isStack) - { - for (int n = 0; n < m_StackSerieData.Count - 1; n++) - yPos += m_StackSerieData[n][i].context.stackHeight; - } - } - np = new Vector3(xPos, yPos); - return valueHig; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs.meta b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs.meta deleted file mode 100644 index b6f3a32..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 34168c2605d4546c291adeb8e857fd62 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs deleted file mode 100644 index ea5b569..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ /dev/null @@ -1,262 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - /// <summary> - /// For polar coord - /// </summary> - internal sealed partial class LineHandler - { - private PolarCoord m_SeriePolar; - - private void UpdateSeriePolarContext() - { - if (m_SeriePolar == null) - return; - - var needCheck = (chart.isPointerInChart && m_SeriePolar.IsPointerEnter()) || m_LegendEnter; - var lineWidth = 0f; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - var needAnimation1 = false; - lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - serie.interact.SetValue(ref needAnimation1, lineWidth, false); - foreach (var serieData in serie.data) - { - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); - serieData.context.highlight = false; - serieData.interact.SetValue(ref needAnimation1, symbolSize); - } - if (needAnimation1) - { - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - } - return; - } - m_LastCheckContextFlag = needCheck; - var themeSymbolSize = chart.theme.serie.lineSymbolSize; - var themeSymbolSelectedSize = chart.theme.serie.lineSymbolSelectedSize; - lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - - var needInteract = false; - if (m_LegendEnter) - { - serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - } - else - { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - var dir = chart.pointerPos - new Vector2(m_SeriePolar.context.center.x, m_SeriePolar.context.center.y); - var pointerAngle = ChartHelper.GetAngle360(Vector2.up, dir); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var angle0 = serieData.context.angle; - var angle1 = i >= serie.dataCount - 1 ? angle0 : serie.data[i + 1].context.angle; - - if (pointerAngle >= angle0 && pointerAngle < angle1) - { - serie.context.pointerItemDataIndex = i; - serie.context.pointerEnter = true; - serieData.context.highlight = true; - } - else - { - serieData.context.highlight = false; - } - } - } - if (needInteract) - { - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - } - - private void DrawPolarLine(VertexHelper vh, Serie serie) - { - var datas = serie.data; - if (datas.Count <= 0) - return; - - m_SeriePolar = chart.GetChartComponent<PolarCoord>(serie.polarIndex); - if (m_SeriePolar == null) - return; - - var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_SeriePolar.index); - var m_RadiusAxis = ComponentHelper.GetRadiusAxis(chart.components, m_SeriePolar.index); - if (m_AngleAxis == null || m_RadiusAxis == null) - return; - - var startAngle = m_AngleAxis.startAngle; - var radius = m_SeriePolar.context.radius; - - var min = m_RadiusAxis.context.minValue; - var max = m_RadiusAxis.context.maxValue; - var firstSerieData = datas[0]; - var lp = GetPolarPos(m_SeriePolar, m_AngleAxis, firstSerieData, min, max, radius); - var cp = Vector3.zero; - var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index, serie.highlight); - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - var currDetailProgress = 0f; - var totalDetailProgress = datas.Count; - - serie.animation.InitProgress(currDetailProgress, totalDetailProgress); - - var ltp = Vector3.zero; - var lbp = Vector3.zero; - var ntp = Vector3.zero; - var nbp = Vector3.zero; - var itp = Vector3.zero; - var ibp = Vector3.zero; - var clp = Vector3.zero; - var crp = Vector3.zero; - bool bitp = true, bibp = true; - for (int i = 1; i < datas.Count; i++) - { - if (serie.animation.CheckDetailBreak(i)) - break; - - var serieData = datas[i]; - - cp = GetPolarPos(m_SeriePolar, m_AngleAxis, datas[i], min, max, radius); - var np = i == datas.Count - 1 ? cp : - GetPolarPos(m_SeriePolar, m_AngleAxis, datas[i + 1], min, max, radius); - - UGLHelper.GetLinePoints(lp, cp, np, lineWidth, - ref ltp, ref lbp, - ref ntp, ref nbp, - ref itp, ref ibp, - ref clp, ref crp, - ref bitp, ref bibp, i); - - if (i == 1) - { - UGL.AddVertToVertexHelper(vh, ltp, lbp, lineColor, false); - } - - if (bitp == bibp) - { - if (bitp) - UGL.AddVertToVertexHelper(vh, itp, ibp, lineColor, true); - else - { - UGL.AddVertToVertexHelper(vh, ltp, clp, lineColor, true); - UGL.AddVertToVertexHelper(vh, ltp, crp, lineColor, true); - } - } - else - { - if (bitp) - { - UGL.AddVertToVertexHelper(vh, itp, clp, lineColor, true); - UGL.AddVertToVertexHelper(vh, itp, crp, lineColor, true); - } - else if (bibp) - { - UGL.AddVertToVertexHelper(vh, clp, ibp, lineColor, true); - UGL.AddVertToVertexHelper(vh, crp, ibp, lineColor, true); - } - } - lp = cp; - } - - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(totalDetailProgress); - serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize)); - chart.RefreshChart(); - } - } - - private void DrawPolarLineSymbol(VertexHelper vh) - { - for (int n = 0; n < chart.series.Count; n++) - { - var serie = chart.series[n]; - - if (!serie.show) - continue; - if (!(serie is Line)) - continue; - - var count = serie.dataCount; - for (int i = 0; i < count; i++) - { - var serieData = serie.GetSerieData(i); - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - if (ChartHelper.IsIngore(serieData.context.position)) - continue; - - bool highlight = serieData.context.highlight || serie.highlight; - if ((!symbol.show || !symbol.ShowSymbol(i, count) || serie.IsPerformanceMode()) && - !serieData.context.highlight) - continue; - - var symbolSize = highlight ? - symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSize) : - symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); - - var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, n, highlight); - var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, n, highlight); - var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, n, highlight, false); - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, highlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, highlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); - - symbolSize = serie.animation.GetSysmbolSize(symbolSize); - chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, serieData.context.position, - symbolColor, symbolToColor, symbolEmptyColor, borderColor, symbol.gap, cornerRadius); - } - } - } - - private Vector3 GetPolarPos(PolarCoord m_Polar, AngleAxis m_AngleAxis, SerieData serieData, double min, - double max, float polarRadius) - { - var angle = 0f; - - if (!m_AngleAxis.clockwise) - { - angle = m_AngleAxis.GetValueAngle((float) serieData.GetData(1)); - } - else - { - angle = m_AngleAxis.GetValueAngle((float) serieData.GetData(1)); - } - - var value = serieData.GetData(0); - var radius = (float) ((value - min) / (max - min) * polarRadius); - - angle = (angle + 360) % 360; - serieData.context.angle = angle; - serieData.context.position = ChartHelper.GetPos(m_Polar.context.center, radius, angle, true); - - return serieData.context.position; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs.meta b/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs.meta deleted file mode 100644 index fd0e63a..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8655c97b8c7e44e44852f8b81a7372b8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.cs deleted file mode 100644 index f15ba49..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - /// <summary> - /// For grid coord - /// </summary> - [UnityEngine.Scripting.Preserve] - internal sealed partial class LineHandler : SerieHandler<Line> - { - public override void Update() - { - base.Update(); - if (serie.IsUseCoord<GridCoord>()) - UpdateSerieGridContext(); - else if (serie.IsUseCoord<PolarCoord>()) - UpdateSeriePolarContext(); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category, - marker, itemFormatter, numericFormatter); - } - - public override void DrawSerie(VertexHelper vh) - { - if (serie.IsUseCoord<PolarCoord>()) - { - DrawPolarLine(vh, serie); - DrawPolarLineSymbol(vh); - } - else if (serie.IsUseCoord<GridCoord>()) - { - DrawLineSerie(vh, serie); - - if (!SeriesHelper.IsStack(chart.series)) - { - DrawLinePoint(vh, serie); - DrawLineArrow(vh, serie); - } - } - } - - public override void DrawTop(VertexHelper vh) - { - if (serie.IsUseCoord<GridCoord>()) - { - if (SeriesHelper.IsStack(chart.series)) - { - DrawLinePoint(vh, serie); - DrawLineArrow(vh, serie); - } - } - } - - public override void RefreshEndLabelInternal() - { - base.RefreshEndLabelInternal(); - if (m_SerieGrid == null) return; - if (!serie.animation.IsFinish()) return; - var endLabelList = m_SerieGrid.context.endLabelList; - if (endLabelList.Count <= 1) return; - - endLabelList.Sort(delegate(ChartLabel a, ChartLabel b) - { - if (a == null || b == null) return 1; - return b.transform.position.y.CompareTo(a.transform.position.y); - }); - var lastY = float.NaN; - for (int i = 0; i < endLabelList.Count; i++) - { - var label = endLabelList[i]; - if (label == null) continue; - if (!label.isAnimationEnd) continue; - var labelPosition = label.transform.localPosition; - if (float.IsNaN(lastY)) - { - lastY = labelPosition.y; - } - else - { - var labelHeight = label.GetTextHeight(); - if (labelPosition.y + labelHeight > lastY) - { - label.SetPosition(new Vector3(labelPosition.x, lastY - labelHeight, labelPosition.z)); - } - lastY = label.transform.localPosition.y; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Line/LineHandler.cs.meta deleted file mode 100644 index 51dec59..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6e3a076ca3ee241c3b8b1088d4519dfa -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs b/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs deleted file mode 100644 index 27d06ae..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs +++ /dev/null @@ -1,551 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - internal static class LineHelper - { - private static List<Vector3> s_CurvesPosList = new List<Vector3>(); - - public static int GetDataAverageRate(Serie serie, GridCoord grid, int maxCount, bool isYAxis) - { - var sampleDist = serie.sampleDist; - var rate = 0; - var width = isYAxis ? grid.context.height : grid.context.width; - if (sampleDist > 0) - rate = (int) ((maxCount - serie.minShow) / (width / sampleDist)); - if (rate < 1) - rate = 1; - return rate; - } - - public static void DrawSerieLineArea(VertexHelper vh, Serie serie, Serie lastStackSerie, - ThemeStyle theme, VisualMap visualMap, bool isY, Axis axis, Axis relativedAxis, GridCoord grid) - { - if (serie.areaStyle == null || !serie.areaStyle.show) - return; - - var srcAreaColor = SerieHelper.GetAreaColor(serie, null, theme, serie.context.colorIndex, false); - var srcAreaToColor = SerieHelper.GetAreaToColor(serie, null, theme, serie.context.colorIndex, false); - var gridXY = (isY ? grid.context.x : grid.context.y); - if (lastStackSerie == null) - { - DrawSerieLineNormalArea(vh, serie, isY, - gridXY + relativedAxis.context.offset, - gridXY, - gridXY + (isY ? grid.context.width : grid.context.height), - srcAreaColor, - srcAreaToColor, - visualMap, - axis, - relativedAxis, - grid); - } - else - { - DrawSerieLineStackArea(vh, serie, lastStackSerie, isY, - gridXY + relativedAxis.context.offset, - gridXY, - gridXY + (isY ? grid.context.width : grid.context.height), - srcAreaColor, - srcAreaToColor, - visualMap); - } - } - - private static void DrawSerieLineNormalArea(VertexHelper vh, Serie serie, bool isY, - float zero, float min, float max, Color32 areaColor, Color32 areaToColor, - VisualMap visualMap, Axis axis, Axis relativedAxis, GridCoord grid) - { - var points = serie.context.drawPoints; - var count = points.Count; - if (count < 2) - return; - - var isBreak = false; - var lp = Vector3.zero; - var isVisualMapGradient = VisualMapHelper.IsNeedAreaGradient(visualMap); - var areaLerp = !ChartHelper.IsValueEqualsColor(areaColor, areaToColor); - var zsp = isY ? - new Vector3(zero, points[0].position.y) : - new Vector3(points[0].position.x, zero); - var zep = isY ? - new Vector3(zero, points[count - 1].position.y) : - new Vector3(points[count - 1].position.x, zero); - - var lastDataIsIgnore = false; - for (int i = 0; i < points.Count; i++) - { - var tp = points[i].position; - var isIgnore = points[i].isIgnoreBreak; - var color = areaColor; - var toColor = areaToColor; - var lerp = areaLerp; - - if (serie.animation.CheckDetailBreak(tp, isY)) - { - isBreak = true; - - var progress = serie.animation.GetCurrDetail(); - var ip = Vector3.zero; - var axisStartPos = isY ? new Vector3(-10000, progress) : new Vector3(progress, -10000); - var axisEndPos = isY ? new Vector3(10000, progress) : new Vector3(progress, 10000); - - if (UGLHelper.GetIntersection(lp, tp, axisStartPos, axisEndPos, ref ip)) - tp = ip; - } - var zp = isY ? new Vector3(zero, tp.y) : new Vector3(tp.x, zero); - if (isVisualMapGradient) - { - color = VisualMapHelper.GetLineGradientColor(visualMap, zp, grid, axis, relativedAxis, areaColor); - toColor = VisualMapHelper.GetLineGradientColor(visualMap, tp, grid, axis, relativedAxis, areaToColor); - lerp = true; - } - if (i > 0) - { - if ((lp.y - zero > 0 && tp.y - zero < 0) || (lp.y - zero < 0 && tp.y - zero > 0)) - { - var ip = Vector3.zero; - if (UGLHelper.GetIntersection(lp, tp, zsp, zep, ref ip)) - { - if (lerp) - AddVertToVertexHelperWithLerpColor(vh, ip, ip, color, toColor, isY, min, max, i > 0); - else - { - if (lastDataIsIgnore) - UGL.AddVertToVertexHelper(vh, ip, ip, ColorUtil.clearColor32, true); - - UGL.AddVertToVertexHelper(vh, ip, ip, toColor, color, i > 0); - - if (isIgnore) - UGL.AddVertToVertexHelper(vh, ip, ip, ColorUtil.clearColor32, true); - } - } - } - } - - if (lerp) - AddVertToVertexHelperWithLerpColor(vh, tp, zp, color, toColor, isY, min, max, i > 0); - else - { - if (lastDataIsIgnore) - UGL.AddVertToVertexHelper(vh, tp, zp, ColorUtil.clearColor32, true); - - UGL.AddVertToVertexHelper(vh, tp, zp, toColor, color, i > 0); - - if (isIgnore) - UGL.AddVertToVertexHelper(vh, tp, zp, ColorUtil.clearColor32, true); - } - lp = tp; - lastDataIsIgnore = isIgnore; - if (isBreak) - break; - } - } - - private static void DrawSerieLineStackArea(VertexHelper vh, Serie serie, Serie lastStackSerie, bool isY, - float zero, float min, float max, Color32 color, Color32 toColor, VisualMap visualMap) - { - if (lastStackSerie == null) - return; - - var upPoints = serie.context.drawPoints; - var downPoints = lastStackSerie.context.drawPoints; - var upCount = upPoints.Count; - var downCount = downPoints.Count; - - if (upCount <= 0 || downCount <= 0) - return; - - var lerp = !ChartHelper.IsValueEqualsColor(color, toColor); - var ltp = upPoints[0].position; - var lbp = downPoints[0].position; - - if (lerp) - AddVertToVertexHelperWithLerpColor(vh, ltp, lbp, color, toColor, isY, min, max, false); - else - UGL.AddVertToVertexHelper(vh, ltp, lbp, color, false); - - int u = 1, d = 1; - var isBreakTop = false; - var isBreakBottom = false; - - while ((u < upCount || d < downCount)) - { - var tp = u < upCount ? upPoints[u].position : upPoints[upCount - 1].position; - var bp = d < downCount ? downPoints[d].position : downPoints[downCount - 1].position; - - var tnp = (u + 1) < upCount ? upPoints[u + 1].position : upPoints[upCount - 1].position; - var bnp = (d + 1) < downCount ? downPoints[d + 1].position : downPoints[downCount - 1].position; - - if (serie.animation.CheckDetailBreak(tp, isY)) - { - isBreakTop = true; - - var progress = serie.animation.GetCurrDetail(); - var ip = Vector3.zero; - - if (UGLHelper.GetIntersection(ltp, tp, - new Vector3(progress, -10000), - new Vector3(progress, 10000), ref ip)) - tp = ip; - else - tp = new Vector3(progress, tp.y); - } - if (serie.animation.CheckDetailBreak(bp, isY)) - { - isBreakBottom = true; - - var progress = serie.animation.GetCurrDetail(); - var ip = Vector3.zero; - - if (UGLHelper.GetIntersection(lbp, bp, - new Vector3(progress, -10000), - new Vector3(progress, 10000), ref ip)) - bp = ip; - else - bp = new Vector3(progress, bp.y); - } - - if (lerp) - AddVertToVertexHelperWithLerpColor(vh, tp, bp, color, toColor, isY, min, max, true); - else - UGL.AddVertToVertexHelper(vh, tp, bp, color, true); - u++; - d++; - if (bp.x < tp.x && bnp.x < tp.x) - u--; - if (tp.x < bp.x && tnp.x < bp.x) - d--; - - ltp = tp; - lbp = bp; - if (isBreakTop && isBreakBottom) - break; - } - } - - private static void AddVertToVertexHelperWithLerpColor(VertexHelper vh, Vector3 tp, Vector3 bp, - Color32 color, Color32 toColor, bool isY, float min, float max, bool needTriangle) - { - var range = max - min; - var color1 = Color32.Lerp(color, toColor, ((isY ? tp.x : tp.y) - min) / range); - var color2 = Color32.Lerp(color, toColor, ((isY ? bp.x : bp.y) - min) / range); - UGL.AddVertToVertexHelper(vh, tp, bp, color1, color2, needTriangle); - } - - internal static void DrawSerieLine(VertexHelper vh, ThemeStyle theme, Serie serie, VisualMap visualMap, - GridCoord grid, Axis axis, Axis relativedAxis, float lineWidth) - { - if (!serie.lineStyle.show || serie.lineStyle.type == LineStyle.Type.None) - return; - - var datas = serie.context.drawPoints; - - var dataCount = datas.Count; - if (dataCount < 2) - return; - - var ltp = Vector3.zero; - var lbp = Vector3.zero; - var ntp = Vector3.zero; - var nbp = Vector3.zero; - var itp = Vector3.zero; - var ibp = Vector3.zero; - var clp = Vector3.zero; - var crp = Vector3.zero; - - var isBreak = false; - var isY = axis is YAxis; - var isVisualMapGradient = VisualMapHelper.IsNeedLineGradient(visualMap); - var isLineStyleGradient = serie.lineStyle.IsNeedGradient(); - - //var highlight = serie.highlight || serie.context.pointerEnter; - var lineColor = SerieHelper.GetLineColor(serie, null, theme, serie.context.colorIndex, false); - - var lastDataIsIgnore = datas[0].isIgnoreBreak; - var smooth = serie.lineType == LineType.Smooth; - for (int i = 1; i < dataCount; i++) - { - var cdata = datas[i]; - var isIgnore = cdata.isIgnoreBreak; - - var cp = cdata.position; - var lp = datas[i - 1].position; - - var np = i == dataCount - 1 ? cp : datas[i + 1].position; - if (serie.animation.CheckDetailBreak(cp, isY)) - { - isBreak = true; - var ip = Vector3.zero; - var progress = serie.animation.GetCurrDetail(); - if (AnimationStyleHelper.GetAnimationPosition(serie.animation, isY, lp, cp, progress, ref ip)) - cp = np = ip; - } - serie.context.lineEndPostion = cp; - serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp); - lastDataIsIgnore = isIgnore; - var handled = false; - if (!smooth) - { - switch (serie.lineStyle.type) - { - case LineStyle.Type.Dashed: - UGL.DrawDashLine(vh, lp, cp, lineWidth, lineColor, lineColor, 0, 0); - handled = true; - break; - case LineStyle.Type.Dotted: - UGL.DrawDotLine(vh, lp, cp, lineWidth, lineColor, lineColor, 0, 0); - handled = true; - break; - case LineStyle.Type.DashDot: - UGL.DrawDashDotLine(vh, lp, cp, lineWidth, lineColor, 0, 0, 0); - handled = true; - break; - case LineStyle.Type.DashDotDot: - UGL.DrawDashDotDotLine(vh, lp, cp, lineWidth, lineColor, 0, 0, 0); - handled = true; - break; - case LineStyle.Type.None: - handled = true; - break; - } - } - if (handled) - { - if (isBreak) - break; - else - continue; - } - bool bitp = true, bibp = true; - UGLHelper.GetLinePoints(lp, cp, np, lineWidth, - ref ltp, ref lbp, - ref ntp, ref nbp, - ref itp, ref ibp, - ref clp, ref crp, - ref bitp, ref bibp, i); - if (i == 1) - { - AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, false, lastDataIsIgnore, isIgnore); - if (dataCount == 2 || isBreak) - { - AddLineVertToVertexHelper(vh, clp, crp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - serie.context.lineEndPostion = cp; - serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp); - break; - } - } - - if (bitp == bibp) - { - if (bitp) - AddLineVertToVertexHelper(vh, itp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - else - { - AddLineVertToVertexHelper(vh, ltp, clp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - AddLineVertToVertexHelper(vh, ltp, crp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - } - } - else - { - if (bitp) - { - AddLineVertToVertexHelper(vh, itp, clp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - AddLineVertToVertexHelper(vh, itp, crp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - } - else if (bibp) - { - AddLineVertToVertexHelper(vh, clp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - AddLineVertToVertexHelper(vh, crp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient, - visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); - } - } - - if (isBreak) - break; - } - } - - public static float GetLineWidth(ref bool interacting, Serie serie, float defaultWidth) - { - var lineWidth = 0f; - if (!serie.interact.TryGetValue(ref lineWidth, ref interacting)) - { - lineWidth = serie.lineStyle.GetWidth(defaultWidth); - serie.interact.SetValue(ref interacting, lineWidth); - } - return lineWidth; - } - - private static void AddLineVertToVertexHelper(VertexHelper vh, Vector3 tp, Vector3 bp, - Color32 lineColor, bool visualMapGradient, bool lineStyleGradient, VisualMap visualMap, - LineStyle lineStyle, GridCoord grid, Axis axis, Axis relativedAxis, bool needTriangle, - bool lastIgnore, bool ignore) - { - if (lastIgnore && needTriangle) - UGL.AddVertToVertexHelper(vh, tp, bp, ColorUtil.clearColor32, true); - - if (visualMapGradient) - { - var color1 = VisualMapHelper.GetLineGradientColor(visualMap, tp, grid, axis, relativedAxis, lineColor); - var color2 = VisualMapHelper.GetLineGradientColor(visualMap, bp, grid, axis, relativedAxis, lineColor); - UGL.AddVertToVertexHelper(vh, tp, bp, color1, color2, needTriangle); - } - else if (lineStyleGradient) - { - var color1 = VisualMapHelper.GetLineStyleGradientColor(lineStyle, tp, grid, axis, lineColor); - var color2 = VisualMapHelper.GetLineStyleGradientColor(lineStyle, bp, grid, axis, lineColor); - UGL.AddVertToVertexHelper(vh, tp, bp, color1, color2, needTriangle); - } - else - { - UGL.AddVertToVertexHelper(vh, tp, bp, lineColor, needTriangle); - } - if (lastIgnore && !needTriangle) - UGL.AddVertToVertexHelper(vh, tp, bp, ColorUtil.clearColor32, false); - if (ignore && needTriangle) - UGL.AddVertToVertexHelper(vh, tp, bp, ColorUtil.clearColor32, false); - } - - internal static void UpdateSerieDrawPoints(Serie serie, Settings setting, ThemeStyle theme, VisualMap visualMap, - float lineWidth, bool isY = false) - { - serie.context.drawPoints.Clear(); - var last = Vector3.zero; - switch (serie.lineType) - { - case LineType.Smooth: - UpdateSmoothLineDrawPoints(serie, setting, isY); - break; - case LineType.StepStart: - case LineType.StepMiddle: - case LineType.StepEnd: - UpdateStepLineDrawPoints(serie, setting, theme, isY, lineWidth); - break; - default: - UpdateNormalLineDrawPoints(serie, setting, visualMap); - break; - } - } - - private static void UpdateNormalLineDrawPoints(Serie serie, Settings setting, VisualMap visualMap) - { - var isVisualMapGradient = VisualMapHelper.IsNeedGradient(visualMap); - if (isVisualMapGradient) - { - var dataPoints = serie.context.dataPoints; - if (dataPoints.Count > 1) - { - var sp = dataPoints[0]; - for (int i = 1; i < dataPoints.Count; i++) - { - var ep = dataPoints[i]; - var ignore = serie.context.dataIgnores[i]; - var dir = (ep - sp).normalized; - var dist = Vector3.Distance(sp, ep); - var segment = (int) (dist / setting.lineSegmentDistance); - serie.context.drawPoints.Add(new PointInfo(sp, ignore)); - for (int j = 1; j < segment; j++) - { - var np = sp + dir * dist * j / segment; - serie.context.drawPoints.Add(new PointInfo(np, ignore)); - } - sp = ep; - if (i == dataPoints.Count - 1) - { - serie.context.drawPoints.Add(new PointInfo(ep, ignore)); - } - } - } - else - { - serie.context.drawPoints.Add(new PointInfo(dataPoints[0], serie.context.dataIgnores[0])); - } - } - else - { - for (int i = 0; i < serie.context.dataPoints.Count; i++) - { - serie.context.drawPoints.Add(new PointInfo(serie.context.dataPoints[i], serie.context.dataIgnores[i])); - } - } - } - - private static void UpdateSmoothLineDrawPoints(Serie serie, Settings setting, bool isY) - { - var points = serie.context.dataPoints; - float smoothness = setting.lineSmoothness; - for (int i = 0; i < points.Count - 1; i++) - { - var sp = points[i]; - var ep = points[i + 1]; - var lsp = i > 0 ? points[i - 1] : sp; - var nep = i < points.Count - 2 ? points[i + 2] : ep; - var ignore = serie.context.dataIgnores[i]; - if (isY) - UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness, setting.lineSmoothStyle); - else - UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness, setting.lineSmoothStyle); - - for (int j = 1; j < s_CurvesPosList.Count; j++) - { - serie.context.drawPoints.Add(new PointInfo(s_CurvesPosList[j], ignore)); - } - } - } - - private static void UpdateStepLineDrawPoints(Serie serie, Settings setting, ThemeStyle theme, bool isY, float lineWidth) - { - var points = serie.context.dataPoints; - var lp = points[0]; - serie.context.drawPoints.Clear(); - serie.context.drawPoints.Add(new PointInfo(lp, serie.context.dataIgnores[0])); - for (int i = 1; i < points.Count; i++) - { - var cp = points[i]; - var ignore = serie.context.dataIgnores[i]; - if ((isY && Mathf.Abs(lp.x - cp.x) <= lineWidth) || - (!isY && Mathf.Abs(lp.y - cp.y) <= lineWidth)) - { - serie.context.drawPoints.Add(new PointInfo(cp, ignore)); - lp = cp; - continue; - } - switch (serie.lineType) - { - case LineType.StepStart: - serie.context.drawPoints.Add(new PointInfo(isY ? - new Vector3(cp.x, lp.y) : - new Vector3(lp.x, cp.y), ignore)); - break; - case LineType.StepMiddle: - serie.context.drawPoints.Add(new PointInfo(isY ? - new Vector3(lp.x, (lp.y + cp.y) / 2) : - new Vector3((lp.x + cp.x) / 2, lp.y), ignore)); - serie.context.drawPoints.Add(new PointInfo(isY ? - new Vector3(cp.x, (lp.y + cp.y) / 2) : - new Vector3((lp.x + cp.x) / 2, cp.y), ignore)); - break; - case LineType.StepEnd: - serie.context.drawPoints.Add(new PointInfo(isY ? - new Vector3(lp.x, cp.y) : - new Vector3(cp.x, lp.y), ignore)); - break; - } - serie.context.drawPoints.Add(new PointInfo(cp, ignore)); - lp = cp; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs.meta b/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs.meta deleted file mode 100644 index ae015c8..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7292748fb01ef44709a94d08f4907dd5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs b/Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs deleted file mode 100644 index 94470d9..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - [SerieHandler(typeof(SimplifiedLineHandler), true)] - [SerieConvert(typeof(SimplifiedBar), typeof(Line))] - [CoordOptions(typeof(GridCoord))] - [DefaultAnimation(AnimationType.LeftToRight)] - [SerieExtraComponent(typeof(AreaStyle))] - [SerieDataExtraComponent()] - [SerieDataExtraField()] - public class SimplifiedLine : Serie, INeedSerieContainer, ISimplifiedSerie - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<SimplifiedLine>(serieName); - serie.symbol.show = false; - var lastValue = 0d; - for (int i = 0; i < 50; i++) - { - if (i < 20) - lastValue += UnityEngine.Random.Range(0, 5); - else - lastValue += UnityEngine.Random.Range(-3, 5); - chart.AddData(serie.index, lastValue); - } - return serie; - } - - public static SimplifiedLine CovertSerie(Serie serie) - { - var newSerie = serie.Clone<SimplifiedLine>(); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs.meta b/Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs.meta deleted file mode 100644 index 486e64b..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLine.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a5740626e12a84a0ca3a984935f61720 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs b/Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs deleted file mode 100644 index 8b2b0e0..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - /// <summary> - /// For grid coord - /// </summary> - [UnityEngine.Scripting.Preserve] - internal sealed class SimplifiedLineHandler : SerieHandler<SimplifiedLine> - { - private GridCoord m_SerieGrid; - - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category, - marker, itemFormatter, numericFormatter); - } - - public override void DrawSerie(VertexHelper vh) - { - DrawLineSerie(vh, serie); - } - - private void UpdateSerieContext() - { - if (m_SerieGrid == null) - return; - - var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter; - var lineWidth = 0f; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - var needAnimation1 = false; - lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - serie.interact.SetValue(ref needAnimation1, lineWidth, false); - foreach (var serieData in serie.data) - { - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); - serieData.context.highlight = false; - serieData.interact.SetValue(ref needAnimation1, symbolSize); - } - if (needAnimation1) - { - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - } - return; - } - m_LastCheckContextFlag = needCheck; - var themeSymbolSize = chart.theme.serie.lineSymbolSize; - var themeSymbolSelectedSize = chart.theme.serie.lineSymbolSelectedSize; - lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - - var needInteract = false; - if (m_LegendEnter) - { - serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - } - else if (serie.context.isTriggerByAxis) - { - serie.context.pointerEnter = true; - serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - - if (i == serie.context.pointerItemDataIndex) - { - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - else - { - serieData.context.highlight = false; - serieData.interact.SetValue(ref needInteract, symbolSize); - } - } - } - else - { - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - var dist = Vector3.Distance(chart.pointerPos, serieData.context.position); - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - - if (dist <= symbolSelectedSize) - { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; - serie.interact.SetValue(ref needInteract, lineWidth, true); - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - else - { - serieData.context.highlight = false; - serieData.interact.SetValue(ref needInteract, symbolSize); - } - } - } - if (needInteract) - { - if (SeriesHelper.IsStack(chart.series)) - chart.RefreshTopPainter(); - else - chart.RefreshPainter(serie); - } - } - - private void DrawLineSerie(VertexHelper vh, SimplifiedLine serie) - { - if (!serie.show) - return; - if (serie.animation.HasFadeOut()) - return; - - var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); - - Axis axis; - Axis relativedAxis; - - if (isY) - { - axis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - relativedAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - } - else - { - axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); - relativedAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); - } - m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - - if (axis == null) - return; - if (relativedAxis == null) - return; - if (m_SerieGrid == null) - return; - - var dataZoom = chart.GetDataZoomOfAxis(axis); - var showData = serie.GetDataList(dataZoom); - - if (showData.Count <= 0) - return; - - var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width; - var scaleWid = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom); - - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : - showData.Count; - int rate = LineHelper.GetDataAverageRate(serie, m_SerieGrid, maxCount, false); - var totalAverage = serie.sampleAverage > 0 ? - serie.sampleAverage : - DataHelper.DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate); - var dataChanging = false; - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - - var interacting = false; - var lineWidth = LineHelper.GetLineWidth(ref interacting, serie, chart.theme.serie.lineWidth); - - axis.context.scaleWidth = scaleWid; - serie.containerIndex = m_SerieGrid.index; - serie.containterInstanceId = m_SerieGrid.instanceId; - - for (int i = serie.minShow; i < maxCount; i += rate) - { - var serieData = showData[i]; - var isIgnore = serie.IsIgnoreValue(serieData); - if (isIgnore) - { - serieData.context.stackHeight = 0; - serieData.context.position = Vector3.zero; - if (serie.ignoreLineBreak && serie.context.dataIgnores.Count > 0) - { - serie.context.dataIgnores[serie.context.dataIgnores.Count - 1] = true; - } - } - else - { - var np = Vector3.zero; - var xValue = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse); - var relativedValue = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, - maxCount, totalAverage, i, dataChangeDuration, ref dataChanging, relativedAxis); - - serieData.context.stackHeight = GetDataPoint(isY, axis, relativedAxis, m_SerieGrid, xValue, relativedValue, - i, scaleWid, false, ref np); - - serieData.context.position = np; - - serie.context.dataPoints.Add(np); - serie.context.dataIgnores.Add(false); - } - } - - if (dataChanging || interacting) - chart.RefreshPainter(serie); - - if (serie.context.dataPoints.Count <= 0) - return; - - serie.animation.InitProgress(serie.context.dataPoints, isY); - - LineHelper.UpdateSerieDrawPoints(serie, chart.settings, chart.theme, null, lineWidth, isY); - LineHelper.DrawSerieLineArea(vh, serie, null, chart.theme, null, isY, axis, relativedAxis, m_SerieGrid); - LineHelper.DrawSerieLine(vh, chart.theme, serie, null, m_SerieGrid, axis, relativedAxis, lineWidth); - - serie.context.vertCount = vh.currentVertCount; - - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - chart.RefreshPainter(serie); - } - } - - private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord grid, double xValue, - double yValue, int i, float scaleWid, bool isStack, ref Vector3 np) - { - float xPos, yPos; - var gridXY = isY ? grid.context.x : grid.context.y; - - if (isY) - { - var valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); - valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); - - xPos = gridXY + valueHig; - yPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue); - } - else - { - - var valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue); - valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig); - - yPos = gridXY + valueHig; - xPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue); - } - np = new Vector3(xPos, yPos); - return yPos; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs.meta deleted file mode 100644 index 6a41fe3..0000000 --- a/Assets/XCharts/Runtime/Serie/Line/SimplifiedLineHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3c4714bd08de34548ac7be3ec6523ee1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Parallel.meta b/Assets/XCharts/Runtime/Serie/Parallel.meta deleted file mode 100644 index 60bd75e..0000000 --- a/Assets/XCharts/Runtime/Serie/Parallel.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c2ba7099a74f54617b446aeaf3d95672 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs b/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs deleted file mode 100644 index 9d6b752..0000000 --- a/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(ParallelHandler), true)] - [RequireChartComponent(typeof(ParallelCoord))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField()] - public class Parallel : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Parallel>(serieName); - serie.lineStyle.width = 0.8f; - serie.lineStyle.opacity = 0.6f; - - for (int i = 0; i < 100; i++) - { - var data = new List<double>() - { - Random.Range(0f, 50f), - Random.Range(0f, 100f), - Random.Range(0f, 1000f), - Random.Range(0, 5), - }; - serie.AddData(data, "data" + i); - } - chart.RefreshChart(); - return serie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs.meta b/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs.meta deleted file mode 100644 index 3663842..0000000 --- a/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 283df79138f274a6ba975ff8f30c6d30 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs b/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs deleted file mode 100644 index 38a6453..0000000 --- a/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class ParallelHandler : SerieHandler<Parallel> - { - private List<Vector3> m_Points = new List<Vector3>(); - - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void DrawSerie(VertexHelper vh) - { - DrawParallelSerie(vh, serie); - } - - private void UpdateSerieContext() - { } - - private void DrawParallelSerie(VertexHelper vh, Parallel serie) - { - if (!serie.show) return; - if (serie.animation.HasFadeOut()) return; - - var parallel = chart.GetChartComponent<ParallelCoord>(serie.parallelIndex); - if (parallel == null) - return; - - var axisCount = parallel.context.parallelAxes.Count; - if (axisCount <= 0) - return; - - var animationIndex = serie.animation.GetCurrIndex(); - var isHorizonal = parallel.orient == Orient.Horizonal; - var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex, false); - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - - float currDetailProgress = !isHorizonal ? - parallel.context.x : - parallel.context.y; - - float totalDetailProgress = !isHorizonal ? - parallel.context.x + parallel.context.width : - parallel.context.y + parallel.context.height; - - serie.animation.InitProgress(currDetailProgress, totalDetailProgress); - - serie.context.dataPoints.Clear(); - serie.containerIndex = parallel.index; - serie.containterInstanceId = parallel.instanceId; - - var currProgress = serie.animation.GetCurrDetail(); - var isSmooth = serie.lineType == LineType.Smooth; - foreach (var serieData in serie.data) - { - m_Points.Clear(); - var count = Mathf.Min(axisCount, serieData.data.Count); - var lp = Vector3.zero; - for (int i = 0; i < count; i++) - { - if (animationIndex >= 0 && i > animationIndex) continue; - var pos = GetPos(parallel, i, serieData.data[i], isHorizonal); - if (!isHorizonal) - { - if (isSmooth) - { - m_Points.Add(pos); - } - else if (pos.x <= currProgress) - { - m_Points.Add(pos); - } - else - { - var currProgressStart = new Vector3(currProgress, parallel.context.y - 50); - var currProgressEnd = new Vector3(currProgress, parallel.context.y + parallel.context.height + 50); - var intersectionPos = Vector3.zero; - - if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) - m_Points.Add(intersectionPos); - else - m_Points.Add(pos); - break; - } - } - else - { - if (isSmooth) - { - m_Points.Add(pos); - } - else if (pos.y <= currProgress) - { - m_Points.Add(pos); - } - else - { - var currProgressStart = new Vector3(parallel.context.x - 50, currProgress); - var currProgressEnd = new Vector3(parallel.context.x + parallel.context.width + 50, currProgress); - var intersectionPos = Vector3.zero; - - if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) - m_Points.Add(intersectionPos); - else - m_Points.Add(pos); - break; - } - } - lp = pos; - } - if (isSmooth) - UGL.DrawCurves(vh, m_Points, lineWidth, lineColor, chart.settings.lineSmoothness, currProgress, isHorizonal); - else - UGL.DrawLine(vh, m_Points, lineWidth, lineColor, isSmooth); - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(totalDetailProgress - currDetailProgress); - chart.RefreshPainter(serie); - } - } - - private static ParallelAxis GetAxis(ParallelCoord parallel, int index) - { - if (index >= 0 && index < parallel.context.parallelAxes.Count) - return parallel.context.parallelAxes[index]; - else - return null; - } - - private static Vector3 GetPos(ParallelCoord parallel, int axisIndex, double dataValue, bool isHorizonal) - { - var axis = GetAxis(parallel, axisIndex); - if (axis == null) - return Vector3.zero; - - var sValueDist = axis.GetDistance(dataValue, axis.context.width); - return new Vector3( - isHorizonal ? axis.context.x + sValueDist : axis.context.x, - isHorizonal ? axis.context.y : axis.context.y + sValueDist); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs.meta deleted file mode 100644 index e190cca..0000000 --- a/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 482b461d91f8c4013bf291153d5810e6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Pie.meta b/Assets/XCharts/Runtime/Serie/Pie.meta deleted file mode 100644 index cd666fa..0000000 --- a/Assets/XCharts/Runtime/Serie/Pie.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: a5dfd0cb375a24f659bf56e113aa6fc8 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Pie/Pie.cs b/Assets/XCharts/Runtime/Serie/Pie/Pie.cs deleted file mode 100644 index 3927879..0000000 --- a/Assets/XCharts/Runtime/Serie/Pie/Pie.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieConvert(typeof(Line), typeof(Bar))] - [SerieHandler(typeof(PieHandler), true)] - [DefaultAnimation(AnimationType.Clockwise)] - [SerieExtraComponent(typeof(LabelStyle), typeof(LabelLine), typeof(TitleStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle), typeof(EmphasisLabelLine))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(LabelLine), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle), typeof(EmphasisLabelLine))] - [SerieDataExtraField("m_Ignore", "m_Selected", "m_Radius")] - public class Pie : Serie - { - public override bool useDataNameForColor { get { return true; } } - public override bool titleJustForSerie { get { return true; } } - - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Pie>(serieName); - chart.AddData(serie.index, 70, "pie1"); - chart.AddData(serie.index, 20, "pie2"); - chart.AddData(serie.index, 10, "pie3"); - return serie; - } - - public static Pie CovertSerie(Serie serie) - { - var newSerie = SerieHelper.CloneSerie<Pie>(serie); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Pie/Pie.cs.meta b/Assets/XCharts/Runtime/Serie/Pie/Pie.cs.meta deleted file mode 100644 index 41dba77..0000000 --- a/Assets/XCharts/Runtime/Serie/Pie/Pie.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 53f0d225949a3450e9e90687759f1714 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs b/Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs deleted file mode 100644 index d8ee94a..0000000 --- a/Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs +++ /dev/null @@ -1,564 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class PieHandler : SerieHandler<Pie> - { - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void DrawSerie(VertexHelper vh) - { - UpdateRuntimeData(serie); - DrawPieLabelLine(vh, serie); - DrawPie(vh, serie); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - UpdateItemSerieParams(ref paramList, ref title, dataIndex, category, - marker, itemFormatter, numericFormatter); - } - - public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) - { - var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); - return SerieLabelHelper.GetRealLabelPosition(serie, serieData, label, labelLine); - } - - public override Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle) - { - return serie.context.center; - } - - public override void OnLegendButtonClick(int index, string legendName, bool show) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataShow(serie, legendName, show); - chart.UpdateLegendColor(legendName, show); - chart.RefreshPainter(serie); - } - - public override void OnLegendButtonEnter(int index, string legendName) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataHighlighted(serie, legendName, true); - chart.RefreshPainter(serie); - } - - public override void OnLegendButtonExit(int index, string legendName) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataHighlighted(serie, legendName, false); - chart.RefreshPainter(serie); - } - - public override void OnPointerDown(PointerEventData eventData) - { - if (!chart.HasSerie<Pie>()) return; - if (chart.pointerPos == Vector2.zero) return; - var refresh = false; - for (int i = 0; i < chart.series.Count; i++) - { - var serie = chart.GetSerie(i); - if (!(serie is Pie)) continue; - var index = GetPiePosIndex(serie, chart.pointerPos); - if (index >= 0) - { - refresh = true; - for (int j = 0; j < serie.data.Count; j++) - { - if (j == index) serie.data[j].context.selected = !serie.data[j].context.selected; - else serie.data[j].context.selected = false; - } - if (chart.onPointerClickPie != null) - { - chart.onPointerClickPie(eventData, i, index); - } - } - } - if (refresh) chart.RefreshChart(); - } - - private void UpdateSerieContext() - { - var needCheck = m_LegendEnter || (chart.isPointerInChart && PointerIsInPieSerie(serie, chart.pointerPos)); - var needInteract = false; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName); - var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false); - var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, false); - serieData.context.highlight = false; - serieData.interact.SetValueAndColor(ref needInteract, serieData.context.outsideRadius, color, toColor); - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - return; - } - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - var dataIndex = GetPiePosIndex(serie, chart.pointerPos); - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - if (dataIndex == i || (m_LegendEnter && m_LegendEnterIndex == i)) - { - serie.context.pointerItemDataIndex = i; - serieData.context.highlight = true; - - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName); - var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, true); - var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, true); - var value = serieData.context.outsideRadius + chart.theme.serie.pieTooltipExtraRadius; - serieData.interact.SetValueAndColor(ref needInteract, value, color, toColor); - } - else - { - serieData.context.highlight = false; - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName); - var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false); - var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, false); - serieData.interact.SetValueAndColor(ref needInteract, serieData.context.outsideRadius, color, toColor); - } - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - private void UpdateRuntimeData(Serie serie) - { - var data = serie.data; - serie.context.dataMax = serie.yMax; - serie.context.startAngle = GetStartAngle(serie); - var runtimePieDataTotal = serie.yTotal; - - SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight); - float startDegree = serie.context.startAngle; - float totalDegree = 0; - float zeroReplaceValue = 0; - int showdataCount = 0; - foreach (var sd in serie.data) - { - if (sd.show && serie.pieRoseType == RoseType.Area) showdataCount++; - sd.context.canShowLabel = false; - } - float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1); - var dataTotalFilterMinAngle = runtimePieDataTotal; - if (isAllZeroValue) - { - totalDegree = 360; - zeroReplaceValue = totalDegree / data.Count; - serie.context.dataMax = zeroReplaceValue; - runtimePieDataTotal = 360; - dataTotalFilterMinAngle = 360; - } - else - { - dataTotalFilterMinAngle = GetTotalAngle(serie, runtimePieDataTotal, ref totalDegree); - } - for (int n = 0; n < data.Count; n++) - { - var serieData = data[n]; - serieData.index = n; - var value = isAllZeroValue ? zeroReplaceValue : serieData.GetCurrData(1, dataChangeDuration); - serieData.context.startAngle = startDegree; - serieData.context.toAngle = startDegree; - serieData.context.halfAngle = startDegree; - serieData.context.currentAngle = startDegree; - if (!serieData.show) - { - continue; - } - float degree = serie.pieRoseType == RoseType.Area ? - (totalDegree / showdataCount) : - (float) (totalDegree * value / dataTotalFilterMinAngle); - if (serie.minAngle > 0 && degree < serie.minAngle) degree = serie.minAngle; - serieData.context.toAngle = startDegree + degree; - if (serieData.radius > 0) - serieData.context.outsideRadius = ChartHelper.GetActualValue(serieData.radius, Mathf.Min(chart.chartWidth, chart.chartHeight)); - else - serieData.context.outsideRadius = serie.pieRoseType > 0 ? - serie.context.insideRadius + (float) ((serie.context.outsideRadius - serie.context.insideRadius) * value / serie.context.dataMax) : - serie.context.outsideRadius; - if (serieData.context.highlight) - { - serieData.context.outsideRadius += chart.theme.serie.pieTooltipExtraRadius; - } - var offset = 0f; - if (serie.pieClickOffset && serieData.selected) - { - offset += chart.theme.serie.pieSelectedOffset; - } - if (serie.animation.CheckDetailBreak(serieData.context.toAngle)) - { - serieData.context.currentAngle = serie.animation.GetCurrDetail(); - } - else - { - serieData.context.currentAngle = serieData.context.toAngle; - } - var halfDegree = (serieData.context.toAngle - startDegree) / 2; - serieData.context.halfAngle = startDegree + halfDegree; - serieData.context.offsetCenter = serie.context.center; - serieData.context.insideRadius = serie.context.insideRadius; - if (offset > 0) - { - var currRad = serieData.context.halfAngle * Mathf.Deg2Rad; - var currSin = Mathf.Sin(currRad); - var currCos = Mathf.Cos(currRad); - serieData.context.offsetRadius = 0; - serieData.context.insideRadius -= serieData.context.offsetRadius; - serieData.context.outsideRadius -= serieData.context.offsetRadius; - if (serie.pieClickOffset && serieData.selected) - { - serieData.context.offsetRadius += chart.theme.serie.pieSelectedOffset; - if (serieData.context.insideRadius > 0) - { - serieData.context.insideRadius += chart.theme.serie.pieSelectedOffset; - } - serieData.context.outsideRadius += chart.theme.serie.pieSelectedOffset; - } - serieData.context.offsetCenter = new Vector3( - serie.context.center.x + serieData.context.offsetRadius * currSin, - serie.context.center.y + serieData.context.offsetRadius * currCos); - } - serieData.context.canShowLabel = serieData.context.currentAngle >= serieData.context.halfAngle; - startDegree = serieData.context.toAngle; - SerieLabelHelper.UpdatePieLabelPosition(serie, serieData); - } - SerieLabelHelper.AvoidLabelOverlap(serie, chart.theme.common); - } - - private double GetTotalAngle(Serie serie, double dataTotal, ref float totalAngle) - { - totalAngle = serie.context.startAngle + 360f; - if (serie.minAngle > 0) - { - var rate = serie.minAngle / 360; - var minAngleValue = dataTotal * rate; - foreach (var serieData in serie.data) - { - var value = serieData.GetData(1); - if (value < minAngleValue) - { - totalAngle -= serie.minAngle; - dataTotal -= value; - } - } - return dataTotal; - } - else - { - return dataTotal; - } - } - - private void DrawPieCenter(VertexHelper vh, Serie serie, ItemStyle itemStyle, float insideRadius) - { - if (!ChartHelper.IsClearColor(itemStyle.centerColor)) - { - var radius = insideRadius - itemStyle.centerGap; - UGL.DrawCricle(vh, serie.context.center, radius, itemStyle.centerColor, chart.settings.cicleSmoothness); - } - } - - private void DrawPie(VertexHelper vh, Serie serie) - { - if (!serie.show || serie.animation.HasFadeOut()) - { - return; - } - var dataChanging = false; - var interacting = false; - var color = ColorUtil.clearColor32; - var toColor = ColorUtil.clearColor32; - var data = serie.data; - serie.animation.InitProgress(0, 360); - for (int n = 0; n < data.Count; n++) - { - var serieData = data[n]; - if (!serieData.show) - { - continue; - } - if (serieData.IsDataChanged()) - dataChanging = true; - - var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.context.highlight); - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName); - var outsideRadius = 0f; - - var borderWidth = itemStyle.borderWidth; - var borderColor = itemStyle.borderColor; - - var progress = AnimationStyleHelper.CheckDataAnimation(chart, serie, n, 1); - var insideRadius = serieData.context.insideRadius * progress; - - //if (!serieData.interact.TryGetValueAndColor(ref outsideRadius, ref color, ref toColor, ref interacting)) - { - color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight); - toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight); - outsideRadius = serieData.context.outsideRadius * progress; - serieData.interact.SetValueAndColor(ref interacting, outsideRadius, color, toColor); - } - - if (serie.pieClickOffset && serieData.selected) - { - var drawEndDegree = serieData.context.currentAngle; - var needRoundCap = serie.roundCap && insideRadius > 0; - UGL.DrawDoughnut(vh, serieData.context.offsetCenter, insideRadius, - outsideRadius, color, toColor, Color.clear, serieData.context.startAngle, - drawEndDegree, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness, - needRoundCap, true); - } - else - { - var drawEndDegree = serieData.context.currentAngle; - var needRoundCap = serie.roundCap && insideRadius > 0; - UGL.DrawDoughnut(vh, serie.context.center, insideRadius, - outsideRadius, color, toColor, Color.clear, serieData.context.startAngle, - drawEndDegree, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness, - needRoundCap, true); - DrawPieCenter(vh, serie, itemStyle, insideRadius); - } - - if (serie.animation.CheckDetailBreak(serieData.context.toAngle)) - break; - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(); - serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize)); - chart.RefreshPainter(serie); - } - if (dataChanging) - { - chart.RefreshPainter(serie); - } - } - - private bool IsAnyPieClickOffset() - { - foreach (var serie in chart.series) - { - if (serie is Pie && serie.pieClickOffset) - return true; - } - return false; - } - - private bool IsAnyPieDataHighlight() - { - foreach (var serie in chart.series) - { - if (serie is Pie) - { - foreach (var serieData in serie.data) - { - if (serieData.context.highlight) - return true; - } - } - } - return false; - } - - private void DrawPieLabelLine(VertexHelper vh, Serie serie) - { - foreach (var serieData in serie.data) - { - var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - if (SerieLabelHelper.CanShowLabel(serie, serieData, serieLabel, 1)) - { - int colorIndex = chart.m_LegendRealShowName.IndexOf(serieData.name); - Color color = chart.theme.GetColor(colorIndex); - DrawPieLabelLine(vh, serie, serieData, color); - } - } - } - - private void DrawPieLabelLine(VertexHelper vh, Serie serie, SerieData serieData, Color color) - { - var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData); - if (serieLabel != null && serieLabel.show && - labelLine != null && labelLine.show && - (serieLabel.IsDefaultPosition(LabelStyle.Position.Outside))) - { - var insideRadius = serieData.context.insideRadius; - var outSideRadius = serieData.context.outsideRadius; - var center = serie.context.center; - var currAngle = serieData.context.halfAngle; - - if (!ChartHelper.IsClearColor(labelLine.lineColor)) - color = labelLine.lineColor; - else if (labelLine.lineType == LabelLine.LineType.HorizontalLine) - color *= color; - - float currSin = Mathf.Sin(currAngle * Mathf.Deg2Rad); - float currCos = Mathf.Cos(currAngle * Mathf.Deg2Rad); - var radius1 = labelLine.lineType == LabelLine.LineType.HorizontalLine ? - serie.context.outsideRadius : outSideRadius; - var radius2 = serie.context.outsideRadius + labelLine.lineLength1; - var radius3 = insideRadius + (outSideRadius - insideRadius) / 2; - if (radius1 < serie.context.insideRadius) radius1 = serie.context.insideRadius; - radius1 -= 0.1f; - var pos0 = new Vector3(center.x + radius3 * currSin, center.y + radius3 * currCos); - var pos1 = new Vector3(center.x + radius1 * currSin, center.y + radius1 * currCos); - var pos2 = serieData.context.labelPosition; - if (pos2.x == 0) - { - pos2 = new Vector3(center.x + radius2 * currSin, center.y + radius2 * currCos); - } - Vector3 pos4, pos6; - var horizontalLineCircleRadius = labelLine.lineWidth * 4f; - var lineCircleDiff = horizontalLineCircleRadius - 0.3f; - var startAngle = serie.context.startAngle; - if (currAngle < 90) - { - var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3; - r4 += labelLine.lineLength1 - lineCircleDiff; - pos6 = pos0 + Vector3.right * lineCircleDiff; - pos4 = pos6 + Vector3.right * r4; - } - else if (currAngle < 180) - { - var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3; - r4 += labelLine.lineLength1 - lineCircleDiff; - pos6 = pos0 + Vector3.right * lineCircleDiff; - pos4 = pos6 + Vector3.right * r4; - } - else if (currAngle < 270) - { - var currSin1 = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad); - var currCos1 = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad); - var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos1 * radius3, 2)) - currSin1 * radius3; - r4 += labelLine.lineLength1 - lineCircleDiff; - pos6 = pos0 + Vector3.left * lineCircleDiff; - pos4 = pos6 + Vector3.left * r4; - } - else - { - var currSin1 = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad); - var currCos1 = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad); - var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos1 * radius3, 2)) - currSin1 * radius3; - r4 += labelLine.lineLength1 - lineCircleDiff; - pos6 = pos0 + Vector3.left * lineCircleDiff; - pos4 = pos6 + Vector3.left * r4; - } - var pos5X = (currAngle - startAngle) % 360 > 180 ? - pos2.x - labelLine.lineLength2 : pos2.x + labelLine.lineLength2; - var pos5 = new Vector3(pos5X, pos2.y); - switch (labelLine.lineType) - { - case LabelLine.LineType.BrokenLine: - UGL.DrawLine(vh, pos1, pos2, pos5, labelLine.lineWidth, color); - break; - case LabelLine.LineType.Curves: - UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, labelLine.lineWidth, color, - chart.settings.lineSmoothness); - break; - case LabelLine.LineType.HorizontalLine: - UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color); - UGL.DrawLine(vh, pos6, pos4, labelLine.lineWidth, color); - break; - } - } - } - - private int GetPiePosIndex(Serie serie, Vector2 local) - { - if (!(serie is Pie)) - return -1; - - var dist = Vector2.Distance(local, serie.context.center); - var maxRadius = serie.context.outsideRadius + 3 * chart.theme.serie.pieSelectedOffset; - if (dist < serie.context.insideRadius || dist > maxRadius) - return -1; - - var dir = local - new Vector2(serie.context.center.x, serie.context.center.y); - var angle = ChartHelper.GetAngle360(Vector2.up, dir); - for (int i = 0; i < serie.data.Count; i++) - { - var serieData = serie.data[i]; - if (angle >= serieData.context.startAngle && angle <= serieData.context.toAngle) - { - var ndist = serieData.selected ? - Vector2.Distance(local, serieData.context.offsetCenter) : - dist; - if (ndist >= serieData.context.insideRadius && ndist <= serieData.context.outsideRadius) - { - return i; - } - } - } - return -1; - } - - private bool PointerIsInPieSerie(Serie serie, Vector2 local) - { - if (!(serie is Pie)) - return false; - - var dist = Vector2.Distance(local, serie.context.center); - if (dist >= serie.context.insideRadius && dist <= serie.context.outsideRadius) - return true; - - return false; - } - - private float GetStartAngle(Serie serie) - { - return serie.clockwise ? (serie.startAngle + 360) % 360 : 360 - serie.startAngle; - } - - private float GetToAngle(Serie serie, float angle) - { - var toAngle = angle + serie.startAngle; - if (!serie.clockwise) - { - toAngle = 360 - angle - serie.startAngle; - } - if (!serie.animation.IsFinish()) - { - var currAngle = serie.animation.GetCurrDetail(); - if (serie.clockwise) - { - toAngle = toAngle > currAngle ? currAngle : toAngle; - } - else - { - toAngle = toAngle < 360 - currAngle ? 360 - currAngle : toAngle; - } - } - return toAngle; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs.meta deleted file mode 100644 index 3c1fddb..0000000 --- a/Assets/XCharts/Runtime/Serie/Pie/PieHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 13b8c981e5910447fbe769d539b77f96 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Radar.meta b/Assets/XCharts/Runtime/Serie/Radar.meta deleted file mode 100644 index 15c0c0c..0000000 --- a/Assets/XCharts/Runtime/Serie/Radar.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 375cebcd4f8c54025ab608f35b1fa8c6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Radar/Radar.cs b/Assets/XCharts/Runtime/Serie/Radar/Radar.cs deleted file mode 100644 index 8af45a9..0000000 --- a/Assets/XCharts/Runtime/Serie/Radar/Radar.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(RadarHandler), true)] - [RequireChartComponent(typeof(RadarCoord))] - [SerieExtraComponent(typeof(LabelStyle), typeof(AreaStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(AreaStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField()] - public class Radar : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - public override bool useDataNameForColor { get { return true; } } - public override bool multiDimensionLabel { get { return radarType == RadarType.Multiple; } } - - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - chart.AddChartComponentWhenNoExist<RadarCoord>(); - var serie = chart.AddSerie<Radar>(serieName); - serie.symbol.show = true; - serie.symbol.type = SymbolType.Circle; - serie.showDataName = true; - List<double> data = new List<double>(); - for (int i = 0; i < 5; i++) - { - data.Add(Random.Range(20, 90)); - } - chart.AddData(serie.index, data, "legendName"); - return serie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Radar/Radar.cs.meta b/Assets/XCharts/Runtime/Serie/Radar/Radar.cs.meta deleted file mode 100644 index 1e2b8e5..0000000 --- a/Assets/XCharts/Runtime/Serie/Radar/Radar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0bda9968e18724e389ff1cbde57baeee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs b/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs deleted file mode 100644 index 374455d..0000000 --- a/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs +++ /dev/null @@ -1,504 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class RadarHandler : SerieHandler<Radar> - { - private RadarCoord m_RadarCoord; - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - public override void DrawSerie(VertexHelper vh) - { - if (!serie.show) return; - switch (serie.radarType) - { - case RadarType.Multiple: - DrawMutipleRadar(vh); - break; - case RadarType.Single: - DrawSingleRadar(vh); - break; - } - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - if (!serie.context.pointerEnter) - return; - dataIndex = serie.context.pointerItemDataIndex; - if (dataIndex < 0) - return; - - if (serie.radarType == RadarType.Single) - { - UpdateItemSerieParams(ref paramList, ref title, dataIndex, category, - marker, itemFormatter, numericFormatter); - return; - } - - var radar = chart.GetChartComponent<RadarCoord>(serie.radarIndex); - if (radar == null) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, dataIndex, false);; - title = serieData.name; - for (int i = 0; i < serieData.data.Count; i++) - { - var indicator = radar.GetIndicator(i); - if (indicator == null) continue; - - var param = new SerieParams(); - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.dimension = i; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = serieData.GetData(i); - param.total = indicator.max; - param.color = color; - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(indicator.name); - param.columns.Add(ChartCached.NumberToStr(serieData.GetData(i), param.numericFormatter)); - - paramList.Add(param); - } - } - - private void UpdateSerieContext() - { - var needCheck = m_LegendEnter || - (chart.isPointerInChart && (m_RadarCoord != null && m_RadarCoord.IsPointerEnter())); - var needInteract = false; - var needHideAll = false; - if (!needCheck) - { - if (m_LastCheckContextFlag == needCheck) - return; - needHideAll = true; - } - m_LastCheckContextFlag = needCheck; - serie.context.pointerEnter = false; - serie.context.pointerItemDataIndex = -1; - var areaStyle = serie.areaStyle; - switch (serie.radarType) - { - case RadarType.Multiple: - for (int i = 0; i < serie.data.Count; i++) - { - var serieData = serie.data[i]; - serieData.index = i; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); - if (needHideAll || m_LegendEnter) - { - serieData.context.highlight = needHideAll ? false : true; - serieData.interact.SetValue(ref needInteract, symbolSize, serieData.context.highlight); - } - else - { - serieData.context.highlight = false; - foreach (var pos in serieData.context.dataPoints) - { - if (Vector3.Distance(chart.pointerPos, pos) < symbolSize * 2) - { - serie.context.pointerEnter = true; - serie.context.pointerItemDataIndex = i; - serieData.context.highlight = true; - break; - } - } - if (!serieData.context.highlight && areaStyle != null) - { - var center = m_RadarCoord.context.center; - var dataPoints = serieData.context.dataPoints; - for (int n = 0; n < dataPoints.Count; n++) - { - var p1 = dataPoints[n]; - var p2 = n >= dataPoints.Count - 1 ? dataPoints[0] : dataPoints[n + 1]; - if (UGLHelper.IsPointInTriangle(p1, center, p2, chart.pointerPos)) - { - serie.context.pointerEnter = true; - serie.context.pointerItemDataIndex = i; - serieData.context.highlight = true; - break; - } - } - } - serieData.interact.SetValue(ref needInteract, symbolSize, serieData.context.highlight); - } - } - break; - case RadarType.Single: - for (int i = 0; i < serie.data.Count; i++) - { - var serieData = serie.data[i]; - serieData.index = i; - if (Vector3.Distance(chart.pointerPos, serieData.context.position) < serie.symbol.size * 2) - { - serie.context.pointerEnter = true; - serie.context.pointerItemDataIndex = i; - return; - } - } - if (!serie.context.pointerEnter && areaStyle != null) - { - var center = m_RadarCoord.context.center; - var dataPoints = serie.data; - for (int n = 0; n < dataPoints.Count; n++) - { - var p1 = dataPoints[n]; - var p2 = n >= dataPoints.Count - 1 ? dataPoints[0] : dataPoints[n + 1]; - if (UGLHelper.IsPointInTriangle(p1.context.position, center, p2.context.position, chart.pointerPos)) - { - serie.context.pointerEnter = true; - serie.context.pointerItemDataIndex = n; - p1.context.highlight = true; - break; - } - } - } - break; - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - private void DrawMutipleRadar(VertexHelper vh) - { - if (!serie.show) return; - m_RadarCoord = chart.GetChartComponent<RadarCoord>(serie.radarIndex); - if (m_RadarCoord == null) return; - - serie.containerIndex = m_RadarCoord.index; - serie.containterInstanceId = m_RadarCoord.instanceId; - - var startPoint = Vector3.zero; - var toPoint = Vector3.zero; - var firstPoint = Vector3.zero; - var indicatorNum = m_RadarCoord.indicatorList.Count; - var angle = 2 * Mathf.PI / indicatorNum; - var centerPos = m_RadarCoord.context.center; - serie.animation.InitProgress(0, 1); - if (!serie.show || serie.animation.HasFadeOut()) - { - return; - } - var rate = serie.animation.GetCurrRate(); - var dataChanging = false; - var interacting = false; - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - SerieHelper.GetAllMinMaxData(serie, m_RadarCoord.ceilRate); - for (int j = 0; j < serie.data.Count; j++) - { - var serieData = serie.data[j]; - string dataName = serieData.name; - if (!serieData.show) - { - continue; - } - var lineStyle = SerieHelper.GetLineStyle(serie, serieData); - var areaStyle = SerieHelper.GetAreaStyle(serie, serieData); - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var isHighlight = serieData.context.highlight; - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName); - var areaColor = SerieHelper.GetAreaColor(serie, serieData, chart.theme, colorIndex, isHighlight); - var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, colorIndex, isHighlight); - var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, colorIndex, isHighlight); - var lineWidth = lineStyle.GetWidth(chart.theme.serie.lineWidth); - int dataCount = m_RadarCoord.indicatorList.Count; - serieData.context.dataPoints.Clear(); - for (int n = 0; n < dataCount; n++) - { - if (n >= serieData.data.Count) break; - var min = m_RadarCoord.GetIndicatorMin(n); - var max = m_RadarCoord.GetIndicatorMax(n); - var value = serieData.GetCurrData(n, dataChangeDuration); - if (serieData.IsDataChanged()) dataChanging = true; - if (max == 0) - { - if (serie.data.Count > 1) - { - SerieHelper.GetMinMaxData(serie, n, out min, out max); - min = ChartHelper.GetMinDivisibleValue(min, 0); - max = ChartHelper.GetMaxDivisibleValue(max, 0); - if (min > 0) min = 0; - } - else - { - max = serie.context.dataMax; - } - } - var radius = (float) (m_RadarCoord.context.dataRadius * (value - min) / (max - min)); - var currAngle = (n + (m_RadarCoord.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle; - radius *= rate; - if (n == 0) - { - startPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle), - centerPos.y + radius * Mathf.Cos(currAngle)); - firstPoint = startPoint; - } - else - { - toPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle), - centerPos.y + radius * Mathf.Cos(currAngle)); - if (areaStyle != null && areaStyle.show) - { - UGL.DrawTriangle(vh, startPoint, toPoint, centerPos, areaColor, areaColor, areaToColor); - } - if (lineStyle.show) - { - ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, toPoint, lineColor); - } - startPoint = toPoint; - } - serieData.context.dataPoints.Add(startPoint); - } - if (areaStyle != null && areaStyle.show) - { - UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor); - } - if (lineStyle.show) - { - ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, firstPoint, lineColor); - } - if (symbol.show && symbol.type != SymbolType.None) - { - for (int m = 0; m < serieData.context.dataPoints.Count; m++) - { - var point = serieData.context.dataPoints[m]; - var symbolSize = isHighlight ? - symbol.GetSelectedSize(null, chart.theme.serie.lineSymbolSelectedSize) : - symbol.GetSize(null, chart.theme.serie.lineSymbolSize); - if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting)) - { - symbolSize = isHighlight ? - symbol.GetSelectedSize(serieData.data, symbolSize) : - symbol.GetSize(serieData.data, symbolSize); - serieData.interact.SetValue(ref interacting, symbolSize); - symbolSize = serie.animation.GetSysmbolSize(symbolSize); - } - var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, j, isHighlight); - var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, j, isHighlight); - var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, j, isHighlight, false); - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); - chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, symbolEmptyColor, borderColor, symbol.gap, cornerRadius); - } - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(1); - chart.RefreshPainter(serie); - } - if (dataChanging || interacting) - { - chart.RefreshPainter(serie); - } - } - - private void DrawSingleRadar(VertexHelper vh) - { - var radar = chart.GetChartComponent<RadarCoord>(serie.radarIndex); - if (radar == null) - return; - - var indicatorNum = radar.indicatorList.Count; - var angle = 2 * Mathf.PI / indicatorNum; - var centerPos = radar.context.center; - serie.animation.InitProgress(0, 1); - serie.context.dataPoints.Clear(); - if (!serie.show || serie.animation.HasFadeOut()) - { - return; - } - var startPoint = Vector3.zero; - var toPoint = Vector3.zero; - var firstPoint = Vector3.zero; - var lastColor = ColorUtil.clearColor32; - var firstColor = ColorUtil.clearColor32; - - var rate = serie.animation.GetCurrRate(); - var dataChanging = false; - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var startIndex = GetStartShowIndex(serie); - var endIndex = GetEndShowIndex(serie); - SerieHelper.UpdateMinMaxData(serie, 1, radar.ceilRate); - for (int j = 0; j < serie.data.Count; j++) - { - var serieData = serie.data[j]; - serieData.index = j; - string dataName = serieData.name; - - if (!serieData.show) - { - serieData.context.labelPosition = Vector3.zero; - continue; - } - var lineStyle = SerieHelper.GetLineStyle(serie, serieData); - var areaStyle = SerieHelper.GetAreaStyle(serie, serieData); - var isHighlight = serie.context.pointerEnter; - var areaColor = SerieHelper.GetAreaColor(serie, serieData, chart.theme, j, isHighlight); - var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, j, isHighlight); - var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, j, isHighlight); - int dataCount = radar.indicatorList.Count; - var index = serieData.index; - var p = radar.context.center; - var max = radar.GetIndicatorMax(index); - var value = serieData.GetCurrData(1, dataChangeDuration); - if (serieData.IsDataChanged()) dataChanging = true; - if (max == 0) - { - max = serie.context.dataMax; - } - if (!radar.IsInIndicatorRange(j, serieData.GetData(1))) - { - lineColor = radar.outRangeColor; - } - var radius = (float) (max < 0 ? radar.context.dataRadius - radar.context.dataRadius * value / max : - radar.context.dataRadius * value / max); - var currAngle = (index + (radar.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle; - radius *= rate; - if (index == startIndex) - { - startPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle), - p.y + radius * Mathf.Cos(currAngle)); - firstPoint = startPoint; - lastColor = lineColor; - firstColor = lineColor; - } - else - { - toPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle), - p.y + radius * Mathf.Cos(currAngle)); - if (areaStyle != null && areaStyle.show) - { - UGL.DrawTriangle(vh, startPoint, toPoint, p, areaColor, areaColor, areaToColor); - } - if (lineStyle.show) - { - if (radar.connectCenter) - ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos, - chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor); - ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, toPoint, chart.theme.serie.lineWidth, - LineStyle.Type.Solid, radar.lineGradient ? lastColor : lineColor, lineColor); - } - startPoint = toPoint; - lastColor = lineColor; - } - serieData.context.position = startPoint; - serieData.context.labelPosition = startPoint; - - if (areaStyle != null && areaStyle.show && j == endIndex) - { - UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor); - } - if (lineStyle.show && j == endIndex) - { - if (radar.connectCenter) - ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos, - chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor); - ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, firstPoint, chart.theme.serie.lineWidth, - LineStyle.Type.Solid, lineColor, radar.lineGradient ? firstColor : lineColor); - } - } - if (serie.symbol.show && serie.symbol.type != SymbolType.None) - { - for (int j = 0; j < serie.data.Count; j++) - { - var serieData = serie.data[j]; - if (!serieData.show) continue; - var isHighlight = serie.highlight || serieData.context.highlight || serie.context.pointerEnter; - var serieIndex = serieData.index; - var symbolSize = isHighlight ? - serie.symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSelectedSize) : - serie.symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); - var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieIndex, isHighlight); - var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight); - var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serieIndex, isHighlight, false); - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); - if (!radar.IsInIndicatorRange(j, serieData.GetData(1))) - { - symbolColor = radar.outRangeColor; - symbolToColor = radar.outRangeColor; - } - chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.context.labelPosition, symbolColor, - symbolToColor, symbolEmptyColor, borderColor, serie.symbol.gap, cornerRadius); - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(1); - chart.RefreshPainter(serie); - } - if (dataChanging) - { - chart.RefreshPainter(serie); - } - } - - private int GetStartShowIndex(Serie serie) - { - for (int i = 0; i < serie.dataCount; i++) - { - if (serie.data[i].show) return i; - } - return 0; - } - private int GetEndShowIndex(Serie serie) - { - for (int i = serie.dataCount - 1; i >= 0; i--) - { - if (serie.data[i].show) return i; - } - return 0; - } - - private void DrawRadarSymbol(VertexHelper vh, Serie serie, SerieData serieData, int serieIndex, bool isHighlight, - List<Vector3> pointList) - { - if (serie.symbol.show && serie.symbol.type != SymbolType.None) - { - var symbolSize = isHighlight ? - serie.symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSelectedSize) : - serie.symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); - var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieIndex, isHighlight); - var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight); - var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serieIndex, isHighlight, false); - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); - foreach (var point in pointList) - { - chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, symbolEmptyColor, borderColor, serie.symbol.gap, cornerRadius); - } - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs.meta deleted file mode 100644 index 5a455a2..0000000 --- a/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c8dd73709db7a4451b2fe6f03476cb7f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Ring.meta b/Assets/XCharts/Runtime/Serie/Ring.meta deleted file mode 100644 index 98724f6..0000000 --- a/Assets/XCharts/Runtime/Serie/Ring.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c15a1b60f1d3c4daca1fcd88d96ae7e7 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Ring/Ring.cs b/Assets/XCharts/Runtime/Serie/Ring/Ring.cs deleted file mode 100644 index d97cdb4..0000000 --- a/Assets/XCharts/Runtime/Serie/Ring/Ring.cs +++ /dev/null @@ -1,44 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(RingHandler), true)] - [SerieExtraComponent(typeof(LabelStyle), typeof(TitleStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(TitleStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField()] - public class Ring : Serie - { - public override bool useDataNameForColor { get { return true; } } - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Ring>(serieName); - serie.roundCap = true; - serie.gap = 10; - serie.radius = new float[] { 0.3f, 0.35f }; - - var label = serie.AddExtraComponent<LabelStyle>(); - label.show = true; - label.position = LabelStyle.Position.Center; - label.formatter = "{d:f0}%"; - label.textStyle.autoColor = true; - label.textStyle.fontSize = 28; - - var titleStyle = serie.AddExtraComponent<TitleStyle>(); - titleStyle.show = false; - titleStyle.offset = new Vector2(0, 30); - - var value = Random.Range(30, 90); - var max = 100; - chart.AddData(serie.index, value, max, "data1"); - return serie; - } - - public override double GetDataTotal(int dimension, SerieData serieData = null) - { - if (serieData == null || serieData.data.Count <= 1) - return base.GetDataTotal(dimension, serieData); - return serieData.GetData(1); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Ring/Ring.cs.meta b/Assets/XCharts/Runtime/Serie/Ring/Ring.cs.meta deleted file mode 100644 index c069450..0000000 --- a/Assets/XCharts/Runtime/Serie/Ring/Ring.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0c7fe8316f26241d8a9f4b3ce94d61bc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs b/Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs deleted file mode 100644 index 70c5f40..0000000 --- a/Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs +++ /dev/null @@ -1,323 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class RingHandler : SerieHandler<Ring> - { - - public override int defaultDimension { get { return 0; } } - - public override void Update() - { - base.Update(); - UpdateSerieContext(); - } - - private void UpdateSerieContext() - { - var needCheck = chart.isPointerInChart || m_LegendEnter; - var needInteract = false; - if (!needCheck) - { - if (m_LastCheckContextFlag != needCheck) - { - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - foreach (var serieData in serie.data) - { - serieData.context.highlight = false; - } - chart.RefreshPainter(serie); - } - return; - } - m_LastCheckContextFlag = needCheck; - if (m_LegendEnter) - { - serie.context.pointerEnter = true; - foreach (var serieData in serie.data) - { - serieData.context.highlight = true; - } - } - else - { - serie.context.pointerEnter = false; - serie.context.pointerItemDataIndex = -1; - var ringIndex = GetRingIndex(chart.pointerPos); - foreach (var serieData in serie.data) - { - if (!needInteract && ringIndex == serieData.index) - { - serie.context.pointerEnter = true; - serie.context.pointerItemDataIndex = ringIndex; - serieData.context.highlight = true; - needInteract = true; - } - else - { - serieData.context.highlight = false; - } - } - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - if (dataIndex < 0) - dataIndex = serie.context.pointerItemDataIndex; - - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.category = category; - param.dimension = defaultDimension; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = serieData.GetData(0); - param.total = serieData.GetData(1); - param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, dataIndex, false); - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);; - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(serieData.name); - param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); - - paramList.Add(param); - } - - public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) - { - var centerRadius = (serieData.context.outsideRadius + serieData.context.insideRadius) / 2; - var startAngle = serieData.context.startAngle; - var toAngle = serieData.context.toAngle; - switch (label.position) - { - case LabelStyle.Position.Bottom: - case LabelStyle.Position.Start: - var px1 = Mathf.Sin(startAngle * Mathf.Deg2Rad) * centerRadius; - var py1 = Mathf.Cos(startAngle * Mathf.Deg2Rad) * centerRadius; - var xDiff = serie.clockwise ? -label.distance : label.distance; - serieData.context.labelPosition = serie.context.center + new Vector3(px1 + xDiff, py1); - break; - case LabelStyle.Position.Top: - case LabelStyle.Position.End: - startAngle += serie.clockwise ? -label.distance : label.distance; - toAngle += serie.clockwise ? label.distance : -label.distance; - var px2 = Mathf.Sin(toAngle * Mathf.Deg2Rad) * centerRadius; - var py2 = Mathf.Cos(toAngle * Mathf.Deg2Rad) * centerRadius; - serieData.context.labelPosition = serie.context.center + new Vector3(px2, py2); - break; - default: //LabelStyle.Position.Center - serieData.context.labelPosition = serie.context.center + label.offset; - break; - } - return serieData.context.labelPosition; - } - - public override void DrawSerie(VertexHelper vh) - { - if (!serie.show || serie.animation.HasFadeOut()) return; - var data = serie.data; - serie.animation.InitProgress(serie.startAngle, serie.startAngle + 360); - SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight); - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var ringWidth = serie.context.outsideRadius - serie.context.insideRadius; - var dataChanging = false; - for (int j = 0; j < data.Count; j++) - { - var serieData = data[j]; - serieData.index = j; - if (!serieData.show) continue; - if (serieData.IsDataChanged()) dataChanging = true; - var value = serieData.GetFirstData(dataChangeDuration); - var max = serieData.GetLastData(); - var degree = (float) (360 * value / max); - var startDegree = GetStartAngle(serie); - var toDegree = GetToAngle(serie, degree); - var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.context.highlight); - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName); - var itemColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight); - var itemToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight); - var outsideRadius = serie.context.outsideRadius - j * (ringWidth + serie.gap); - var insideRadius = outsideRadius - ringWidth; - var borderWidth = itemStyle.borderWidth; - var borderColor = itemStyle.borderColor; - var roundCap = serie.roundCap && insideRadius > 0; - - serieData.context.startAngle = serie.clockwise ? startDegree : toDegree; - serieData.context.toAngle = serie.clockwise ? toDegree : startDegree; - serieData.context.insideRadius = insideRadius; - serieData.context.outsideRadius = serieData.radius > 0 ? serieData.radius : outsideRadius; - DrawBackground(vh, serie, serieData, j, insideRadius, outsideRadius); - UGL.DrawDoughnut(vh, serie.context.center, insideRadius, outsideRadius, itemColor, itemToColor, - Color.clear, startDegree, toDegree, borderWidth, borderColor, 0, chart.settings.cicleSmoothness, - roundCap, serie.clockwise); - DrawCenter(vh, serie, serieData, insideRadius, j == data.Count - 1); - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(360); - chart.RefreshChart(); - } - if (dataChanging) - { - chart.RefreshChart(); - } - } - - public override void OnLegendButtonClick(int index, string legendName, bool show) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataShow(serie, legendName, show); - chart.UpdateLegendColor(legendName, show); - chart.RefreshPainter(serie); - } - - public override void OnLegendButtonEnter(int index, string legendName) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataHighlighted(serie, legendName, true); - chart.RefreshPainter(serie); - } - - public override void OnLegendButtonExit(int index, string legendName) - { - if (!serie.IsLegendName(legendName)) - return; - LegendHelper.CheckDataHighlighted(serie, legendName, false); - chart.RefreshPainter(serie); - } - - public override void OnPointerDown(PointerEventData eventData) - { } - - private float GetStartAngle(Serie serie) - { - return serie.clockwise ? serie.startAngle : 360 - serie.startAngle; - } - - private float GetToAngle(Serie serie, float angle) - { - var toAngle = angle + serie.startAngle; - if (!serie.clockwise) - { - toAngle = 360 - angle - serie.startAngle; - } - if (!serie.animation.IsFinish()) - { - var currAngle = serie.animation.GetCurrDetail(); - if (serie.clockwise) - { - toAngle = toAngle > currAngle ? currAngle : toAngle; - } - else - { - toAngle = toAngle < 360 - currAngle ? 360 - currAngle : toAngle; - } - } - return toAngle; - } - - private void DrawCenter(VertexHelper vh, Serie serie, SerieData serieData, float insideRadius, bool last) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - if (!ChartHelper.IsClearColor(itemStyle.centerColor) && last) - { - var radius = insideRadius - itemStyle.centerGap; - var smoothness = chart.settings.cicleSmoothness; - UGL.DrawCricle(vh, serie.context.center, radius, itemStyle.centerColor, smoothness); - } - } - - private void DrawBackground(VertexHelper vh, Serie serie, SerieData serieData, int index, float insideRadius, float outsideRadius) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, index, false); - if (itemStyle.backgroundWidth != 0) - { - var centerRadius = (outsideRadius + insideRadius) / 2; - var inradius = centerRadius - itemStyle.backgroundWidth / 2; - var outradius = centerRadius + itemStyle.backgroundWidth / 2; - UGL.DrawDoughnut(vh, serie.context.center, inradius, - outradius, backgroundColor, Color.clear, chart.settings.cicleSmoothness); - } - else - { - UGL.DrawDoughnut(vh, serie.context.center, insideRadius, - outsideRadius, backgroundColor, Color.clear, chart.settings.cicleSmoothness); - } - } - - private void DrawBorder(VertexHelper vh, Serie serie, SerieData serieData, float insideRadius, float outsideRadius) - { - var itemStyle = SerieHelper.GetItemStyle(serie, serieData); - if (itemStyle.show && itemStyle.borderWidth > 0 && !ChartHelper.IsClearColor(itemStyle.borderColor)) - { - UGL.DrawDoughnut(vh, serie.context.center, outsideRadius, - outsideRadius + itemStyle.borderWidth, itemStyle.borderColor, - Color.clear, chart.settings.cicleSmoothness); - UGL.DrawDoughnut(vh, serie.context.center, insideRadius, - insideRadius + itemStyle.borderWidth, itemStyle.borderColor, - Color.clear, chart.settings.cicleSmoothness); - } - } - - private int GetRingIndex(Vector2 local) - { - var dist = Vector2.Distance(local, serie.context.center); - if (dist > serie.context.outsideRadius) return -1; - Vector2 dir = local - new Vector2(serie.context.center.x, serie.context.center.y); - float angle = VectorAngle(Vector2.up, dir); - for (int i = 0; i < serie.data.Count; i++) - { - var serieData = serie.data[i]; - serieData.index = i; - if (dist >= serieData.context.insideRadius && - dist <= serieData.context.outsideRadius && - angle >= serieData.context.startAngle && - angle <= serieData.context.toAngle) - { - return i; - } - } - return -1; - } - - private float VectorAngle(Vector2 from, Vector2 to) - { - float angle; - - Vector3 cross = Vector3.Cross(from, to); - angle = Vector2.Angle(from, to); - angle = cross.z > 0 ? -angle : angle; - angle = (angle + 360) % 360; - return angle; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs.meta deleted file mode 100644 index 293edfb..0000000 --- a/Assets/XCharts/Runtime/Serie/Ring/RingHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8c3c486efd6d8464a88d8f4b572b7bc4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter.meta b/Assets/XCharts/Runtime/Serie/Scatter.meta deleted file mode 100644 index 916354d..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 97fc5bddab1db4321aa7377ab8b8b8bc -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs b/Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs deleted file mode 100644 index bb0cbb5..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace XCharts.Runtime -{ - [System.Serializable] - public class BaseScatter : Serie, INeedSerieContainer - { - public int containerIndex { get; internal set; } - public int containterInstanceId { get; internal set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs.meta b/Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs.meta deleted file mode 100644 index 8b9933e..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dba0ca827ad4d4b9989def35aba66665 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs b/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs deleted file mode 100644 index f8a3aa7..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs +++ /dev/null @@ -1,350 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal class BaseScatterHandler<T> : SerieHandler<T> where T : BaseScatter - { - private GridCoord m_Grid; - - public override void Update() - { - UpdateSerieContext(); - } - - public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category, - string marker, string itemFormatter, string numericFormatter, - ref List<SerieParams> paramList, ref string title) - { - dataIndex = serie.context.pointerItemDataIndex; - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - title = serie.serieName; - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.category = category; - param.dimension = 1; - param.dataCount = serie.dataCount; - param.serieData = serieData; - param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - param.columns.Clear(); - - param.columns.Add(param.marker); - if (!string.IsNullOrEmpty(serieData.name)) - param.columns.Add(serieData.name); - param.columns.Add(ChartCached.NumberToStr(serieData.GetData(1), param.numericFormatter)); - - paramList.Add(param); - } - - public override void DrawSerie(VertexHelper vh) - { - if (serie.IsUseCoord<SingleAxisCoord>()) - { - DrawSingAxisScatterSerie(vh, serie); - } - else if (serie.IsUseCoord<GridCoord>()) - { - DrawScatterSerie(vh, serie); - } - } - - private void UpdateSerieContext() - { - var needCheck = m_LegendEnter || (chart.isPointerInChart && (m_Grid == null || m_Grid.IsPointerEnter())); - - var needHideAll = false; - if (!needCheck) - { - if (m_LastCheckContextFlag == needCheck) - return; - needHideAll = true; - } - m_LastCheckContextFlag = needCheck; - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - var themeSymbolSize = chart.theme.serie.scatterSymbolSize; - var themeSymbolSelectedSize = chart.theme.serie.scatterSymbolSelectedSize; - var needInteract = false; - for (int i = serie.dataCount - 1; i >= 0; i--) - { - var serieData = serie.data[i]; - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize); - var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize); - if (m_LegendEnter || - (!needHideAll && Vector3.Distance(serieData.context.position, chart.pointerPos) <= symbolSize)) - { - serie.context.pointerItemDataIndex = i; - serie.context.pointerEnter = true; - serieData.context.highlight = true; - serieData.interact.SetValue(ref needInteract, symbolSelectedSize); - } - else - { - serieData.context.highlight = false; - serieData.interact.SetValue(ref needInteract, symbolSize); - } - } - if (needInteract) - { - chart.RefreshPainter(serie); - } - } - - protected virtual void DrawScatterSerie(VertexHelper vh, BaseScatter serie) - { - if (serie.animation.HasFadeOut()) - return; - - if (!serie.show) - return; - - XAxis xAxis; - if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) - return; - - YAxis yAxis; - if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) - return; - - if (!chart.TryGetChartComponent<GridCoord>(out m_Grid, xAxis.gridIndex)) - return; - - DataZoom xDataZoom; - DataZoom yDataZoom; - chart.GetDataZoomOfSerie(serie, out xDataZoom, out yDataZoom); - - var theme = chart.theme; - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > serie.dataCount ? serie.dataCount : serie.maxShow) : - serie.dataCount; - serie.animation.InitProgress(0, 1); - var rate = serie.animation.GetCurrRate(); - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var dataChanging = false; - var interacting = false; - var dataList = serie.GetDataList(xDataZoom); - var isEffectScatter = serie is EffectScatter; - var colorIndex = serie.context.colorIndex; - - serie.containerIndex = m_Grid.index; - serie.containterInstanceId = m_Grid.instanceId; - - foreach (var serieData in dataList) - { - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - if (!symbol.ShowSymbol(serieData.index, maxCount)) - continue; - - var highlight = serie.highlight || serieData.context.highlight; - var color = SerieHelper.GetItemColor(serie, serieData, theme, colorIndex, highlight); - var toColor = SerieHelper.GetItemToColor(serie, serieData, theme, colorIndex, highlight); - var emptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, theme, colorIndex, highlight, false); - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, theme, highlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); - double xValue = serieData.GetCurrData(0, dataChangeDuration, xAxis.inverse); - double yValue = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse); - - if (serieData.IsDataChanged()) - dataChanging = true; - - float pX = m_Grid.context.x + xAxis.axisLine.GetWidth(theme.axis.lineWidth); - float pY = m_Grid.context.y + yAxis.axisLine.GetWidth(theme.axis.lineWidth); - float xDataHig = GetDataHig(xAxis, xValue, m_Grid.context.width); - float yDataHig = GetDataHig(yAxis, yValue, m_Grid.context.height); - var pos = new Vector3(pX + xDataHig, pY + yDataHig); - - if (!m_Grid.Contains(pos)) - continue; - - serie.context.dataPoints.Add(pos); - serieData.context.position = pos; - var datas = serieData.data; - var symbolSize = serie.highlight || serieData.context.highlight ? - theme.serie.scatterSymbolSelectedSize : - theme.serie.scatterSymbolSize; - if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting)) - { - symbolSize = highlight ? - symbol.GetSelectedSize(serieData.data, symbolSize) : - symbol.GetSize(serieData.data, symbolSize); - serieData.interact.SetValue(ref interacting, symbolSize); - } - - symbolSize *= rate; - - if (isEffectScatter) - { - for (int count = 0; count < symbol.animationSize.Count; count++) - { - var nowSize = symbol.animationSize[count]; - color.a = (byte) (255 * (symbolSize - nowSize) / symbolSize); - chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, - color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius); - } - chart.RefreshPainter(serie); - } - else - { - if (symbolSize > 100) symbolSize = 100; - chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, - color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius); - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(1); - chart.RefreshPainter(serie); - } - if (dataChanging || interacting) - { - chart.RefreshPainter(serie); - } - } - - protected virtual void DrawSingAxisScatterSerie(VertexHelper vh, BaseScatter serie) - { - if (serie.animation.HasFadeOut()) - return; - - if (!serie.show) - return; - - var axis = chart.GetChartComponent<SingleAxis>(serie.singleAxisIndex); - if (axis == null) - return; - - DataZoom xDataZoom; - DataZoom yDataZoom; - chart.GetDataZoomOfSerie(serie, out xDataZoom, out yDataZoom); - - var theme = chart.theme; - int maxCount = serie.maxShow > 0 ? - (serie.maxShow > serie.dataCount ? serie.dataCount : serie.maxShow) : - serie.dataCount; - serie.animation.InitProgress(0, 1); - - var rate = serie.animation.GetCurrRate(); - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var dataChanging = false; - var dataList = serie.GetDataList(xDataZoom); - var isEffectScatter = serie is EffectScatter; - var colorIndex = serie.context.colorIndex; - - serie.containerIndex = axis.index; - serie.containterInstanceId = axis.instanceId; - - foreach (var serieData in dataList) - { - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - if (!symbol.ShowSymbol(serieData.index, maxCount)) - continue; - - var highlight = serie.highlight || serieData.context.highlight; - var color = SerieHelper.GetItemColor(serie, serieData, theme, colorIndex, highlight); - var toColor = SerieHelper.GetItemToColor(serie, serieData, theme, colorIndex, highlight); - var emptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, theme, colorIndex, highlight, false); - var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight); - var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, theme, highlight); - var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); - var xValue = serieData.GetCurrData(0, dataChangeDuration, axis.inverse); - - if (serieData.IsDataChanged()) - dataChanging = true; - - var pos = Vector3.zero; - if (axis.orient == Orient.Horizonal) - { - var xDataHig = GetDataHig(axis, xValue, axis.context.width); - var yDataHig = axis.context.height / 2; - pos = new Vector3(axis.context.x + xDataHig, axis.context.y + yDataHig); - } - else - { - var yDataHig = GetDataHig(axis, xValue, axis.context.width); - var xDataHig = axis.context.height / 2; - pos = new Vector3(axis.context.x + xDataHig, axis.context.y + yDataHig); - } - serie.context.dataPoints.Add(pos); - serieData.context.position = pos; - - var datas = serieData.data; - var symbolSize = 0f; - if (serie.highlight || serieData.context.highlight) - symbolSize = symbol.GetSelectedSize(datas, theme.serie.scatterSymbolSelectedSize); - else - symbolSize = symbol.GetSize(datas, theme.serie.scatterSymbolSize); - symbolSize *= rate; - - if (isEffectScatter) - { - if (symbolSize > 100) symbolSize = 100; - for (int count = 0; count < symbol.animationSize.Count; count++) - { - var nowSize = symbol.animationSize[count]; - color.a = (byte) (255 * (symbolSize - nowSize) / symbolSize); - chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, - color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius); - } - chart.RefreshPainter(serie); - } - else - { - if (symbolSize > 100) symbolSize = 100; - chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, - color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius); - } - } - if (!serie.animation.IsFinish()) - { - serie.animation.CheckProgress(1); - chart.RefreshPainter(serie); - } - if (dataChanging) - { - chart.RefreshPainter(serie); - } - } - - private static float GetDataHig(Axis axis, double value, float totalWidth) - { - if (axis.IsLog()) - { - int minIndex = axis.GetLogMinIndex(); - float nowIndex = axis.GetLogValue(value); - return (nowIndex - minIndex) / axis.splitNumber * totalWidth; - } - else if (axis.IsCategory()) - { - if (axis.boundaryGap) - { - float tick = (float) (totalWidth / (axis.context.minMaxRange + 1)); - return tick / 2 + (float) (value - axis.context.minValue) * tick; - } - else - { - return (float) ((value - axis.context.minValue) / axis.context.minMaxRange * totalWidth); - } - } - else - { - return (float) ((value - axis.context.minValue) / axis.context.minMaxRange * totalWidth); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs.meta deleted file mode 100644 index f665940..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 31373c1595ff249188e33330f2eff1ed -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs b/Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs deleted file mode 100644 index f221917..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(EffectScatterHandler), true)] - [CoordOptions(typeof(GridCoord), typeof(SingleAxisCoord))] - [SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField("m_Radius")] - public class EffectScatter : BaseScatter - { - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<EffectScatter>(serieName); - serie.symbol.show = true; - serie.symbol.type = SymbolType.Circle; - serie.itemStyle.opacity = 0.8f; - serie.clip = false; - for (int i = 0; i < 10; i++) - { - chart.AddData(serie.index, Random.Range(10, 100), Random.Range(10, 100)); - } - return serie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs.meta b/Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs.meta deleted file mode 100644 index d452884..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c34d4976ef53c48a4b091d52694d8a7f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs b/Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs deleted file mode 100644 index 0ace159..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs +++ /dev/null @@ -1,25 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class EffectScatterHandler : BaseScatterHandler<EffectScatter> - { - private float m_EffectScatterSpeed = 15; - - public override void Update() - { - base.Update(); - var symbolSize = serie.symbol.GetSize(null, chart.theme.serie.scatterSymbolSize); - for (int i = 0; i < serie.symbol.animationSize.Count; ++i) - { - serie.symbol.animationSize[i] += m_EffectScatterSpeed * Time.deltaTime; - if (serie.symbol.animationSize[i] > symbolSize) - { - serie.symbol.animationSize[i] = i * 5; - } - chart.RefreshPainter(serie); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs.meta deleted file mode 100644 index 5b7d2b7..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/EffectScatterHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bb7c24770dff64d7b857f459de7b2333 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs b/Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs deleted file mode 100644 index f633d74..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs +++ /dev/null @@ -1,27 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - [System.Serializable] - [SerieHandler(typeof(ScatterHandler), true)] - [CoordOptions(typeof(GridCoord), typeof(SingleAxisCoord))] - [SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))] - [SerieDataExtraField("m_Radius")] - public class Scatter : BaseScatter - { - public static Serie AddDefaultSerie(BaseChart chart, string serieName) - { - var serie = chart.AddSerie<Scatter>(serieName); - serie.symbol.show = true; - serie.symbol.type = SymbolType.Circle; - serie.itemStyle.opacity = 0.8f; - serie.clip = false; - for (int i = 0; i < 10; i++) - { - chart.AddData(serie.index, Random.Range(10, 100), Random.Range(10, 100)); - } - return serie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs.meta b/Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs.meta deleted file mode 100644 index e7e72d0..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/Scatter.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 75a031f5547984317b5659a03d7f5e32 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs b/Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs deleted file mode 100644 index 9174cd3..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace XCharts.Runtime -{ - [UnityEngine.Scripting.Preserve] - internal sealed class ScatterHandler : BaseScatterHandler<Scatter> - { } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs.meta b/Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs.meta deleted file mode 100644 index 51d8f55..0000000 --- a/Assets/XCharts/Runtime/Serie/Scatter/ScatterHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7ee7d7a8f04034cd38fd9d43f1a41825 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs b/Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs deleted file mode 100644 index 01f21b9..0000000 --- a/Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using UnityEngine; - -namespace XCharts.Runtime -{ - public partial class Serie - { - public static Dictionary<Type, string> extraComponentMap = new Dictionary<Type, string> - { { typeof(LabelStyle), "m_Labels" }, - { typeof(LabelLine), "m_LabelLines" }, - { typeof(EndLabelStyle), "m_EndLabels" }, - { typeof(LineArrow), "m_LineArrows" }, - { typeof(AreaStyle), "m_AreaStyles" }, - { typeof(TitleStyle), "m_TitleStyles" }, - { typeof(EmphasisItemStyle), "m_EmphasisItemStyles" }, - { typeof(EmphasisLabelStyle), "m_EmphasisLabels" }, - { typeof(EmphasisLabelLine), "m_EmphasisLabelLines" }, - }; - - [SerializeField][IgnoreDoc] private List<LabelStyle> m_Labels = new List<LabelStyle>(); - [SerializeField][IgnoreDoc] private List<LabelLine> m_LabelLines = new List<LabelLine>(); - [SerializeField][IgnoreDoc] private List<EndLabelStyle> m_EndLabels = new List<EndLabelStyle>(); - [SerializeField][IgnoreDoc] private List<LineArrow> m_LineArrows = new List<LineArrow>(); - [SerializeField][IgnoreDoc] private List<AreaStyle> m_AreaStyles = new List<AreaStyle>(); - [SerializeField][IgnoreDoc] private List<TitleStyle> m_TitleStyles = new List<TitleStyle>(); - [SerializeField][IgnoreDoc] private List<EmphasisItemStyle> m_EmphasisItemStyles = new List<EmphasisItemStyle>(); - [SerializeField][IgnoreDoc] private List<EmphasisLabelStyle> m_EmphasisLabels = new List<EmphasisLabelStyle>(); - [SerializeField][IgnoreDoc] private List<EmphasisLabelLine> m_EmphasisLabelLines = new List<EmphasisLabelLine>(); - - /// <summary> - /// The style of area. - /// |区域填充样式。 - /// </summary> - public AreaStyle areaStyle { get { return m_AreaStyles.Count > 0 ? m_AreaStyles[0] : null; } } - /// <summary> - /// Text label of graphic element,to explain some data information about graphic item like value, name and so on. - /// |图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。 - /// </summary> - public LabelStyle label { get { return m_Labels.Count > 0 ? m_Labels[0] : null; } } - public LabelStyle endLabel { get { return m_EndLabels.Count > 0 ? m_EndLabels[0] : null; } } - /// <summary> - /// The line of label. - /// |标签上的视觉引导线。 - /// </summary> - public LabelLine labelLine { get { return m_LabelLines.Count > 0 ? m_LabelLines[0] : null; } } - /// <summary> - /// The arrow of line. - /// |折线图的箭头。 - /// </summary> - public LineArrow lineArrow { get { return m_LineArrows.Count > 0 ? m_LineArrows[0] : null; } } - /// <summary> - /// 高亮的图形样式 - /// </summary> - public EmphasisItemStyle emphasisItemStyle { get { return m_EmphasisItemStyles.Count > 0 ? m_EmphasisItemStyles[0] : null; } } - /// <summary> - /// 高亮时的标签样式 - /// </summary> - public EmphasisLabelStyle emphasisLabel { get { return m_EmphasisLabels.Count > 0 ? m_EmphasisLabels[0] : null; } } - /// <summary> - /// 高亮时的标签引导线样式 - /// </summary> - public EmphasisLabelLine emphasisLabelLine { get { return m_EmphasisLabelLines.Count > 0 ? m_EmphasisLabelLines[0] : null; } } - /// <summary> - /// the icon of data. - /// |数据项标题样式。 - /// </summary> - public TitleStyle titleStyle { get { return m_TitleStyles.Count > 0 ? m_TitleStyles[0] : null; } } - - public void RemoveAllExtraComponent() - { - var serieType = GetType(); - foreach (var kv in extraComponentMap) - { - ReflectionUtil.InvokeListClear(this, serieType.GetField(kv.Value)); - } - SetAllDirty(); - } - - public T AddExtraComponent<T>() where T : ChildComponent, ISerieExtraComponent - { - return AddExtraComponent(typeof(T)) as T; - } - - public ISerieExtraComponent AddExtraComponent(Type type) - { - if (GetType().IsDefined(typeof(SerieExtraComponentAttribute), false)) - { - var attr = GetType().GetAttribute<SerieExtraComponentAttribute>(); - if (attr.Contains(type)) - { - var fieldName = string.Empty; - if (extraComponentMap.TryGetValue(type, out fieldName)) - { - var field = typeof(Serie).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); - if (ReflectionUtil.InvokeListCount(this, field) <= 0) - { - var extraComponent = Activator.CreateInstance(type) as ISerieExtraComponent; - ReflectionUtil.InvokeListAdd(this, field, extraComponent); - SetAllDirty(); - return extraComponent; - } - else - { - return ReflectionUtil.InvokeListGet<ISerieExtraComponent>(this, field, 0); - } - } - } - } - throw new System.Exception(string.Format("Serie {0} not support extra component: {1}", - GetType().Name, type.Name)); - } - - public void RemoveExtraComponent<T>() where T : ISerieExtraComponent - { - RemoveExtraComponent(typeof(T)); - } - - public void RemoveExtraComponent(Type type) - { - if (GetType().IsDefined(typeof(SerieExtraComponentAttribute), false)) - { - var attr = GetType().GetAttribute<SerieExtraComponentAttribute>(); - if (attr.Contains(type)) - { - var fieldName = string.Empty; - if (extraComponentMap.TryGetValue(type, out fieldName)) - { - var field = typeof(Serie).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); - ReflectionUtil.InvokeListClear(this, field); - SetAllDirty(); - return; - } - } - } - throw new System.Exception(string.Format("Serie {0} not support extra component: {1}", - GetType().Name, type.Name)); - } - - private void RemoveExtraComponentList<T>(List<T> list) where T : ISerieExtraComponent - { - if (list.Count > 0) - { - list.Clear(); - SetAllDirty(); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs.meta b/Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs.meta deleted file mode 100644 index 97d8db3..0000000 --- a/Assets/XCharts/Runtime/Serie/Serie.ExtraComponent.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9c4f3a01039fd4e7fbf771a65ede0069 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/Serie.cs b/Assets/XCharts/Runtime/Serie/Serie.cs deleted file mode 100644 index 96895ea..0000000 --- a/Assets/XCharts/Runtime/Serie/Serie.cs +++ /dev/null @@ -1,1765 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - /// <summary> - /// Whether to show as Nightingale chart, which distinguishs data through radius. - /// 是否展示成南丁格尔图,通过半径区分数据大小。 - /// </summary> - public enum RoseType - { - /// <summary> - /// Don't show as Nightingale chart. - /// |不展示成南丁格尔玫瑰图。 - /// </summary> - None, - /// <summary> - /// Use central angle to show the percentage of data, radius to show data size. - /// |扇区圆心角展现数据的百分比,半径展现数据的大小。 - /// </summary> - Radius, - /// <summary> - /// All the sectors will share the same central angle, the data size is shown only through radiuses. - /// |所有扇区圆心角相同,仅通过半径展现数据大小。 - /// </summary> - Area - } - - /// <summary> - /// the type of line chart. - /// |折线图样式类型 - /// </summary> - public enum LineType - { - /// <summary> - /// the normal line chart, - /// |普通折线图。 - /// </summary> - Normal, - /// <summary> - /// the smooth line chart, - /// |平滑曲线。 - /// </summary> - Smooth, - /// <summary> - /// step line. - /// |阶梯线图:当前点。 - /// </summary> - StepStart, - /// <summary> - /// step line. - /// |阶梯线图:当前点和下一个点的中间。 - /// </summary> - StepMiddle, - /// <summary> - /// step line. - /// |阶梯线图:下一个拐点。 - /// </summary> - StepEnd - } - - /// <summary> - /// the type of bar. |柱状图类型。 - /// </summary> - public enum BarType - { - /// <summary> - /// normal bar. - /// |普通柱形图。 - /// </summary> - Normal, - /// <summary> - /// zebra bar. - /// |斑马柱形图。 - /// </summary> - Zebra, - /// <summary> - /// capsule bar. - /// |胶囊柱形图。 - /// </summary> - Capsule - } - - /// <summary> - /// the type of radar. |雷达图类型。 - /// </summary> - public enum RadarType - { - /// <summary> - /// multiple radar. - /// |多圈雷达图。此时可一个雷达里绘制多个圈,一个serieData就可组成一个圈(多维数据)。 - /// </summary> - Multiple, - /// <summary> - /// single radar. - /// |单圈雷达图。此时一个雷达只能绘制一个圈,多个serieData组成一个圈,数据取自`data[1]`。 - /// </summary> - Single - } - - /// <summary> - /// 采样类型 - /// </summary> - public enum SampleType - { - /// <summary> - /// Take a peak. When the average value of the filter point is greater than or equal to 'sampleAverage', - /// take the maximum value; If you do it the other way around, you get the minimum. - /// |取峰值。 - /// </summary> - Peak, - /// <summary> - /// Take the average of the filter points. - /// |取过滤点的平均值。 - /// </summary> - Average, - /// <summary> - /// Take the maximum value of the filter point. - /// |取过滤点的最大值。 - /// </summary> - Max, - /// <summary> - /// Take the minimum value of the filter point. - /// |取过滤点的最小值。 - /// </summary> - Min, - /// <summary> - /// Take the sum of the filter points. - /// |取过滤点的和。 - /// </summary> - Sum - } - - /// <summary> - /// 数据排序方式 - /// </summary> - public enum SerieDataSortType - { - /// <summary> - /// 按 data 的顺序 - /// </summary> - None, - /// <summary> - /// 升序 - /// </summary> - Ascending, - /// <summary> - /// 降序 - /// </summary> - Descending, - } - - /// <summary> - /// 对齐方式 - /// </summary> - public enum Align - { - Center, - Left, - Right - } - - /// <summary> - /// 系列。 - /// </summary> - [System.Serializable] - public partial class Serie : BaseSerie, IComparable - { - [SerializeField] private int m_Index; - [SerializeField] private bool m_Show = true; - [SerializeField] private string m_CoordSystem = "GridCoord"; - [SerializeField] private string m_SerieType = ""; - [SerializeField] private string m_SerieName; - [SerializeField] private string m_Stack; - [SerializeField] private int m_XAxisIndex = 0; - [SerializeField] private int m_YAxisIndex = 0; - [SerializeField] private int m_RadarIndex = 0; - [SerializeField] private int m_VesselIndex = 0; - [SerializeField] private int m_PolarIndex = 0; - [SerializeField] private int m_SingleAxisIndex = 0; - [SerializeField] private int m_ParallelIndex = 0; - [SerializeField] protected int m_MinShow; - [SerializeField] protected int m_MaxShow; - [SerializeField] protected int m_MaxCache; - - [SerializeField] private float m_SampleDist = 0; - [SerializeField] private SampleType m_SampleType = SampleType.Average; - [SerializeField] private float m_SampleAverage = 0; - - [SerializeField] private LineType m_LineType = LineType.Normal; - [SerializeField] private BarType m_BarType = BarType.Normal; - [SerializeField] private bool m_BarPercentStack = false; - [SerializeField] private float m_BarWidth = 0; - [SerializeField] private float m_BarGap = 0.1f; - [SerializeField] private float m_BarZebraWidth = 4f; - [SerializeField] private float m_BarZebraGap = 2f; - - [SerializeField] private float m_Min; - [SerializeField] private float m_Max; - [SerializeField] private float m_MinSize = 0f; - [SerializeField] private float m_MaxSize = 1f; - [SerializeField] private float m_StartAngle; - [SerializeField] private float m_EndAngle; - [SerializeField] private float m_MinAngle; - [SerializeField] private bool m_Clockwise = true; - [SerializeField] private bool m_RoundCap; - [SerializeField] private int m_SplitNumber; - [SerializeField] private bool m_ClickOffset = true; - [SerializeField] private RoseType m_RoseType = RoseType.None; - [SerializeField] private float m_Gap; - [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.48f }; - [SerializeField] private float[] m_Radius = new float[2] { 0, 0.28f }; - - [SerializeField][Range(1, 10)] private int m_ShowDataDimension; - [SerializeField] private bool m_ShowDataName; - [SerializeField] private bool m_Clip = false; - [SerializeField] private bool m_Ignore = false; - [SerializeField] private double m_IgnoreValue = 0; - [SerializeField] private bool m_IgnoreLineBreak = false; - [SerializeField] private bool m_ShowAsPositiveNumber = false; - [SerializeField] private bool m_Large = true; - [SerializeField] private int m_LargeThreshold = 200; - [SerializeField] private bool m_AvoidLabelOverlap = false; - [SerializeField] private RadarType m_RadarType = RadarType.Multiple; - [SerializeField] private bool m_PlaceHolder = false; - - [SerializeField] private SerieDataSortType m_DataSortType = SerieDataSortType.Descending; - [SerializeField] private Orient m_Orient = Orient.Vertical; - [SerializeField] private Align m_Align = Align.Center; - [SerializeField] private float m_Left; - [SerializeField] private float m_Right; - [SerializeField] private float m_Top; - [SerializeField] private float m_Bottom; - [SerializeField] private bool m_InsertDataToHead; - - [SerializeField] private LineStyle m_LineStyle = new LineStyle(); - [SerializeField] private SerieSymbol m_Symbol = new SerieSymbol(); - [SerializeField] private AnimationStyle m_Animation = new AnimationStyle(); - [SerializeField] private ItemStyle m_ItemStyle = new ItemStyle(); - [SerializeField] private List<SerieData> m_Data = new List<SerieData>(); - - [NonSerialized] internal int m_FilterStart; - [NonSerialized] internal int m_FilterEnd; - [NonSerialized] internal double m_FilterStartValue; - [NonSerialized] internal double m_FilterEndValue; - [NonSerialized] internal int m_FilterMinShow; - [NonSerialized] internal bool m_NeedUpdateFilterData; - [NonSerialized] public List<SerieData> m_FilterData = new List<SerieData>(); - [NonSerialized] private bool m_NameDirty; - - /// <summary> - /// The index of serie. - /// |系列索引。 - /// </summary> - public int index { get { return m_Index; } internal set { m_Index = value; } } - /// <summary> - /// Whether to show serie in chart. - /// |系列是否显示在图表上。 - /// </summary> - public bool show - { - get { return m_Show; } - set { if (PropertyUtil.SetStruct(ref m_Show, value)) { SetVerticesDirty(); SetSerieNameDirty(); } } - } - /// <summary> - /// the chart coord system of serie. - /// |使用的坐标系。 - /// </summary> - public string coordSystem - { - get { return m_CoordSystem; } - set { if (PropertyUtil.SetClass(ref m_CoordSystem, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// the type of serie. - /// |系列类型。 - /// </summary> - public string serieType - { - get { return m_SerieType; } - set { if (PropertyUtil.SetClass(ref m_SerieType, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// Series name used for displaying in tooltip and filtering with legend. - /// |系列名称,用于 tooltip 的显示,legend 的图例筛选。 - /// </summary> - public string serieName - { - get { return m_SerieName; } - set { if (PropertyUtil.SetClass(ref m_SerieName, value)) { SetVerticesDirty(); SetSerieNameDirty(); } } - } - /// <summary> - /// Legend name. When the serie name is not empty, the legend name is the series name; Otherwise, it is index. - /// |图例名称。当系列名称不为空时,图例名称即为系列名称;反之则为索引index。 - /// </summary> - public string legendName { get { return string.IsNullOrEmpty(serieName) ? ChartCached.IntToStr(index) : serieName; } } - /// <summary> - /// If stack the value. On the same category axis, the series with the same stack name would be put on top of each other. - /// |数据堆叠,同个类目轴上系列配置相同的stack值后,后一个系列的值会在前一个系列的值上相加。 - /// </summary> - public string stack - { - get { return m_Stack; } - set { if (PropertyUtil.SetClass(ref m_Stack, value)) SetVerticesDirty(); } - } - /// <summary> - /// the index of XAxis. - /// |使用X轴的index。 - /// </summary> - public int xAxisIndex - { - get { return m_XAxisIndex; } - set { if (PropertyUtil.SetStruct(ref m_XAxisIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// the index of YAxis. - /// |使用Y轴的index。 - /// </summary> - public int yAxisIndex - { - get { return m_YAxisIndex; } - set { if (PropertyUtil.SetStruct(ref m_YAxisIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// Index of radar component that radar chart uses. - /// |雷达图所使用的 radar 组件的 index。 - /// </summary> - public int radarIndex - { - get { return m_RadarIndex; } - set { if (PropertyUtil.SetStruct(ref m_RadarIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// Index of vesel component that liquid chart uses. - /// |水位图所使用的 vessel 组件的 index。 - /// </summary> - public int vesselIndex - { - get { return m_VesselIndex; } - set { if (PropertyUtil.SetStruct(ref m_VesselIndex, value)) SetVerticesDirty(); } - } - /// <summary> - /// Index of polar component that serie uses. - /// |所使用的 polar 组件的 index。 - /// </summary> - public int polarIndex - { - get { return m_PolarIndex; } - set { if (PropertyUtil.SetStruct(ref m_PolarIndex, value)) SetVerticesDirty(); } - } - /// <summary>s - /// Index of single axis component that serie uses. - /// |所使用的 singleAxis 组件的 index。 - /// </summary> - public int singleAxisIndex - { - get { return m_SingleAxisIndex; } - set { if (PropertyUtil.SetStruct(ref m_SingleAxisIndex, value)) SetAllDirty(); } - } - /// <summary>s - /// Index of parallel coord component that serie uses. - /// |所使用的 parallel coord 组件的 index。 - /// </summary> - public int parallelIndex - { - get { return m_ParallelIndex; } - set { if (PropertyUtil.SetStruct(ref m_ParallelIndex, value)) SetAllDirty(); } - } - /// <summary> - /// The min number of data to show in chart. - /// |系列所显示数据的最小索引 - /// </summary> - public int minShow - { - get { return m_MinShow; } - set { if (PropertyUtil.SetStruct(ref m_MinShow, value < 0 ? 0 : value)) { SetVerticesDirty(); } } - } - /// <summary> - /// The max number of data to show in chart. - /// |系列所显示数据的最大索引 - /// </summary> - public int maxShow - { - get { return m_MaxShow; } - set { if (PropertyUtil.SetStruct(ref m_MaxShow, value < 0 ? 0 : value)) { SetVerticesDirty(); } } - } - /// <summary> - /// The max number of serie data cache. - /// The first data will be remove when the size of serie data is larger then maxCache. - /// |系列中可缓存的最大数据量。默认为0没有限制,大于0时超过指定值会移除旧数据再插入新数据。 - /// </summary> - public int maxCache - { - get { return m_MaxCache; } - set { if (PropertyUtil.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) { SetVerticesDirty(); } } - } - - /// <summary> - /// the symbol of serie data item. - /// |标记的图形。 - /// </summary> - public SerieSymbol symbol - { - get { return m_Symbol; } - set { if (PropertyUtil.SetClass(ref m_Symbol, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// The type of line chart. - /// |折线图样式类型。 - /// </summary> - public LineType lineType - { - get { return m_LineType; } - set { if (PropertyUtil.SetStruct(ref m_LineType, value)) SetVerticesDirty(); } - } - /// <summary> - /// the min pixel dist of sample. - /// |采样的最小像素距离,默认为0时不采样。当两个数据点间的水平距离小于改值时,开启采样,保证两点间的水平距离不小于改值。 - /// </summary> - public float sampleDist - { - get { return m_SampleDist; } - set { if (PropertyUtil.SetStruct(ref m_SampleDist, value < 0 ? 0 : value)) SetVerticesDirty(); } - } - /// <summary> - /// the type of sample. - /// |采样类型。当sampleDist大于0时有效。 - /// </summary> - public SampleType sampleType - { - get { return m_SampleType; } - set { if (PropertyUtil.SetStruct(ref m_SampleType, value)) SetVerticesDirty(); } - } - /// <summary> - /// 设定的采样平均值。当sampleType 为 Peak 时,用于和过滤数据的平均值做对比是取最大值还是最小值。默认为0时会实时计算所有数据的平均值。 - /// </summary> - public float sampleAverage - { - get { return m_SampleAverage; } - set { if (PropertyUtil.SetStruct(ref m_SampleAverage, value)) SetVerticesDirty(); } - } - /// <summary> - /// The style of line. - /// |线条样式。 - /// </summary> - public LineStyle lineStyle - { - get { return m_LineStyle; } - set { if (PropertyUtil.SetClass(ref m_LineStyle, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// 柱形图类型。 - /// </summary> - public BarType barType - { - get { return m_BarType; } - set { if (PropertyUtil.SetStruct(ref m_BarType, value)) SetVerticesDirty(); } - } - /// <summary> - /// 柱形图是否为百分比堆积。相同stack的serie只要有一个barPercentStack为true,则就显示成百分比堆叠柱状图。 - /// </summary> - public bool barPercentStack - { - get { return m_BarPercentStack; } - set { if (PropertyUtil.SetStruct(ref m_BarPercentStack, value)) SetVerticesDirty(); } - } - /// <summary> - /// The width of the bar. Adaptive when default 0. - /// |柱条的宽度,不设时自适应。支持设置成相对于类目宽度的百分比。 - /// </summary> - public float barWidth - { - get { return m_BarWidth; } - set { if (PropertyUtil.SetStruct(ref m_BarWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// The gap between bars between different series, is a percent value like '0.3f' , which means 30% of the bar width, can be set as a fixed value. - /// Set barGap as '-1' can overlap bars that belong to different series, which is useful when making a series of bar be background. - /// In a single coodinate system, this attribute is shared by multiple 'bar' series. - /// This attribute should be set on the last 'bar' series in the coodinate system, - /// then it will be adopted by all 'bar' series in the coordinate system. - /// |不同系列的柱间距离。为百分比(如 '0.3f',表示柱子宽度的 30%) - /// 如果想要两个系列的柱子重叠,可以设置 barGap 为 '-1f'。这在用柱子做背景的时候有用。 - /// 在同一坐标系上,此属性会被多个 'bar' 系列共享。此属性应设置于此坐标系中最后一个 'bar' 系列上才会生效,并且是对此坐标系中所有 'bar' 系列生效。 - /// </summary> - public float barGap - { - get { return m_BarGap; } - set { if (PropertyUtil.SetStruct(ref m_BarGap, value)) SetVerticesDirty(); } - } - /// <summary> - /// 斑马线的粗细。 - /// </summary> - public float barZebraWidth - { - get { return m_BarZebraWidth; } - set { if (PropertyUtil.SetStruct(ref m_BarZebraWidth, value < 0 ? 0 : value)) SetVerticesDirty(); } - } - /// <summary> - /// 斑马线的间距。 - /// </summary> - public float barZebraGap - { - get { return m_BarZebraGap; } - set { if (PropertyUtil.SetStruct(ref m_BarZebraGap, value < 0 ? 0 : value)) SetVerticesDirty(); } - } - - /// <summary> - /// Whether offset when mouse click pie chart item. - /// |鼠标点击时是否开启偏移,一般用在PieChart图表中。 - /// </summary> - public bool pieClickOffset - { - get { return m_ClickOffset; } - set { if (PropertyUtil.SetStruct(ref m_ClickOffset, value)) SetVerticesDirty(); } - } - /// <summary> - /// Whether to show as Nightingale chart. - /// |是否展示成南丁格尔图,通过半径区分数据大小。 - /// </summary> - public RoseType pieRoseType - { - get { return m_RoseType; } - set { if (PropertyUtil.SetStruct(ref m_RoseType, value)) SetVerticesDirty(); } - } - /// <summary> - /// gap of item. - /// |间距。 - /// </summary> - public float gap - { - get { return m_Gap; } - set { if (PropertyUtil.SetStruct(ref m_Gap, value)) SetVerticesDirty(); } - } - /// <summary> - /// the center of chart. - /// |中心点。 - /// </summary> - public float[] center - { - get { return m_Center; } - set { if (value != null && value.Length == 2) { m_Center = value; SetVerticesDirty(); } } - } - /// <summary> - /// the radius of chart. - /// |半径。radius[0]表示内径,radius[1]表示外径。 - /// </summary> - public float[] radius - { - get { return m_Radius; } - set { if (value != null && value.Length == 2) { m_Radius = value; SetVerticesDirty(); } } - } - /// <summary> - /// 最小值。 - /// </summary> - public float min - { - get { return m_Min; } - set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetVerticesDirty(); } - } - /// <summary> - /// 最大值。 - /// </summary> - public float max - { - get { return m_Max; } - set { if (PropertyUtil.SetStruct(ref m_Max, value)) SetVerticesDirty(); } - } - /// <summary> - /// 数据最小值 min 映射的宽度。 - /// </summary> - public float minSize - { - get { return m_MinSize; } - set { if (PropertyUtil.SetStruct(ref m_MinSize, value)) SetVerticesDirty(); } - } - /// <summary> - /// 数据最大值 max 映射的宽度。 - /// </summary> - public float maxSize - { - get { return m_MaxSize; } - set { if (PropertyUtil.SetStruct(ref m_MaxSize, value)) SetVerticesDirty(); } - } - /// <summary> - /// 起始角度。和时钟一样,12点钟位置是0度,顺时针到360度。 - /// </summary> - public float startAngle - { - get { return m_StartAngle; } - set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetVerticesDirty(); } - } - /// <summary> - /// 结束角度。和时钟一样,12点钟位置是0度,顺时针到360度。 - /// </summary> - public float endAngle - { - get { return m_EndAngle; } - set { if (PropertyUtil.SetStruct(ref m_EndAngle, value)) SetVerticesDirty(); } - } - /// <summary> - /// The minimum angle of sector(0-360). It prevents some sector from being too small when value is small. - /// |最小的扇区角度(0-360)。用于防止某个值过小导致扇区太小影响交互。 - /// </summary> - public float minAngle - { - get { return m_MinAngle; } - set { if (PropertyUtil.SetStruct(ref m_MinAngle, value)) SetVerticesDirty(); } - } - /// <summary> - /// 是否顺时针。 - /// </summary> - public bool clockwise - { - get { return m_Clockwise; } - set { if (PropertyUtil.SetStruct(ref m_Clockwise, value)) SetVerticesDirty(); } - } - /// <summary> - /// 刻度分割段数。最大可设置36。 - /// </summary> - public int splitNumber - { - get { return m_SplitNumber; } - set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value > 36 ? 36 : value)) SetVerticesDirty(); } - } - /// <summary> - /// 是否开启圆弧效果。 - /// </summary> - public bool roundCap - { - get { return m_RoundCap; } - set { if (PropertyUtil.SetStruct(ref m_RoundCap, value)) SetVerticesDirty(); } - } - /// <summary> - /// 是否开启忽略数据。当为 true 时,数据值为 ignoreValue 时不进行绘制。 - /// </summary> - public bool ignore - { - get { return m_Ignore; } - set { if (PropertyUtil.SetStruct(ref m_Ignore, value)) SetVerticesDirty(); } - } - /// <summary> - /// 忽略数据的默认值。当ignore为true才有效。 - /// </summary> - public double ignoreValue - { - get { return m_IgnoreValue; } - set { if (PropertyUtil.SetStruct(ref m_IgnoreValue, value)) SetVerticesDirty(); } - } - /// <summary> - /// 忽略数据时折线是断开还是连接。默认false为连接。 - /// </summary> - /// <value></value> - public bool ignoreLineBreak - { - get { return m_IgnoreLineBreak; } - set { if (PropertyUtil.SetStruct(ref m_IgnoreLineBreak, value)) SetVerticesDirty(); } - } - /// <summary> - /// 雷达图类型。 - /// </summary> - public RadarType radarType - { - get { return m_RadarType; } - set { if (PropertyUtil.SetStruct(ref m_RadarType, value)) SetVerticesDirty(); } - } - /// <summary> - /// The start animation. - /// |起始动画。 - /// </summary> - public AnimationStyle animation - { - get { return m_Animation; } - set { if (PropertyUtil.SetClass(ref m_Animation, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// The style of data item. - /// |图形样式。 - /// </summary> - public ItemStyle itemStyle - { - get { return m_ItemStyle; } - set { if (PropertyUtil.SetClass(ref m_ItemStyle, value, true)) SetVerticesDirty(); } - } - /// <summary> - /// 数据项里的数据维数。 - /// </summary> - public int showDataDimension { get { return m_ShowDataDimension; } set { m_ShowDataDimension = value; } } - /// <summary> - /// 在Editor的inpsector上是否显示name参数 - /// </summary> - public bool showDataName { get { return m_ShowDataName; } set { m_ShowDataName = value; } } - /// <summary> - /// If clip the overflow on the coordinate system. - /// |是否裁剪超出坐标系部分的图形。 - /// </summary> - public bool clip - { - get { return m_Clip; } - set { if (PropertyUtil.SetStruct(ref m_Clip, value)) SetVerticesDirty(); } - } - /// <summary> - /// Show negative number as positive number. - /// |将负数数值显示为正数。一般和`AxisLabel`的`showAsPositiveNumber`配合使用。仅在折线图和柱状图中有效。 - /// </summary> - public bool showAsPositiveNumber - { - get { return m_ShowAsPositiveNumber; } - set { if (PropertyUtil.SetStruct(ref m_ShowAsPositiveNumber, value)) SetComponentDirty(); } - } - /// <summary> - /// 是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。 - /// 开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。 - /// 缺点:优化后不能自定义设置单个数据项的样式,不能显示Label。 - /// </summary> - public bool large - { - get { return m_Large; } - set { if (PropertyUtil.SetStruct(ref m_Large, value)) SetAllDirty(); } - } - /// <summary> - /// 开启大数量优化的阈值。只有当开启了large并且数据量大于该阀值时才进入性能模式。 - /// </summary> - public int largeThreshold - { - get { return m_LargeThreshold; } - set { if (PropertyUtil.SetStruct(ref m_LargeThreshold, value)) SetAllDirty(); } - } - /// <summary> - /// 在饼图且标签外部显示的情况下,是否启用防止标签重叠策略,默认关闭,在标签拥挤重叠的情况下会挪动各个标签的位置,防止标签间的重叠。 - /// </summary> - public bool avoidLabelOverlap - { - get { return m_AvoidLabelOverlap; } - set { if (PropertyUtil.SetStruct(ref m_AvoidLabelOverlap, value)) SetVerticesDirty(); } - } - - /// <summary> - /// Distance between component and the left side of the container. - /// |组件离容器左侧的距离。 - /// </summary> - public float left - { - get { return m_Left; } - set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the right side of the container. - /// |组件离容器右侧的距离。 - /// </summary> - public float right - { - get { return m_Right; } - set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the top side of the container. - /// |组件离容器上侧的距离。 - /// </summary> - public float top - { - get { return m_Top; } - set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); } - } - /// <summary> - /// Distance between component and the bottom side of the container. - /// |组件离容器下侧的距离。 - /// </summary> - public float bottom - { - get { return m_Bottom; } - set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); } - } - /// <summary> - /// Whether to add new data at the head or at the end of the list. - /// |添加新数据时是在列表的头部还是尾部加入。 - /// </summary> - public bool insertDataToHead - { - get { return m_InsertDataToHead; } - set { if (PropertyUtil.SetStruct(ref m_InsertDataToHead, value)) SetAllDirty(); } - } - /// <summary> - /// 组件的数据排序。 - /// </summary> - public SerieDataSortType dataSortType - { - get { return m_DataSortType; } - set { if (PropertyUtil.SetStruct(ref m_DataSortType, value)) SetVerticesDirty(); } - } - /// <summary> - /// 组件的朝向。 - /// </summary> - public Orient orient - { - get { return m_Orient; } - set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetVerticesDirty(); } - } - /// <summary> - /// 组件水平方向对齐方式。 - /// </summary> - public Align align - { - get { return m_Align; } - set { if (PropertyUtil.SetStruct(ref m_Align, value)) SetVerticesDirty(); } - } - /// <summary> - /// 占位模式。占位模式时,数据有效但不参与渲染和显示。 - /// </summary> - public bool placeHolder - { - get { return m_PlaceHolder; } - set { if (PropertyUtil.SetStruct(ref m_PlaceHolder, value)) SetAllDirty(); } - } - /// <summary> - /// 系列中的数据内容数组。SerieData可以设置1到n维数据。 - /// </summary> - public List<SerieData> data { get { return m_Data; } } - - public override bool vertsDirty - { - get - { - return m_VertsDirty || - symbol.vertsDirty || - lineStyle.vertsDirty || - itemStyle.vertsDirty || - (lineArrow != null && lineArrow.vertsDirty) || - (areaStyle != null && areaStyle.vertsDirty) || - (label != null && label.vertsDirty) || - (labelLine != null && labelLine.vertsDirty) || - (emphasisItemStyle != null && emphasisItemStyle.vertsDirty) || - (titleStyle != null && titleStyle.vertsDirty) || - AnySerieDataVerticesDirty(); - } - } - - public override bool componentDirty - { - get - { - return m_ComponentDirty || - symbol.componentDirty || - (titleStyle != null && titleStyle.componentDirty) || - (label != null && label.componentDirty) || - (labelLine != null && labelLine.componentDirty) || - (emphasisLabel != null && emphasisLabel.componentDirty) || - (emphasisLabelLine != null && emphasisLabelLine.componentDirty); - } - } - public override void ClearVerticesDirty() - { - base.ClearVerticesDirty(); - foreach (var serieData in m_Data) - serieData.ClearVerticesDirty(); - symbol.ClearVerticesDirty(); - lineStyle.ClearVerticesDirty(); - itemStyle.ClearVerticesDirty(); - if (areaStyle != null) - areaStyle.ClearVerticesDirty(); - if (label != null) - label.ClearVerticesDirty(); - if (emphasisItemStyle != null) - emphasisItemStyle.ClearVerticesDirty(); - if (lineArrow != null) - lineArrow.ClearVerticesDirty(); - if (titleStyle != null) - titleStyle.ClearVerticesDirty(); - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - foreach (var serieData in m_Data) - serieData.ClearComponentDirty(); - symbol.ClearComponentDirty(); - lineStyle.ClearComponentDirty(); - itemStyle.ClearComponentDirty(); - if (areaStyle != null) - areaStyle.ClearComponentDirty(); - if (label != null) - label.ClearComponentDirty(); - if (emphasisLabel != null) - emphasisLabel.ClearComponentDirty(); - if (emphasisLabelLine != null) - emphasisLabelLine.ClearComponentDirty(); - if (lineArrow != null) - lineArrow.ClearComponentDirty(); - if (titleStyle != null) - titleStyle.ClearComponentDirty(); - } - - public override void SetAllDirty() - { - base.SetAllDirty(); - labelDirty = true; - titleDirty = true; - } - - private bool AnySerieDataVerticesDirty() - { - if (this is ISimplifiedSerie) - return false; - foreach (var serieData in m_Data) - if (serieData.vertsDirty) return true; - return false; - } - - private bool AnySerieDataComponentDirty() - { - if (this is ISimplifiedSerie) - return false; - foreach (var serieData in m_Data) - if (serieData.componentDirty) return true; - return false; - } - /// <summary> - /// Whether the serie is highlighted. - /// |该系列是否高亮,一般由图例悬停触发。 - /// </summary> - public bool highlight { get; internal set; } - /// <summary> - /// the count of data list. - /// |数据项个数。 - /// </summary> - public int dataCount { get { return m_Data.Count; } } - public bool nameDirty { get { return m_NameDirty; } } - public bool labelDirty { get; set; } - public bool titleDirty { get; set; } - public bool dataDirty { get; set; } - - private void SetSerieNameDirty() - { - m_NameDirty = true; - } - - public void ClearSerieNameDirty() - { - m_NameDirty = false; - } - - public override void ClearDirty() - { - base.ClearDirty(); - } - - /// <summary> - /// 维度Y对应数据中最大值。 - /// </summary> - public double yMax - { - get - { - var max = double.MinValue; - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[1]) && sdata.data[1] > max) - { - max = sdata.data[1]; - } - } - return max; - } - } - - /// <summary> - /// 维度X对应数据中的最大值。 - /// </summary> - public double xMax - { - get - { - var max = double.MinValue; - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[0]) && sdata.data[0] > max) - { - max = sdata.data[0]; - } - } - return max; - } - } - - /// <summary> - /// 维度Y对应数据的最小值。 - /// </summary> - public double yMin - { - get - { - var min = double.MaxValue; - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[1]) && sdata.data[1] < min) - { - min = sdata.data[1]; - } - } - return min; - } - } - - /// <summary> - /// 维度X对应数据的最小值。 - /// </summary> - public double xMin - { - get - { - var min = double.MaxValue; - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[0]) && sdata.data[0] < min) - { - min = sdata.data[0]; - } - } - return min; - } - } - - /// <summary> - /// 维度Y数据的总和。 - /// </summary> - public double yTotal - { - get - { - double total = 0; - if (IsPerformanceMode()) - { - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[1])) - total += sdata.data[1]; - } - } - else - { - var duration = animation.GetUpdateAnimationDuration(); - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[1])) - total += sdata.GetCurrData(1, duration); - } - } - return total; - } - } - - /// <summary> - /// 维度X数据的总和。 - /// </summary> - public double xTotal - { - get - { - double total = 0; - foreach (var sdata in data) - { - if (sdata.show && !IsIgnoreValue(sdata.data[1])) - total += sdata.data[0]; - } - return total; - } - } - - public void ResetInteract() - { - interact.Reset(); - foreach (var serieData in m_Data) - serieData.interact.Reset(); - } - - /// <summary> - /// 清空所有数据 - /// </summary> - public override void ClearData() - { - while (m_Data.Count > 0) - { - RemoveData(0); - } - m_Data.Clear(); - m_NeedUpdateFilterData = true; - dataDirty = true; - SetVerticesDirty(); - } - - /// <summary> - /// 移除指定索引的数据 - /// </summary> - /// <param name="index"></param> - public void RemoveData(int index) - { - if (index >= 0 && index < m_Data.Count) - { - if (!string.IsNullOrEmpty(m_Data[index].name)) - { - SetSerieNameDirty(); - } - SetVerticesDirty(); - var serieData = m_Data[index]; - SerieDataPool.Release(serieData); - if (serieData.labelObject != null) - { - SerieLabelPool.Release(serieData.labelObject.gameObject); - } - m_Data.RemoveAt(index); - m_NeedUpdateFilterData = true; - labelDirty = true; - dataDirty = true; - } - } - - /// <summary> - /// 添加一个数据到维度Y(此时维度X对应的数据是索引) - /// </summary> - /// <param name="value"></param> - /// <param name="dataName"></param> - /// <param name="dataId">the unique id of data</param> - public SerieData AddYData(double value, string dataName = null, string dataId = null) - { - CheckMaxCache(); - int xValue = m_Data.Count; - var serieData = SerieDataPool.Get(); - serieData.data.Add(xValue); - serieData.data.Add(value); - serieData.name = dataName; - serieData.index = xValue; - serieData.id = dataId; - AddSerieData(serieData); - m_ShowDataDimension = 1; - SetVerticesDirty(); - CheckDataName(dataName); - labelDirty = true; - dataDirty = true; - return serieData; - } - - public void AddSerieData(SerieData serieData) - { - if (m_InsertDataToHead) - m_Data.Insert(0, serieData); - else - m_Data.Add(serieData); - SetVerticesDirty(); - dataDirty = true; - m_NeedUpdateFilterData = true; - } - - private void CheckDataName(string dataName) - { - if (string.IsNullOrEmpty(dataName)) - SetSerieNameDirty(); - else - m_ShowDataName = true; - } - - /// <summary> - /// 添加(x,y)数据到维度X和维度Y - /// </summary> - /// <param name="xValue"></param> - /// <param name="yValue"></param> - /// <param name="dataName"></param> - /// <param name="dataId">the unique id of data</param> - public SerieData AddXYData(double xValue, double yValue, string dataName = null, string dataId = null) - { - CheckMaxCache(); - var serieData = SerieDataPool.Get(); - serieData.data.Clear(); - serieData.data.Add(xValue); - serieData.data.Add(yValue); - serieData.name = dataName; - serieData.index = m_Data.Count; - serieData.id = dataId; - AddSerieData(serieData); - m_ShowDataDimension = 2; - SetVerticesDirty(); - CheckDataName(dataName); - labelDirty = true; - return serieData; - } - - /// <summary> - /// 添加 (open, close, lowest, heighest) 数据 - /// </summary> - /// <param name="open"></param> - /// <param name="close"></param> - /// <param name="lowest"></param> - /// <param name="heighest"></param> - /// <param name="dataName"></param> - /// <param name="dataId">the unique id of data</param> - /// <returns></returns> - public SerieData AddData(double open, double close, double lowest, double heighest, string dataName = null, string dataId = null) - { - CheckMaxCache(); - var serieData = SerieDataPool.Get(); - serieData.data.Clear(); - serieData.data.Add(open); - serieData.data.Add(close); - serieData.data.Add(lowest); - serieData.data.Add(heighest); - serieData.name = dataName; - serieData.index = m_Data.Count; - serieData.id = dataId; - AddSerieData(serieData); - m_ShowDataDimension = 4; - SetVerticesDirty(); - CheckDataName(dataName); - labelDirty = true; - return serieData; - } - - /// <summary> - /// 将一组数据添加到系列中。 - /// 如果数据只有一个,默认添加到维度Y中。 - /// </summary> - /// <param name="valueList"></param> - /// <param name="dataName"></param> - /// <param name="dataId">the unique id of data</param> - public SerieData AddData(List<double> valueList, string dataName = null, string dataId = null) - { - if (valueList == null || valueList.Count == 0) return null; - if (valueList.Count == 1) - return AddYData(valueList[0], dataName, dataId); - else if (valueList.Count == 2) - return AddXYData(valueList[0], valueList[1], dataName, dataId); - else - { - CheckMaxCache(); - m_ShowDataDimension = valueList.Count; - var serieData = SerieDataPool.Get(); - serieData.name = dataName; - serieData.index = m_Data.Count; - serieData.id = dataId; - for (int i = 0; i < valueList.Count; i++) - { - serieData.data.Add(valueList[i]); - } - AddSerieData(serieData); - SetVerticesDirty(); - CheckDataName(dataName); - labelDirty = true; - return serieData; - } - } - - public SerieData AddChildData(SerieData parent, double value, string name, string id) - { - var serieData = new SerieData(); - serieData.name = name; - serieData.index = m_Data.Count; - serieData.id = id; - serieData.data = new List<double>() { m_Data.Count, value }; - AddChildData(parent, serieData); - return serieData; - } - - public SerieData AddChildData(SerieData parent, List<double> value, string name, string id) - { - var serieData = new SerieData(); - serieData.name = name; - serieData.index = m_Data.Count; - serieData.id = id; - serieData.data = new List<double>(value); - AddChildData(parent, serieData); - return serieData; - } - - public void AddChildData(SerieData parent, SerieData serieData) - { - serieData.parentId = parent.id; - serieData.context.parent = parent; - - if (!m_Data.Contains(serieData)) - AddSerieData(serieData); - - if (!parent.context.children.Contains(serieData)) - { - parent.context.children.Add(serieData); - } - } - - private void CheckMaxCache() - { - if (m_MaxCache <= 0) return; - while (m_Data.Count >= m_MaxCache) - { - m_NeedUpdateFilterData = true; - if (m_InsertDataToHead) RemoveData(m_Data.Count - 1); - else RemoveData(0); - } - } - - /// <summary> - /// 获得指定index指定维数的数据 - /// </summary> - /// <param name="index"></param> - /// <param name="dimension"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public double GetData(int index, int dimension, DataZoom dataZoom = null) - { - if (index < 0 || dimension < 0) return 0; - var serieData = GetSerieData(index, dataZoom); - if (serieData != null && dimension < serieData.data.Count) - { - var value = serieData.GetData(dimension); - if (showAsPositiveNumber) - value = Math.Abs(value); - return value; - } - else - { - return 0; - } - } - - /// <summary> - /// 获得维度Y索引对应的数据 - /// </summary> - /// <param name="index"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public double GetYData(int index, DataZoom dataZoom = null) - { - if (index < 0) return 0; - var serieData = GetDataList(dataZoom); - if (index < serieData.Count) - { - var value = serieData[index].data[1]; - if (showAsPositiveNumber) - value = Math.Abs(value); - return value; - } - return 0; - } - - public double GetYCurrData(int index, DataZoom dataZoom = null) - { - if (index < 0) return 0; - var serieData = GetDataList(dataZoom); - if (index < serieData.Count) - { - var value = serieData[index].GetCurrData(1, animation.GetUpdateAnimationDuration()); - if (showAsPositiveNumber) - value = Math.Abs(value); - return value; - } - return 0; - } - - /// <summary> - /// 获得维度Y索引对应的数据和数据名 - /// </summary> - /// <param name="index">索引</param> - /// <param name="yData">对应的数据值</param> - /// <param name="dataName">对应的数据名</param> - /// <param name="dataZoom">区域缩放</param> - public void GetYData(int index, out double yData, out string dataName, DataZoom dataZoom = null) - { - yData = 0; - dataName = null; - if (index < 0) return; - var serieData = GetDataList(dataZoom); - if (index < serieData.Count) - { - yData = serieData[index].data[1]; - if (showAsPositiveNumber) - yData = Math.Abs(yData); - dataName = serieData[index].name; - } - } - - /// <summary> - /// 获得指定索引的数据项 - /// </summary> - /// <param name="index"></param> - /// <param name="dataZoom"></param> - /// <returns></returns> - public SerieData GetSerieData(int index, DataZoom dataZoom = null) - { - var data = GetDataList(dataZoom); - if (index >= 0 && index <= data.Count - 1) - return data[index]; - return null; - } - - public SerieData GetSerieData(string id, DataZoom dataZoom = null) - { - var data = GetDataList(dataZoom); - foreach (var serieData in data) - { - var target = GetSerieData(serieData, id); - if (target != null) return target; - } - return null; - } - - public SerieData GetSerieData(SerieData parent, string id) - { - if (id.Equals(parent.id)) return parent; - foreach (var child in parent.context.children) - { - var data = GetSerieData(child, id); - if (data != null) - { - return data; - } - } - return null; - } - - /// <summary> - /// 获得指定索引的维度X和维度Y的数据 - /// </summary> - /// <param name="index"></param> - /// <param name="dataZoom"></param> - /// <param name="xValue"></param> - /// <param name="yVlaue"></param> - public void GetXYData(int index, DataZoom dataZoom, out double xValue, out double yVlaue) - { - xValue = 0; - yVlaue = 0; - if (index < 0) return; - var showData = GetDataList(dataZoom); - if (index < showData.Count) - { - var serieData = showData[index]; - xValue = serieData.data[0]; - yVlaue = serieData.data[1]; - if (showAsPositiveNumber) - { - xValue = Math.Abs(xValue); - yVlaue = Math.Abs(yVlaue); - } - } - } - - public virtual double GetDataTotal(int dimension, SerieData serieData = null) - { - if (m_Max > 0) return m_Max; - - double total = 0; - foreach (var sdata in data) - { - if (sdata.show) - total += sdata.GetData(dimension); - } - return total; - } - - /// <summary> - /// 获得系列的数据列表 - /// </summary> - /// <param name="dataZoom"></param> - /// <returns></returns> - public List<SerieData> GetDataList(DataZoom dataZoom = null) - { - if (dataZoom != null && dataZoom.enable && - (dataZoom.IsContainsXAxis(xAxisIndex) || dataZoom.IsContainsYAxis(yAxisIndex))) - { - SerieHelper.UpdateFilterData(this, dataZoom); - return m_FilterData; - } - else - { - return useSortData && context.sortedData.Count > 0 ? context.sortedData : m_Data; - } - } - - /// <summary> - /// 更新指定索引的维度Y数据 - /// </summary> - /// <param name="index"></param> - /// <param name="value"></param> - public bool UpdateYData(int index, double value) - { - UpdateData(index, 1, value); - return true; - } - - /// <summary> - /// 更新指定索引的维度X和维度Y的数据 - /// </summary> - /// <param name="index"></param> - /// <param name="xValue"></param> - /// <param name="yValue"></param> - public bool UpdateXYData(int index, float xValue, float yValue) - { - var flag1 = UpdateData(index, 0, xValue); - var flag2 = UpdateData(index, 1, yValue); - return flag1 || flag2; - } - - /// <summary> - /// 更新指定索引指定维数的数据 - /// </summary> - /// <param name="index">要更新数据的索引</param> - /// <param name="dimension">要更新数据的维数</param> - /// <param name="value">新的数据值</param> - public bool UpdateData(int index, int dimension, double value) - { - if (index >= 0 && index < m_Data.Count) - { - var animationOpen = animation.enable; - var animationDuration = animation.GetUpdateAnimationDuration(); - var flag = m_Data[index].UpdateData(dimension, value, animationOpen, animationDuration); - if (flag) - { - SetVerticesDirty(); - dataDirty = true; - } - return flag; - } - else - { - return false; - } - } - - /// <summary> - /// 更新指定索引的数据项数据列表 - /// </summary> - /// <param name="index"></param> - /// <param name="values"></param> - public bool UpdateData(int index, List<double> values) - { - if (index >= 0 && index < m_Data.Count && values != null) - { - var serieData = m_Data[index]; - var animationOpen = animation.enable; - var animationDuration = animation.GetUpdateAnimationDuration(); - for (int i = 0; i < values.Count; i++) - serieData.UpdateData(i, values[i], animationOpen, animationDuration); - SetVerticesDirty(); - dataDirty = true; - return true; - } - return false; - } - - public bool UpdateDataName(int index, string name) - { - if (index >= 0 && index < m_Data.Count) - { - var serieData = m_Data[index]; - serieData.name = name; - SetSerieNameDirty(); - if (serieData.labelObject != null) - { - serieData.labelObject.SetText(name == null ? "" : name); - } - return true; - } - return false; - } - - /// <summary> - /// 清除所有数据的高亮标志 - /// </summary> - public void ClearHighlight() - { - highlight = false; - foreach (var serieData in m_Data) - serieData.context.highlight = false; - } - - /// <summary> - /// 设置指定索引的数据为高亮状态 - /// </summary> - public void SetHighlight(int index, bool flag) - { - var serieData = GetSerieData(index); - if (serieData != null) - serieData.context.highlight = flag; - } - - public float GetBarWidth(float categoryWidth, int barCount = 0) - { - if (m_BarWidth == 0) - { - var width = ChartHelper.GetActualValue(0.6f, categoryWidth); - if (barCount == 0) - return width < 1 ? categoryWidth : width; - else - return width / barCount; - } - else - return ChartHelper.GetActualValue(m_BarWidth, categoryWidth); - } - - public bool IsIgnoreIndex(int index, int dimension = 1) - { - var serieData = GetSerieData(index); - if (serieData != null) - return IsIgnoreValue(serieData, dimension); - return false; - } - - public bool IsIgnoreValue(SerieData serieData, int dimension = 1) - { - return serieData.ignore || IsIgnoreValue(serieData.GetData(dimension)); - } - - public bool IsIgnoreValue(double value) - { - return m_Ignore && MathUtil.Approximately(value, m_IgnoreValue); - } - - public bool IsIgnorePoint(int index) - { - if (index >= 0 && index < dataCount) - { - return ChartHelper.IsIngore(data[index].context.position); - } - return false; - } - - public bool IsSerie<T>() where T : Serie - { - return this is T; - } - - public bool IsUseCoord<T>() where T : CoordSystem - { - return ChartCached.GetTypeName<T>().Equals(m_CoordSystem); - } - - public bool SetCoord<T>() where T : CoordSystem - { - if (GetType().IsDefined(typeof(CoordOptionsAttribute), false)) - { - var attribute = GetType().GetAttribute<CoordOptionsAttribute>(); - if (attribute.Contains<T>()) - { - m_CoordSystem = typeof(T).Name; - return true; - } - } - Debug.LogError("not support coord system:" + typeof(T)); - return false; - } - - /// <summary> - /// 是否为性能模式。性能模式下不绘制Symbol,不刷新Label,不单独设置数据项配置。 - /// </summary> - public bool IsPerformanceMode() - { - return m_Large && m_Data.Count > m_LargeThreshold; - } - - public bool IsLegendName(string legendName) - { - if (useDataNameForColor) - { - return IsSerieDataLegendName(legendName) || IsSerieLegendName(legendName); - } - else - { - return IsSerieLegendName(legendName); - } - } - - public bool IsSerieLegendName(string legendName) - { - return legendName.Equals(this.legendName); - } - - public bool IsSerieDataLegendName(string legendName) - { - foreach (var serieData in m_Data) - { - if (legendName.Equals(serieData.legendName)) - return true; - } - return false; - } - - /// <summary> - /// 启用或取消初始动画 - /// </summary> - public void AnimationEnable(bool flag) - { - if (animation.enable) animation.enable = flag; - SetVerticesDirty(); - } - - /// <summary> - /// 渐入动画 - /// </summary> - public void AnimationFadeIn() - { - if (animation.enable) animation.FadeIn(); - SetVerticesDirty(); - } - - /// <summary> - /// 渐出动画 - /// </summary> - public void AnimationFadeOut() - { - if (animation.enable) animation.FadeOut(); - SetVerticesDirty(); - } - - /// <summary> - /// 暂停动画 - /// </summary> - public void AnimationPause() - { - if (animation.enable) animation.Pause(); - SetVerticesDirty(); - } - - /// <summary> - /// 继续动画 - /// </summary> - public void AnimationResume() - { - if (animation.enable) animation.Resume(); - SetVerticesDirty(); - } - - /// <summary> - /// 重置动画 - /// </summary> - public void AnimationReset() - { - if (animation.enable) animation.Reset(); - SetVerticesDirty(); - } - - /// <summary> - /// 重置动画 - /// </summary> - public void AnimationRestart() - { - if (animation.enable) animation.Restart(); - SetVerticesDirty(); - } - - public int CompareTo(object obj) - { - return index.CompareTo((obj as Serie).index); - } - - public T Clone<T>() where T : Serie - { - var newSerie = Activator.CreateInstance<T>(); - SerieHelper.CopySerie(this, newSerie); - return newSerie; - } - - public Serie Clone() - { - var newSerie = Activator.CreateInstance(GetType()) as Serie; - SerieHelper.CopySerie(this, newSerie); - return newSerie; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Serie.cs.meta b/Assets/XCharts/Runtime/Serie/Serie.cs.meta deleted file mode 100644 index 5a02397..0000000 --- a/Assets/XCharts/Runtime/Serie/Serie.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aa9c09045961a4ea9a34a098f099f2a1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/SerieContext.cs b/Assets/XCharts/Runtime/Serie/SerieContext.cs deleted file mode 100644 index 931513f..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieContext.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public struct PointInfo - { - public Vector3 position; - public bool isIgnoreBreak; - - public PointInfo(Vector3 pos, bool ignore) - { - this.position = pos; - this.isIgnoreBreak = ignore; - } - } - - public class SerieContext - { - /// <summary> - /// 鼠标是否进入serie - /// </summary> - public bool pointerEnter; - /// <summary> - /// 鼠标当前指示的数据项索引(单个) - /// </summary> - public int pointerItemDataIndex = -1; - /// <summary> - /// 鼠标所在轴线上的数据项索引(可能有多个) - /// </summary> - public List<int> pointerAxisDataIndexs = new List<int>(); - public bool isTriggerByAxis = false; - - /// <summary> - /// 中心点 - /// </summary> - public Vector3 center; - /// <summary> - /// 线段终点 - /// </summary> - public Vector3 lineEndPostion; - public double lineEndValue; - /// <summary> - /// 内半径 - /// </summary> - public float insideRadius; - /// <summary> - /// 外半径 - /// </summary> - public float outsideRadius; - public float startAngle; - /// <summary> - /// 最大值 - /// </summary> - public double dataMax; - /// <summary> - /// 最小值 - /// </summary> - public double dataMin; - public double checkValue; - /// <summary> - /// 左下角坐标X - /// </summary> - public float x; - /// <summary> - /// 左下角坐标Y - /// </summary> - public float y; - /// <summary> - /// 宽 - /// </summary> - public float width; - /// <summary> - /// 高 - /// </summary> - public float height; - /// <summary> - /// 矩形区域 - /// </summary> - public Rect rect; - /// <summary> - /// 绘制顶点数 - /// </summary> - public int vertCount; - /// <summary> - /// 数据对应的位置坐标。 - /// </summary> - public List<Vector3> dataPoints = new List<Vector3>(); - /// <summary> - /// 数据对应的位置坐标是否忽略(忽略时连线是透明的),dataIgnore 和 dataPoints 一一对应。 - /// </summary> - public List<bool> dataIgnores = new List<bool>(); - /// <summary> - /// 排序后的数据 - /// </summary> - public List<SerieData> sortedData = new List<SerieData>(); - public List<SerieData> rootData = new List<SerieData>(); - /// <summary> - /// theme的颜色索引 - /// </summary> - public int colorIndex; - /// <summary> - /// 绘制点 - /// </summary> - public List<PointInfo> drawPoints = new List<PointInfo>(); - public SerieParams param = new SerieParams(); - public ChartLabel titleObject { get; set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/SerieContext.cs.meta b/Assets/XCharts/Runtime/Serie/SerieContext.cs.meta deleted file mode 100644 index 0966877..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 87f333572a32a4cb39aa0a05ed97983a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/SerieData.cs b/Assets/XCharts/Runtime/Serie/SerieData.cs deleted file mode 100644 index bfa99c1..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieData.cs +++ /dev/null @@ -1,565 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using XUGL; - -namespace XCharts.Runtime -{ - /// <summary> - /// A data item of serie. - /// |系列中的一个数据项。可存储数据名和1-n维个数据。 - /// </summary> - [System.Serializable] - public class SerieData : ChildComponent - { - public static List<string> extraFieldList = new List<string>() - { - "m_Id", - "m_ParentId", - "m_Ignore", - "m_Selected", - "m_Radius" - }; - public static Dictionary<Type, string> extraComponentMap = new Dictionary<Type, string> - { { typeof(ItemStyle), "m_ItemStyles" }, - { typeof(LabelStyle), "m_Labels" }, - { typeof(LabelLine), "m_LabelLines" }, - { typeof(SerieSymbol), "m_Symbols" }, - { typeof(LineStyle), "m_LineStyles" }, - { typeof(AreaStyle), "m_AreaStyles" }, - { typeof(TitleStyle), "m_TitleStyles" }, - { typeof(EmphasisItemStyle), "m_EmphasisItemStyles" }, - { typeof(EmphasisLabelStyle), "m_EmphasisLabels" }, - { typeof(EmphasisLabelLine), "m_EmphasisLabelLines" }, - }; - - [SerializeField] private int m_Index; - [SerializeField] private string m_Name; - [SerializeField] private string m_Id; - [SerializeField] private string m_ParentId; - [SerializeField] private bool m_Ignore; - [SerializeField] private bool m_Selected; - [SerializeField] private float m_Radius; - [SerializeField][IgnoreDoc] private List<ItemStyle> m_ItemStyles = new List<ItemStyle>(); - [SerializeField][IgnoreDoc] private List<LabelStyle> m_Labels = new List<LabelStyle>(); - [SerializeField][IgnoreDoc] private List<LabelLine> m_LabelLines = new List<LabelLine>(); - [SerializeField][IgnoreDoc] private List<SerieSymbol> m_Symbols = new List<SerieSymbol>(); - [SerializeField][IgnoreDoc] private List<LineStyle> m_LineStyles = new List<LineStyle>(); - [SerializeField][IgnoreDoc] private List<AreaStyle> m_AreaStyles = new List<AreaStyle>(); - [SerializeField][IgnoreDoc] private List<TitleStyle> m_TitleStyles = new List<TitleStyle>(); - [SerializeField][IgnoreDoc] private List<EmphasisItemStyle> m_EmphasisItemStyles = new List<EmphasisItemStyle>(); - [SerializeField][IgnoreDoc] private List<EmphasisLabelStyle> m_EmphasisLabels = new List<EmphasisLabelStyle>(); - [SerializeField][IgnoreDoc] private List<EmphasisLabelLine> m_EmphasisLabelLines = new List<EmphasisLabelLine>(); - [SerializeField] private List<double> m_Data = new List<double>(); - - [NonSerialized] public SerieDataContext context = new SerieDataContext(); - [NonSerialized] public InteractData interact = new InteractData(); - - public ChartLabel labelObject { get; set; } - public ChartLabel titleObject { get; set; } - - private bool m_Show = true; - /// <summary> - /// the index of SerieData. - /// |数据项索引。 - /// </summary> - public override int index { get { return m_Index; } set { m_Index = value; } } - /// <summary> - /// the name of data item. - /// |数据项名称。 - /// </summary> - public string name { get { return m_Name; } set { m_Name = value; } } - /// <summary> - /// the id of data. - /// |数据项的唯一id。唯一id不是必须设置的。 - /// </summary> - public string id { get { return m_Id; } set { m_Id = value; } } - /// <summary> - /// the id of parent SerieData. - /// |父节点id。父节点id不是必须设置的。 - /// </summary> - public string parentId { get { return m_ParentId; } set { m_ParentId = value; } } - /// <summary> - /// 是否忽略数据。当为 true 时,数据不进行绘制。 - /// </summary> - public bool ignore - { - get { return m_Ignore; } - set { if (PropertyUtil.SetStruct(ref m_Ignore, value)) SetVerticesDirty(); } - } - /// <summary> - /// 自定义半径。可用在饼图中自定义某个数据项的半径。 - /// </summary> - public float radius { get { return m_Radius; } set { m_Radius = value; } } - /// <summary> - /// Whether the data item is selected. - /// |该数据项是否被选中。 - /// </summary> - public bool selected { get { return m_Selected; } set { m_Selected = value; } } - /// <summary> - /// 数据项图例名称。当数据项名称不为空时,图例名称即为系列名称;反之则为索引index。 - /// </summary> - /// <value></value> - public string legendName { get { return string.IsNullOrEmpty(name) ? ChartCached.IntToStr(index) : name; } } - - /// <summary> - /// 单个数据项的标签设置。 - /// </summary> - public LabelStyle labelStyle { get { return m_Labels.Count > 0 ? m_Labels[0] : null; } } - public LabelLine labelLine { get { return m_LabelLines.Count > 0 ? m_LabelLines[0] : null; } } - /// <summary> - /// 单个数据项的样式设置。 - /// </summary> - public ItemStyle itemStyle { get { return m_ItemStyles.Count > 0 ? m_ItemStyles[0] : null; } } - /// <summary> - /// 单个数据项的标记设置。 - /// </summary> - public SerieSymbol symbol { get { return m_Symbols.Count > 0 ? m_Symbols[0] : null; } } - public LineStyle lineStyle { get { return m_LineStyles.Count > 0 ? m_LineStyles[0] : null; } } - public AreaStyle areaStyle { get { return m_AreaStyles.Count > 0 ? m_AreaStyles[0] : null; } } - public TitleStyle titleStyle { get { return m_TitleStyles.Count > 0 ? m_TitleStyles[0] : null; } } - /// <summary> - /// 高亮的图形样式 - /// </summary> - public EmphasisItemStyle emphasisItemStyle { get { return m_EmphasisItemStyles.Count > 0 ? m_EmphasisItemStyles[0] : null; } } - /// <summary> - /// 高亮时的标签样式 - /// </summary> - public EmphasisLabelStyle emphasisLabel { get { return m_EmphasisLabels.Count > 0 ? m_EmphasisLabels[0] : null; } } - /// <summary> - /// 高亮时的标签引导线样式 - /// </summary> - public EmphasisLabelLine emphasisLabelLine { get { return m_EmphasisLabelLines.Count > 0 ? m_EmphasisLabelLines[0] : null; } } - - /// <summary> - /// An arbitrary dimension data list of data item. - /// |可指定任意维数的数值列表。 - /// </summary> - public List<double> data { get { return m_Data; } set { m_Data = value; } } - /// <summary> - /// [default:true] Whether the data item is showed. - /// |该数据项是否要显示。 - /// </summary> - public bool show { get { return m_Show; } set { m_Show = value; } } - - private List<double> m_PreviousData = new List<double>(); - private List<float> m_DataUpdateTime = new List<float>(); - private List<bool> m_DataUpdateFlag = new List<bool>(); - private List<Vector2> m_PolygonPoints = new List<Vector2>(); - - public override bool vertsDirty - { - get - { - return m_VertsDirty || - (labelLine != null && labelLine.vertsDirty) || - (itemStyle != null && itemStyle.vertsDirty) || - (symbol != null && symbol.vertsDirty) || - (lineStyle != null && lineStyle.vertsDirty) || - (areaStyle != null && areaStyle.vertsDirty) || - (emphasisItemStyle != null && emphasisItemStyle.vertsDirty); - } - } - public override bool componentDirty - { - get - { - return m_ComponentDirty || - (labelStyle != null && labelStyle.componentDirty) || - (labelLine != null && labelLine.componentDirty) || - (titleStyle != null && titleStyle.componentDirty) || - (emphasisLabel != null && emphasisLabel.componentDirty) || - (emphasisLabelLine != null && emphasisLabelLine.componentDirty); - } - } - - public override void ClearVerticesDirty() - { - base.ClearVerticesDirty(); - if (labelLine != null) labelLine.ClearVerticesDirty(); - if (itemStyle != null) itemStyle.ClearVerticesDirty(); - if (lineStyle != null) lineStyle.ClearVerticesDirty(); - if (areaStyle != null) areaStyle.ClearVerticesDirty(); - if (symbol != null) symbol.ClearVerticesDirty(); - if (emphasisItemStyle != null) emphasisItemStyle.ClearVerticesDirty(); - } - - public override void ClearComponentDirty() - { - base.ClearComponentDirty(); - if (labelLine != null) labelLine.ClearComponentDirty(); - if (itemStyle != null) itemStyle.ClearComponentDirty(); - if (lineStyle != null) lineStyle.ClearComponentDirty(); - if (areaStyle != null) areaStyle.ClearComponentDirty(); - if (symbol != null) symbol.ClearComponentDirty(); - if (emphasisLabel != null) emphasisLabel.ClearComponentDirty(); - if (emphasisLabelLine != null) emphasisLabelLine.ClearComponentDirty(); - } - - public void Reset() - { - index = 0; - m_Id = null; - m_ParentId = null; - labelObject = null; - m_Name = string.Empty; - m_Show = true; - context.Reset(); - interact.Reset(); - m_Data.Clear(); - m_PreviousData.Clear(); - m_DataUpdateTime.Clear(); - m_DataUpdateFlag.Clear(); - m_Labels.Clear(); - m_LabelLines.Clear(); - m_ItemStyles.Clear(); - m_Symbols.Clear(); - m_LineStyles.Clear(); - m_AreaStyles.Clear(); - m_TitleStyles.Clear(); - m_EmphasisItemStyles.Clear(); - m_EmphasisLabels.Clear(); - m_EmphasisLabelLines.Clear(); - } - - public T GetOrAddComponent<T>() where T : ChildComponent, ISerieDataComponent - { - return GetOrAddComponent(typeof(T)) as T; - } - - public ISerieDataComponent GetOrAddComponent(Type type) - { - if (type == typeof(ItemStyle)) - { - if (m_ItemStyles.Count == 0) - m_ItemStyles.Add(new ItemStyle() { show = true }); - return m_ItemStyles[0]; - } - else if (type == typeof(LabelStyle)) - { - if (m_Labels.Count == 0) - m_Labels.Add(new LabelStyle() { show = true }); - return m_Labels[0]; - } - else if (type == typeof(LabelLine)) - { - if (m_LabelLines.Count == 0) - m_LabelLines.Add(new LabelLine() { show = true }); - return m_LabelLines[0]; - } - else if (type == typeof(EmphasisItemStyle)) - { - if (m_EmphasisItemStyles.Count == 0) - m_EmphasisItemStyles.Add(new EmphasisItemStyle() { show = true }); - return m_EmphasisItemStyles[0]; - } - else if (type == typeof(EmphasisLabelStyle)) - { - if (m_EmphasisLabels.Count == 0) - m_EmphasisLabels.Add(new EmphasisLabelStyle() { show = true }); - return m_EmphasisLabels[0]; - } - else if (type == typeof(EmphasisLabelLine)) - { - if (m_EmphasisLabelLines.Count == 0) - m_EmphasisLabelLines.Add(new EmphasisLabelLine() { show = true }); - return m_EmphasisLabelLines[0]; - } - else if (type == typeof(SerieSymbol)) - { - if (m_Symbols.Count == 0) - m_Symbols.Add(new SerieSymbol() { show = true }); - return m_Symbols[0]; - } - else if (type == typeof(LineStyle)) - { - if (m_LineStyles.Count == 0) - m_LineStyles.Add(new LineStyle() { show = true }); - return m_LineStyles[0]; - } - else if (type == typeof(AreaStyle)) - { - if (m_AreaStyles.Count == 0) - m_AreaStyles.Add(new AreaStyle() { show = true }); - return m_AreaStyles[0]; - } - else if (type == typeof(TitleStyle)) - { - if (m_TitleStyles.Count == 0) - m_TitleStyles.Add(new TitleStyle() { show = true }); - return m_TitleStyles[0]; - } - else - { - throw new System.Exception("SerieData not support component:" + type); - } - } - - public void RemoveAllComponent() - { - m_ItemStyles.Clear(); - m_Labels.Clear(); - m_LabelLines.Clear(); - m_Symbols.Clear(); - m_EmphasisItemStyles.Clear(); - m_EmphasisLabels.Clear(); - m_EmphasisLabelLines.Clear(); - m_LineStyles.Clear(); - m_AreaStyles.Clear(); - m_TitleStyles.Clear(); - } - - public void RemoveComponent<T>() where T : ISerieDataComponent - { - RemoveComponent(typeof(T)); - } - - public void RemoveComponent(Type type) - { - if (type == typeof(ItemStyle)) - m_ItemStyles.Clear(); - else if (type == typeof(LabelStyle)) - m_Labels.Clear(); - else if (type == typeof(LabelLine)) - m_LabelLines.Clear(); - else if (type == typeof(EmphasisItemStyle)) - m_EmphasisItemStyles.Clear(); - else if (type == typeof(EmphasisLabelStyle)) - m_EmphasisLabels.Clear(); - else if (type == typeof(EmphasisLabelLine)) - m_EmphasisLabelLines.Clear(); - else if (type == typeof(SerieSymbol)) - m_Symbols.Clear(); - else if (type == typeof(LineStyle)) - m_LineStyles.Clear(); - else if (type == typeof(AreaStyle)) - m_AreaStyles.Clear(); - else if (type == typeof(TitleStyle)) - m_TitleStyles.Clear(); - else - throw new System.Exception("SerieData not support component:" + type); - } - public double GetData(int index, bool inverse = false) - { - if (index >= 0 && index < m_Data.Count) - { - return inverse ? -m_Data[index] : m_Data[index]; - } - else return 0; - } - - public double GetData(int index, double min, double max) - { - if (index >= 0 && index < m_Data.Count) - { - var value = m_Data[index]; - if (value < min) return min; - else if (value > max) return max; - else return value; - } - else return 0; - } - - public double GetPreviousData(int index, bool inverse = false) - { - if (index >= 0 && index < m_PreviousData.Count) - { - return inverse ? -m_PreviousData[index] : m_PreviousData[index]; - } - else return 0; - } - - public double GetFirstData(float animationDuration = 500f) - { - if (m_Data.Count > 0) return GetCurrData(0, animationDuration); - return 0; - } - - public double GetLastData() - { - if (m_Data.Count > 0) return m_Data[m_Data.Count - 1]; - return 0; - } - - public double GetCurrData(int index, float animationDuration = 500f, bool inverse = false) - { - return GetCurrData(index, animationDuration, inverse, 0, 0); - } - - public double GetCurrData(int index, float animationDuration, bool inverse, double min, double max) - { - if (index < m_DataUpdateFlag.Count && m_DataUpdateFlag[index] && animationDuration > 0) - { - var time = Time.time - m_DataUpdateTime[index]; - var total = animationDuration / 1000; - - var rate = time / total; - if (rate > 1) rate = 1; - if (rate < 1) - { - CheckLastData(); - var curr = MathUtil.Lerp(GetPreviousData(index), GetData(index), rate); - if (min != 0 || max != 0) - { - if (inverse) - { - var temp = min; - min = -max; - max = -temp; - } - var pre = m_PreviousData[index]; - if (pre < min) - { - m_PreviousData[index] = min; - curr = min; - } - else if (pre > max) - { - m_PreviousData[index] = max; - curr = max; - } - } - curr = inverse ? -curr : curr; - return curr; - } - else - { - m_DataUpdateFlag[index] = false; - return GetData(index, inverse); - } - } - else - { - return GetData(index, inverse); - } - } - - /// <summary> - /// the maxinum value. - /// |最大值。 - /// </summary> - public double GetMaxData(bool inverse = false) - { - if (m_Data.Count == 0) return 0; - var temp = double.MinValue; - for (int i = 0; i < m_Data.Count; i++) - { - var value = GetData(i, inverse); - if (value > temp) temp = value; - } - return temp; - } - - /// <summary> - /// the mininum value. - /// |最小值。 - /// </summary> - public double GetMinData(bool inverse = false) - { - if (m_Data.Count == 0) return 0; - var temp = double.MaxValue; - for (int i = 0; i < m_Data.Count; i++) - { - var value = GetData(i, inverse); - if (value < temp) temp = value; - } - return temp; - } - - public double GetTotalData() - { - var total = 0d; - foreach (var value in m_Data) - total += value; - return total; - } - - public bool UpdateData(int dimension, double value, bool updateAnimation, float animationDuration = 500f) - { - if (dimension >= 0 && dimension < data.Count) - { - CheckLastData(); - m_PreviousData[dimension] = GetCurrData(dimension, animationDuration); - //m_PreviousData[dimension] = data[dimension];; - m_DataUpdateTime[dimension] = Time.time; - m_DataUpdateFlag[dimension] = updateAnimation; - data[dimension] = value; - return true; - } - return false; - } - - public bool UpdateData(int dimension, double value) - { - if (dimension >= 0 && dimension < data.Count) - { - data[dimension] = value; - return true; - } - return false; - } - - private void CheckLastData() - { - if (m_PreviousData.Count != m_Data.Count) - { - m_PreviousData.Clear(); - m_DataUpdateTime.Clear(); - m_DataUpdateFlag.Clear(); - for (int i = 0; i < m_Data.Count; i++) - { - m_PreviousData.Add(m_Data[i]); - m_DataUpdateTime.Add(Time.time); - m_DataUpdateFlag.Add(false); - } - } - } - - public bool IsDataChanged() - { - for (int i = 0; i < m_DataUpdateFlag.Count; i++) - if (m_DataUpdateFlag[i]) return true; - return false; - } - - public float GetLabelWidth() - { - if (labelObject != null) return labelObject.GetTextWidth(); - else return 0; - } - - public float GetLabelHeight() - { - if (labelObject != null) return labelObject.GetTextHeight(); - return 0; - } - - public void SetLabelActive(bool flag) - { - if (labelObject != null) labelObject.SetActive(flag); - } - public void SetIconActive(bool flag) - { - if (labelObject != null) labelObject.SetActive(flag); - } - - public void SetPolygon(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4) - { - m_PolygonPoints.Clear(); - m_PolygonPoints.Add(p1); - m_PolygonPoints.Add(p2); - m_PolygonPoints.Add(p3); - m_PolygonPoints.Add(p4); - } - public void SetPolygon(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 p5) - { - SetPolygon(p1, p2, p3, p4); - m_PolygonPoints.Add(p5); - } - - public bool IsInPolygon(Vector2 p) - { - return UGLHelper.IsPointInPolygon(p, m_PolygonPoints); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/SerieData.cs.meta b/Assets/XCharts/Runtime/Serie/SerieData.cs.meta deleted file mode 100644 index 93cfdac..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieData.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dbf44007311214228976678a623479b9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/SerieDataContext.cs b/Assets/XCharts/Runtime/Serie/SerieDataContext.cs deleted file mode 100644 index d2bdf49..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieDataContext.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public class SerieDataContext - { - public Vector3 labelPosition; - /// <summary> - /// 开始角度 - /// </summary> - public float startAngle; - /// <summary> - /// 结束角度 - /// </summary> - public float toAngle; - /// <summary> - /// 一半时的角度 - /// </summary> - public float halfAngle; - /// <summary> - /// 当前角度 - /// </summary> - public float currentAngle; - /// <summary> - /// 饼图数据项的内半径 - /// </summary> - public float insideRadius; - /// <summary> - /// 饼图数据项的偏移半径 - /// </summary> - public float offsetRadius; - public float outsideRadius; - public Vector3 position; - public List<Vector3> dataPoints = new List<Vector3>(); - public List<ChartLabel> dataLabels = new List<ChartLabel>(); - public List<SerieData> children = new List<SerieData>(); - /// <summary> - /// 绘制区域。 - /// </summary> - public Rect rect; - public Rect backgroundRect; - public Rect subRect; - public int level; - public SerieData parent; - public Color32 color; - public double area; - public float angle; - public Vector3 offsetCenter; - public Vector3 areaCenter; - public float stackHeight; - public bool isClip; - public bool canShowLabel = true; - public Image symbol; - /// <summary> - /// Whether the data item is highlighted. - /// |该数据项是否被高亮,一般由鼠标悬停或图例悬停触发高亮。 - /// </summary> - public bool highlight - { - get { return m_Highligth; } - set - { - m_Highligth = value; - } - } - private bool m_Highligth; - public bool selected; - - public void Reset() - { - canShowLabel = true; - highlight = false; - parent = null; - symbol = null; - rect = Rect.zero; - subRect = Rect.zero; - children.Clear(); - dataPoints.Clear(); - dataLabels.Clear(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/SerieDataContext.cs.meta b/Assets/XCharts/Runtime/Serie/SerieDataContext.cs.meta deleted file mode 100644 index a202cbb..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieDataContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6fa67a86e80b4456cbe76ef4b330f3fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/SerieHandler.cs b/Assets/XCharts/Runtime/Serie/SerieHandler.cs deleted file mode 100644 index 8a2594b..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieHandler.cs +++ /dev/null @@ -1,579 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -namespace XCharts.Runtime -{ - public abstract class SerieHandler - { - public BaseChart chart { get; internal set; } - public SerieHandlerAttribute attribute { get; internal set; } - public virtual int defaultDimension { get; internal set; } - - public virtual void InitComponent() { } - public virtual void RemoveComponent() { } - public virtual void CheckComponent(StringBuilder sb) { } - public virtual void Update() { } - public virtual void DrawBase(VertexHelper vh) { } - public virtual void DrawSerie(VertexHelper vh) { } - public virtual void DrawTop(VertexHelper vh) { } - public virtual void OnPointerClick(PointerEventData eventData) { } - public virtual void OnPointerDown(PointerEventData eventData) { } - public virtual void OnPointerUp(PointerEventData eventData) { } - public virtual void OnPointerEnter(PointerEventData eventData) { } - public virtual void OnPointerExit(PointerEventData eventData) { } - public virtual void OnDrag(PointerEventData eventData) { } - public virtual void OnBeginDrag(PointerEventData eventData) { } - public virtual void OnEndDrag(PointerEventData eventData) { } - public virtual void OnScroll(PointerEventData eventData) { } - public virtual void RefreshLabelNextFrame() { } - public virtual void RefreshLabelInternal() { } - public virtual void UpdateTooltipSerieParams(int dataIndex, bool showCategory, - string category, string marker, - string itemFormatter, string numericFormatter, - ref List<SerieParams> 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) { } - internal abstract void SetSerie(Serie serie); - } - - public abstract class SerieHandler<T> : SerieHandler where T : Serie - { - private static readonly string s_SerieLabelObjectName = "label"; - private static readonly string s_SerieTitleObjectName = "title"; - private static readonly string s_SerieRootObjectName = "serie"; - private static readonly string s_SerieEndLabelObjectName = "end_label"; - protected GameObject m_SerieRoot; - protected GameObject m_SerieLabelRoot; - protected bool m_InitedLabel; - protected bool m_NeedInitComponent; - protected bool m_RefreshLabel; - protected bool m_LastCheckContextFlag = false; - protected bool m_LegendEnter = false; - protected int m_LegendEnterIndex; - protected ChartLabel m_EndLabel; - - public T serie { get; internal set; } - public GameObject labelObject { get { return m_SerieLabelRoot; } } - - internal override void SetSerie(Serie serie) - { - this.serie = (T) serie; - this.serie.context.param.serieType = typeof(T); - m_NeedInitComponent = true; - AnimationStyleHelper.UpdateSerieAnimation(serie); - } - - public override void Update() - { - if (m_NeedInitComponent) - { - m_NeedInitComponent = false; - InitComponent(); - } - if (m_RefreshLabel) - { - m_RefreshLabel = false; - RefreshLabelInternal(); - RefreshEndLabelInternal(); - } - if (serie.dataDirty) - { - SeriesHelper.UpdateSerieNameList(chart, ref chart.m_LegendRealShowName); - serie.OnDataUpdate(); - serie.dataDirty = false; - } - if (serie.label != null && (serie.labelDirty || serie.label.componentDirty)) - { - serie.labelDirty = false; - serie.label.ClearComponentDirty(); - InitSerieLabel(); - InitSerieEndLabel(); - } - if (serie.endLabel != null && serie.endLabel.componentDirty) - { - serie.endLabel.ClearComponentDirty(); - InitSerieEndLabel(); - } - if (serie.titleStyle != null && (serie.titleDirty || serie.titleStyle.componentDirty)) - { - serie.titleDirty = false; - serie.titleStyle.ClearComponentDirty(); - InitSerieTitle(); - } - if (serie.nameDirty) - { - foreach (var component in chart.components) - { - if (component is Legend) - component.SetAllDirty(); - } - chart.RefreshChart(); - serie.ClearSerieNameDirty(); - } - if (serie.vertsDirty) - { - chart.RefreshPainter(serie); - serie.ResetInteract(); - serie.ClearVerticesDirty(); - } - } - - public override void RefreshLabelNextFrame() - { - m_RefreshLabel = true; - } - - public override void InitComponent() - { - m_InitedLabel = false; - InitRoot(); - InitSerieLabel(); - InitSerieTitle(); - InitSerieEndLabel(); - } - - public override void RemoveComponent() - { - ChartHelper.SetActive(m_SerieRoot, false); - } - - public override void OnLegendButtonClick(int index, string legendName, bool show) - { - if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName)) - { - LegendHelper.CheckDataShow(serie, legendName, show); - chart.UpdateLegendColor(legendName, show); - chart.RefreshPainter(serie); - } - else if (serie.IsLegendName(legendName)) - { - chart.SetSerieActive(serie, show); - chart.RefreshPainter(serie); - } - } - - public override void OnLegendButtonEnter(int index, string legendName) - { - if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName)) - { - LegendHelper.CheckDataHighlighted(serie, legendName, true); - chart.RefreshPainter(serie); - } - else if (serie.IsLegendName(legendName)) - { - m_LegendEnter = true; - chart.RefreshPainter(serie); - } - } - - public override void OnLegendButtonExit(int index, string legendName) - { - if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName)) - { - LegendHelper.CheckDataHighlighted(serie, legendName, false); - chart.RefreshPainter(serie); - } - else if (serie.IsLegendName(legendName)) - { - m_LegendEnter = false; - chart.RefreshPainter(serie); - } - } - - private void InitRoot() - { - if (m_SerieRoot != null) - { - var rect = ChartHelper.GetOrAddComponent<RectTransform>(m_SerieRoot); - rect.localPosition = Vector3.zero; - rect.sizeDelta = chart.chartSizeDelta; - rect.anchorMin = chart.chartMinAnchor; - rect.anchorMax = chart.chartMaxAnchor; - rect.pivot = chart.chartPivot; - return; - } - var objName = s_SerieRootObjectName + "_" + serie.index; - m_SerieRoot = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor, - chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - m_SerieRoot.hideFlags = chart.chartHideFlags; - ChartHelper.SetActive(m_SerieRoot, true); - ChartHelper.HideAllObject(m_SerieRoot); - } - - private void InitSerieLabel() - { - InitRoot(); - m_SerieLabelRoot = ChartHelper.AddObject(s_SerieLabelObjectName, m_SerieRoot.transform, - chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - m_SerieLabelRoot.hideFlags = chart.chartHideFlags; - SerieLabelPool.ReleaseAll(m_SerieLabelRoot.transform); - //ChartHelper.DestroyAllChildren(m_SerieLabelRoot.transform); - int count = 0; - SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight); - for (int j = 0; j < serie.data.Count; j++) - { - var serieData = serie.data[j]; - serieData.index = count; - serieData.labelObject = null; - if (AddSerieLabel(m_SerieLabelRoot, serieData, ref count)) - { - m_InitedLabel = true; - count++; - } - } - RefreshLabelInternal(); - } - - protected bool AddSerieLabel(GameObject serieLabelRoot, SerieData serieData, ref int count) - { - if (serieData == null) - return false; - if (serieLabelRoot == null) - return false; - if (serie.IsPerformanceMode()) - return false; - - if (count == -1) count = serie.dataCount; - var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - if (serieLabel == null) - { - serieLabel = SerieHelper.GetSerieEmphasisLabel(serie, serieData); - if (serieLabel == null || !serieLabel.show) - return false; - } - - var dataAutoColor = GetSerieDataAutoColor(serieData); - serieData.context.dataLabels.Clear(); - if (serie.multiDimensionLabel) - { - for (int i = 0; i < serieData.data.Count; i++) - { - var textName = string.Format("{0}_{1}_{2}_{3}", s_SerieLabelObjectName, serie.index, serieData.index, i); - var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common, - "", dataAutoColor, TextAnchor.MiddleCenter); - label.SetActive(serieLabel.show); - serieData.context.dataLabels.Add(label); - } - } - else - { - var textName = ChartCached.GetSerieLabelName(s_SerieLabelObjectName, serie.index, serieData.index); - var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common, - "", dataAutoColor, TextAnchor.MiddleCenter); - label.SetActive(serieLabel.show); - serieData.labelObject = label; - } - - if (serieData.context.children.Count > 0) - { - foreach (var childSerieData in serieData.context.children) - { - AddSerieLabel(serieLabelRoot, childSerieData, ref count); - count++; - } - } - return true; - } - - private void InitSerieEndLabel() - { - if (serie.endLabel == null) - { - if (m_EndLabel != null) - { - m_EndLabel.SetActive(false); - m_EndLabel = null; - } - return; - } - InitRoot(); - 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); - RefreshEndLabelInternal(); - } - - private void InitSerieTitle() - { - InitRoot(); - var serieTitleRoot = ChartHelper.AddObject(s_SerieTitleObjectName, m_SerieRoot.transform, - chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); - serieTitleRoot.hideFlags = chart.chartHideFlags; - SerieLabelPool.ReleaseAll(serieTitleRoot.transform); - ChartHelper.RemoveComponent<Text>(serieTitleRoot); - - SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight); - - if (serie.titleJustForSerie) - { - var titleStyle = SerieHelper.GetTitleStyle(serie, null); - if (titleStyle != null) - { - var color = chart.GetItemColor(serie, null); - var content = string.Empty; - if (string.IsNullOrEmpty(titleStyle.formatter)) - { - content = serie.serieName; - } - else - { - content = titleStyle.formatter; - FormatterHelper.ReplaceContent(ref content, 0, titleStyle.numericFormatter, serie, chart); - } - var label = ChartHelper.AddChartLabel("title_" + 0, serieTitleRoot.transform, titleStyle, chart.theme.common, - content, color, TextAnchor.MiddleCenter); - serie.context.titleObject = label; - label.SetActive(titleStyle.show); - var labelPosition = GetSerieDataTitlePosition(null, titleStyle); - var offset = titleStyle.GetOffset(serie.context.insideRadius); - label.SetPosition(labelPosition + offset); - } - } - else - { - for (int i = 0; i < serie.dataCount; i++) - { - var serieData = serie.data[i]; - var titleStyle = SerieHelper.GetTitleStyle(serie, serieData); - if (titleStyle == null) continue; - var color = chart.GetItemColor(serie, serieData); - var content = string.Empty; - if (string.IsNullOrEmpty(titleStyle.formatter)) - { - content = serieData.name; - } - else - { - content = titleStyle.formatter; - FormatterHelper.ReplaceContent(ref content, 0, titleStyle.numericFormatter, serie, chart); - } - FormatterHelper.ReplaceContent(ref content, i, titleStyle.numericFormatter, serie, chart); - var label = ChartHelper.AddChartLabel("title_" + i, serieTitleRoot.transform, titleStyle, chart.theme.common, - content, color, TextAnchor.MiddleCenter); - serieData.titleObject = label; - label.SetActive(titleStyle.show); - var labelPosition = GetSerieDataTitlePosition(serieData, titleStyle); - var offset = titleStyle.GetOffset(serie.context.insideRadius); - label.SetPosition(labelPosition + offset); - } - } - } - - public override void RefreshLabelInternal() - { - if (!m_InitedLabel) - return; - - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - foreach (var serieData in serie.data) - { - if (serieData.labelObject == null && serieData.context.dataLabels.Count <= 0) - continue; - var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); - var emphasisLabel = SerieHelper.GetSerieEmphasisLabel(serie, serieData); - var isHighlight = (serieData.context.highlight && emphasisLabel != null && emphasisLabel.show); - var isIgnore = serie.IsIgnoreIndex(serieData.index, defaultDimension); - var currLabel = isHighlight && emphasisLabel != null ? emphasisLabel : serieLabel; - if (serie.show && - currLabel != null && - (currLabel.show || isHighlight) && - serieData.context.canShowLabel && - !isIgnore) - { - if (serie.multiDimensionLabel) - { - var total = serieData.GetTotalData(); - var color = chart.GetItemColor(serie, serieData); - for (int i = 0; i < serieData.context.dataLabels.Count; i++) - { - if (i >= serieData.context.dataPoints.Count) continue; - var labelObject = serieData.context.dataLabels[i]; - var value = serieData.GetCurrData(i, dataChangeDuration); - var content = string.IsNullOrEmpty(currLabel.formatter) ? - ChartCached.NumberToStr(value, serieLabel.numericFormatter) : - SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, - currLabel, color); - var offset = GetSerieDataLabelOffset(serieData, currLabel); - labelObject.SetActive(!isIgnore); - labelObject.SetText(content); - labelObject.SetPosition(serieData.context.dataPoints[i] + offset); - labelObject.UpdateIcon(currLabel.icon); - if (currLabel.textStyle.autoColor) - { - var dataAutoColor = GetSerieDataAutoColor(serieData); - if (!ChartHelper.IsClearColor(dataAutoColor)) - labelObject.SetTextColor(dataAutoColor); - } - } - } - else - { - var value = serieData.GetCurrData(defaultDimension, dataChangeDuration); - var total = serie.GetDataTotal(defaultDimension, serieData); - var color = chart.GetItemColor(serie, serieData); - var content = string.IsNullOrEmpty(currLabel.formatter) ? - ChartCached.NumberToStr(value, serieLabel.numericFormatter) : - SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, - currLabel, color); - serieData.SetLabelActive(!isIgnore); - serieData.labelObject.UpdateIcon(currLabel.icon); - serieData.labelObject.SetText(content); - UpdateLabelPosition(serieData, currLabel); - if (currLabel.textStyle.autoColor) - { - var dataAutoColor = GetSerieDataAutoColor(serieData); - if (!ChartHelper.IsClearColor(dataAutoColor)) - serieData.labelObject.SetTextColor(dataAutoColor); - } - } - } - else - { - serieData.SetLabelActive(false); - foreach (var labelObject in serieData.context.dataLabels) - { - labelObject.SetActive(false); - } - } - } - } - - public virtual void RefreshEndLabelInternal() - { - if (m_EndLabel == null) - return; - var endLabelStyle = serie.endLabel; - if (endLabelStyle == null) - return; - var dataCount = serie.context.drawPoints.Count; - var active = endLabelStyle.show && dataCount > 0; - m_EndLabel.SetActive(active); - if (active) - { - var value = serie.context.lineEndValue; - var content = SerieLabelHelper.GetFormatterContent(serie, null, value, 0, - endLabelStyle, Color.clear); - m_EndLabel.SetText(content); - m_EndLabel.SetPosition(serie.context.lineEndPostion + endLabelStyle.offset); - } - m_EndLabel.isAnimationEnd = serie.animation.IsFinish(); - } - - private void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel) - { - var labelPosition = GetSerieDataLabelPosition(serieData, currLabel); - var offset = GetSerieDataLabelOffset(serieData, currLabel); - serieData.labelObject.SetPosition(labelPosition + offset); - } - - public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label) - { - return ChartHelper.IsZeroVector(serieData.context.labelPosition) ? - serieData.context.position : - serieData.context.labelPosition; - } - - public virtual Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label) - { - return label.GetOffset(serie.context.insideRadius); - } - - public virtual Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle) - { - return serieData.context.position; - } - - public virtual Color GetSerieDataAutoColor(SerieData serieData) - { - var colorIndex = serie.useDataNameForColor ? serieData.index : serie.index; - return (Color) SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false, false); - } - - protected void UpdateCoordSerieParams(ref List<SerieParams> paramList, ref string title, - int dataIndex, bool showCategory, string category, string marker, - string itemFormatter, string numericFormatter) - { - if (dataIndex < 0) - dataIndex = serie.context.pointerItemDataIndex; - - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - if (TooltipHelper.IsIgnoreItemFormatter(itemFormatter)) - return; - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.category = category; - param.dimension = 1; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = serieData.GetData(1); - param.total = serie.yTotal; - param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false); - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = itemFormatter; - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(showCategory ? category : serie.serieName); - param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); - - paramList.Add(param); - } - - protected void UpdateItemSerieParams(ref List<SerieParams> paramList, ref string title, - int dataIndex, string category, string marker, - string itemFormatter, string numericFormatter, int dimension = 1) - { - if (dataIndex < 0) - dataIndex = serie.context.pointerItemDataIndex; - - if (dataIndex < 0) - return; - - var serieData = serie.GetSerieData(dataIndex); - if (serieData == null) - return; - - itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter); - if (TooltipHelper.IsIgnoreItemFormatter(itemFormatter)) - return; - - var colorIndex = chart.GetLegendRealShowNameIndex(serieData.name); - - var param = serie.context.param; - param.serieName = serie.serieName; - param.serieIndex = serie.index; - param.category = category; - param.dimension = dimension; - param.serieData = serieData; - param.dataCount = serie.dataCount; - param.value = serieData.GetData(param.dimension); - param.total = SerieHelper.GetMaxData(serie, dimension); - param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false); - param.marker = SerieHelper.GetItemMarker(serie, serieData, marker); - param.itemFormatter = itemFormatter; - param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter); - param.columns.Clear(); - - param.columns.Add(param.marker); - param.columns.Add(serieData.name); - param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter)); - - paramList.Add(param); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/SerieHandler.cs.meta b/Assets/XCharts/Runtime/Serie/SerieHandler.cs.meta deleted file mode 100644 index 87f9fd8..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieHandler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7f2bc0a6a80a84eae9c87842c954bc32 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Serie/SerieParams.cs b/Assets/XCharts/Runtime/Serie/SerieParams.cs deleted file mode 100644 index d2948a8..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieParams.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public class SerieParams - { - public Type serieType; - public int serieIndex; - public string serieName; - public string marker = "●"; - public string category; - public int dimension; - public SerieData serieData; - public int dataCount; - public double value; - public double total; - public Color32 color; - public string itemFormatter; - public string numericFormatter; - public List<string> columns = new List<string>(); - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/SerieParams.cs.meta b/Assets/XCharts/Runtime/Serie/SerieParams.cs.meta deleted file mode 100644 index f8f138f..0000000 --- a/Assets/XCharts/Runtime/Serie/SerieParams.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c46808eb5842743c5b02d03c4c503228 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme.meta b/Assets/XCharts/Runtime/Theme.meta deleted file mode 100644 index 6987280..0000000 --- a/Assets/XCharts/Runtime/Theme.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b421f1dec4b2943d19640698c2504c6b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/AxisTheme.cs b/Assets/XCharts/Runtime/Theme/AxisTheme.cs deleted file mode 100644 index be4496b..0000000 --- a/Assets/XCharts/Runtime/Theme/AxisTheme.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - [Serializable] - public class BaseAxisTheme : ComponentTheme - { - [SerializeField] protected LineStyle.Type m_LineType = LineStyle.Type.Solid; - [SerializeField] protected float m_LineWidth = 1f; - [SerializeField] protected float m_LineLength = 0f; - [SerializeField] protected Color32 m_LineColor; - [SerializeField] protected LineStyle.Type m_SplitLineType = LineStyle.Type.Dashed; - [SerializeField] protected float m_SplitLineWidth = 1f; - [SerializeField] protected float m_SplitLineLength = 0f; - [SerializeField] protected Color32 m_SplitLineColor; - [SerializeField] protected float m_TickWidth = 1f; - [SerializeField] protected float m_TickLength = 5f; - [SerializeField] protected Color32 m_TickColor; - [SerializeField] protected List<Color32> m_SplitAreaColors = new List<Color32>(); - - /// <summary> - /// the type of line. - /// |坐标轴线类型。 - /// </summary> - public LineStyle.Type lineType - { - get { return m_LineType; } - set { if (PropertyUtil.SetStruct(ref m_LineType, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of line. - /// |坐标轴线宽。 - /// </summary> - public float lineWidth - { - get { return m_LineWidth; } - set { if (PropertyUtil.SetStruct(ref m_LineWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the length of line. - /// |坐标轴线长。 - /// </summary> - public float lineLength - { - get { return m_LineLength; } - set { if (PropertyUtil.SetStruct(ref m_LineLength, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of line. - /// |坐标轴线颜色。 - /// </summary> - public Color32 lineColor - { - get { return m_LineColor; } - set { if (PropertyUtil.SetColor(ref m_LineColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// the type of split line. - /// |分割线线类型。 - /// </summary> - public LineStyle.Type splitLineType - { - get { return m_SplitLineType; } - set { if (PropertyUtil.SetStruct(ref m_SplitLineType, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of split line. - /// |分割线线宽。 - /// </summary> - public float splitLineWidth - { - get { return m_SplitLineWidth; } - set { if (PropertyUtil.SetStruct(ref m_SplitLineWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the length of split line. - /// |分割线线长。 - /// </summary> - public float splitLineLength - { - get { return m_SplitLineLength; } - set { if (PropertyUtil.SetStruct(ref m_SplitLineLength, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of line. - /// |分割线线颜色。 - /// </summary> - public Color32 splitLineColor - { - get { return m_SplitLineColor; } - set { if (PropertyUtil.SetColor(ref m_SplitLineColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// the length of tick. - /// |刻度线线长。 - /// </summary> - public float tickLength - { - get { return m_TickLength; } - set { if (PropertyUtil.SetStruct(ref m_TickLength, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of tick. - /// |刻度线线宽。 - /// </summary> - public float tickWidth - { - get { return m_TickWidth; } - set { if (PropertyUtil.SetStruct(ref m_TickWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of tick. - /// |坐标轴线颜色。 - /// </summary> - public Color32 tickColor - { - get { return m_TickColor; } - set { if (PropertyUtil.SetColor(ref m_TickColor, value)) SetVerticesDirty(); } - } - - public List<Color32> splitAreaColors - { - get { return m_SplitAreaColors; } - set { if (value != null) { m_SplitAreaColors = value; SetVerticesDirty(); } } - } - - public BaseAxisTheme(ThemeType theme) : base(theme) - { - m_FontSize = XCSettings.fontSizeLv4; - m_LineType = XCSettings.axisLineType; - m_LineWidth = XCSettings.axisLineWidth; - m_LineLength = 0; - m_SplitLineType = XCSettings.axisSplitLineType; - m_SplitLineWidth = XCSettings.axisSplitLineWidth; - m_SplitLineLength = 0; - m_TickWidth = XCSettings.axisTickWidth; - m_TickLength = XCSettings.axisTickLength; - switch (theme) - { - case ThemeType.Default: - m_LineColor = ColorUtil.GetColor("#514D4D"); - m_TickColor = ColorUtil.GetColor("#514D4D"); - m_SplitLineColor = ColorUtil.GetColor("#51515120"); - m_SplitAreaColors = new List<Color32> - { - new Color32(250, 250, 250, 77), - new Color32(200, 200, 200, 77) - }; - break; - case ThemeType.Light: - m_LineColor = ColorUtil.GetColor("#514D4D"); - m_TickColor = ColorUtil.GetColor("#514D4D"); - m_SplitLineColor = ColorUtil.GetColor("#51515120"); - m_SplitAreaColors = new List<Color32> - { - new Color32(250, 250, 250, 77), - new Color32(200, 200, 200, 77) - }; - break; - case ThemeType.Dark: - m_LineColor = ColorUtil.GetColor("#B9B8CE"); - m_TickColor = ColorUtil.GetColor("#B9B8CE"); - m_SplitLineColor = ColorUtil.GetColor("#484753"); - m_SplitAreaColors = new List<Color32> - { - new Color32(255, 255, 255, (byte) (0.02f * 255)), - new Color32(255, 255, 255, (byte) (0.05f * 255)) - }; - break; - } - } - - public void Copy(BaseAxisTheme theme) - { - base.Copy(theme); - m_LineType = theme.lineType; - m_LineWidth = theme.lineWidth; - m_LineLength = theme.lineLength; - m_LineColor = theme.lineColor; - m_SplitLineType = theme.splitLineType; - m_SplitLineWidth = theme.splitLineWidth; - m_SplitLineLength = theme.splitLineLength; - m_SplitLineColor = theme.splitLineColor; - m_TickWidth = theme.tickWidth; - m_TickLength = theme.tickLength; - m_TickColor = theme.tickColor; - ChartHelper.CopyList(m_SplitAreaColors, theme.splitAreaColors); - } - } - - [Serializable] - public class AxisTheme : BaseAxisTheme - { - public AxisTheme(ThemeType theme) : base(theme) - { } - } - - [Serializable] - public class RadiusAxisTheme : BaseAxisTheme - { - public RadiusAxisTheme(ThemeType theme) : base(theme) - { } - } - - [Serializable] - public class AngleAxisTheme : BaseAxisTheme - { - public AngleAxisTheme(ThemeType theme) : base(theme) - { } - } - - [Serializable] - public class PolarAxisTheme : BaseAxisTheme - { - public PolarAxisTheme(ThemeType theme) : base(theme) - { } - } - - [Serializable] - public class RadarAxisTheme : BaseAxisTheme - { - public RadarAxisTheme(ThemeType theme) : base(theme) - { - m_SplitAreaColors.Clear(); - switch (theme) - { - case ThemeType.Dark: - m_SplitAreaColors.Add(ThemeStyle.GetColor("#6f6f6f")); - m_SplitAreaColors.Add(ThemeStyle.GetColor("#606060")); - break; - case ThemeType.Default: - m_SplitAreaColors.Add(ThemeStyle.GetColor("#f6f6f6")); - m_SplitAreaColors.Add(ThemeStyle.GetColor("#e7e7e7")); - break; - case ThemeType.Light: - m_SplitAreaColors.Add(ThemeStyle.GetColor("#f6f6f6")); - m_SplitAreaColors.Add(ThemeStyle.GetColor("#e7e7e7")); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/AxisTheme.cs.meta b/Assets/XCharts/Runtime/Theme/AxisTheme.cs.meta deleted file mode 100644 index cc88ab9..0000000 --- a/Assets/XCharts/Runtime/Theme/AxisTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: aefd22e76a6f642c9985b1a29e389858 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/ComponentTheme.cs b/Assets/XCharts/Runtime/Theme/ComponentTheme.cs deleted file mode 100644 index 91141cf..0000000 --- a/Assets/XCharts/Runtime/Theme/ComponentTheme.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - [Serializable] - public class ComponentTheme : ChildComponent - { - [SerializeField] protected Font m_Font; - [SerializeField] protected Color m_TextColor; - [SerializeField] protected Color m_TextBackgroundColor; - [SerializeField] protected int m_FontSize = 18; -#if dUI_TextMeshPro - [SerializeField] protected TMP_FontAsset m_TMPFont; -#endif - - /// <summary> - /// the font of text. - /// |字体。 - /// </summary> - public Font font - { - get { return m_Font; } - set { m_Font = value; SetComponentDirty(); } - } - /// <summary> - /// the color of text. - /// |文本颜色。 - /// </summary> - public Color textColor - { - get { return m_TextColor; } - set { if (PropertyUtil.SetColor(ref m_TextColor, value)) SetComponentDirty(); } - } - /// <summary> - /// the color of text. - /// |文本颜色。 - /// </summary> - public Color textBackgroundColor - { - get { return m_TextBackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_TextBackgroundColor, value)) SetComponentDirty(); } - } - /// <summary> - /// the font size of text. - /// |文本字体大小。 - /// </summary> - public int fontSize - { - get { return m_FontSize; } - set { if (PropertyUtil.SetStruct(ref m_FontSize, value)) SetComponentDirty(); } - } - -#if dUI_TextMeshPro - /// <summary> - /// the font of chart text。 - /// |字体。 - /// </summary> - public TMP_FontAsset tmpFont - { - get { return m_TMPFont; } - set { m_TMPFont = value; SetComponentDirty(); } - } -#endif - - public ComponentTheme(ThemeType theme) - { - m_FontSize = XCSettings.fontSizeLv3; - switch (theme) - { - case ThemeType.Default: - m_TextColor = ColorUtil.GetColor("#514D4D"); - break; - case ThemeType.Light: - m_TextColor = ColorUtil.GetColor("#514D4D"); - break; - case ThemeType.Dark: - m_TextColor = ColorUtil.GetColor("#B9B8CE"); - break; - } - } - - public virtual void Copy(ComponentTheme theme) - { - m_Font = theme.font; - m_FontSize = theme.fontSize; - m_TextColor = theme.textColor; - m_TextBackgroundColor = theme.textBackgroundColor; -#if dUI_TextMeshPro - m_TMPFont = theme.tmpFont; -#endif - } - - public virtual void Reset(ComponentTheme defaultTheme) - { - Copy(defaultTheme); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/ComponentTheme.cs.meta b/Assets/XCharts/Runtime/Theme/ComponentTheme.cs.meta deleted file mode 100644 index e401a88..0000000 --- a/Assets/XCharts/Runtime/Theme/ComponentTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e78d1c80572324fc0b5cc5c935a2e34c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/DataZoomTheme.cs b/Assets/XCharts/Runtime/Theme/DataZoomTheme.cs deleted file mode 100644 index 0c4a886..0000000 --- a/Assets/XCharts/Runtime/Theme/DataZoomTheme.cs +++ /dev/null @@ -1,125 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - public class DataZoomTheme : ComponentTheme - { - [SerializeField] protected float m_BorderWidth; - [SerializeField] protected float m_DataLineWidth; - [SerializeField] protected Color32 m_FillerColor; - [SerializeField] protected Color32 m_BorderColor; - [SerializeField] protected Color32 m_DataLineColor; - [SerializeField] protected Color32 m_DataAreaColor; - [SerializeField] protected Color32 m_BackgroundColor; - - /// <summary> - /// the width of border line. - /// |边框线宽。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of data line. - /// |数据阴影线宽。 - /// </summary> - public float dataLineWidth - { - get { return m_DataLineWidth; } - set { if (PropertyUtil.SetStruct(ref m_DataLineWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of dataZoom data area. - /// |数据区域颜色。 - /// </summary> - public Color32 fillerColor - { - get { return m_FillerColor; } - set { if (PropertyUtil.SetColor(ref m_FillerColor, value)) SetVerticesDirty(); } - } - - /// <summary> - /// the color of dataZoom border. - /// |边框颜色。 - /// </summary> - public Color32 borderColor - { - get { return m_BorderColor; } - set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetComponentDirty(); } - } - /// <summary> - /// the color of data area line. - /// |数据阴影的线条颜色。 - /// </summary> - public Color32 dataLineColor - { - get { return m_DataLineColor; } - set { if (PropertyUtil.SetColor(ref m_DataLineColor, value)) SetComponentDirty(); } - } - /// <summary> - /// the color of data area line. - /// |数据阴影的填充颜色。 - /// </summary> - public Color32 dataAreaColor - { - get { return m_DataAreaColor; } - set { if (PropertyUtil.SetColor(ref m_DataAreaColor, value)) SetComponentDirty(); } - } - /// <summary> - /// the background color of datazoom. - /// |背景颜色。 - /// </summary> - public Color32 backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_BackgroundColor, value)) SetComponentDirty(); } - } - - public DataZoomTheme(ThemeType theme) : base(theme) - { - m_BorderWidth = XCSettings.dataZoomBorderWidth; - m_DataLineWidth = XCSettings.dataZoomDataLineWidth; - m_BackgroundColor = Color.clear; - switch (theme) - { - case ThemeType.Default: - m_TextColor = ColorUtil.GetColor("#333"); - m_FillerColor = new Color32(167, 183, 204, 110); - m_BorderColor = ColorUtil.GetColor("#ddd"); - m_DataLineColor = ColorUtil.GetColor("#2f4554"); - m_DataAreaColor = new Color32(47, 69, 84, 85); - break; - case ThemeType.Light: - m_TextColor = ColorUtil.GetColor("#333"); - m_FillerColor = new Color32(167, 183, 204, 110); - m_BorderColor = ColorUtil.GetColor("#ddd"); - m_DataLineColor = ColorUtil.GetColor("#2f4554"); - m_DataAreaColor = new Color32(47, 69, 84, 85); - break; - case ThemeType.Dark: - m_TextColor = ColorUtil.GetColor("#B9B8CE"); - m_FillerColor = new Color32(135, 163, 206, (byte) (0.2f * 255)); - m_BorderColor = ColorUtil.GetColor("#71708A"); - m_DataLineColor = ColorUtil.GetColor("#71708A"); - m_DataAreaColor = ColorUtil.GetColor("#71708A"); - break; - } - } - - public void Copy(DataZoomTheme theme) - { - base.Copy(theme); - m_BorderWidth = theme.borderWidth; - m_DataLineWidth = theme.dataLineWidth; - m_FillerColor = theme.fillerColor; - m_BorderColor = theme.borderColor; - m_DataLineColor = theme.dataLineColor; - m_DataAreaColor = theme.dataAreaColor; - m_BackgroundColor = theme.backgroundColor; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/DataZoomTheme.cs.meta b/Assets/XCharts/Runtime/Theme/DataZoomTheme.cs.meta deleted file mode 100644 index 9545b7f..0000000 --- a/Assets/XCharts/Runtime/Theme/DataZoomTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ba535ef75742b4825b3cc2be4df6716f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/LegendTheme.cs b/Assets/XCharts/Runtime/Theme/LegendTheme.cs deleted file mode 100644 index 259abd4..0000000 --- a/Assets/XCharts/Runtime/Theme/LegendTheme.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - [Serializable] - public class LegendTheme : ComponentTheme - { - [SerializeField] protected Color m_UnableColor; - - /// <summary> - /// the color of text. - /// |文本颜色。 - /// </summary> - public Color unableColor - { - get { return m_UnableColor; } - set { if (PropertyUtil.SetColor(ref m_UnableColor, value)) SetComponentDirty(); } - } - - public void Copy(LegendTheme theme) - { - base.Copy(theme); - m_UnableColor = theme.unableColor; - } - - public LegendTheme(ThemeType theme) : base(theme) - { - m_UnableColor = ColorUtil.GetColor("#cccccc"); - - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/LegendTheme.cs.meta b/Assets/XCharts/Runtime/Theme/LegendTheme.cs.meta deleted file mode 100644 index d544c65..0000000 --- a/Assets/XCharts/Runtime/Theme/LegendTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a86fb06a6b71c4735b87769ee0708293 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/SerieTheme.cs b/Assets/XCharts/Runtime/Theme/SerieTheme.cs deleted file mode 100644 index f22e0c6..0000000 --- a/Assets/XCharts/Runtime/Theme/SerieTheme.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - public class SerieTheme : ChildComponent - { - [SerializeField] protected float m_LineWidth; - [SerializeField] protected float m_LineSymbolSize; - [SerializeField] protected float m_ScatterSymbolSize; - [SerializeField] protected float m_PieTooltipExtraRadius; - [SerializeField] protected float m_SelectedRate = 1.3f; - [SerializeField] protected float m_PieSelectedOffset; - [SerializeField] protected Color32 m_CandlestickColor = new Color32(235, 84, 84, 255); - [SerializeField] protected Color32 m_CandlestickColor0 = new Color32(71, 178, 98, 255); - [SerializeField] protected float m_CandlestickBorderWidth = 1; - [SerializeField] protected Color32 m_CandlestickBorderColor = new Color32(235, 84, 84, 255); - [SerializeField] protected Color32 m_CandlestickBorderColor0 = new Color32(71, 178, 98, 255); - - /// <summary> - /// the color of text. - /// |文本颜色。 - /// </summary> - public float lineWidth - { - get { return m_LineWidth; } - set { if (PropertyUtil.SetStruct(ref m_LineWidth, value)) SetVerticesDirty(); } - } - public float lineSymbolSize - { - get { return m_LineSymbolSize; } - set { if (PropertyUtil.SetStruct(ref m_LineSymbolSize, value)) SetVerticesDirty(); } - } - public float lineSymbolSelectedSize { get { return lineSymbolSize * selectedRate; } } - public float scatterSymbolSize - { - get { return m_ScatterSymbolSize; } - set { if (PropertyUtil.SetStruct(ref m_ScatterSymbolSize, value)) SetVerticesDirty(); } - } - public float scatterSymbolSelectedSize { get { return scatterSymbolSize * selectedRate; } } - public float selectedRate - { - get { return m_SelectedRate; } - set { if (PropertyUtil.SetStruct(ref m_SelectedRate, value)) SetVerticesDirty(); } - } - - /// <summary> - /// 饼图鼠标移到高亮时的额外半径 - /// </summary> - public float pieTooltipExtraRadius - { - get { return m_PieTooltipExtraRadius; } - set { if (PropertyUtil.SetStruct(ref m_PieTooltipExtraRadius, value < 0 ? 0f : value)) SetVerticesDirty(); } - } - /// <summary> - /// 饼图选中时的中心点偏移 - /// </summary> - public float pieSelectedOffset - { - get { return m_PieSelectedOffset; } - set { if (PropertyUtil.SetStruct(ref m_PieSelectedOffset, value < 0 ? 0f : value)) SetVerticesDirty(); } - } - /// <summary> - /// K线图阳线(涨)填充色 - /// </summary> - public Color32 candlestickColor - { - get { return m_CandlestickColor; } - set { if (PropertyUtil.SetColor(ref m_CandlestickColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// K线图阴线(跌)填充色 - /// </summary> - public Color32 candlestickColor0 - { - get { return m_CandlestickColor0; } - set { if (PropertyUtil.SetColor(ref m_CandlestickColor0, value)) SetVerticesDirty(); } - } - /// <summary> - /// K线图阳线(跌)边框色 - /// </summary> - public Color32 candlestickBorderColor - { - get { return m_CandlestickBorderColor; } - set { if (PropertyUtil.SetColor(ref m_CandlestickBorderColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// K线图阴线(跌)边框色 - /// </summary> - public Color32 candlestickBorderColor0 - { - get { return m_CandlestickBorderColor0; } - set { if (PropertyUtil.SetColor(ref m_CandlestickBorderColor0, value)) SetVerticesDirty(); } - } - - /// <summary> - /// K线图边框宽度 - /// </summary> - public float candlestickBorderWidth - { - get { return m_CandlestickBorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_CandlestickBorderWidth, value < 0 ? 0f : value)) SetVerticesDirty(); } - } - - public void Copy(SerieTheme theme) - { - m_LineWidth = theme.lineWidth; - m_LineSymbolSize = theme.lineSymbolSize; - m_ScatterSymbolSize = theme.scatterSymbolSize; - selectedRate = theme.selectedRate; - m_PieTooltipExtraRadius = theme.pieTooltipExtraRadius; - m_PieSelectedOffset = theme.pieSelectedOffset; - m_CandlestickColor = theme.candlestickColor; - m_CandlestickColor0 = theme.candlestickColor0; - m_CandlestickBorderColor = theme.candlestickBorderColor; - m_CandlestickBorderColor0 = theme.candlestickBorderColor0; - m_CandlestickBorderWidth = theme.candlestickBorderWidth; - } - - public SerieTheme(ThemeType theme) - { - m_LineWidth = XCSettings.serieLineWidth; - m_LineSymbolSize = XCSettings.serieLineSymbolSize; - m_ScatterSymbolSize = XCSettings.serieScatterSymbolSize; - m_PieTooltipExtraRadius = XCSettings.pieTooltipExtraRadius; - m_PieSelectedOffset = XCSettings.pieSelectedOffset; - m_CandlestickBorderWidth = XCSettings.serieCandlestickBorderWidth; - switch (theme) - { - case ThemeType.Default: - m_CandlestickColor = ColorUtil.GetColor("#eb5454"); - m_CandlestickColor0 = ColorUtil.GetColor("#47b262"); - m_CandlestickBorderColor = ColorUtil.GetColor("#eb5454"); - m_CandlestickBorderColor0 = ColorUtil.GetColor("#47b262"); - break; - case ThemeType.Light: - m_CandlestickColor = ColorUtil.GetColor("#eb5454"); - m_CandlestickColor0 = ColorUtil.GetColor("#47b262"); - m_CandlestickBorderColor = ColorUtil.GetColor("#eb5454"); - m_CandlestickBorderColor0 = ColorUtil.GetColor("#47b262"); - break; - case ThemeType.Dark: - m_CandlestickColor = ColorUtil.GetColor("#f64e56"); - m_CandlestickColor0 = ColorUtil.GetColor("#54ea92"); - m_CandlestickBorderColor = ColorUtil.GetColor("#f64e56"); - m_CandlestickBorderColor0 = ColorUtil.GetColor("#54ea92"); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/SerieTheme.cs.meta b/Assets/XCharts/Runtime/Theme/SerieTheme.cs.meta deleted file mode 100644 index 6649238..0000000 --- a/Assets/XCharts/Runtime/Theme/SerieTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9030b0e4afb164967b4991247947b195 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/SubTitleTheme.cs b/Assets/XCharts/Runtime/Theme/SubTitleTheme.cs deleted file mode 100644 index 7e0ae93..0000000 --- a/Assets/XCharts/Runtime/Theme/SubTitleTheme.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [Serializable] - public class SubTitleTheme : ComponentTheme - { - public SubTitleTheme(ThemeType theme) : base(theme) - { - m_FontSize = XCSettings.fontSizeLv2; - switch (theme) - { - case ThemeType.Default: - m_TextColor = ColorUtil.GetColor("#969696"); - break; - case ThemeType.Light: - m_TextColor = ColorUtil.GetColor("#969696"); - break; - case ThemeType.Dark: - m_TextColor = ColorUtil.GetColor("#B9B8CE"); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/SubTitleTheme.cs.meta b/Assets/XCharts/Runtime/Theme/SubTitleTheme.cs.meta deleted file mode 100644 index c296a35..0000000 --- a/Assets/XCharts/Runtime/Theme/SubTitleTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c642293f2d6674cbb85d1f081b9d89e8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/Theme.cs b/Assets/XCharts/Runtime/Theme/Theme.cs deleted file mode 100644 index bd6e4bc..0000000 --- a/Assets/XCharts/Runtime/Theme/Theme.cs +++ /dev/null @@ -1,407 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - /// <summary> - /// Theme. - /// |主题相关配置。 - /// </summary> - [Serializable] - public class Theme : ScriptableObject - { - [SerializeField] private ThemeType m_ThemeType = ThemeType.Default; - [SerializeField] private string m_ThemeName = ThemeType.Default.ToString(); - [SerializeField] private Font m_Font; -#if dUI_TextMeshPro - [SerializeField] private TMP_FontAsset m_TMPFont; -#endif - - [SerializeField] private Color32 m_ContrastColor; - [SerializeField] private Color32 m_BackgroundColor; - -#if UNITY_2020_2 - [NonReorderable] -#endif - [SerializeField] private List<Color32> m_ColorPalette = new List<Color32>(13); - - [SerializeField] private ComponentTheme m_Common; - [SerializeField] private TitleTheme m_Title; - [SerializeField] private SubTitleTheme m_SubTitle; - [SerializeField] private LegendTheme m_Legend; - [SerializeField] private AxisTheme m_Axis; - [SerializeField] private TooltipTheme m_Tooltip; - [SerializeField] private DataZoomTheme m_DataZoom; - [SerializeField] private VisualMapTheme m_VisualMap; - [SerializeField] private SerieTheme m_Serie; - - /// <summary> - /// the theme of chart. - /// |主题类型。 - /// </summary> - public ThemeType themeType - { - get { return m_ThemeType; } - set { PropertyUtil.SetStruct(ref m_ThemeType, value); } - } - /// <summary> - /// the name of theme. - /// |主题名称。 - /// </summary> - public string themeName - { - get { return m_ThemeName; } - set { PropertyUtil.SetClass(ref m_ThemeName, value); } - } - - /// <summary> - /// the contrast color of chart. - /// |对比色。 - /// </summary> - public Color32 contrastColor - { - get { return m_ContrastColor; } - set { PropertyUtil.SetColor(ref m_ContrastColor, value); } - } - /// <summary> - /// the background color of chart. - /// |背景颜色。 - /// </summary> - public Color32 backgroundColor - { - get { return m_BackgroundColor; } - set { PropertyUtil.SetColor(ref m_BackgroundColor, value); } - } - - /// <summary> - /// The color list of palette. If no color is set in series, the colors would be adopted sequentially and circularly from this list as the colors of series. - /// |调色盘颜色列表。如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色。 - /// </summary> - public List<Color32> colorPalette { get { return m_ColorPalette; } set { m_ColorPalette = value; } } - public ComponentTheme common { get { return m_Common; } set { m_Common = value; } } - public TitleTheme title { get { return m_Title; } set { m_Title = value; } } - public SubTitleTheme subTitle { get { return m_SubTitle; } set { m_SubTitle = value; } } - public LegendTheme legend { get { return m_Legend; } set { m_Legend = value; } } - public AxisTheme axis { get { return m_Axis; } set { m_Axis = value; } } - public TooltipTheme tooltip { get { return m_Tooltip; } set { m_Tooltip = value; } } - public DataZoomTheme dataZoom { get { return m_DataZoom; } set { m_DataZoom = value; } } - public VisualMapTheme visualMap { get { return m_VisualMap; } set { m_VisualMap = value; } } - public SerieTheme serie { get { return m_Serie; } set { m_Serie = value; } } -#if dUI_TextMeshPro - /// <summary> - /// the font of chart text。 - /// |主题字体。 - /// </summary> - public TMP_FontAsset tmpFont - { - get { return m_TMPFont; } - set - { - m_TMPFont = value; - SyncTMPFontToSubComponent(); - } - } -#endif - /// <summary> - /// the font of chart text。 - /// |主题字体。 - /// </summary> - public Font font - { - get { return m_Font; } - set - { - m_Font = value; - SyncFontToSubComponent(); - } - } - - // void OnEnable() - // { - // } - - // void OnDisable() - // { - // } - - public void SetDefaultFont() - { -#if dUI_TextMeshPro - tmpFont = XCSettings.tmpFont; - SyncTMPFontToSubComponent(); -#else - font = XCSettings.font; - SyncFontToSubComponent(); -#endif - } - - /// <summary> - /// Gets the color of the specified index from the palette. - /// |获得调色盘对应系列索引的颜色值。 - /// </summary> - /// <param name="index">编号索引</param> - /// <returns>the color,or Color.clear when failed.颜色值,失败时返回Color.clear</returns> - public Color32 GetColor(int index) - { - if (index < 0) index = 0; - var newIndex = index < m_ColorPalette.Count ? index : index % m_ColorPalette.Count; - if (newIndex < m_ColorPalette.Count) - return m_ColorPalette[newIndex]; - else return Color.clear; - } - - public void CheckWarning(StringBuilder sb) - { -#if dUI_TextMeshPro - if (m_TMPFont == null) - { - sb.AppendFormat("warning:theme->tmpFont is null\n"); - } -#else - if (m_Font == null) - { - sb.AppendFormat("warning:theme->font is null\n"); - } -#endif - if (m_ColorPalette.Count == 0) - { - sb.AppendFormat("warning:theme->colorPalette is empty\n"); - } - for (int i = 0; i < m_ColorPalette.Count; i++) - { - if (!ChartHelper.IsClearColor(m_ColorPalette[i]) && m_ColorPalette[i].a == 0) - sb.AppendFormat("warning:theme->colorPalette[{0}] alpha = 0\n", i); - } - } - - Dictionary<int, string> _colorDic = new Dictionary<int, string>(); - /// <summary> - /// Gets the hexadecimal color string of the specified index from the palette. - /// |获得指定索引的十六进制颜色值字符串。 - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public string GetColorStr(int index) - { - if (index < 0) - { - index = 0; - } - index = index % m_ColorPalette.Count; - if (_colorDic.ContainsKey(index)) return _colorDic[index]; - else - { - _colorDic[index] = ColorUtility.ToHtmlStringRGBA(GetColor(index)); - return _colorDic[index]; - } - } - - public bool CopyTheme(ThemeType theme) - { - switch (theme) - { - case ThemeType.Dark: - ResetToDarkTheme(this); - return true; - case ThemeType.Default: - ResetToDefaultTheme(this); - return true; - } - return false; - } - - /// <summary> - /// copy all configurations from theme. - /// |复制主题的所有配置。 - /// </summary> - /// <param name="theme"></param> - public void CopyTheme(Theme theme) - { - m_ThemeType = theme.themeType; - m_ThemeName = theme.themeName; -#if dUI_TextMeshPro - tmpFont = theme.tmpFont; -#endif - font = theme.font; - m_BackgroundColor = theme.backgroundColor; - m_Common.Copy(theme.common); - m_Legend.Copy(theme.legend); - m_Title.Copy(theme.title); - m_SubTitle.Copy(theme.subTitle); - m_Axis.Copy(theme.axis); - m_Tooltip.Copy(theme.tooltip); - m_DataZoom.Copy(theme.dataZoom); - m_VisualMap.Copy(theme.visualMap); - m_Serie.Copy(theme.serie); - ChartHelper.CopyList(m_ColorPalette, theme.colorPalette); - } - - /// <summary> - /// Clear all custom configurations. - /// |重置,清除所有自定义配置。 - /// </summary> - public bool ResetTheme() - { - switch (m_ThemeType) - { - case ThemeType.Default: - ResetToDefaultTheme(this); - return true; - case ThemeType.Dark: - ResetToDarkTheme(this); - return true; - case ThemeType.Custom: - return false; - } - return false; - } - - /// <summary> - /// 克隆主题。 - /// </summary> - /// <returns></returns> - public Theme CloneTheme() - { - var theme = ScriptableObject.CreateInstance<Theme>(); - InitChartComponentTheme(theme); - theme.CopyTheme(this); - return theme; - } - - /// <summary> - /// default theme. - /// |默认主题。 - /// </summary> - /// <value></value> - public static void ResetToDefaultTheme(Theme theme) - { - theme.themeType = ThemeType.Default; - theme.themeName = ThemeType.Default.ToString(); - theme.backgroundColor = new Color32(255, 255, 255, 255); - theme.colorPalette = new List<Color32> - { - ColorUtil.GetColor("#5470c6"), - ColorUtil.GetColor("#91cc75"), - ColorUtil.GetColor("#fac858"), - ColorUtil.GetColor("#ee6666"), - ColorUtil.GetColor("#73c0de"), - ColorUtil.GetColor("#3ba272"), - ColorUtil.GetColor("#fc8452"), - ColorUtil.GetColor("#9a60b4"), - ColorUtil.GetColor("#ea7ccc"), - - }; - InitChartComponentTheme(theme); - } - - /// <summary> - /// dark theme. - /// |暗主题。 - /// </summary> - /// <value></value> - public static void ResetToDarkTheme(Theme theme) - { - theme.themeType = ThemeType.Dark; - theme.themeName = ThemeType.Dark.ToString(); - theme.backgroundColor = ColorUtil.GetColor("#100C2A"); - theme.colorPalette = new List<Color32> - { - ColorUtil.GetColor("#4992ff"), - ColorUtil.GetColor("#7cffb2"), - ColorUtil.GetColor("#fddd60"), - ColorUtil.GetColor("#ff6e76"), - ColorUtil.GetColor("#58d9f9"), - ColorUtil.GetColor("#05c091"), - ColorUtil.GetColor("#ff8a45"), - ColorUtil.GetColor("#8d48e3"), - ColorUtil.GetColor("#dd79ff"), - }; - InitChartComponentTheme(theme); - } - - public static Theme EmptyTheme - { - get - { - var theme = ScriptableObject.CreateInstance<Theme>(); - theme.themeType = ThemeType.Custom; - theme.themeName = ThemeType.Custom.ToString(); - theme.backgroundColor = Color.clear; - theme.colorPalette = new List<Color32>(); - InitChartComponentTheme(theme); - return theme; - } - } - - public void SyncFontToSubComponent() - { - common.font = font; - title.font = font; - subTitle.font = font; - legend.font = font; - axis.font = font; - tooltip.font = font; - dataZoom.font = font; - visualMap.font = font; - } - -#if dUI_TextMeshPro - public void SyncTMPFontToSubComponent() - { - common.tmpFont = tmpFont; - title.tmpFont = tmpFont; - subTitle.tmpFont = tmpFont; - legend.tmpFont = tmpFont; - axis.tmpFont = tmpFont; - tooltip.tmpFont = tmpFont; - dataZoom.tmpFont = tmpFont; - visualMap.tmpFont = tmpFont; - } -#endif - - private static void InitChartComponentTheme(Theme theme) - { - theme.common = new ComponentTheme(theme.themeType); - theme.title = new TitleTheme(theme.themeType); - theme.subTitle = new SubTitleTheme(theme.themeType); - theme.legend = new LegendTheme(theme.themeType); - theme.axis = new AxisTheme(theme.themeType); - theme.tooltip = new TooltipTheme(theme.themeType); - theme.dataZoom = new DataZoomTheme(theme.themeType); - theme.visualMap = new VisualMapTheme(theme.themeType); - theme.serie = new SerieTheme(theme.themeType); - theme.SetDefaultFont(); - } - - /// <summary> - /// Convert the html string to color. - /// |将字符串颜色值转成Color。 - /// </summary> - /// <param name="hexColorStr"></param> - /// <returns></returns> - public static Color32 GetColor(string hexColorStr) - { - Color color; - ColorUtility.TryParseHtmlString(hexColorStr, out color); - return (Color32) color; - } - - public void SetColorPalette(List<string> hexColorStringList) - { - m_ColorPalette.Clear(); - foreach (var hexColor in hexColorStringList) - m_ColorPalette.Add(ColorUtil.GetColor(hexColor)); - - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/Theme.cs.meta b/Assets/XCharts/Runtime/Theme/Theme.cs.meta deleted file mode 100644 index 15f4828..0000000 --- a/Assets/XCharts/Runtime/Theme/Theme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6c59330ca0f4443b69f06b890a44f32e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/ThemeStyle.cs b/Assets/XCharts/Runtime/Theme/ThemeStyle.cs deleted file mode 100644 index aaa616e..0000000 --- a/Assets/XCharts/Runtime/Theme/ThemeStyle.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using UnityEngine; -#if dUI_TextMeshPro -using TMPro; -#endif - -namespace XCharts.Runtime -{ - /// <summary> - /// 主题 - /// </summary> - public enum ThemeType - { - /// <summary> - /// 默认主题。 - /// </summary> - Default, - /// <summary> - /// 亮主题。 - /// </summary> - Light, - /// <summary> - /// 暗主题。 - /// </summary> - Dark, - /// <summary> - /// 自定义主题。 - /// </summary> - Custom, - } - - [Serializable] - /// <summary> - /// Theme. - /// |主题相关配置。 - /// </summary> - public class ThemeStyle : ChildComponent - { - [SerializeField] private bool m_Show = true; - [SerializeField] private Theme m_SharedTheme; - [SerializeField] private bool m_TransparentBackground = false; - [SerializeField] private bool m_EnableCustomTheme = false; - [SerializeField] private Font m_CustomFont; - [SerializeField] private Color32 m_CustomBackgroundColor; -#if UNITY_2020_2 - [NonReorderable] -#endif - [SerializeField] private List<Color32> m_CustomColorPalette = new List<Color32>(13); - - public bool show { get { return m_Show; } } - /// <summary> - /// the theme of chart. - /// |主题类型。 - /// </summary> - public ThemeType themeType - { - get { return sharedTheme.themeType; } - } - public string themeName - { - get { return sharedTheme.themeName; } - } - - public Theme sharedTheme - { - get { return m_SharedTheme; } - set { m_SharedTheme = value; SetAllDirty(); } - } - - /// <summary> - /// the contrast color of chart. - /// |对比色。 - /// </summary> - public Color32 contrastColor - { - get { return sharedTheme.contrastColor; } - } - /// <summary> - /// the background color of chart. - /// |背景颜色。 - /// </summary> - public Color32 backgroundColor - { - get - { - if (m_TransparentBackground) return ColorUtil.clearColor32; - else return m_EnableCustomTheme ? m_CustomBackgroundColor : sharedTheme.backgroundColor; - } - } - /// <summary> - /// Whether the background color is transparent. When true, the background color is not drawn. - /// |是否透明背景颜色。当设置为true时,不绘制背景颜色。 - /// </summary> - public bool transparentBackground - { - get { return m_TransparentBackground; } - set { m_TransparentBackground = value; SetAllDirty(); } - } - /// <summary> - /// Whether to customize theme colors. When set to true, - /// you can use 'sync color to custom' to synchronize the theme color to the custom color. It can also be set manually. - /// |是否自定义主题颜色。当设置为true时,可以用‘sync color to custom’同步主题的颜色到自定义颜色。也可以手动设置。 - /// </summary> - /// <value></value> - public bool enableCustomTheme - { - get { return m_EnableCustomTheme; } - set { m_EnableCustomTheme = value; _colorDic.Clear(); SetAllDirty(); } - } - /// <summary> - /// the custom background color of chart. - /// |自定义的背景颜色。 - /// </summary> - public Color32 customBackgroundColor - { - get { return m_CustomBackgroundColor; } - set { m_CustomBackgroundColor = value; SetAllDirty(); } - } - - /// <summary> - /// The color list of palette. If no color is set in series, the colors would be adopted sequentially and circularly from this list as the colors of series. - /// |调色盘颜色列表。如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色。 - /// </summary> - public List<Color32> colorPalette - { - get { return m_EnableCustomTheme ? m_CustomColorPalette : sharedTheme.colorPalette; } - } - public List<Color32> customColorPalette { get { return m_CustomColorPalette; } set { m_CustomColorPalette = value; SetVerticesDirty(); } } - public ComponentTheme common { get { return sharedTheme.common; } } - public TitleTheme title { get { return sharedTheme.title; } } - public SubTitleTheme subTitle { get { return sharedTheme.subTitle; } } - public LegendTheme legend { get { return sharedTheme.legend; } } - public AxisTheme axis { get { return sharedTheme.axis; } } - public TooltipTheme tooltip { get { return sharedTheme.tooltip; } } - public DataZoomTheme dataZoom { get { return sharedTheme.dataZoom; } } - public VisualMapTheme visualMap { get { return sharedTheme.visualMap; } } - public SerieTheme serie { get { return sharedTheme.serie; } } - - /// <summary> - /// Gets the color of the specified index from the palette. - /// |获得调色盘对应系列索引的颜色值。 - /// </summary> - /// <param name="index">编号索引</param> - /// <returns>the color,or Color.clear when failed.颜色值,失败时返回Color.clear</returns> - public Color32 GetColor(int index) - { - if (colorPalette.Count <= 0) return Color.clear; - if (index < 0) index = 0; - var newIndex = index < colorPalette.Count ? index : index % colorPalette.Count; - if (newIndex < colorPalette.Count) - return colorPalette[newIndex]; - else return Color.clear; - } - - public Color32 GetBackgroundColor(Background background) - { - if (background != null && background.show && !background.autoColor) - return background.imageColor; - else - return backgroundColor; - } - - public void SyncSharedThemeColorToCustom() - { - m_CustomBackgroundColor = sharedTheme.backgroundColor; - m_CustomColorPalette.Clear(); - foreach (var color in sharedTheme.colorPalette) - { - m_CustomColorPalette.Add(color); - } - SetAllDirty(); - } - - public void CheckWarning(StringBuilder sb) - { -#if dUI_TextMeshPro - if (sharedTheme.tmpFont == null) - { - sb.AppendFormat("warning:theme->tmpFont is null\n"); - } -#else - if (sharedTheme.font == null) - { - sb.AppendFormat("warning:theme->font is null\n"); - } -#endif - if (sharedTheme.colorPalette.Count == 0) - { - sb.AppendFormat("warning:theme->colorPalette is empty\n"); - } - for (int i = 0; i < sharedTheme.colorPalette.Count; i++) - { - if (!ChartHelper.IsClearColor(sharedTheme.colorPalette[i]) && sharedTheme.colorPalette[i].a == 0) - sb.AppendFormat("warning:theme->colorPalette[{0}] alpha = 0\n", i); - } - } - - Dictionary<int, string> _colorDic = new Dictionary<int, string>(); - /// <summary> - /// Gets the hexadecimal color string of the specified index from the palette. - /// |获得指定索引的十六进制颜色值字符串。 - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public string GetColorStr(int index) - { - if (index < 0) - { - index = 0; - } - index = index % colorPalette.Count; - if (_colorDic.ContainsKey(index)) return _colorDic[index]; - else - { - _colorDic[index] = ColorUtility.ToHtmlStringRGBA(GetColor(index)); - return _colorDic[index]; - } - } - - /// <summary> - /// Convert the html string to color. - /// |将字符串颜色值转成Color。 - /// </summary> - /// <param name="hexColorStr"></param> - /// <returns></returns> - public static Color32 GetColor(string hexColorStr) - { - Color color; - ColorUtility.TryParseHtmlString(hexColorStr, out color); - return (Color32) color; - } - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/ThemeStyle.cs.meta b/Assets/XCharts/Runtime/Theme/ThemeStyle.cs.meta deleted file mode 100644 index ba89424..0000000 --- a/Assets/XCharts/Runtime/Theme/ThemeStyle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd363d1f78f9d47dab079b1376cf0680 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/TitleTheme.cs b/Assets/XCharts/Runtime/Theme/TitleTheme.cs deleted file mode 100644 index e675cf5..0000000 --- a/Assets/XCharts/Runtime/Theme/TitleTheme.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace XCharts.Runtime -{ - [Serializable] - public class TitleTheme : ComponentTheme - { - public TitleTheme(ThemeType theme) : base(theme) - { - m_FontSize = XCSettings.fontSizeLv1; - switch (theme) - { - case ThemeType.Default: - m_TextColor = ColorUtil.GetColor("#514D4D"); - break; - case ThemeType.Light: - break; - case ThemeType.Dark: - m_TextColor = ColorUtil.GetColor("#EEF1FA"); - break; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/TitleTheme.cs.meta b/Assets/XCharts/Runtime/Theme/TitleTheme.cs.meta deleted file mode 100644 index a409e26..0000000 --- a/Assets/XCharts/Runtime/Theme/TitleTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 6649bc33964624c14a13ce34dd7eae77 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/TooltipTheme.cs b/Assets/XCharts/Runtime/Theme/TooltipTheme.cs deleted file mode 100644 index a0d0dab..0000000 --- a/Assets/XCharts/Runtime/Theme/TooltipTheme.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - public class TooltipTheme : ComponentTheme - { - - [SerializeField] protected LineStyle.Type m_LineType = LineStyle.Type.Solid; - [SerializeField] protected float m_LineWidth = 1f; - [SerializeField] protected Color32 m_LineColor; - [SerializeField] protected Color32 m_AreaColor; - [SerializeField] protected Color32 m_LabelTextColor; - [SerializeField] protected Color32 m_LabelBackgroundColor; - - /// <summary> - /// the type of line. - /// |坐标轴线类型。 - /// </summary> - public LineStyle.Type lineType - { - get { return m_LineType; } - set { if (PropertyUtil.SetStruct(ref m_LineType, value)) SetVerticesDirty(); } - } - /// <summary> - /// the width of line. - /// |指示线线宽。 - /// </summary> - public float lineWidth - { - get { return m_LineWidth; } - set { if (PropertyUtil.SetStruct(ref m_LineWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of line. - /// |指示线颜色。 - /// </summary> - public Color32 lineColor - { - get { return m_LineColor; } - set { if (PropertyUtil.SetColor(ref m_LineColor, value)) SetVerticesDirty(); } - } - - /// <summary> - /// the color of line. - /// |区域指示的颜色。 - /// </summary> - public Color32 areaColor - { - get { return m_AreaColor; } - set { if (PropertyUtil.SetColor(ref m_AreaColor, value)) SetVerticesDirty(); } - } - /// <summary> - /// the text color of tooltip cross indicator's axis label. - /// |十字指示器坐标轴标签的文本颜色。 - /// </summary> - public Color32 labelTextColor - { - get { return m_LabelTextColor; } - set { if (PropertyUtil.SetColor(ref m_LabelTextColor, value)) SetComponentDirty(); } - } - - /// <summary> - /// the background color of tooltip cross indicator's axis label. - /// |十字指示器坐标轴标签的背景颜色。 - /// </summary> - public Color32 labelBackgroundColor - { - get { return m_LabelBackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_LabelBackgroundColor, value)) SetComponentDirty(); } - } - - public TooltipTheme(ThemeType theme) : base(theme) - { - m_LineType = LineStyle.Type.Solid; - m_LineWidth = XCSettings.tootipLineWidth; - switch (theme) - { - case ThemeType.Default: - m_TextBackgroundColor = ColorUtil.GetColor("#FFFFFFFF"); - m_TextColor = ColorUtil.GetColor("#000000FF"); - m_AreaColor = ColorUtil.GetColor("#51515120"); - m_LabelTextColor = ColorUtil.GetColor("#FFFFFFFF"); - m_LabelBackgroundColor = ColorUtil.GetColor("#292929FF"); - m_LineColor = ColorUtil.GetColor("#29292964"); - break; - case ThemeType.Light: - m_TextBackgroundColor = ColorUtil.GetColor("#FFFFFFFF"); - m_TextColor = ColorUtil.GetColor("#000000FF"); - m_AreaColor = ColorUtil.GetColor("#51515120"); - m_LabelTextColor = ColorUtil.GetColor("#FFFFFFFF"); - m_LabelBackgroundColor = ColorUtil.GetColor("#292929FF"); - m_LineColor = ColorUtil.GetColor("#29292964"); - break; - case ThemeType.Dark: - m_TextBackgroundColor = ColorUtil.GetColor("#FFFFFFFF"); - m_TextColor = ColorUtil.GetColor("#000000FF"); - m_AreaColor = ColorUtil.GetColor("#51515120"); - m_LabelTextColor = ColorUtil.GetColor("#FFFFFFFF"); - m_LabelBackgroundColor = ColorUtil.GetColor("#292929FF"); - m_LineColor = ColorUtil.GetColor("#29292964"); - break; - } - } - - public void Copy(TooltipTheme theme) - { - base.Copy(theme); - m_LineType = theme.lineType; - m_LineWidth = theme.lineWidth; - m_LineColor = theme.lineColor; - m_AreaColor = theme.areaColor; - m_LabelTextColor = theme.labelTextColor; - m_LabelBackgroundColor = theme.labelBackgroundColor; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/TooltipTheme.cs.meta b/Assets/XCharts/Runtime/Theme/TooltipTheme.cs.meta deleted file mode 100644 index 534835c..0000000 --- a/Assets/XCharts/Runtime/Theme/TooltipTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f38f041e827e042a88338628b2b2c0db -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Theme/VisualMapTheme.cs b/Assets/XCharts/Runtime/Theme/VisualMapTheme.cs deleted file mode 100644 index 3810838..0000000 --- a/Assets/XCharts/Runtime/Theme/VisualMapTheme.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using UnityEngine; - -namespace XCharts.Runtime -{ - [Serializable] - public class VisualMapTheme : ComponentTheme - { - [SerializeField] protected float m_BorderWidth; - [SerializeField] protected Color32 m_BorderColor; - [SerializeField] protected Color32 m_BackgroundColor; - [SerializeField][Range(10, 50)] protected float m_TriangeLen = 20f; - - /// <summary> - /// the width of border. - /// |边框线宽。 - /// </summary> - public float borderWidth - { - get { return m_BorderWidth; } - set { if (PropertyUtil.SetStruct(ref m_BorderWidth, value)) SetVerticesDirty(); } - } - /// <summary> - /// the color of dataZoom border. - /// |边框颜色。 - /// </summary> - public Color32 borderColor - { - get { return m_BorderColor; } - set { if (PropertyUtil.SetColor(ref m_BorderColor, value)) SetComponentDirty(); } - } - - /// <summary> - /// the background color of visualmap. - /// |背景颜色。 - /// </summary> - public Color32 backgroundColor - { - get { return m_BackgroundColor; } - set { if (PropertyUtil.SetColor(ref m_BackgroundColor, value)) SetComponentDirty(); } - } - /// <summary> - /// 可视化组件的调节三角形边长。 - /// </summary> - /// <value></value> - public float triangeLen - { - get { return m_TriangeLen; } - set { if (PropertyUtil.SetStruct(ref m_TriangeLen, value < 0 ? 1f : value)) SetVerticesDirty(); } - } - - public VisualMapTheme(ThemeType theme) : base(theme) - { - m_BorderWidth = XCSettings.visualMapBorderWidth; - m_TriangeLen = XCSettings.visualMapTriangeLen; - m_FontSize = XCSettings.fontSizeLv4; - switch (theme) - { - case ThemeType.Default: - m_TextColor = ColorUtil.GetColor("#333"); - m_BorderColor = ColorUtil.GetColor("#ccc"); - m_BackgroundColor = ColorUtil.clearColor32; - break; - case ThemeType.Light: - m_TextColor = ColorUtil.GetColor("#333"); - m_BorderColor = ColorUtil.GetColor("#ccc"); - m_BackgroundColor = ColorUtil.clearColor32; - break; - case ThemeType.Dark: - m_TextColor = ColorUtil.GetColor("#B9B8CE"); - m_BorderColor = ColorUtil.GetColor("#ccc"); - m_BackgroundColor = ColorUtil.clearColor32; - break; - } - } - - public void Copy(VisualMapTheme theme) - { - base.Copy(theme); - m_TriangeLen = theme.triangeLen; - m_BorderWidth = theme.borderWidth; - m_BorderColor = theme.borderColor; - m_BackgroundColor = theme.backgroundColor; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Theme/VisualMapTheme.cs.meta b/Assets/XCharts/Runtime/Theme/VisualMapTheme.cs.meta deleted file mode 100644 index e737722..0000000 --- a/Assets/XCharts/Runtime/Theme/VisualMapTheme.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 35e5797039b994b23850aaa7ca827766 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities.meta b/Assets/XCharts/Runtime/Utilities.meta deleted file mode 100644 index 8665a90..0000000 --- a/Assets/XCharts/Runtime/Utilities.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c3e4cdd9c66b14907bd1934dd8037eee -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities/ColorUtil.cs b/Assets/XCharts/Runtime/Utilities/ColorUtil.cs deleted file mode 100644 index ab650e4..0000000 --- a/Assets/XCharts/Runtime/Utilities/ColorUtil.cs +++ /dev/null @@ -1,22 +0,0 @@ -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class ColorUtil - { - public static readonly Color32 clearColor32 = new Color32(0, 0, 0, 0); - public static readonly Vector2 zeroVector2 = Vector2.zero; - /// <summary> - /// Convert the html string to color. - /// |将字符串颜色值转成Color。 - /// </summary> - /// <param name="hexColorStr"></param> - /// <returns></returns> - public static Color32 GetColor(string hexColorStr) - { - Color color; - ColorUtility.TryParseHtmlString(hexColorStr, out color); - return (Color32) color; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Utilities/ColorUtil.cs.meta b/Assets/XCharts/Runtime/Utilities/ColorUtil.cs.meta deleted file mode 100644 index a53ccbb..0000000 --- a/Assets/XCharts/Runtime/Utilities/ColorUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4260c3b8fdaff435a8bc10375b812bd8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs b/Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs deleted file mode 100644 index 361218f..0000000 --- a/Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace XCharts.Runtime -{ - public static class DateTimeUtil - { - //private static readonly DateTime k_DateTime1970 = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Local); - private static readonly DateTime k_DateTime1970 = new DateTime(1970, 1, 1); - public static readonly int ONE_SECOND = 1; - public static readonly int ONE_MINUTE = ONE_SECOND * 60; - public static readonly int ONE_HOUR = ONE_MINUTE * 60; - public static readonly int ONE_DAY = ONE_HOUR * 24; - public static readonly int ONE_MONTH = ONE_DAY * 30; - public static readonly int ONE_YEAR = ONE_DAY * 365; - public static readonly int MIN_TIME_SPLIT_NUMBER = 4; - - private static string s_YearDateFormatter = "yyyy"; - //private static string s_MonthDateFormatter = "MM"; - //private static string s_DayDateFormatter = "dd"; - private static string s_HourDateFormatter = "HH:mm"; - private static string s_MinuteDateFormatter = "HH:mm"; - private static string s_SecondDateFormatter = "HH:mm:ss"; - //private static string s_DateFormatter = "yyyy-MM-dd HH:mm:ss"; - - public static int GetTimestamp() - { - return (int) (DateTime.Now - k_DateTime1970).TotalSeconds; - } - - public static int GetTimestamp(DateTime time) - { - return (int) (time - k_DateTime1970).TotalSeconds; - } - - public static DateTime GetDateTime(int timestamp) - { - long span = ((long) timestamp) * 10000000; - return k_DateTime1970.Add(new TimeSpan(span)); - } - - internal static string GetDateTimeFormatString(DateTime dateTime, double range) - { - var dateString = String.Empty; - if (range >= DateTimeUtil.ONE_YEAR * DateTimeUtil.MIN_TIME_SPLIT_NUMBER) - { - dateString = dateTime.ToString(s_YearDateFormatter); - } - else if (range >= DateTimeUtil.ONE_MONTH * DateTimeUtil.MIN_TIME_SPLIT_NUMBER) - { - dateString = dateTime.Month == 1 ? - dateTime.ToString(s_YearDateFormatter) : - XCSettings.lang.GetMonthAbbr(dateTime.Month); - } - else if (range >= DateTimeUtil.ONE_DAY * DateTimeUtil.MIN_TIME_SPLIT_NUMBER) - { - dateString = dateTime.Day == 1 ? - XCSettings.lang.GetMonthAbbr(dateTime.Month) : - XCSettings.lang.GetDay(dateTime.Day); - } - else if (range >= DateTimeUtil.ONE_HOUR * DateTimeUtil.MIN_TIME_SPLIT_NUMBER) - { - dateString = dateTime.ToString(s_HourDateFormatter); - } - else if (range >= DateTimeUtil.ONE_MINUTE * DateTimeUtil.MIN_TIME_SPLIT_NUMBER) - { - dateString = dateTime.ToString(s_MinuteDateFormatter); - } - else - { - dateString = dateTime.ToString(s_SecondDateFormatter); - } - return dateString; - } - - /// <summary> - /// 根据给定的最大最小时间戳范围,计算合适的Tick值 - /// </summary> - /// <param name="list"></param> - /// <param name="minTimestamp"></param> - /// <param name="maxTimestamp"></param> - /// <param name="splitNumber"></param> - internal static void UpdateTimeAxisDateTimeList(List<double> list, int minTimestamp, int maxTimestamp, int splitNumber) - { - list.Clear(); - var range = maxTimestamp - minTimestamp; - if (range <= 0) return; - if (splitNumber <= 0) splitNumber = 1; - var dtMin = DateTimeUtil.GetDateTime(minTimestamp); - var dtMax = DateTimeUtil.GetDateTime(maxTimestamp); - if (range >= ONE_YEAR * MIN_TIME_SPLIT_NUMBER) - { - var num = Math.Max(range / (splitNumber * ONE_YEAR), 1); - var dtStart = new DateTime(dtMin.Year + 1, 1, 1); - while (dtStart.Ticks < dtMax.Ticks) - { - list.Add(DateTimeUtil.GetTimestamp(dtStart)); - dtStart = dtStart.AddYears(num); - } - } - else if (range >= ONE_MONTH * MIN_TIME_SPLIT_NUMBER) - { - var num = Math.Max(range / (splitNumber * ONE_MONTH), 1); - var dtStart = new DateTime(dtMin.Year, dtMin.Month, 1).AddMonths(1); - while (dtStart.Ticks < dtMax.Ticks) - { - list.Add(DateTimeUtil.GetTimestamp(dtStart)); - dtStart = dtStart.AddMonths(num); - } - } - else if (range >= ONE_DAY * MIN_TIME_SPLIT_NUMBER) - { - var tick = GetTickSecond(range, splitNumber, ONE_DAY); - var startTimestamp = (minTimestamp - minTimestamp % tick) + tick; - AddTickTimestamp(list, startTimestamp, maxTimestamp, tick); - } - else if (range >= ONE_HOUR * MIN_TIME_SPLIT_NUMBER) - { - var tick = GetTickSecond(range, splitNumber, ONE_HOUR); - var startTimestamp = (minTimestamp - minTimestamp % tick) + tick; - AddTickTimestamp(list, startTimestamp, maxTimestamp, tick); - } - else if (range >= ONE_MINUTE * MIN_TIME_SPLIT_NUMBER) - { - var tick = GetTickSecond(range, splitNumber, ONE_MINUTE); - var startTimestamp = (minTimestamp - minTimestamp % tick) + tick; - AddTickTimestamp(list, startTimestamp, maxTimestamp, tick); - } - else - { - var tick = GetTickSecond(range, splitNumber, ONE_SECOND); - var startTimestamp = (minTimestamp - minTimestamp % tick) + tick; - AddTickTimestamp(list, startTimestamp, maxTimestamp, tick); - } - } - - private static int GetTickSecond(int range, int splitNumber, int tickSecond) - { - var num = 0; - if (splitNumber > 0) - { - num = Math.Max(range / (splitNumber * tickSecond), 1); - } - else - { - num = 1; - var tick = tickSecond; - while (range / tick > 8) - { - num++; - tick = num * tickSecond; - } - } - return num * tickSecond; - } - - private static void AddTickTimestamp(List<double> list, int startTimestamp, int maxTimestamp, int tickSecond) - { - while (startTimestamp < maxTimestamp) - { - list.Add(startTimestamp); - startTimestamp += tickSecond; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs.meta b/Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs.meta deleted file mode 100644 index ac2244b..0000000 --- a/Assets/XCharts/Runtime/Utilities/DateTimeUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0f0ac80f189a04b5c826f40c8bc8af64 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs b/Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs deleted file mode 100644 index 12a24c8..0000000 --- a/Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs +++ /dev/null @@ -1,89 +0,0 @@ -#if UNITY_EDITOR - -using System; -using System.Reflection; -using System.Text; -using UnityEditor; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class DefineSymbolsUtil - { - private static readonly StringBuilder s_StringBuilder = new StringBuilder(); - - public static void AddGlobalDefine(string symbol) - { - var flag = false; - var num = 0; - foreach (var buildTargetGroup in (BuildTargetGroup[]) Enum.GetValues(typeof(BuildTargetGroup))) - { - if (IsValidBuildTargetGroup(buildTargetGroup)) - { - var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); - symbols = symbols.Replace(" ", ""); - if (Array.IndexOf(symbols.Split(';'), symbol) != -1) continue; - flag = true; - num++; - var defines = symbols + (symbols.Length > 0 ? ";" + symbol : symbol); - PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines); - } - } - if (flag) - { - Debug.LogFormat("Added global define symbol \"{0}\" to {1} BuildTargetGroups.", symbol, num); - } - } - - public static void RemoveGlobalDefine(string symbol) - { - var flag = false; - var num = 0; - foreach (var buildTargetGroup in (BuildTargetGroup[]) Enum.GetValues(typeof(BuildTargetGroup))) - { - if (IsValidBuildTargetGroup(buildTargetGroup)) - { - var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';'); - if (Array.IndexOf(symbols, symbol) == -1) continue; - flag = true; - num++; - s_StringBuilder.Length = 0; - foreach (var str in symbols) - { - if (!str.Equals(symbol)) - { - if (s_StringBuilder.Length > 0) s_StringBuilder.Append(";"); - s_StringBuilder.Append(str); - } - } - PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, s_StringBuilder.ToString()); - } - } - if (flag) - { - Debug.LogFormat("Removed global define symbol \"{0}\" to {1} BuildTargetGroups.", symbol, num); - } - } - - private static bool IsValidBuildTargetGroup(BuildTargetGroup group) - { - if (group == BuildTargetGroup.Unknown) return false; - var type = Type.GetType("UnityEditor.Modules.ModuleManager, UnityEditor.dll"); - if (type == null) return true; - var method1 = type.GetMethod("GetTargetStringFromBuildTargetGroup", BindingFlags.Static | BindingFlags.NonPublic); - var method2 = typeof(PlayerSettings).GetMethod("GetPlatformName", BindingFlags.Static | BindingFlags.NonPublic); - if (method1 == null || method2 == null) return true; - var str1 = (string) method1.Invoke(null, new object[] { group }); - var str2 = (string) method2.Invoke(null, new object[] { group }); - if (string.IsNullOrEmpty(str1)) - { - return !string.IsNullOrEmpty(str2); - } - else - { - return true; - } - } - } -} -#endif \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs.meta b/Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs.meta deleted file mode 100644 index eae3d81..0000000 --- a/Assets/XCharts/Runtime/Utilities/DefineSymbolsUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 91545951242fa441eb1a9bba3a6ad5a7 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities/PropertyUtil.cs b/Assets/XCharts/Runtime/Utilities/PropertyUtil.cs deleted file mode 100644 index 313ac3d..0000000 --- a/Assets/XCharts/Runtime/Utilities/PropertyUtil.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class PropertyUtil - { - public static bool SetColor(ref Color currentValue, Color newValue) - { - if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a) - return false; - - currentValue = newValue; - return true; - } - - public static bool SetColor(ref Color32 currentValue, Color32 newValue) - { - if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a) - return false; - - currentValue = newValue; - return true; - } - - public static bool SetStruct<T>(ref T currentValue, T newValue) where T : struct - { - if (EqualityComparer<T>.Default.Equals(currentValue, newValue)) - return false; - - currentValue = newValue; - return true; - } - - public static bool SetClass<T>(ref T currentValue, T newValue, bool notNull = false) where T : class - { - if (notNull) - { - if (newValue == null) - { - Debug.LogError("can not be null."); - return false; - } - } - if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue))) - return false; - - currentValue = newValue; - return true; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Utilities/PropertyUtil.cs.meta b/Assets/XCharts/Runtime/Utilities/PropertyUtil.cs.meta deleted file mode 100644 index 9292ef0..0000000 --- a/Assets/XCharts/Runtime/Utilities/PropertyUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b1f52eadd805d43aea47947fb81e761f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs b/Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs deleted file mode 100644 index 5af73af..0000000 --- a/Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using UnityEngine; - -namespace XCharts.Runtime -{ - public static class ReflectionUtil - { - private static Dictionary<object, MethodInfo> listClearMethodInfoCaches = new Dictionary<object, MethodInfo>(); - private static Dictionary<object, MethodInfo> listAddMethodInfoCaches = new Dictionary<object, MethodInfo>(); - - public static void InvokeListClear(object obj, FieldInfo field) - { - var list = field.GetValue(obj); - MethodInfo method; - if (!listClearMethodInfoCaches.TryGetValue(list, out method)) - { - method = list.GetType().GetMethod("Clear"); - listClearMethodInfoCaches[list] = method; - } - method.Invoke(list, new object[] { }); - } - public static int InvokeListCount(object obj, FieldInfo field) - { - var list = field.GetValue(obj); - return (int) list.GetType().GetProperty("Count").GetValue(list, null); - } - - public static void InvokeListAdd(object obj, FieldInfo field, object item) - { - var list = field.GetValue(obj); - MethodInfo method; - if (!listAddMethodInfoCaches.TryGetValue(list, out method)) - { - method = list.GetType().GetMethod("Add"); - listAddMethodInfoCaches[list] = method; - } - method.Invoke(list, new object[] { item }); - } - - public static T InvokeListGet<T>(object obj, FieldInfo field, int i) - { - var list = field.GetValue(obj); - var item = list.GetType().GetProperty("Item").GetValue(list, new object[] { i }); - return (T) item; - } - - public static void InvokeListAddTo<T>(object obj, FieldInfo field, Action<T> callback) - { - var list = field.GetValue(obj); - var listType = list.GetType(); - var count = Convert.ToInt32(listType.GetProperty("Count").GetValue(list, null)); - for (int i = 0; i < count; i++) - { - var item = listType.GetProperty("Item").GetValue(list, new object[] { i }); - callback((T) item); - } - } - - public static object DeepCloneSerializeField(object obj) - { - if (obj == null) - return null; - - var type = obj.GetType(); - if (type.IsValueType || type == typeof(string)) - { - return obj; - } - else if (type.IsArray) - { - var elementType = Type.GetType(type.FullName.Replace("[]", string.Empty)); - var array = obj as Array; - var copied = Array.CreateInstance(elementType, array.Length); - for (int i = 0; i < array.Length; i++) - copied.SetValue(DeepCloneSerializeField(array.GetValue(i)), i); - return Convert.ChangeType(copied, obj.GetType()); - } - else if (type.IsClass) - { - object returnObj; - var listObj = obj as IList; - if (listObj != null) - { - var properties = type.GetProperties(); - var customList = typeof(List<>).MakeGenericType((properties[properties.Length - 1]).PropertyType); - returnObj = (IList) Activator.CreateInstance(customList); - var list = (IList) returnObj; - foreach (var item in ((IList) obj)) - { - if (item == null) - continue; - list.Add(DeepCloneSerializeField(item)); - } - } - else - { - try - { - returnObj = Activator.CreateInstance(type); - } - catch - { - return null; - } - var fileds = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - for (int i = 0; i < fileds.Length; i++) - { - var field = fileds[i]; - if (!field.IsDefined(typeof(SerializeField), false)) - continue; - var filedValue = field.GetValue(obj); - if (filedValue == null) - { - field.SetValue(returnObj, filedValue); - } - else - { - field.SetValue(returnObj, DeepCloneSerializeField(filedValue)); - } - } - } - return returnObj; - } - else - { - throw new ArgumentException("DeepCloneSerializeField: Unknown type:" + type + "," + obj); - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs.meta b/Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs.meta deleted file mode 100644 index 77dc154..0000000 --- a/Assets/XCharts/Runtime/Utilities/ReflectionUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 03acc4ee710ff4bad9a1740391c86cb9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs b/Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs deleted file mode 100644 index 8bd0fe0..0000000 --- a/Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using UnityEngine; -using UnityEngine.Assertions; - -namespace XCharts.Runtime -{ - public static class RuntimeUtil - { - public static bool HasSubclass(Type type) - { - var typeMap = GetAllTypesDerivedFrom(type); - foreach (var t in typeMap) - { - return true; - } - return false; - } - - public static IEnumerable<Type> GetAllTypesDerivedFrom<T>() - { -#if UNITY_EDITOR && UNITY_2019_2_OR_NEWER - return UnityEditor.TypeCache.GetTypesDerivedFrom<T>(); -#else - return GetAllAssemblyTypes().Where(t => t.IsSubclassOf(typeof(T))); -#endif - } - public static IEnumerable<Type> GetAllTypesDerivedFrom(Type type) - { -#if UNITY_EDITOR && UNITY_2019_2_OR_NEWER - return UnityEditor.TypeCache.GetTypesDerivedFrom(type); -#else - return GetAllAssemblyTypes().Where(t => t.IsSubclassOf(type)); -#endif - } - - static IEnumerable<Type> m_AssemblyTypes; - - public static IEnumerable<Type> GetAllAssemblyTypes() - { - if (m_AssemblyTypes == null) - { - m_AssemblyTypes = AppDomain.CurrentDomain.GetAssemblies() - .SelectMany(t => - { - var innerTypes = new Type[0]; - try - { - innerTypes = t.GetTypes(); - } - catch { } - return innerTypes; - }); - } - return m_AssemblyTypes; - } - - public static T GetAttribute<T>(this Type type, bool check = true) where T : Attribute - { - if (type.IsDefined(typeof(T), false)) - return (T) type.GetCustomAttributes(typeof(T), false) [0]; - else - { - if (check) - Assert.IsTrue(false, "Attribute not found:" + type.Name); - return null; - } - } - public static T GetAttribute<T>(this MemberInfo type, bool check = true) where T : Attribute - { - if (type.IsDefined(typeof(T), false)) - return (T) type.GetCustomAttributes(typeof(T), false) [0]; - else - { - if (check) - Assert.IsTrue(false, "Attribute not found:" + type.Name); - return null; - } - } - - - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs.meta b/Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs.meta deleted file mode 100644 index 448e24e..0000000 --- a/Assets/XCharts/Runtime/Utilities/RuntimeUtil.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 44becf1664ae64397b44adcf65e6d8d2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Widgets.meta b/Assets/XCharts/Runtime/Widgets.meta deleted file mode 100644 index acbde32..0000000 --- a/Assets/XCharts/Runtime/Widgets.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 5e8b7c21c2d5a45f09bfd4028bbe5f63 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Widgets/ProgressBar.cs b/Assets/XCharts/Runtime/Widgets/ProgressBar.cs deleted file mode 100644 index 8efac8a..0000000 --- a/Assets/XCharts/Runtime/Widgets/ProgressBar.cs +++ /dev/null @@ -1,51 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [ExecuteInEditMode] - [RequireComponent(typeof(RectTransform))] - [DisallowMultipleComponent] - public class ProgressBar : BaseChart - { - [SerializeField][Range(0f, 1f)] private float m_Value = 0.5f; - [SerializeField] private Color m_BackgroundColor = new Color32(255, 233, 233, 255); - [SerializeField] private Color m_StartColor = Color.blue; - [SerializeField] private Color m_EndColor = Color.red; - [SerializeField] private float[] m_CornerRadius = new float[] { 0, 0, 0, 0 }; - - public float value { get { return m_Value; } set { m_Value = value; SetVerticesDirty(); } } - public Color32 backgroundColor { get { return m_BackgroundColor; } set { m_BackgroundColor = value; SetVerticesDirty(); } } - public Color32 startColor { get { return m_StartColor; } set { m_StartColor = value; SetVerticesDirty(); } } - public Color32 endColor { get { return m_EndColor; } set { m_EndColor = value; SetVerticesDirty(); } } - public float[] cornerRadius { get { return m_CornerRadius; } set { m_CornerRadius = value; SetVerticesDirty(); } } - -#if UNITY_EDITOR - protected override void Reset() - { - base.Reset(); - var title = GetOrAddChartComponent<Title>(); - title.text = "ProgressBar"; - title.show = false; - SetSize(580, 4); - RemoveData(); - } -#endif - - protected override void OnDrawPainterBase(VertexHelper vh, Painter painter) - { - vh.Clear(); - var centerPos = new Vector3(chartPosition.x + m_ChartWidth / 2, chartPosition.y + m_ChartHeight / 2); - UGL.DrawRoundRectangle(vh, centerPos, m_ChartWidth, m_ChartHeight, m_BackgroundColor, m_BackgroundColor, - 0, m_CornerRadius, true); - - var valueWidth = m_Value * m_ChartWidth; - var valuePos = new Vector3(chartPosition.x + valueWidth / 2, centerPos.y); - var endColor = Color.Lerp(m_StartColor, m_EndColor, m_Value); - UGL.DrawRoundRectangle(vh, valuePos, valueWidth, m_ChartHeight, m_StartColor, endColor, 0, - m_CornerRadius, true); - } - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Widgets/ProgressBar.cs.meta b/Assets/XCharts/Runtime/Widgets/ProgressBar.cs.meta deleted file mode 100644 index 1b34a70..0000000 --- a/Assets/XCharts/Runtime/Widgets/ProgressBar.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cd18af5634e604a3c97fb1ff0fc5d682 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Widgets/SVGImage.cs b/Assets/XCharts/Runtime/Widgets/SVGImage.cs deleted file mode 100644 index 1e12c97..0000000 --- a/Assets/XCharts/Runtime/Widgets/SVGImage.cs +++ /dev/null @@ -1,33 +0,0 @@ -using UnityEngine; -using UnityEngine.UI; -using XUGL; - -namespace XCharts.Runtime -{ - [ExecuteInEditMode] - public class SVGImage : MaskableGraphic - { - [SerializeField] private bool m_MirrorY; - [SerializeField] private string m_SVGPath; - - private SVGPath m_Path; - - public string svgPath { set { m_SVGPath = value; } get { return m_SVGPath; } } - public bool mirrorY { set { m_MirrorY = value; } get { return m_MirrorY; } } - - protected override void Awake() - { - base.Awake(); - m_Path = SVGPath.Parse(m_SVGPath); - m_Path.mirrorY = m_MirrorY; - } - - protected override void OnPopulateMesh(VertexHelper vh) - { - vh.Clear(); - if (m_Path != null) - m_Path.Draw(vh); - } - - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Widgets/SVGImage.cs.meta b/Assets/XCharts/Runtime/Widgets/SVGImage.cs.meta deleted file mode 100644 index cf55b08..0000000 --- a/Assets/XCharts/Runtime/Widgets/SVGImage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fe10ee35a038646b6aedfffb30f84024 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XCharts.Runtime.asmdef b/Assets/XCharts/Runtime/XCharts.Runtime.asmdef deleted file mode 100644 index aa9babc..0000000 --- a/Assets/XCharts/Runtime/XCharts.Runtime.asmdef +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "XCharts.Runtime", - "references": [ - ], - "optionalUnityReferences": [], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [] -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XCharts.Runtime.asmdef.meta b/Assets/XCharts/Runtime/XCharts.Runtime.asmdef.meta deleted file mode 100644 index 2b08206..0000000 --- a/Assets/XCharts/Runtime/XCharts.Runtime.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: dd8043639e4014317a7246f064330196 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL.meta b/Assets/XCharts/Runtime/XUGL.meta deleted file mode 100644 index 53b2bee..0000000 --- a/Assets/XCharts/Runtime/XUGL.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: c4fe06f67e9674b808b44154ab0e5fc3 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/SVG.meta b/Assets/XCharts/Runtime/XUGL/SVG.meta deleted file mode 100644 index bd6001d..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6e78d1d27fb8f42948af1c6050eb6a46 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVG.cs b/Assets/XCharts/Runtime/XUGL/SVG/SVG.cs deleted file mode 100644 index 791620d..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVG.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XUGL -{ - public static class SVG - { - public static bool yMirror = false; - public static void Test(VertexHelper vh) - { - //UGL.DrawSvgPath(vh, "path://M600,800 C625,700 725,700 750,800 S875,900 900,800"); - //UGL.DrawSvgPath(vh, "path://M67.335,33.596L67.335,33.596c-0.002-1.39-1.153-3.183-3.328-4.218h-9.096v-2.07h5.371 c-4.939-2.07-11.199-4.141-14.89-4.141H19.72v12.421v5.176h38.373c4.033,0,8.457-1.035,9.142-5.176h-0.027 c0.076-0.367,0.129-0.751,0.129-1.165L67.335,33.596L67.335,33.596z M27.999,30.413h-3.105v-4.141h3.105V30.413z M35.245,30.413 h-3.104v-4.141h3.104V30.413z M42.491,30.413h-3.104v-4.141h3.104V30.413z M49.736,30.413h-3.104v-4.141h3.104V30.413z M14.544,40.764c1.143,0,2.07-0.927,2.07-2.07V35.59V25.237c0-1.145-0.928-2.07-2.07-2.07H-9.265c-1.143,0-2.068,0.926-2.068,2.07 v10.351v3.105c0,1.144,0.926,2.07,2.068,2.07H14.544L14.544,40.764z M8.333,26.272h3.105v4.141H8.333V26.272z M1.087,26.272h3.105 v4.141H1.087V26.272z M-6.159,26.272h3.105v4.141h-3.105V26.272z M-9.265,41.798h69.352v1.035H-9.265V41.798z"); - //UGL.DrawSvgPath(vh, "path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z"); - - //人体 - UGL.DrawSvgPath(vh, "path://M36.7,102.84c-1.17,2.54-2.99,4.98-3.39,7.63c-1.51,9.89-3.31,19.58-1.93,29.95 c0.95,7.15-2.91,14.82-3.57,22.35c-0.64,7.36-0.2,14.86,0.35,22.25c0.12,1.68,2.66,3.17,4.67,5.4c-0.6,0.82-1.5,2.22-2.58,3.48 c-0.96,1.12-1.96,2.35-3.21,3.04c-1.71,0.95-3.71,2.03-5.51,1.9c-1.18-0.08-3.04-2.13-3.16-3.43c-0.44-4.72,0-9.52-0.41-14.25 c-0.94-10.88-2.32-21.72-3.24-32.61c-0.49-5.84-1.63-12.01-0.35-17.54c3.39-14.56,2.8-28.84,0.36-43.4 c-2.71-16.16-1.06-32.4,0.54-48.59c0.91-9.22,4.62-17.36,8.53-25.57c1.32-2.77,1.88-6.84,0.87-9.62C21.89-3.77,18.09-11,14.7-18.38 c-0.56,0.1-1.13,0.21-1.69,0.31C10.17-11.52,6.29-5.2,4.71,1.65C2.05,13.21-4.42,22.3-11.43,31.28c-1.32,1.69-2.51,3.5-3.98,5.04 c-4.85,5.08-3.25,10.98-2.32,16.82c0.25,1.53,0.52,3.06,0.77,4.59c-0.53,0.22-1.07,0.43-1.6,0.65c-1.07-2.09-2.14-4.19-3.28-6.44 c-6.39,2.91-2.67,9.6-5.23,15.16c-1.61-3.31-2.77-5.68-3.93-8.06c0-0.33,0-0.67,0-1c6.96-16.08,14.63-31.9,20.68-48.31 C-5.24-4.07-2.03-18.55,2-32.73c0.36-1.27,0.75-2.53,0.98-3.82c1.36-7.75,4.19-10.23,11.88-10.38c1.76-0.04,3.52-0.21,5.76-0.35 c-0.55-3.95-1.21-7.3-1.45-10.68c-0.61-8.67,0.77-16.69,7.39-23.19c2.18-2.14,4.27-4.82,5.25-7.65c2.39-6.88,11.66-9,16.94-8.12 c5.92,0.99,12.15,7.93,12.16,14.12c0.01,9.89-5.19,17.26-12.24,23.68c-2.17,1.97-5.35,4.77-5.17,6.94c0.31,3.78,4.15,5.66,8.08,6.04 c1.82,0.18,3.7,0.37,5.49,0.1c5.62-0.85,8.8,2.17,10.85,6.73C73.38-27.19,78.46-14.9,84.2-2.91c1.52,3.17,4.52,5.91,7.41,8.09 c7.64,5.77,15.57,11.16,23.45,16.61c2.28,1.58,4.64,3.23,7.21,4.14c5.18,1.84,8.09,5.63,9.82,10.46c0.45,1.24,0.19,3.71-0.6,4.18 c-1.06,0.63-3.15,0.27-4.44-0.38c-7.05-3.54-12.84-8.88-19.14-13.5c-3.5-2.57-7.9-4-12.03-5.6c-9.44-3.66-17.73-8.42-22.5-18.09 c-2.43-4.94-6.09-9.27-9.69-14.61c-1.2,10.98-4.46,20.65,1.14,31.19c6.62,12.47,5.89,26.25,1.21,39.49 c-2.52,7.11-6.5,13.74-8.67,20.94c-1.91,6.33-2.2,13.15-3.23,19.75c-0.72,4.63-0.84,9.48-2.36,13.84 c-2.49,7.16-6.67,13.83-5.84,21.82c0.42,4.02,1.29,7.99,2.1,12.8c-3.74-0.49-7.47-0.4-10.67-1.66c-1.33-0.53-2.43-4.11-2.07-6.01 c1.86-9.94,3.89-19.69,0.07-29.74C34.55,108.63,36.19,105.52,36.7,102.84c1.25-8.45,2.51-16.89,3.71-24.9 c-0.83-0.58-0.85-0.59-0.87-0.61c-0.03,0.16-0.07,0.32-0.09,0.48C38.53,86.15,37.62,94.5,36.7,102.84z"); - - //UGL.DrawSvgPath(vh, "path://M29.902,23.275c1.86,0,3.368-1.506,3.368-3.365c0-1.859-1.508-3.365-3.368-3.365 c-1.857,0-3.365,1.506-3.365,3.365C26.537,21.769,28.045,23.275,29.902,23.275z M36.867,30.74c-1.666-0.467-3.799-1.6-4.732-4.199 c-0.932-2.6-3.131-2.998-4.797-2.998s-7.098,3.894-7.098,3.894c-1.133,1.001-2.1,6.502-0.967,6.769 c1.133,0.269,1.266-1.533,1.934-3.599c0.666-2.065,3.797-3.466,3.797-3.466s0.201,2.467-0.398,3.866 c-0.599,1.399-1.133,2.866-1.467,6.198s-1.6,3.665-3.799,6.266c-2.199,2.598-0.6,3.797,0.398,3.664 c1.002-0.133,5.865-5.598,6.398-6.998c0.533-1.397,0.668-3.732,0.668-3.732s0,0,2.199,1.867c2.199,1.865,2.332,4.6,2.998,7.73 s2.332,0.934,2.332-0.467c0-1.401,0.269-5.465-1-7.064c-1.265-1.6-3.73-3.465-3.73-5.265s1.199-3.732,1.199-3.732 c0.332,1.667,3.335,3.065,5.599,3.399C38.668,33.206,38.533,31.207,36.867,30.74z"); - - //钟表指针 - //UGL.DrawSvgPath(vh, "path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z"); - - //钟表指针 - //UGL.DrawSvgPath(vh, "path://M2.9,0.7L2.9,0.7c1.4,0,2.6,1.2,2.6,2.6v115c0,1.4-1.2,2.6-2.6,2.6l0,0c-1.4,0-2.6-1.2-2.6-2.6V3.3C0.3,1.9,1.4,0.7,2.9,0.7z"); - } - - public static void DrawPath(VertexHelper vh, string path) - { - var svgPath = SVGPath.Parse(path); - DrawPath(vh, svgPath); - } - - public static void DrawPath(VertexHelper vh, SVGPath path) - { - path.Draw(vh); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVG.cs.meta b/Assets/XCharts/Runtime/XUGL/SVG/SVG.cs.meta deleted file mode 100644 index 133f0d2..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVG.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cbe2b3aa282ad4cd9b469792fde7e092 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs b/Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs deleted file mode 100644 index 9239ee1..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs +++ /dev/null @@ -1,202 +0,0 @@ -using System.Collections.Generic; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.UI; - -namespace XUGL -{ - public class SVGPath - { - private static Regex s_PathRegex = new Regex(@"(([a-z]|[A-Z])(\d|\.|,|-)*)"); - private static Regex s_PathValueRegex = new Regex(@"(^[a-z]|[A-Z])\s*(-?\d+\.*\d*)*[\s|,|-]*(\d+\.*\d*)*"); - private static Regex s_PathValueRegex2 = new Regex(@"(-?\d+\.?\d*)"); - public bool mirrorY = true; - public List<SVGPathSeg> segs = new List<SVGPathSeg>(); - - public void AddSegment(SVGPathSeg seg) - { - segs.Add(seg); - } - - public static SVGPath Parse(string path) - { - if (string.IsNullOrEmpty(path)) - return new SVGPath(); - if (path.StartsWith("path://")) - { - path = path.Substring(7); - } - path = path.Replace(' ', ','); - var mc = s_PathRegex.Matches(path); - var svgPath = new SVGPath(); - - foreach (var m in mc) - { - var key = m.ToString(); - if (key.Equals("Z") || key.Equals("z")) - { - var seg = new SVGPathSeg(SVGPathSegType.Z); - seg.raw = key; - seg.relative = key.Equals("z"); - svgPath.AddSegment(seg); - } - else - { - var type = s_PathValueRegex.Match(key).Groups[1].ToString().ToCharArray() [0]; - var mc3 = s_PathValueRegex2.Matches(key); - SVGPathSeg seg = null; - switch (type) - { - case 'M': - case 'm': - seg = new SVGPathSeg(SVGPathSegType.M); - seg.relative = type == 'm'; - break; - case 'L': - case 'l': - seg = new SVGPathSeg(SVGPathSegType.L); - seg.relative = type == 'l'; - break; - case 'H': - case 'h': - seg = new SVGPathSeg(SVGPathSegType.H); - seg.relative = type == 'h'; - break; - case 'V': - case 'v': - seg = new SVGPathSeg(SVGPathSegType.V); - seg.relative = type == 'v'; - break; - case 'C': - case 'c': - seg = new SVGPathSeg(SVGPathSegType.C); - seg.relative = type == 'c'; - break; - case 'S': - case 's': - seg = new SVGPathSeg(SVGPathSegType.S); - seg.relative = type == 's'; - break; - case 'Q': - case 'q': - seg = new SVGPathSeg(SVGPathSegType.Q); - seg.relative = type == 'q'; - break; - case 'T': - case 't': - seg = new SVGPathSeg(SVGPathSegType.T); - seg.relative = type == 't'; - break; - case 'A': - case 'a': - seg = new SVGPathSeg(SVGPathSegType.A); - seg.relative = type == 'a'; - break; - } - if (seg != null) - { - seg.raw = key; - foreach (var m3 in mc3) - { - // if (type == 'c' || type == 'C') - //Debug.LogError("\tmc3:" + type + "," + m3.ToString()); - float p; - if (float.TryParse(m3.ToString(), out p)) - seg.parameters.Add(p); - } - svgPath.AddSegment(seg); - } - } - } - // Debug.LogError(path); - // foreach (var cmd in svgPath.commands) - // { - // Debug.LogError(cmd.raw); - // } - return svgPath; - } - - public void Draw(VertexHelper vh) - { - var sp = Vector2.zero; - var np = Vector2.zero; - var posList = new List<Vector3>(); - var bezierList = new List<Vector3>(); - var cp2 = Vector2.zero; - foreach (var seg in segs) - { - switch (seg.type) - { - case SVGPathSegType.M: - sp = np = seg.relative ? np + seg.p1 : seg.p1; - if (posList.Count > 0) - { - DrawPosList(vh, posList); - } - posList.Add(np); - break; - case SVGPathSegType.L: - np = seg.relative ? np + seg.p1 : seg.p1; - posList.Add(np); - break; - case SVGPathSegType.H: - np = seg.relative ? np + new Vector2(seg.value, 0) : new Vector2(seg.value, np.y); - posList.Add(np); - break; - case SVGPathSegType.V: - np = seg.relative ? np + new Vector2(0, seg.value) : new Vector2(np.x, seg.value); - posList.Add(np); - break; - case SVGPathSegType.C: - var cp1 = seg.relative ? np + seg.p1 : seg.p1; - cp2 = seg.relative ? np + seg.p2 : seg.p2; - var ep = seg.relative ? np + seg.p3 : seg.p3; - var dist = (int) Vector2.Distance(np, ep) * 2; - if (dist < 2) dist = 2; - UGLHelper.GetBezierList2(ref bezierList, np, ep, dist, cp1, cp2); - for (int n = 1; n < bezierList.Count; n++) - posList.Add(bezierList[n]); - np = ep; - break; - case SVGPathSegType.S: - cp1 = np + (np - cp2).normalized * Vector2.Distance(np, cp2); - var scp2 = seg.relative ? np + seg.p1 : seg.p1; - ep = seg.relative ? np + seg.p2 : seg.p2; - dist = (int) Vector2.Distance(np, ep) * 2; - if (dist < 2) dist = 2; - UGLHelper.GetBezierList2(ref bezierList, np, ep, dist, cp1, scp2); - for (int n = 1; n < bezierList.Count; n++) - posList.Add(bezierList[n]); - break; - case SVGPathSegType.Z: - posList.Add(sp); - DrawPosList(vh, posList); - break; - case SVGPathSegType.Q: - case SVGPathSegType.T: - case SVGPathSegType.A: - default: - Debug.LogError("unknow seg:" + seg.type); - break; - } - } - if (posList.Count > 0) - DrawPosList(vh, posList); - //UGL.DrawCricle(vh, sp, 1, Color.black); - } - - private void DrawPosList(VertexHelper vh, List<Vector3> posList) - { - if (mirrorY) - { - for (int i = posList.Count - 1; i >= 0; i--) - { - var pos = posList[i]; - posList[i] = new Vector3(pos.x, -pos.y); - } - } - UGL.DrawLine(vh, posList, 1f, Color.red, false); - posList.Clear(); - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs.meta b/Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs.meta deleted file mode 100644 index 20f5c8d..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVGPath.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c4119dc5490ec4f8bbcc67aa6eee024a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs b/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs deleted file mode 100644 index acce361..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.UI; - -namespace XUGL -{ - public class SVGPathSeg - { - public SVGPathSegType type; - public bool relative; - public List<float> parameters = new List<float>(); - public string raw; - - public SVGPathSeg(SVGPathSegType type) - { - this.type = type; - } - - public float value - { - get - { - if (type == SVGPathSegType.H) - return SVG.yMirror ? -parameters[0] : parameters[0]; - else - return parameters[0]; - } - } - public float x { get { return parameters[0]; } } - public float y { get { return SVG.yMirror ? -parameters[1] : parameters[1]; } } - public Vector2 p1 { get { return new Vector2(parameters[0], (SVG.yMirror ? -parameters[1] : parameters[1])); } } - public Vector2 p2 { get { return new Vector2(parameters[2], (SVG.yMirror ? -parameters[3] : parameters[3])); } } - public Vector2 p3 { get { return new Vector2(parameters[4], (SVG.yMirror ? -parameters[5] : parameters[5])); } } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs.meta b/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs.meta deleted file mode 100644 index 8127559..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSeg.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2c97d44ceb28a471aa3d657f3984e6b1 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs b/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs deleted file mode 100644 index 174dc1c..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Collections.Generic; -using System.Text.RegularExpressions; -using UnityEngine; -using UnityEngine.UI; - -namespace XUGL -{ - public enum SVGPathSegType - { - /// <summary> - /// move to - /// </summary> - M, - /// <summary> - /// line to - /// </summary> - L, - /// <summary> - /// horizontal line to - /// </summary> - H, - /// <summary> - /// vertial line to - /// </summary> - V, - /// <summary> - /// curve to - /// </summary> - C, - /// <summary> - /// smooth curve to - /// </summary> - S, - /// <summary> - /// quadratic bezier curve - /// </summary> - Q, - /// <summary> - /// smooth quadratic bezier curve to - /// </summary> - T, - /// <summary> - /// elliptical Arc - /// </summary> - A, - /// <summary> - /// close path - /// </summary> - Z - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs.meta b/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs.meta deleted file mode 100644 index 217d4b6..0000000 --- a/Assets/XCharts/Runtime/XUGL/SVG/SVGPathSegType.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ebd7fe1a38c81433697bbe21c2e962ba -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/UGL.cs b/Assets/XCharts/Runtime/XUGL/UGL.cs deleted file mode 100644 index b260a52..0000000 --- a/Assets/XCharts/Runtime/XUGL/UGL.cs +++ /dev/null @@ -1,1901 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XUGL -{ - /// <summary> - /// UGUI Graphics Library. - /// |UGUI 图形库 - /// </summary> - public static class UGL - { - private static readonly Color32 s_ClearColor32 = new Color32(0, 0, 0, 0); - private static readonly Vector2 s_ZeroVector2 = Vector2.zero; - private static UIVertex[] s_Vertex = new UIVertex[4]; - private static List<Vector3> s_CurvesPosList = new List<Vector3>(); - - /// <summary> - /// Draw a arrow. 画箭头 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始位置</param> - /// <param name="arrowPoint">箭头位置</param> - /// <param name="width">箭头宽</param> - /// <param name="height">箭头长</param> - /// <param name="offset">相对箭头位置的偏移</param> - /// <param name="dent">箭头凹度</param> - /// <param name="color">颜色</param> - public static void DrawArrow(VertexHelper vh, Vector3 startPoint, Vector3 arrowPoint, float width, - float height, float offset, float dent, Color32 color) - { - var dir = (arrowPoint - startPoint).normalized; - var sharpPos = arrowPoint + (offset + height / 4) * dir; - var middle = sharpPos + (dent - height) * dir; - var diff = Vector3.Cross(dir, Vector3.forward).normalized * width / 2; - var left = sharpPos - height * dir + diff; - var right = sharpPos - height * dir - diff; - DrawTriangle(vh, middle, sharpPos, left, color); - DrawTriangle(vh, middle, sharpPos, right, color); - } - - /// <summary> - /// Draw a line. 画直线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起点</param> - /// <param name="endPoint">终点</param> - /// <param name="width">线宽</param> - /// <param name="color">颜色</param> - public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color) - { - DrawLine(vh, startPoint, endPoint, width, color, color); - } - - /// <summary> - /// Draw a line. 画直线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起点</param> - /// <param name="endPoint">终点</param> - /// <param name="width">线宽</param> - /// <param name="color">颜色</param> - /// <param name="toColor">渐变颜色</param> - public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, Color32 color, Color32 toColor) - { - if (startPoint == endPoint) return; - Vector3 v = Vector3.Cross(endPoint - startPoint, Vector3.forward).normalized * width; - s_Vertex[0].position = startPoint - v; - s_Vertex[1].position = endPoint - v; - s_Vertex[2].position = endPoint + v; - s_Vertex[3].position = startPoint + v; - - for (int j = 0; j < 4; j++) - { - s_Vertex[j].color = j == 0 || j == 3 ? color : toColor; - s_Vertex[j].uv0 = s_ZeroVector2; - } - vh.AddUIVertexQuad(s_Vertex); - } - - /// <summary> - /// Draw a line defined by three points. 画一条由3个点确定的折线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始点</param> - /// <param name="middlePoint">中间转折点</param> - /// <param name="endPoint">终点</param> - /// <param name="width">线宽</param> - /// <param name="color">颜色</param> - public static void DrawLine(VertexHelper vh, Vector3 startPoint, Vector3 middlePoint, Vector3 endPoint, - float width, Color32 color) - { - var dir1 = (middlePoint - startPoint).normalized; - var dir2 = (endPoint - middlePoint).normalized; - var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized; - var dir2v = Vector3.Cross(dir2, Vector3.forward).normalized; - var dir3 = (dir1 + dir2).normalized; - var isDown = Vector3.Cross(dir1, dir2).z <= 0; - var angle = (180 - Vector3.Angle(dir1, dir2)) * Mathf.Deg2Rad / 2; - var diff = width / Mathf.Sin(angle); - var dirDp = Vector3.Cross(dir3, Vector3.forward).normalized; - var dnPos = middlePoint + (isDown ? dirDp : -dirDp) * diff; - var upPos1 = middlePoint + (isDown ? -dir1v : dir1v) * width; - var upPos2 = middlePoint + (isDown ? -dir2v : dir2v) * width; - var startUp = startPoint - dir1v * width; - var startDn = startPoint + dir1v * width; - var endUp = endPoint - dir2v * width; - var endDn = endPoint + dir2v * width; - if (isDown) - { - DrawQuadrilateral(vh, startDn, startUp, upPos1, dnPos, color); - DrawQuadrilateral(vh, dnPos, upPos2, endUp, endDn, color); - DrawTriangle(vh, dnPos, upPos1, upPos2, color); - } - else - { - DrawQuadrilateral(vh, startDn, startUp, dnPos, upPos1, color); - DrawQuadrilateral(vh, upPos2, dnPos, endUp, endDn, color); - DrawTriangle(vh, dnPos, upPos1, upPos2, color); - } - } - - public static void DrawLine(VertexHelper vh, List<Vector3> points, float width, Color32 color, bool smooth, bool closepath = false) - { - for (int i = points.Count - 1; i >= 1; i--) - { - if (UGLHelper.IsValueEqualsVector3(points[i], points[i - 1])) - points.RemoveAt(i); - } - if (points.Count < 2) return; - else if (points.Count <= 2) - { - DrawLine(vh, points[0], points[1], width, color); - } - else if (smooth) - { - DrawCurves(vh, points, width, color, 2); - } - else - { - var ltp = Vector3.zero; - var lbp = Vector3.zero; - var ntp = Vector3.zero; - var nbp = Vector3.zero; - var itp = Vector3.zero; - var ibp = Vector3.zero; - var ctp = Vector3.zero; - var cbp = Vector3.zero; - if (closepath && !UGLHelper.IsValueEqualsVector3(points[points.Count - 1], points[0])) - { - points.Add(points[0]); - } - for (int i = 1; i < points.Count - 1; i++) - { - bool bitp = true, bibp = true; - UGLHelper.GetLinePoints(points[i - 1], points[i], points[i + 1], width, - ref ltp, ref lbp, - ref ntp, ref nbp, - ref itp, ref ibp, - ref ctp, ref cbp, - ref bitp, ref bibp); - if (i == 1) - { - vh.AddVert(ltp, color, Vector2.zero); - vh.AddVert(lbp, color, Vector2.zero); - } - if (bitp == bibp) - { - AddVertToVertexHelper(vh, itp, ibp, color); - } - else - { - if (bitp) - { - AddVertToVertexHelper(vh, itp, ctp, color); - AddVertToVertexHelper(vh, itp, cbp, color); - } - else - { - AddVertToVertexHelper(vh, ctp, ibp, color); - AddVertToVertexHelper(vh, cbp, ibp, color); - } - } - } - AddVertToVertexHelper(vh, ntp, nbp, color); - } - } - - public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top, - Vector3 bottom, Color32 color, bool needTriangle = true) - { - AddVertToVertexHelper(vh, top, bottom, color, color, needTriangle); - } - - public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top, - Vector3 bottom, Color32 topColor, Color32 bottomColor, bool needTriangle = true) - { - var lastVertCount = vh.currentVertCount; - vh.AddVert(top, topColor, Vector2.zero); - vh.AddVert(bottom, bottomColor, Vector2.zero); - if (needTriangle) - { - var indexRt = lastVertCount; - var indexRb = indexRt + 1; - var indexLt = indexRt - 2; - var indexLb = indexLt + 1; - vh.AddTriangle(indexLt, indexRb, indexLb); - vh.AddTriangle(indexLt, indexRt, indexRb); - } - } - - /// <summary> - /// Draw a dash line. 画虚线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始点</param> - /// <param name="endPoint">结束点</param> - /// <param name="width">线宽</param> - /// <param name="color">起始颜色</param> - /// <param name="toColor">结束颜色</param> - /// <param name="lineLength">实线部分长度,默认为线宽的12倍</param> - /// <param name="gapLength">间隙部分长度,默认为线宽的3倍</param> - /// <param name="posList">可选,输出的关键点</param> - public static void DrawDashLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, - Color32 color, Color32 toColor, float lineLength = 0f, float gapLength = 0f, List<Vector3> posList = null) - { - float dist = Vector3.Distance(startPoint, endPoint); - if (dist < 0.1f) return; - if (lineLength == 0) lineLength = 12 * width; - if (gapLength == 0) gapLength = 3 * width; - int segment = Mathf.CeilToInt(dist / (lineLength + gapLength)); - Vector3 dir = (endPoint - startPoint).normalized; - Vector3 sp = startPoint, np; - var isGradient = !color.Equals(toColor); - if (posList != null) posList.Clear(); - for (int i = 1; i <= segment; i++) - { - if (posList != null) posList.Add(sp); - np = startPoint + dir * dist * i / segment; - var dashep = np - dir * gapLength; - DrawLine(vh, sp, dashep, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / segment) : color); - sp = np; - } - if (posList != null) posList.Add(endPoint); - DrawLine(vh, sp, endPoint, width, toColor); - } - - /// <summary> - /// Draw a dot line. 画点线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始点</param> - /// <param name="endPoint">结束点</param> - /// <param name="width">线宽</param> - /// <param name="color">起始颜色</param> - /// <param name="toColor">结束颜色</param> - /// <param name="lineLength">实线部分长度,默认为线宽的3倍</param> - /// <param name="gapLength">间隙部分长度,默认为线宽的3倍</param> - /// <param name="posList">可选,输出的关键点</param> - public static void DrawDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, - Color32 color, Color32 toColor, float lineLength = 0f, float gapLength = 0f, List<Vector3> posList = null) - { - var dist = Vector3.Distance(startPoint, endPoint); - if (dist < 0.1f) return; - if (lineLength == 0) lineLength = 3 * width; - if (gapLength == 0) gapLength = 3 * width; - var segment = Mathf.CeilToInt(dist / (lineLength + gapLength)); - var dir = (endPoint - startPoint).normalized; - var sp = startPoint; - var np = Vector3.zero; - var isGradient = !color.Equals(toColor); - if (posList != null) posList.Clear(); - for (int i = 1; i <= segment; i++) - { - if (posList != null) posList.Add(sp); - np = startPoint + dir * dist * i / segment; - var dashep = np - dir * gapLength; - DrawLine(vh, sp, dashep, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / segment) : color); - sp = np; - } - if (posList != null) posList.Add(endPoint); - DrawLine(vh, sp, endPoint, width, toColor); - } - - /// <summary> - /// Draw a dash-dot line. 画点划线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始点</param> - /// <param name="endPoint">结束点</param> - /// <param name="width">线宽</param> - /// <param name="color">颜色</param> - /// <param name="dashLength">划线长,默认15倍线宽</param> - /// <param name="dotLength">点线长,默认3倍线宽</param> - /// <param name="gapLength">间隙长,默认5倍线宽</param> - /// <param name="posList">可选,输出的关键点</param> - public static void DrawDashDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, - Color32 color, float dashLength = 0f, float dotLength = 0, float gapLength = 0f, - List<Vector3> posList = null) - { - float dist = Vector3.Distance(startPoint, endPoint); - if (dist < 0.1f) return; - if (dashLength == 0) dashLength = 15 * width; - if (dotLength == 0) dotLength = 3 * width; - if (gapLength == 0) gapLength = 5 * width; - int segment = Mathf.CeilToInt(dist / (dashLength + 2 * gapLength + dotLength)); - Vector3 dir = (endPoint - startPoint).normalized; - Vector3 sp = startPoint, np; - if (posList != null) posList.Clear(); - for (int i = 1; i <= segment; i++) - { - if (posList != null) posList.Add(sp); - np = startPoint + dir * dist * i / segment; - var dashep = np - dir * (2 * gapLength + dotLength); - DrawLine(vh, sp, dashep, width, color); - if (posList != null) posList.Add(dashep); - var dotsp = dashep + gapLength * dir; - var dotep = dotsp + dotLength * dir; - DrawLine(vh, dotsp, dotep, width, color); - if (posList != null) posList.Add(dotsp); - sp = np; - } - if (posList != null) posList.Add(endPoint); - DrawLine(vh, sp, endPoint, width, color); - } - - /// <summary> - /// Draw a dash-dot-dot line. 画双点划线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始点</param> - /// <param name="endPoint">结束点</param> - /// <param name="width">线宽</param> - /// <param name="color">颜色</param> - /// <param name="dashLength">折线长,默认15倍线宽</param> - /// <param name="dotLength">点线长,默认3倍线宽</param> - /// <param name="gapLength">间隙长,默认5倍线宽</param> - /// <param name="posList">可选,输出的关键点</param> - public static void DrawDashDotDotLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, - Color32 color, float dashLength = 0f, float dotLength = 0f, float gapLength = 0f, - List<Vector3> posList = null) - { - float dist = Vector3.Distance(startPoint, endPoint); - if (dist < 0.1f) return; - if (dashLength == 0) dashLength = 15 * width; - if (dotLength == 0) dotLength = 3 * width; - if (gapLength == 0) gapLength = 5 * width; - int segment = Mathf.CeilToInt(dist / (dashLength + 3 * gapLength + 2 * dotLength)); - Vector3 dir = (endPoint - startPoint).normalized; - Vector3 sp = startPoint, np; - if (posList != null) posList.Clear(); - for (int i = 1; i <= segment; i++) - { - if (posList != null) posList.Add(sp); - np = startPoint + dir * dist * i / segment; - var dashep = np - dir * (3 * gapLength + 2 * dotLength); - DrawLine(vh, sp, dashep, width, color); - if (posList != null) posList.Add(dashep); - var dotsp = dashep + gapLength * dir; - var dotep = dotsp + dotLength * dir; - DrawLine(vh, dotsp, dotep, width, color); - if (posList != null) posList.Add(dotep); - var dotsp2 = dotep + gapLength * dir; - var dotep2 = dotsp2 + dotLength * dir; - DrawLine(vh, dotsp2, dotep2, width, color); - if (posList != null) posList.Add(dotep2); - sp = np; - } - if (posList != null) posList.Add(endPoint); - DrawLine(vh, sp, endPoint, width, color); - } - - /// <summary> - /// Draw a zebar-line. 画斑马线 - /// </summary> - /// <param name="vh"></param> - /// <param name="startPoint">起始点</param> - /// <param name="endPoint">结束点</param> - /// <param name="width">线宽</param> - /// <param name="zebraWidth">斑马条纹宽</param> - /// <param name="zebraGap">间隙宽</param> - /// <param name="color">起始颜色</param> - /// <param name="toColor">结束颜色</param> - public static void DrawZebraLine(VertexHelper vh, Vector3 startPoint, Vector3 endPoint, float width, - float zebraWidth, float zebraGap, Color32 color, Color32 toColor, float maxDistance) - { - var dist = Vector3.Distance(startPoint, endPoint); - if (dist < 0.1f) return; - if (zebraWidth == 0) zebraWidth = 3 * width; - if (zebraGap == 0) zebraGap = 3 * width; - var allSegment = Mathf.CeilToInt(maxDistance / (zebraWidth + zebraGap)); - var segment = Mathf.CeilToInt(dist / maxDistance * allSegment); - var dir = (endPoint - startPoint).normalized; - var sp = startPoint; - var np = Vector3.zero; - var isGradient = !color.Equals(toColor); - zebraWidth = (maxDistance - zebraGap * (allSegment - 1)) / allSegment; - for (int i = 1; i <= segment; i++) - { - np = sp + dir * zebraWidth; - DrawLine(vh, sp, np, width, isGradient ? Color32.Lerp(color, toColor, i * 1.0f / allSegment) : color); - sp = np + dir * zebraGap; - } - } - - /// <summary> - /// Draw a diamond. 画菱形(钻石形状) - /// </summary> - /// <param name="vh"></param> - /// <param name="center">中心点</param> - /// <param name="size">尺寸</param> - /// <param name="color">颜色</param> - public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color) - { - DrawDiamond(vh, center, size, color, color); - } - - /// <summary> - /// Draw a diamond. 画菱形(钻石形状) - /// </summary> - /// <param name="vh"></param> - /// <param name="center">中心点</param> - /// <param name="size">尺寸</param> - /// <param name="color">渐变色1</param> - /// <param name="toColor">渐变色2</param> - public static void DrawDiamond(VertexHelper vh, Vector3 center, float size, Color32 color, Color32 toColor) - { - var p1 = new Vector2(center.x - size, center.y); - var p2 = new Vector2(center.x, center.y + size); - var p3 = new Vector2(center.x + size, center.y); - var p4 = new Vector2(center.x, center.y - size); - DrawTriangle(vh, p4, p1, p2, color, color, toColor); - DrawTriangle(vh, p3, p4, p2, color, color, toColor); - } - - /// <summary> - /// Draw a square. 画正方形 - /// </summary> - /// <param name="center">中心点</param> - /// <param name="radius">半径</param> - /// <param name="color">颜色</param> - public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color) - { - DrawSquare(vh, center, radius, color, color, true); - } - - /// <summary> - /// Draw a square. 画带渐变的正方形 - /// </summary> - /// <param name="vh"></param> - /// <param name="center">中心点</param> - /// <param name="radius">半径</param> - /// <param name="color">渐变色1</param> - /// <param name="toColor">渐变色2</param> - /// <param name="vertical">渐变是否为垂直方向</param> - public static void DrawSquare(VertexHelper vh, Vector3 center, float radius, Color32 color, - Color32 toColor, bool vertical = true) - { - Vector3 p1, p2, p3, p4; - if (vertical) - { - p1 = new Vector3(center.x + radius, center.y - radius); - p2 = new Vector3(center.x - radius, center.y - radius); - p3 = new Vector3(center.x - radius, center.y + radius); - p4 = new Vector3(center.x + radius, center.y + radius); - } - else - { - p1 = new Vector3(center.x - radius, center.y - radius); - p2 = new Vector3(center.x - radius, center.y + radius); - p3 = new Vector3(center.x + radius, center.y + radius); - p4 = new Vector3(center.x + radius, center.y - radius); - } - DrawQuadrilateral(vh, p1, p2, p3, p4, color, toColor); - } - - /// <summary> - /// Draw a rectangle. 画带长方形 - /// </summary> - /// <param name="p1">起始点</param> - /// <param name="p2">结束点</param> - /// <param name="radius">半径</param> - /// <param name="color">颜色</param> - public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color) - { - DrawRectangle(vh, p1, p2, radius, color, color); - } - - /// <summary> - /// Draw a rectangle. 画带渐变的长方形 - /// </summary> - /// <param name="vh"></param> - /// <param name="p1">起始点</param> - /// <param name="p2">结束点</param> - /// <param name="radius">半径</param> - /// <param name="color">渐变色1</param> - /// <param name="toColor">渐变色2</param> - public static void DrawRectangle(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color, - Color32 toColor) - { - var dir = (p2 - p1).normalized; - var dirv = Vector3.Cross(dir, Vector3.forward).normalized; - - var p3 = p1 + dirv * radius; - var p4 = p1 - dirv * radius; - var p5 = p2 - dirv * radius; - var p6 = p2 + dirv * radius; - DrawQuadrilateral(vh, p3, p4, p5, p6, color, toColor); - } - - /// <summary> - /// Draw a rectangle. 画长方形 - /// </summary> - /// <param name="vh"></param> - /// <param name="p">中心点</param> - /// <param name="xRadius">x宽</param> - /// <param name="yRadius">y宽</param> - /// <param name="color">颜色</param> - /// <param name="vertical">是否垂直方向</param> - public static void DrawRectangle(VertexHelper vh, Vector3 p, float xRadius, float yRadius, - Color32 color, bool vertical = true) - { - DrawRectangle(vh, p, xRadius, yRadius, color, color, vertical); - } - - /// <summary> - /// Draw a rectangle. 画带渐变的长方形 - /// </summary> - /// <param name="vh"></param> - /// <param name="p">中心点</param> - /// <param name="xRadius">x宽</param> - /// <param name="yRadius">y宽</param> - /// <param name="color">渐变色1</param> - /// <param name="toColor">渐变色2</param> - /// <param name="vertical">是否垂直方向</param> - public static void DrawRectangle(VertexHelper vh, Vector3 p, float xRadius, float yRadius, - Color32 color, Color32 toColor, bool vertical = true) - { - Vector3 p1, p2, p3, p4; - if (vertical) - { - p1 = new Vector3(p.x + xRadius, p.y - yRadius); - p2 = new Vector3(p.x - xRadius, p.y - yRadius); - p3 = new Vector3(p.x - xRadius, p.y + yRadius); - p4 = new Vector3(p.x + xRadius, p.y + yRadius); - } - else - { - p1 = new Vector3(p.x - xRadius, p.y - yRadius); - p2 = new Vector3(p.x - xRadius, p.y + yRadius); - p3 = new Vector3(p.x + xRadius, p.y + yRadius); - p4 = new Vector3(p.x + xRadius, p.y - yRadius); - } - - DrawQuadrilateral(vh, p1, p2, p3, p4, color, toColor); - } - - public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color) - { - DrawRectangle(vh, rect.center, rect.width / 2, rect.height / 2, color, color, true); - } - - public static void DrawRectangle(VertexHelper vh, Rect rect, Color32 color, Color32 toColor) - { - DrawRectangle(vh, rect.center, rect.width / 2, rect.height / 2, color, toColor, true); - } - - public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color) - { - DrawRectangle(vh, rect, border, color, color); - } - - public static void DrawRectangle(VertexHelper vh, Rect rect, float border, Color32 color, Color32 toColor) - { - DrawRectangle(vh, rect.center, rect.width / 2 - border, rect.height / 2 - border, color, toColor, true); - } - - /// <summary> - /// Draw a quadrilateral. 画任意的四边形 - /// </summary> - /// <param name="vh"></param> - /// <param name="p1"></param> - /// <param name="p2"></param> - /// <param name="p3"></param> - /// <param name="p4"></param> - /// <param name="color"></param> - public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, - Color32 color) - { - DrawQuadrilateral(vh, p1, p2, p3, p4, color, color); - } - - /// <summary> - /// Draw a quadrilateral. 画任意带渐变的四边形 - /// </summary> - /// <param name="vh"></param> - /// <param name="p1"></param> - /// <param name="p2"></param> - /// <param name="p3"></param> - /// <param name="p4"></param> - /// <param name="startColor"></param> - /// <param name="toColor"></param> - public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, - Color32 startColor, Color32 toColor) - { - DrawQuadrilateral(vh, p1, p2, p3, p4, startColor, startColor, toColor, toColor); - } - - public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, - Color32 color1, Color32 color2, Color32 color3, Color32 color4) - { - s_Vertex[0].position = p1; - s_Vertex[1].position = p2; - s_Vertex[2].position = p3; - s_Vertex[3].position = p4; - s_Vertex[0].color = color1; - s_Vertex[1].color = color2; - s_Vertex[2].color = color3; - s_Vertex[3].color = color4; - for (int j = 0; j < 4; j++) - { - s_Vertex[j].uv0 = s_ZeroVector2; - } - vh.AddUIVertexQuad(s_Vertex); - } - - public static void InitCornerRadius(float[] cornerRadius, float width, float height, bool horizontal, - bool invert, ref float brLt, ref float brRt, ref float brRb, ref float brLb, ref bool needRound) - { - if (cornerRadius == null || cornerRadius.Length == 0) return; - if (invert) - { - if (horizontal) - { - brLt = cornerRadius.Length > 0 ? cornerRadius[1] : 0; - brRt = cornerRadius.Length > 1 ? cornerRadius[0] : 0; - brRb = cornerRadius.Length > 2 ? cornerRadius[3] : 0; - brLb = cornerRadius.Length > 3 ? cornerRadius[2] : 0; - } - else - { - brLt = cornerRadius.Length > 0 ? cornerRadius[3] : 0; - brRt = cornerRadius.Length > 1 ? cornerRadius[2] : 0; - brRb = cornerRadius.Length > 2 ? cornerRadius[1] : 0; - brLb = cornerRadius.Length > 3 ? cornerRadius[0] : 0; - } - } - else - { - brLt = cornerRadius.Length > 0 ? cornerRadius[0] : 0; - brRt = cornerRadius.Length > 1 ? cornerRadius[1] : 0; - brRb = cornerRadius.Length > 2 ? cornerRadius[2] : 0; - brLb = cornerRadius.Length > 3 ? cornerRadius[3] : 0; - } - - needRound = brLb != 0 || brRt != 0 || brRb != 0 || brLb != 0; - if (needRound) - { - var min = Mathf.Min(width, height); - if (brLt == 1 && brRt == 1 && brRb == 1 && brLb == 1) - { - brLt = brRt = brRb = brLb = min / 2; - return; - } - if (brLt > 0 && brLt <= 1) brLt = brLt * min; - if (brRt > 0 && brRt <= 1) brRt = brRt * min; - if (brRb > 0 && brRb <= 1) brRb = brRb * min; - if (brLb > 0 && brLb <= 1) brLb = brLb * min; - if (horizontal) - { - if (brLb + brLt >= height) - { - var total = brLb + brLt; - brLb = height * (brLb / total); - brLt = height * (brLt / total); - } - if (brRt + brRb >= height) - { - var total = brRt + brRb; - brRt = height * (brRt / total); - brRb = height * (brRb / total); - } - if (brLt + brRt >= width) - { - var total = brLt + brRt; - brLt = width * (brLt / total); - brRt = width * (brRt / total); - } - if (brRb + brLb >= width) - { - var total = brRb + brLb; - brRb = width * (brRb / total); - brLb = width * (brLb / total); - } - } - else - { - if (brLt + brRt >= width) - { - var total = brLt + brRt; - brLt = width * (brLt / total); - brRt = width * (brRt / total); - } - if (brRb + brLb >= width) - { - var total = brRb + brLb; - brRb = width * (brRb / total); - brLb = width * (brLb / total); - } - if (brLb + brLt >= height) - { - var total = brLb + brLt; - brLb = height * (brLb / total); - brLt = height * (brLt / total); - } - if (brRt + brRb >= height) - { - var total = brRt + brRb; - brRt = height * (brRt / total); - brRb = height * (brRb / total); - } - } - } - } - - public static void DrawRoundRectangle(VertexHelper vh, Rect rect, - Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null, bool isYAxis = false, - float smoothness = 2, bool invert = false) - { - DrawRoundRectangle(vh, rect.center, rect.width, rect.height, color, toColor, rotate, cornerRadius, - isYAxis, smoothness, invert); - } - - /// <summary> - /// 绘制圆角矩形 - /// </summary> - /// <param name="vh"></param> - /// <param name="center"></param> - /// <param name="rectWidth"></param> - /// <param name="rectHeight"></param> - /// <param name="color"></param> - /// <param name="toColor"></param> - /// <param name="rotate"></param> - /// <param name="cornerRadius"></param> - /// <param name="horizontal"></param> - /// <param name="smoothness"></param> - /// <param name="invert"></param> - public static void DrawRoundRectangle(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight, - Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null, bool horizontal = false, - float smoothness = 2, bool invert = false) - { - if (invert) - { - var temp = toColor; - toColor = color; - color = temp; - } - var isGradient = !UGLHelper.IsValueEqualsColor(color, toColor); - var halfWid = rectWidth / 2; - var halfHig = rectHeight / 2; - float brLt = 0, brRt = 0, brRb = 0, brLb = 0; - bool needRound = false; - InitCornerRadius(cornerRadius, rectWidth, rectHeight, horizontal, invert, ref brLt, ref brRt, ref brRb, - ref brLb, ref needRound); - var tempCenter = Vector3.zero; - var lbIn = new Vector3(center.x - halfWid, center.y - halfHig); - var ltIn = new Vector3(center.x - halfWid, center.y + halfHig); - var rtIn = new Vector3(center.x + halfWid, center.y + halfHig); - var rbIn = new Vector3(center.x + halfWid, center.y - halfHig); - if (needRound) - { - var lbIn2 = lbIn; - var ltIn2 = ltIn; - var rtIn2 = rtIn; - var rbIn2 = rbIn; - var roundLb = lbIn; - var roundLt = ltIn; - var roundRt = rtIn; - var roundRb = rbIn; - if (brLt > 0) - { - roundLt = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt); - ltIn = roundLt + brLt * Vector3.left; - ltIn2 = roundLt + brLt * Vector3.up; - } - if (brRt > 0) - { - roundRt = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt); - rtIn = roundRt + brRt * Vector3.up; - rtIn2 = roundRt + brRt * Vector3.right; - } - if (brRb > 0) - { - roundRb = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb); - rbIn = roundRb + brRb * Vector3.right; - rbIn2 = roundRb + brRb * Vector3.down; - } - if (brLb > 0) - { - roundLb = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb); - lbIn = roundLb + brLb * Vector3.left; - lbIn2 = roundLb + brLb * Vector3.down; - } - - if (horizontal) - { - var maxLeft = Mathf.Max(brLt, brLb); - var maxRight = Mathf.Max(brRt, brRb); - var ltInRight = ltIn + maxLeft * Vector3.right; - var lbInRight = lbIn + maxLeft * Vector3.right; - var rtIn2Left = rtIn2 + maxRight * Vector3.left; - var rbInLeft = rbIn + maxRight * Vector3.left; - - var roundLbRight = roundLb + (maxLeft - brLb) * Vector3.right; - var lbIn2Right = lbIn2 + (maxLeft - brLb) * Vector3.right; - if (roundLbRight.x > roundRb.x) roundLbRight.x = roundRb.x; - if (lbIn2Right.x > roundRb.x) lbIn2Right.x = roundRb.x; - - var ltIn2Right = ltIn2 + (maxLeft - brLt) * Vector3.right; - var roundLtRight = roundLt + (maxLeft - brLt) * Vector3.right; - if (ltIn2Right.x > roundRt.x) ltIn2Right.x = roundRt.x; - if (roundLtRight.x > roundRt.x) roundLtRight.x = roundRt.x; - - var roundRtLeft = roundRt + (maxRight - brRt) * Vector3.left; - var rtInLeft = rtIn + (maxRight - brRt) * Vector3.left; - if (roundRtLeft.x < roundLt.x) roundRtLeft.x = roundLt.x; - if (rtInLeft.x < roundLt.x) rtInLeft.x = roundLt.x; - - var rbIn2Left = rbIn2 + (maxRight - brRb) * Vector3.left; - var roundRbLeft = roundRb + (maxRight - brRb) * Vector3.left; - if (rbIn2Left.x < roundLb.x) rbIn2Left.x = roundLb.x; - if (roundRbLeft.x < roundLb.x) roundRbLeft.x = roundLb.x; - if (!isGradient) - { - DrawSector(vh, roundLt, brLt, color, color, 270, 360, 1, horizontal, smoothness); - DrawSector(vh, roundRt, brRt, toColor, toColor, 0, 90, 1, horizontal, smoothness); - DrawSector(vh, roundRb, brRb, toColor, toColor, 90, 180, 1, horizontal, smoothness); - DrawSector(vh, roundLb, brLb, color, color, 180, 270, 1, horizontal, smoothness); - - DrawQuadrilateral(vh, ltIn, ltInRight, lbInRight, lbIn, color, color); - DrawQuadrilateral(vh, lbIn2, roundLb, roundLbRight, lbIn2Right, color, color); - DrawQuadrilateral(vh, roundLt, ltIn2, ltIn2Right, roundLtRight, color, color); - - DrawQuadrilateral(vh, rbInLeft, rtIn2Left, rtIn2, rbIn, toColor, toColor); - DrawQuadrilateral(vh, roundRtLeft, rtInLeft, rtIn, roundRt, toColor, toColor); - DrawQuadrilateral(vh, rbIn2Left, roundRbLeft, roundRb, rbIn2, toColor, toColor); - - var clt = new Vector3(center.x - halfWid + maxLeft, center.y + halfHig); - var crt = new Vector3(center.x + halfWid - maxRight, center.y + halfHig); - var crb = new Vector3(center.x + halfWid - maxRight, center.y - halfHig); - var clb = new Vector3(center.x - halfWid + maxLeft, center.y - halfHig); - if (crt.x > clt.x) - { - DrawQuadrilateral(vh, clb, clt, crt, crb, color, toColor); - } - } - else - { - var tempLeftColor = Color32.Lerp(color, toColor, maxLeft / rectWidth); - var upLeftColor = Color32.Lerp(color, tempLeftColor, brLt / maxLeft); - var downLeftColor = Color32.Lerp(color, tempLeftColor, brLb / maxLeft); - - var tempRightColor = Color32.Lerp(color, toColor, (rectWidth - maxRight) / rectWidth); - var upRightColor = Color32.Lerp(tempRightColor, toColor, (maxRight - brRt) / maxRight); - var downRightColor = Color32.Lerp(tempRightColor, toColor, (maxRight - brRb) / maxRight); - - DrawSector(vh, roundLt, brLt, color, upLeftColor, 270, 360, 1, horizontal, smoothness); - DrawSector(vh, roundRt, brRt, upRightColor, toColor, 0, 90, 1, horizontal, smoothness); - DrawSector(vh, roundRb, brRb, downRightColor, toColor, 90, 180, 1, horizontal, smoothness); - DrawSector(vh, roundLb, brLb, color, downLeftColor, 180, 270, 1, horizontal, smoothness); - - DrawQuadrilateral(vh, lbIn, ltIn, ltInRight, lbInRight, color, tempLeftColor); - DrawQuadrilateral(vh, lbIn2, roundLb, roundLbRight, lbIn2Right, downLeftColor, - roundLbRight.x == roundRb.x ? downRightColor : tempLeftColor); - DrawQuadrilateral(vh, roundLt, ltIn2, ltIn2Right, roundLtRight, upLeftColor, - ltIn2Right.x == roundRt.x ? upRightColor : tempLeftColor); - - DrawQuadrilateral(vh, rbInLeft, rtIn2Left, rtIn2, rbIn, tempRightColor, toColor); - DrawQuadrilateral(vh, roundRtLeft, rtInLeft, rtIn, roundRt, - roundRtLeft.x == roundLt.x ? upLeftColor : tempRightColor, upRightColor); - DrawQuadrilateral(vh, rbIn2Left, roundRbLeft, roundRb, rbIn2, - rbIn2Left.x == roundLb.x ? downLeftColor : tempRightColor, downRightColor); - - var clt = new Vector3(center.x - halfWid + maxLeft, center.y + halfHig); - var crt = new Vector3(center.x + halfWid - maxRight, center.y + halfHig); - var crb = new Vector3(center.x + halfWid - maxRight, center.y - halfHig); - var clb = new Vector3(center.x - halfWid + maxLeft, center.y - halfHig); - if (crt.x > clt.x) - { - DrawQuadrilateral(vh, clb, clt, crt, crb, tempLeftColor, tempRightColor); - } - } - } - else - { - var maxup = Mathf.Max(brLt, brRt); - var maxdown = Mathf.Max(brLb, brRb); - var clt = new Vector3(center.x - halfWid, center.y + halfHig - maxup); - var crt = new Vector3(center.x + halfWid, center.y + halfHig - maxup); - var crb = new Vector3(center.x + halfWid, center.y - halfHig + maxdown); - var clb = new Vector3(center.x - halfWid, center.y - halfHig + maxdown); - var lbIn2Up = lbIn2 + maxdown * Vector3.up; - var rbIn2Up = rbIn2 + maxdown * Vector3.up; - var rtInDown = rtIn + maxup * Vector3.down; - var ltIn2Down = ltIn2 + maxup * Vector3.down; - - var roundLtDown = roundLt + (maxup - brLt) * Vector3.down; - var ltInDown = ltIn + (maxup - brLt) * Vector3.down; - if (roundLtDown.y < roundLb.y) roundLtDown.y = roundLb.y; - if (ltInDown.y < roundLb.y) ltInDown.y = roundLb.y; - - var rtIn2Down = rtIn2 + (maxup - brRt) * Vector3.down; - var roundRtDown = roundRt + (maxup - brRt) * Vector3.down; - if (rtIn2Down.y < roundRb.y) rtIn2Down.y = roundRb.y; - if (roundRtDown.y < roundRb.y) roundRtDown.y = roundRb.y; - - var lbInUp = lbIn + (maxdown - brLb) * Vector3.up; - var roundLbUp = roundLb + (maxdown - brLb) * Vector3.up; - if (lbInUp.y > roundLt.y) lbInUp.y = roundLt.y; - if (roundLbUp.y > roundLt.y) roundLbUp.y = roundLt.y; - - var roundRbUp = roundRb + (maxdown - brRb) * Vector3.up; - var rbInUp = rbIn + (maxdown - brRb) * Vector3.up; - if (roundRbUp.y > roundRt.y) roundRbUp.y = roundRt.y; - if (rbInUp.y > roundRt.y) rbInUp.y = roundRt.y; - - if (!isGradient) - { - DrawSector(vh, roundLt, brLt, toColor, toColor, 270, 360, 1, horizontal, smoothness); - DrawSector(vh, roundRt, brRt, toColor, toColor, 0, 90, 1, horizontal, smoothness); - DrawSector(vh, roundRb, brRb, color, color, 90, 180, 1, horizontal, smoothness); - DrawSector(vh, roundLb, brLb, color, color, 180, 270, 1, horizontal, smoothness); - - DrawQuadrilateral(vh, ltIn2, rtIn, rtInDown, ltIn2Down, toColor, toColor); - DrawQuadrilateral(vh, ltIn, roundLt, roundLtDown, ltInDown, toColor, toColor); - DrawQuadrilateral(vh, roundRt, rtIn2, rtIn2Down, roundRtDown, toColor, toColor); - - DrawQuadrilateral(vh, lbIn2, lbIn2Up, rbIn2Up, rbIn2, color, color); - DrawQuadrilateral(vh, lbIn, lbInUp, roundLbUp, roundLb, color, color); - DrawQuadrilateral(vh, roundRb, roundRbUp, rbInUp, rbIn, color, color); - if (clt.y > clb.y) - { - DrawQuadrilateral(vh, clt, crt, crb, clb, toColor, color); - } - } - else - { - var tempUpColor = Color32.Lerp(color, toColor, (rectHeight - maxup) / rectHeight); - var leftUpColor = Color32.Lerp(tempUpColor, toColor, (maxup - brLt) / maxup); - var rightUpColor = Color32.Lerp(tempUpColor, toColor, (maxup - brRt) / maxup); - var tempDownColor = Color32.Lerp(color, toColor, maxdown / rectHeight); - var leftDownColor = Color32.Lerp(color, tempDownColor, brLb / maxdown); - var rightDownColor = Color32.Lerp(color, tempDownColor, brRb / maxdown); - - DrawSector(vh, roundLt, brLt, leftUpColor, toColor, 270, 360, 1, horizontal, smoothness); - DrawSector(vh, roundRt, brRt, rightUpColor, toColor, 0, 90, 1, horizontal, smoothness); - DrawSector(vh, roundRb, brRb, rightDownColor, color, 90, 180, 1, horizontal, smoothness); - DrawSector(vh, roundLb, brLb, leftDownColor, color, 180, 270, 1, horizontal, smoothness); - - DrawQuadrilateral(vh, ltIn2, rtIn, rtInDown, ltIn2Down, toColor, tempUpColor); - DrawQuadrilateral(vh, ltIn, roundLt, roundLtDown, ltInDown, leftUpColor, - roundLtDown.y == roundLb.y ? leftDownColor : tempUpColor); - DrawQuadrilateral(vh, roundRt, rtIn2, rtIn2Down, roundRtDown, rightUpColor, - rtIn2Down.y == roundRb.y ? rightDownColor : tempUpColor); - - DrawQuadrilateral(vh, rbIn2, lbIn2, lbIn2Up, rbIn2Up, color, tempDownColor); - DrawQuadrilateral(vh, roundLb, lbIn, lbInUp, roundLbUp, leftDownColor, - lbInUp.y == roundLt.y ? leftUpColor : tempDownColor); - DrawQuadrilateral(vh, rbIn, roundRb, roundRbUp, rbInUp, rightDownColor, - roundRbUp.y == roundRt.y ? rightUpColor : tempDownColor); - if (clt.y > clb.y) - { - DrawQuadrilateral(vh, clt, crt, crb, clb, tempUpColor, tempDownColor); - } - } - } - } - else - { - if (horizontal) - DrawQuadrilateral(vh, lbIn, ltIn, rtIn, rbIn, color, toColor); - else - DrawQuadrilateral(vh, rbIn, lbIn, ltIn, rtIn, color, toColor); - } - } - - /// <summary> - /// 绘制(圆角)边框 - /// </summary> - /// <param name="vh"></param> - /// <param name="center"></param> - /// <param name="rectWidth"></param> - /// <param name="rectHeight"></param> - /// <param name="borderWidth"></param> - /// <param name="color"></param> - /// <param name="rotate"></param> - /// <param name="cornerRadius"></param> - /// <param name="invertCorner"></param> - /// <param name="extWidth"></param> - public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight, - float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null, - bool horizontal = false, float smoothness = 1f, bool invertCorner = false, float extWidth = 0) - { - DrawBorder(vh, center, rectWidth, rectHeight, borderWidth, color, s_ClearColor32, rotate, - cornerRadius, horizontal, smoothness, invertCorner, extWidth); - } - - /// <summary> - /// 绘制(圆角)边框 - /// </summary> - /// <param name="vh"></param> - /// <param name="rect"></param> - /// <param name="borderWidth"></param> - /// <param name="color"></param> - /// <param name="rotate"></param> - /// <param name="cornerRadius"></param> - /// <param name="horizontal"></param> - /// <param name="smoothness"></param> - /// <param name="invertCorner"></param> - /// <param name="extWidth"></param> - public static void DrawBorder(VertexHelper vh, Rect rect, - float borderWidth, Color32 color, float rotate = 0, float[] cornerRadius = null, - bool horizontal = false, float smoothness = 1f, bool invertCorner = false, float extWidth = 0) - { - DrawBorder(vh, rect.center, rect.width, rect.height, borderWidth, color, s_ClearColor32, rotate, - cornerRadius, horizontal, smoothness, invertCorner, extWidth); - } - - /// <summary> - /// 绘制(圆角)边框 - /// </summary> - /// <param name="vh"></param> - /// <param name="center"></param> - /// <param name="rectWidth"></param> - /// <param name="rectHeight"></param> - /// <param name="borderWidth"></param> - /// <param name="color"></param> - /// <param name="toColor"></param> - /// <param name="rotate"></param> - /// <param name="cornerRadius"></param> - /// <param name="horizontal"></param> - /// <param name="smoothness"></param> - /// <param name="invertCorner"></param> - /// <param name="extWidth"></param> - public static void DrawBorder(VertexHelper vh, Vector3 center, float rectWidth, float rectHeight, - float borderWidth, Color32 color, Color32 toColor, float rotate = 0, float[] cornerRadius = null, - bool horizontal = false, float smoothness = 1f, bool invertCorner = false, float extWidth = 0) - { - if (borderWidth == 0 || UGLHelper.IsClearColor(color)) return; - var halfWid = rectWidth / 2; - var halfHig = rectHeight / 2; - var lbIn = new Vector3(center.x - halfWid - extWidth, center.y - halfHig - extWidth); - var lbOt = new Vector3(center.x - halfWid - borderWidth - extWidth, center.y - halfHig - borderWidth - extWidth); - var ltIn = new Vector3(center.x - halfWid - extWidth, center.y + halfHig + extWidth); - var ltOt = new Vector3(center.x - halfWid - borderWidth - extWidth, center.y + halfHig + borderWidth + extWidth); - var rtIn = new Vector3(center.x + halfWid + extWidth, center.y + halfHig + extWidth); - var rtOt = new Vector3(center.x + halfWid + borderWidth + extWidth, center.y + halfHig + borderWidth + extWidth); - var rbIn = new Vector3(center.x + halfWid + extWidth, center.y - halfHig - extWidth); - var rbOt = new Vector3(center.x + halfWid + borderWidth + extWidth, center.y - halfHig - borderWidth - extWidth); - float brLt = 0, brRt = 0, brRb = 0, brLb = 0; - bool needRound = false; - InitCornerRadius(cornerRadius, rectWidth, rectHeight, horizontal, invertCorner, ref brLt, ref brRt, ref brRb, - ref brLb, ref needRound); - var tempCenter = Vector3.zero; - if (UGLHelper.IsClearColor(toColor)) - { - toColor = color; - } - if (needRound) - { - var lbIn2 = lbIn; - var lbOt2 = lbOt; - var ltIn2 = ltIn; - var ltOt2 = ltOt; - var rtIn2 = rtIn; - var rtOt2 = rtOt; - var rbIn2 = rbIn; - var rbOt2 = rbOt; - //if (brLt > 0) - { - tempCenter = new Vector3(center.x - halfWid + brLt, center.y + halfHig - brLt); - brLt += extWidth; - DrawDoughnut(vh, tempCenter, brLt, brLt + borderWidth, horizontal ? color : toColor, s_ClearColor32, - 270, 360, smoothness); - ltIn = tempCenter + brLt * Vector3.left; - ltOt = tempCenter + (brLt + borderWidth) * Vector3.left; - ltIn2 = tempCenter + brLt * Vector3.up; - ltOt2 = tempCenter + (brLt + borderWidth) * Vector3.up; - } - //if (brRt > 0) - { - tempCenter = new Vector3(center.x + halfWid - brRt, center.y + halfHig - brRt); - brRt += extWidth; - DrawDoughnut(vh, tempCenter, brRt, brRt + borderWidth, toColor, s_ClearColor32, 0, 90, smoothness); - rtIn = tempCenter + brRt * Vector3.up; - rtOt = tempCenter + (brRt + borderWidth) * Vector3.up; - rtIn2 = tempCenter + brRt * Vector3.right; - rtOt2 = tempCenter + (brRt + borderWidth) * Vector3.right; - } - //if (brRb > 0) - { - tempCenter = new Vector3(center.x + halfWid - brRb, center.y - halfHig + brRb); - brRb += extWidth; - DrawDoughnut(vh, tempCenter, brRb, brRb + borderWidth, horizontal ? toColor : color, s_ClearColor32, - 90, 180, smoothness); - rbIn = tempCenter + brRb * Vector3.right; - rbOt = tempCenter + (brRb + borderWidth) * Vector3.right; - rbIn2 = tempCenter + brRb * Vector3.down; - rbOt2 = tempCenter + (brRb + borderWidth) * Vector3.down; - } - //if (brLb > 0) - { - tempCenter = new Vector3(center.x - halfWid + brLb, center.y - halfHig + brLb); - brLb += extWidth; - DrawDoughnut(vh, tempCenter, brLb, brLb + borderWidth, color, s_ClearColor32, 180, 270, smoothness); - lbIn = tempCenter + brLb * Vector3.left; - lbOt = tempCenter + (brLb + borderWidth) * Vector3.left; - lbIn2 = tempCenter + brLb * Vector3.down; - lbOt2 = tempCenter + (brLb + borderWidth) * Vector3.down; - } - if (horizontal) - { - DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, color); - DrawQuadrilateral(vh, ltIn2, ltOt2, rtOt, rtIn, color, toColor); - DrawQuadrilateral(vh, rtIn2, rtOt2, rbOt, rbIn, toColor, toColor); - DrawQuadrilateral(vh, rbIn2, rbOt2, lbOt2, lbIn2, toColor, color); - } - else - { - DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, toColor); - DrawQuadrilateral(vh, ltIn2, ltOt2, rtOt, rtIn, toColor, toColor); - DrawQuadrilateral(vh, rtIn2, rtOt2, rbOt, rbIn, toColor, color); - DrawQuadrilateral(vh, rbIn2, rbOt2, lbOt2, lbIn2, color, color); - } - } - else - { - if (rotate > 0) - { - lbIn = UGLHelper.RotateRound(lbIn, center, Vector3.forward, rotate); - lbOt = UGLHelper.RotateRound(lbOt, center, Vector3.forward, rotate); - ltIn = UGLHelper.RotateRound(ltIn, center, Vector3.forward, rotate); - ltOt = UGLHelper.RotateRound(ltOt, center, Vector3.forward, rotate); - rtIn = UGLHelper.RotateRound(rtIn, center, Vector3.forward, rotate); - rtOt = UGLHelper.RotateRound(rtOt, center, Vector3.forward, rotate); - rbIn = UGLHelper.RotateRound(rbIn, center, Vector3.forward, rotate); - rbOt = UGLHelper.RotateRound(rbOt, center, Vector3.forward, rotate); - } - if (horizontal) - { - DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, color); - DrawQuadrilateral(vh, ltIn, ltOt, rtOt, rtIn, color, toColor); - DrawQuadrilateral(vh, rtIn, rtOt, rbOt, rbIn, toColor, toColor); - DrawQuadrilateral(vh, rbIn, rbOt, lbOt, lbIn, toColor, color); - } - else - { - DrawQuadrilateral(vh, lbIn, lbOt, ltOt, ltIn, color, toColor); - DrawQuadrilateral(vh, ltIn, ltOt, rtOt, rtIn, toColor, toColor); - DrawQuadrilateral(vh, rtIn, rtOt, rbOt, rbIn, toColor, color); - DrawQuadrilateral(vh, rbIn, rbOt, lbOt, lbIn, color, color); - } - } - } - - public static void DrawTriangle(VertexHelper vh, Vector3 p1, - Vector3 p2, Vector3 p3, Color32 color) - { - DrawTriangle(vh, p1, p2, p3, color, color, color); - } - - public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color) - { - DrawTriangle(vh, pos, size, color, color); - } - - public static void DrawTriangle(VertexHelper vh, Vector3 pos, float size, Color32 color, Color32 toColor) - { - var x = size * Mathf.Cos(30 * Mathf.PI / 180); - var y = size * Mathf.Sin(30 * Mathf.PI / 180); - var p1 = new Vector2(pos.x - x, pos.y - y); - var p2 = new Vector2(pos.x, pos.y + size); - var p3 = new Vector2(pos.x + x, pos.y - y); - DrawTriangle(vh, p1, p2, p3, color, toColor, color); - } - - public static void DrawTriangle(VertexHelper vh, Vector3 p1, - Vector3 p2, Vector3 p3, Color32 color, Color32 color2, Color32 color3) - { - UIVertex v1 = new UIVertex(); - v1.position = p1; - v1.color = color; - v1.uv0 = s_ZeroVector2; - UIVertex v2 = new UIVertex(); - v2.position = p2; - v2.color = color2; - v2.uv0 = s_ZeroVector2; - UIVertex v3 = new UIVertex(); - v3.position = p3; - v3.color = color3; - v3.uv0 = s_ZeroVector2; - int startIndex = vh.currentVertCount; - vh.AddVert(v1); - vh.AddVert(v2); - vh.AddVert(v3); - vh.AddTriangle(startIndex, startIndex + 1, startIndex + 2); - } - - public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color, - float smoothness = 2f) - { - DrawCricle(vh, center, radius, color, color, 0, s_ClearColor32, smoothness); - } - - public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color, - Color32 toColor, float smoothness = 2f) - { - DrawSector(vh, center, radius, color, toColor, 0, 360, 0, s_ClearColor32, smoothness); - } - - public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color, - Color32 toColor, float borderWidth, Color32 borderColor, float smoothness = 2f) - { - DrawSector(vh, center, radius, color, toColor, 0, 360, borderWidth, borderColor, smoothness); - } - - public static void DrawCricle(VertexHelper vh, Vector3 center, float radius, Color32 color, - float borderWidth, Color32 borderColor, float smoothness = 2f) - { - DrawCricle(vh, center, radius, color, color, borderWidth, borderColor, smoothness); - } - - public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness, - Color32 color, Color32 emptyColor, float smoothness = 2f) - { - DrawDoughnut(vh, center, radius - tickness, radius, color, color, emptyColor, 0, 360, 0, s_ClearColor32, - 0, smoothness); - } - - public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness, - Color32 color, Color32 emptyColor, float borderWidth, Color32 borderColor, float smoothness = 2f) - { - DrawDoughnut(vh, center, radius - tickness, radius, color, color, emptyColor, 0, 360, borderWidth, - borderColor, 0, smoothness); - } - - public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness, - Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f) - { - DrawDoughnut(vh, center, radius - tickness, radius, color, toColor, emptyColor, 0, 360, 0, - s_ClearColor32, 0, smoothness); - } - - public static void DrawEmptyCricle(VertexHelper vh, Vector3 center, float radius, float tickness, - Color32 color, Color32 toColor, Color32 emptyColor, float borderWidth, Color32 borderColor, - float smoothness = 2f) - { - DrawDoughnut(vh, center, radius - tickness, radius, color, toColor, emptyColor, 0, 360, borderWidth, - borderColor, 0, smoothness); - } - - public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, - float startDegree, float toDegree, float smoothness = 2f) - { - DrawSector(vh, center, radius, color, color, startDegree, toDegree, 0, s_ClearColor32, smoothness); - } - - public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor, - float startDegree, float toDegree, int gradientType = 0, bool isYAxis = false, float smoothness = 2f) - { - DrawSector(vh, center, radius, color, toColor, startDegree, toDegree, 0, s_ClearColor32, 0, smoothness, - gradientType, isYAxis); - } - - public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, - float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f) - { - DrawSector(vh, center, radius, color, color, startDegree, toDegree, borderWidth, borderColor, smoothness); - } - - public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor, - float startDegree, float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f) - { - DrawSector(vh, center, radius, color, toColor, startDegree, toDegree, borderWidth, borderColor, 0, smoothness); - } - - /// <summary> - /// 绘制扇形(可带边框、有空白边距、3种类型渐变) - /// </summary> - /// <param name="vh"></param> - /// <param name="center">中心点</param> - /// <param name="radius">半径</param> - /// <param name="color">颜色</param> - /// <param name="toColor">渐变颜色</param> - /// <param name="startDegree">开始角度</param> - /// <param name="toDegree">结束角度</param> - /// <param name="borderWidth">边框宽度</param> - /// <param name="borderColor">边框颜色</param> - /// <param name="gap">边距</param> - /// <param name="smoothness">光滑度</param> - /// <param name="gradientType">渐变类型,0:向圆形渐变,1:水平或垂直渐变,2:开始角度向结束角度渐变</param> - /// <param name="isYAxis">水平渐变还是垂直渐变,gradientType为1时生效</param> - public static void DrawSector(VertexHelper vh, Vector3 center, float radius, Color32 color, Color32 toColor, - float startDegree, float toDegree, float borderWidth, Color32 borderColor, float gap, - float smoothness, int gradientType = 0, bool isYAxis = false) - { - if (radius == 0) return; - if (gap > 0 && Mathf.Abs(toDegree - startDegree) >= 360) gap = 0; - radius -= borderWidth; - smoothness = (smoothness < 0 ? 2f : smoothness); - int segments = (int) ((2 * Mathf.PI * radius) * (Mathf.Abs(toDegree - startDegree) / 360) / smoothness); - if (segments < 1) segments = 1; - float startAngle = startDegree * Mathf.Deg2Rad; - float toAngle = toDegree * Mathf.Deg2Rad; - float realStartAngle = startAngle; - float realToAngle = toAngle; - float halfAngle = (toAngle - startAngle) / 2; - float borderAngle = 0; - float spaceAngle = 0; - - var p2 = center + radius * UGLHelper.GetDire(startAngle); - var p3 = Vector3.zero; - var p4 = Vector3.zero; - var spaceCenter = center; - var realCenter = center; - var lastP4 = center; - var lastColor = color; - var needBorder = borderWidth != 0; - var needSpace = gap != 0; - var borderLineWidth = needSpace ? borderWidth : borderWidth / 2; - var lastPos = Vector3.zero; - var middleDire = UGLHelper.GetDire(startAngle + halfAngle); - if (needBorder || needSpace) - { - float spaceDiff = 0f; - float borderDiff = 0f; - if (needSpace) - { - spaceDiff = gap / Mathf.Sin(halfAngle); - spaceCenter = center + spaceDiff * middleDire; - realCenter = spaceCenter; - spaceAngle = 2 * Mathf.Asin(gap / (2 * radius)); - realStartAngle = startAngle + spaceAngle; - realToAngle = toAngle - spaceAngle; - if (realToAngle < realStartAngle) realToAngle = realStartAngle; - p2 = UGLHelper.GetPos(center, radius, realStartAngle); - } - if (needBorder) - { - borderDiff = borderLineWidth / Mathf.Sin(halfAngle); - realCenter += borderDiff * middleDire; - borderAngle = 2 * Mathf.Asin(borderLineWidth / (2 * radius)); - realStartAngle = realStartAngle + borderAngle; - realToAngle = realToAngle - borderAngle; - if (realToAngle < realStartAngle) - { - realToAngle = realStartAngle; - p2 = UGLHelper.GetPos(center, radius, realStartAngle); - } - else - { - var borderX1 = UGLHelper.GetPos(center, radius, realStartAngle); - DrawQuadrilateral(vh, realCenter, spaceCenter, p2, borderX1, borderColor); - p2 = borderX1; - - var borderX2 = UGLHelper.GetPos(center, radius, realToAngle); - var pEnd = UGLHelper.GetPos(center, radius, toAngle - spaceAngle); - DrawQuadrilateral(vh, realCenter, borderX2, pEnd, spaceCenter, borderColor); - } - } - } - float segmentAngle = (realToAngle - realStartAngle) / segments; - bool isLeft = startDegree >= 180; - for (int i = 0; i <= segments; i++) - { - float currAngle = realStartAngle + i * segmentAngle; - p3 = center + radius * UGLHelper.GetDire(currAngle); - if (gradientType == 1) - { - if (isYAxis) - { - p4 = new Vector3(p3.x, realCenter.y); - var dist = p4.x - realCenter.x; - var tcolor = Color32.Lerp(color, toColor, dist >= 0 ? - dist / radius : - Mathf.Min(radius + dist, radius) / radius); - if (isLeft && (i == segments || i == 0)) tcolor = toColor; - DrawQuadrilateral(vh, lastP4, p2, p3, p4, lastColor, tcolor); - lastP4 = p4; - lastColor = tcolor; - } - else - { - p4 = new Vector3(realCenter.x, p3.y); - var tcolor = Color32.Lerp(color, toColor, Mathf.Abs(p4.y - realCenter.y) / radius); - DrawQuadrilateral(vh, lastP4, p2, p3, p4, lastColor, tcolor); - lastP4 = p4; - lastColor = tcolor; - } - } - else if (gradientType == 2) - { - var tcolor = Color32.Lerp(color, toColor, i / segments); - DrawQuadrilateral(vh, realCenter, p2, p3, realCenter, lastColor, tcolor); - lastColor = tcolor; - } - else - { - AddVertToVertexHelper(vh, p3, realCenter, color, toColor, i > 0); - } - p2 = p3; - - } - if (needBorder || needSpace) - { - if (realToAngle > realStartAngle) - { - var borderX2 = center + radius * UGLHelper.GetDire(realToAngle); - DrawTriangle(vh, realCenter, p2, borderX2, toColor, color, color); - if (needBorder) - { - var realStartDegree = (realStartAngle - borderAngle) * Mathf.Rad2Deg; - var realToDegree = (realToAngle + borderAngle) * Mathf.Rad2Deg; - DrawDoughnut(vh, center, radius, radius + borderWidth, borderColor, s_ClearColor32, - realStartDegree, realToDegree, smoothness); - } - } - } - } - - public static void DrawRoundCap(VertexHelper vh, Vector3 center, float width, float radius, float angle, - bool clockwise, Color32 color, bool end) - { - var px = Mathf.Sin(angle * Mathf.Deg2Rad) * radius; - var py = Mathf.Cos(angle * Mathf.Deg2Rad) * radius; - var pos = new Vector3(px, py) + center; - if (end) - { - if (clockwise) - DrawSector(vh, pos, width, color, angle, angle + 180, 0, s_ClearColor32); - else - DrawSector(vh, pos, width, color, angle, angle - 180, 0, s_ClearColor32); - } - else - { - if (clockwise) - DrawSector(vh, pos, width, color, angle + 180, angle + 360, 0, s_ClearColor32); - else - DrawSector(vh, pos, width, color, angle - 180, angle - 360, 0, s_ClearColor32); - } - } - - public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius, - Color32 color, Color32 emptyColor, float smoothness = 2f) - { - DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, 0, 360, 0, - s_ClearColor32, 0, smoothness); - } - - public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius, - Color32 color, Color32 emptyColor, float startDegree, - float toDegree, float smoothness = 1f) - { - DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree, - 0, s_ClearColor32, 0, smoothness); - } - - public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius, - Color32 color, Color32 emptyColor, float startDegree, - float toDegree, float borderWidth, Color32 borderColor, float smoothness = 2f) - { - DrawDoughnut(vh, center, insideRadius, outsideRadius, color, color, emptyColor, startDegree, toDegree, - borderWidth, borderColor, 0, smoothness); - } - - public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius, - Color32 color, Color32 toColor, Color32 emptyColor, float smoothness = 2f) - { - DrawDoughnut(vh, center, insideRadius, outsideRadius, color, toColor, emptyColor, 0, 360, 0, - s_ClearColor32, 0, smoothness); - } - - public static void DrawDoughnut(VertexHelper vh, Vector3 center, float insideRadius, float outsideRadius, - Color32 color, Color32 toColor, Color32 emptyColor, float startDegree, float toDegree, float borderWidth, - Color32 borderColor, float gap, float smoothness, bool roundCap = false, bool clockwise = true) - { - if (toDegree - startDegree == 0) return; - if (gap > 0 && Mathf.Abs(toDegree - startDegree) >= 360) gap = 0; - if (insideRadius <= 0) - { - DrawSector(vh, center, outsideRadius, color, toColor, startDegree, toDegree, borderWidth, borderColor, - gap, smoothness); - return; - } - outsideRadius -= borderWidth; - insideRadius += borderWidth; - smoothness = smoothness < 0 ? 2f : smoothness; - Vector3 p1, p2, p3, p4, e1, e2; - var needBorder = borderWidth != 0; - var needSpace = gap != 0; - var diffAngle = Mathf.Abs(toDegree - startDegree) * Mathf.Deg2Rad; - - int segments = (int) ((2 * Mathf.PI * outsideRadius) * (diffAngle * Mathf.Rad2Deg / 360) / smoothness); - if (segments < 1) segments = 1; - float startAngle = startDegree * Mathf.Deg2Rad; - float toAngle = toDegree * Mathf.Deg2Rad; - - float realStartOutAngle = startAngle; - float realToOutAngle = toAngle; - float realStartInAngle = startAngle; - float realToInAngle = toAngle; - float halfAngle = (toAngle - startAngle) / 2; - float borderAngle = 0, borderInAngle = 0, borderHalfAngle = 0; - float spaceAngle = 0, spaceInAngle = 0, spaceHalfAngle = 0; - - var spaceCenter = center; - var realCenter = center; - var startDire = new Vector3(Mathf.Sin(startAngle), Mathf.Cos(startAngle)).normalized; - var toDire = new Vector3(Mathf.Sin(toAngle), Mathf.Cos(toAngle)).normalized; - var middleDire = new Vector3(Mathf.Sin(startAngle + halfAngle), Mathf.Cos(startAngle + halfAngle)).normalized; - p1 = center + insideRadius * startDire; - p2 = center + outsideRadius * startDire; - e1 = center + insideRadius * toDire; - e2 = center + outsideRadius * toDire; - if (roundCap) - { - var roundRadius = (outsideRadius - insideRadius) / 2; - var roundAngleRadius = insideRadius + roundRadius; - var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius); - if (diffAngle < 2 * roundAngle) - { - roundCap = false; - } - } - if (needBorder || needSpace) - { - if (needSpace) - { - var spaceDiff = gap / Mathf.Sin(halfAngle); - spaceCenter = center + Mathf.Abs(spaceDiff) * middleDire; - realCenter = spaceCenter; - spaceAngle = 2 * Mathf.Asin(gap / (2 * outsideRadius)); - spaceInAngle = 2 * Mathf.Asin(gap / (2 * insideRadius)); - spaceHalfAngle = 2 * Mathf.Asin(gap / (2 * (insideRadius + (outsideRadius - insideRadius) / 2))); - if (clockwise) - { - p1 = UGLHelper.GetPos(center, insideRadius, startAngle + spaceInAngle, false); - e1 = UGLHelper.GetPos(center, insideRadius, toAngle - spaceInAngle, false); - realStartOutAngle = startAngle + spaceAngle; - realToOutAngle = toAngle - spaceAngle; - realStartInAngle = startAngle + spaceInAngle; - realToInAngle = toAngle - spaceInAngle; - } - else - { - p1 = UGLHelper.GetPos(center, insideRadius, startAngle - spaceInAngle, false); - e1 = UGLHelper.GetPos(center, insideRadius, toAngle + spaceInAngle, false); - realStartOutAngle = startAngle - spaceAngle; - realToOutAngle = toAngle + spaceAngle; - realStartInAngle = startAngle - spaceInAngle; - realToOutAngle = toAngle + spaceInAngle; - } - p2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false); - e2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false); - } - if (needBorder) - { - var borderDiff = borderWidth / Mathf.Sin(halfAngle); - realCenter += Mathf.Abs(borderDiff) * middleDire; - borderAngle = 2 * Mathf.Asin(borderWidth / (2 * outsideRadius)); - borderInAngle = 2 * Mathf.Asin(borderWidth / (2 * insideRadius)); - borderHalfAngle = 2 * Mathf.Asin(borderWidth / (2 * (insideRadius + (outsideRadius - insideRadius) / 2))); - if (clockwise) - { - realStartOutAngle = realStartOutAngle + borderAngle; - realToOutAngle = realToOutAngle - borderAngle; - realStartInAngle = startAngle + spaceInAngle + borderInAngle; - realToInAngle = toAngle - spaceInAngle - borderInAngle; - var newp1 = UGLHelper.GetPos(center, insideRadius, startAngle + spaceInAngle + borderInAngle, false); - var newp2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false); - if (!roundCap) DrawQuadrilateral(vh, newp2, newp1, p1, p2, borderColor); - p1 = newp1; - p2 = newp2; - if (toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle) - { - var newe1 = UGLHelper.GetPos(center, insideRadius, toAngle - spaceInAngle - borderInAngle, false); - var newe2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false); - if (!roundCap) DrawQuadrilateral(vh, newe2, e2, e1, newe1, borderColor); - e1 = newe1; - e2 = newe2; - } - } - else - { - realStartOutAngle = realStartOutAngle - borderAngle; - realToOutAngle = realToOutAngle + borderAngle; - realStartInAngle = startAngle - spaceInAngle - borderInAngle; - realToInAngle = toAngle + spaceInAngle + borderInAngle; - var newp1 = UGLHelper.GetPos(center, insideRadius, startAngle - spaceInAngle - borderInAngle, false); - var newp2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle, false); - if (!roundCap) DrawQuadrilateral(vh, newp2, newp1, p1, p2, borderColor); - p1 = newp1; - p2 = newp2; - if (toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle) - { - var newe1 = UGLHelper.GetPos(center, insideRadius, toAngle + spaceInAngle + borderInAngle, false); - var newe2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle, false); - if (!roundCap) DrawQuadrilateral(vh, newe2, e2, e1, newe1, borderColor); - e1 = newe1; - e2 = newe2; - } - } - } - } - if (roundCap) - { - var roundRadius = (outsideRadius - insideRadius) / 2; - var roundAngleRadius = insideRadius + roundRadius; - var roundAngle = Mathf.Atan(roundRadius / roundAngleRadius); - if (clockwise) - { - realStartOutAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle; - realStartInAngle = startAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle; - } - else - { - realStartOutAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle; - realStartInAngle = startAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle; - } - var roundTotalDegree = realStartOutAngle * Mathf.Rad2Deg; - var roundCenter = center + roundAngleRadius * UGLHelper.GetDire(realStartOutAngle); - var sectorStartDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree; - var sectorToDegree = clockwise ? roundTotalDegree + 360 : roundTotalDegree + 180; - DrawSector(vh, roundCenter, roundRadius, color, sectorStartDegree, sectorToDegree, smoothness / 2); - if (needBorder) - { - DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor, - s_ClearColor32, sectorStartDegree, sectorToDegree, smoothness / 2); - } - p1 = UGLHelper.GetPos(center, insideRadius, realStartOutAngle); - p2 = UGLHelper.GetPos(center, outsideRadius, realStartOutAngle); - - if (clockwise) - { - realToOutAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle; - realToInAngle = toAngle - 2 * spaceHalfAngle - borderHalfAngle - roundAngle; - if (realToOutAngle < realStartOutAngle) realToOutAngle = realStartOutAngle; - } - else - { - realToOutAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle; - realToInAngle = toAngle + 2 * spaceHalfAngle + borderHalfAngle + roundAngle; - if (realToOutAngle > realStartOutAngle) realToOutAngle = realStartOutAngle; - } - roundTotalDegree = realToOutAngle * Mathf.Rad2Deg; - roundCenter = center + roundAngleRadius * UGLHelper.GetDire(realToOutAngle); - sectorStartDegree = clockwise ? roundTotalDegree : roundTotalDegree + 180; - sectorToDegree = clockwise ? roundTotalDegree + 180 : roundTotalDegree + 360; - DrawSector(vh, roundCenter, roundRadius, toColor, sectorStartDegree, sectorToDegree, smoothness / 2); - if (needBorder) - { - DrawDoughnut(vh, roundCenter, roundRadius, roundRadius + borderWidth, borderColor, - s_ClearColor32, sectorStartDegree, sectorToDegree, smoothness / 2); - } - e1 = UGLHelper.GetPos(center, insideRadius, realToOutAngle); - e2 = UGLHelper.GetPos(center, outsideRadius, realToOutAngle); - } - var segmentAngle = (realToInAngle - realStartInAngle) / segments; - var isGradient = !UGLHelper.IsValueEqualsColor(color, toColor); - for (int i = 0; i <= segments; i++) - { - float currAngle = realStartInAngle + i * segmentAngle; - p3 = new Vector3(center.x + outsideRadius * Mathf.Sin(currAngle), - center.y + outsideRadius * Mathf.Cos(currAngle)); - p4 = new Vector3(center.x + insideRadius * Mathf.Sin(currAngle), - center.y + insideRadius * Mathf.Cos(currAngle)); - if (isGradient) - { - var tcolor = Color32.Lerp(color, toColor, i * 1.0f / segments); - AddVertToVertexHelper(vh, p3, p4, tcolor, tcolor, i > 0); - } - else - { - AddVertToVertexHelper(vh, p3, p4, color, color, i > 0); - } - p1 = p4; - p2 = p3; - } - if (!UGLHelper.IsClearColor(emptyColor)) - { - for (int i = 0; i <= segments; i++) - { - float currAngle = realStartInAngle + i * segmentAngle; - p4 = new Vector3(center.x + insideRadius * Mathf.Sin(currAngle), - center.y + insideRadius * Mathf.Cos(currAngle)); - AddVertToVertexHelper(vh, center, p4, emptyColor, emptyColor, i > 0); - } - } - if (needBorder || needSpace || roundCap) - { - if (clockwise) - { - var isInAngleFixed = toAngle - spaceInAngle - 2 * borderInAngle > realStartOutAngle; - if (isInAngleFixed) DrawQuadrilateral(vh, p2, e2, e1, p1, color, toColor); - else DrawTriangle(vh, p2, e2, p1, color, color, toColor); - if (needBorder) - { - var realStartDegree = (realStartOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg; - var realToDegree = (realToOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg; - if (realToDegree < realStartOutAngle) realToDegree = realStartOutAngle; - var inStartDegree = roundCap ? realStartDegree : (startAngle + spaceInAngle) * Mathf.Rad2Deg; - var inToDegree = roundCap ? realToDegree : (toAngle - spaceInAngle) * Mathf.Rad2Deg; - if (inToDegree < inStartDegree) inToDegree = inStartDegree; - if (isInAngleFixed) DrawDoughnut(vh, center, insideRadius - borderWidth, insideRadius, borderColor, - s_ClearColor32, inStartDegree, inToDegree, smoothness); - DrawDoughnut(vh, center, outsideRadius, outsideRadius + borderWidth, borderColor, s_ClearColor32, - realStartDegree, realToDegree, smoothness); - } - } - else - { - var isInAngleFixed = toAngle + spaceInAngle + 2 * borderInAngle < realStartOutAngle; - if (isInAngleFixed) DrawQuadrilateral(vh, p2, e2, e1, p1, color, toColor); - else DrawTriangle(vh, p2, e2, p1, color, color, toColor); - if (needBorder) - { - var realStartDegree = (realStartOutAngle + (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg; - var realToDegree = (realToOutAngle - (roundCap ? 0 : borderAngle)) * Mathf.Rad2Deg; - var inStartDegree = roundCap ? realStartDegree : (startAngle - spaceInAngle) * Mathf.Rad2Deg; - var inToDegree = roundCap ? realToDegree : (toAngle + spaceInAngle) * Mathf.Rad2Deg; - if (inToDegree > inStartDegree) inToDegree = inStartDegree; - if (isInAngleFixed) - { - DrawDoughnut(vh, center, insideRadius - borderWidth, insideRadius, borderColor, - s_ClearColor32, inStartDegree, inToDegree, smoothness); - } - DrawDoughnut(vh, center, outsideRadius, outsideRadius + borderWidth, borderColor, - s_ClearColor32, realStartDegree, realToDegree, smoothness); - } - } - } - } - - /// <summary> - /// 画贝塞尔曲线 - /// </summary> - /// <param name="vh"></param> - /// <param name="sp">起始点</param> - /// <param name="ep">结束点</param> - /// <param name="cp1">控制点1</param> - /// <param name="cp2">控制点2</param> - /// <param name="lineWidth">曲线宽</param> - /// <param name="lineColor">曲线颜色</param> - public static void DrawCurves(VertexHelper vh, Vector3 sp, Vector3 ep, Vector3 cp1, Vector3 cp2, - float lineWidth, Color32 lineColor, float smoothness) - { - var dist = Vector3.Distance(sp, ep); - var segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness)); - UGLHelper.GetBezierList2(ref s_CurvesPosList, sp, ep, segment, cp1, cp2); - DrawCurvesInternal(vh, s_CurvesPosList, lineWidth, lineColor); - } - - public static void DrawCurves(VertexHelper vh, List<Vector3> points, float width, Color32 color, - float smoothness, float currProgress = float.PositiveInfinity, bool isYAxis = false) - { - for (int i = 0; i < points.Count - 1; i++) - { - var sp = points[i]; - var ep = points[i + 1]; - var lsp = i > 0 ? points[i - 1] : sp; - var nep = i < points.Count - 2 ? points[i + 2] : ep; - var smoothness2 = smoothness; - if (currProgress != float.PositiveInfinity) - { - if (isYAxis) - smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f; - else - smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f; - } - if (isYAxis) - UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness2); - else - UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2); - - DrawCurvesInternal(vh, s_CurvesPosList, width, color, currProgress, isYAxis); - } - } - - private static void DrawCurvesInternal(VertexHelper vh, List<Vector3> curvesPosList, float lineWidth, - Color32 lineColor, float currProgress = float.PositiveInfinity, bool isYAxis = false) - { - if (curvesPosList.Count > 1) - { - var start = curvesPosList[0]; - var to = Vector3.zero; - var dir = curvesPosList[1] - start; - var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth; - var startUp = start - diff; - var startDn = start + diff; - var toUp = Vector3.zero; - var toDn = Vector3.zero; - - var lastVertCount = vh.currentVertCount; - AddVertToVertexHelper(vh, startUp, startDn, lineColor, false); - for (int i = 1; i < curvesPosList.Count; i++) - { - to = curvesPosList[i]; - if (currProgress != float.PositiveInfinity) - { - if (isYAxis && to.y > currProgress) - break; - if (!isYAxis && to.x > currProgress) - break; - } - - diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth; - toUp = to - diff; - toDn = to + diff; - - AddVertToVertexHelper(vh, toUp, toDn, lineColor); - - startUp = toUp; - startDn = toDn; - start = to; - } - AddVertToVertexHelper(vh, toUp, toDn, lineColor); - } - } - - public static void DrawSvgPath(VertexHelper vh, string path) - { - SVG.DrawPath(vh, path); - } - - public static void DrawEllipse(VertexHelper vh, Vector3 center, float w, float h, Color32 color, float smoothness = 1) - { - DrawEllipse(vh, center, w, h, color, smoothness, 0, s_ClearColor32, 0, 360); - } - - public static void DrawEllipse(VertexHelper vh, Vector3 center, float w, float h, Color32 color, float smoothness, - float borderWidth, Color32 borderColor, - float startAngle, float endAngle) - { - startAngle = (startAngle + 360) % 360; - endAngle = (endAngle + 360) % 360; - if (endAngle < startAngle) - endAngle += 360; - if (endAngle <= startAngle) - return; - - var angle = startAngle; - var lp = Vector2.zero; - var fill = color.a != 0; - var border = borderWidth != 0 && borderColor.a != 0; - if (!fill && !border) - return; - - var startTriangleIndex = vh.currentVertCount; - if (fill) - { - vh.AddVert(center, color, Vector2.zero); - } - if (smoothness < 0.5f) - smoothness = 0.5f; - - var i = 0; - while (angle <= endAngle) - { - var rad = angle * Mathf.Deg2Rad; - var x = center.x + w * Mathf.Cos(rad); - var y = center.y + h * Mathf.Sin(rad); - var p1 = new Vector3(x, y); - vh.AddVert(p1, color, Vector2.zero); - if (border) - { - var dire = (p1 - center).normalized; - var diff = dire * borderWidth; - var p2 = p1 + diff; - vh.AddVert(p1, borderColor, Vector2.zero); - vh.AddVert(p2, borderColor, Vector2.zero); - - if (i > 0) - { - var index = startTriangleIndex + i * 3 + 2; - vh.AddTriangle(index - 3, index + 1, index - 2); - vh.AddTriangle(index - 3, index, index + 1); - if (fill) - vh.AddTriangle(startTriangleIndex, index - 1, index - 4); - } - } - else if (i > 0 && fill) - { - var index = startTriangleIndex + i; - vh.AddTriangle(startTriangleIndex, index + 1, index); - } - i++; - angle += smoothness; - } - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/UGL.cs.meta b/Assets/XCharts/Runtime/XUGL/UGL.cs.meta deleted file mode 100644 index 0ca349f..0000000 --- a/Assets/XCharts/Runtime/XUGL/UGL.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 463dc57c2fc1849379941a7facf8dc84 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/UGLExample.cs b/Assets/XCharts/Runtime/XUGL/UGLExample.cs deleted file mode 100644 index a245ec7..0000000 --- a/Assets/XCharts/Runtime/XUGL/UGLExample.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; -using UnityEngine.UI; - -namespace XUGL -{ - [ExecuteInEditMode] - public class UGLExample : MaskableGraphic - { - private float m_Width = 800; - private float m_Height = 800; - private Vector3 m_Center = Vector3.zero; - private Vector3 m_LeftTopPos = Vector3.zero; - private Color32 m_BackgroundColor = new Color32(224, 224, 224, 255); - private Color32 m_DrawColor = new Color32(255, 132, 142, 255); - private float[] m_BorderRadius = new float[] { 5, 5, 10, 10 }; - - protected override void Awake() - { - base.Awake(); - var rectTransform = GetComponent<RectTransform>(); - rectTransform.sizeDelta = new Vector2(500, 500); - rectTransform.anchorMin = new Vector2(0.5f, 0.5f); - rectTransform.anchorMax = new Vector2(0.5f, 0.5f); - rectTransform.pivot = new Vector2(0.5f, 0.5f); - m_Center = Vector3.zero; - m_LeftTopPos = new Vector3(-m_Width / 2, m_Height / 2); - } - - protected override void OnPopulateMesh(VertexHelper vh) - { - Vector3 sp, cp, ep; - vh.Clear(); - - //背景边框 - UGL.DrawSquare(vh, m_Center, m_Width / 2, m_BackgroundColor); - UGL.DrawBorder(vh, m_Center, m_Width, m_Height, 40, Color.green, Color.red, 0, m_BorderRadius, false, 1); - - //点 - UGL.DrawCricle(vh, m_LeftTopPos + new Vector3(20, -20), 10, m_DrawColor); - - //直线 - sp = new Vector3(m_LeftTopPos.x + 50, m_LeftTopPos.y - 20); - ep = new Vector3(m_LeftTopPos.x + 250, m_LeftTopPos.y - 20); - UGL.DrawLine(vh, sp, ep, 3, m_DrawColor); - - //3点确定的折线 - sp = new Vector3(m_LeftTopPos.x + 20, m_LeftTopPos.y - 100); - cp = new Vector3(m_LeftTopPos.x + 200, m_LeftTopPos.y - 40); - ep = new Vector3(m_LeftTopPos.x + 250, m_LeftTopPos.y - 80); - UGL.DrawLine(vh, sp, cp, ep, 5, m_DrawColor); - - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/UGLExample.cs.meta b/Assets/XCharts/Runtime/XUGL/UGLExample.cs.meta deleted file mode 100644 index e216aea..0000000 --- a/Assets/XCharts/Runtime/XUGL/UGLExample.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: e8a87ea5df031473da3eb5fb8f57e20a -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs b/Assets/XCharts/Runtime/XUGL/UGLHelper.cs deleted file mode 100644 index 9d17934..0000000 --- a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs +++ /dev/null @@ -1,389 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -namespace XUGL -{ - public static class UGLHelper - { - public static bool IsValueEqualsColor(Color32 color1, Color32 color2) - { - return color1.a == color2.a && - color1.b == color2.b && - color1.g == color2.g && - color1.r == color2.r; - } - - public static bool IsValueEqualsColor(Color color1, Color color2) - { - return color1.a == color2.a && - color1.b == color2.b && - color1.g == color2.g && - color1.r == color2.r; - } - - public static bool IsValueEqualsString(string str1, string str2) - { - if (str1 == null && str2 == null) - return true; - else if (str1 != null && str2 != null) - return str1.Equals(str2); - else return false; - } - - public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2) - { - return v1.x == v2.x && - v1.y == v2.y; - } - - public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2) - { - return v1.x == v2.x && - v1.y == v2.y && - v1.z == v2.z; - } - - public static bool IsValueEqualsVector3(Vector3 v1, Vector2 v2) - { - return v1.x == v2.x && - v1.y == v2.y; - } - - public static bool IsValueEqualsList<T>(List<T> list1, List<T> list2) - { - if (list1 == null || list2 == null) - return false; - - if (list1.Count != list2.Count) - return false; - - for (int i = 0; i < list1.Count; i++) - { - if (list1[i] == null && list2[i] == null) - { } - else - { - if (list1[i] != null) - { - if (!list1[i].Equals(list2[i])) - return false; - } - else - { - if (!list2[i].Equals(list1[i])) - return false; - } - } - } - return true; - } - - public static bool IsClearColor(Color32 color) - { - return color.a == 0 && - color.b == 0 && - color.g == 0 && - color.r == 0; - } - - public static bool IsClearColor(Color color) - { - return color.a == 0 && - color.b == 0 && - color.g == 0 && - color.r == 0; - } - - public static bool IsZeroVector(Vector3 pos) - { - return pos.x == 0 && - pos.y == 0 && - pos.z == 0; - } - - public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle) - { - Vector3 point = Quaternion.AngleAxis(angle, axis) * (position - center); - Vector3 resultVec3 = center + point; - return resultVec3; - } - - public static void GetBezierList(ref List<Vector3> posList, Vector3 sp, Vector3 ep, - Vector3 lsp, Vector3 nep, float smoothness = 2f, float k = 2.0f) - { - float dist = Mathf.Abs(sp.x - ep.x); - Vector3 cp1, cp2; - var dir = (ep - sp).normalized; - var diff = dist / k; - if (lsp == sp) - { - cp1 = sp + dist / k * dir * 1; - cp1.y = sp.y; - cp1 = sp; - } - else - { - cp1 = sp + (ep - lsp).normalized * diff; - } - if (nep == ep) cp2 = ep; - else cp2 = ep - (nep - sp).normalized * diff; - dist = Vector3.Distance(sp, ep); - int segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness)); - if (segment < 1) segment = (int) (dist / 0.5f); - if (segment < 4) segment = 4; - GetBezierList2(ref posList, sp, ep, segment, cp1, cp2); - if (posList.Count < 2) - { - posList.Clear(); - posList.Add(sp); - posList.Add(ep); - } - } - - public static void GetBezierListVertical(ref List<Vector3> posList, Vector3 sp, Vector3 ep, - float smoothness = 2f, float k = 2.0f) - { - Vector3 dir = (ep - sp).normalized; - float dist = Vector3.Distance(sp, ep); - Vector3 cp1 = sp + dist / k * dir * 1; - Vector3 cp2 = sp + dist / k * dir * (k - 1); - cp1.x = sp.x; - cp2.x = ep.x; - int segment = (int) (dist / (smoothness <= 0 ? 2f : smoothness)); - GetBezierList2(ref posList, sp, ep, segment, cp1, cp2); - if (posList.Count < 2) - { - posList.Clear(); - posList.Add(sp); - posList.Add(ep); - } - } - - public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp) - { - List<Vector3> list = new List<Vector3>(); - for (int i = 0; i < segment; i++) - { - list.Add(GetBezier(i / (float) segment, sp, cp, ep)); - } - list.Add(ep); - return list; - } - - public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, - int segment, Vector3 cp, Vector3 cp2) - { - posList.Clear(); - if (posList.Capacity < segment + 1) - { - posList.Capacity = segment + 1; - } - for (int i = 0; i < segment; i++) - { - posList.Add((GetBezier2(i / (float) segment, sp, cp, cp2, ep))); - } - posList.Add(ep); - } - - public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep) - { - Vector3 aa = sp + (cp - sp) * t; - Vector3 bb = cp + (ep - cp) * t; - return aa + (bb - aa) * t; - } - - public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep) - { - t = Mathf.Clamp01(t); - var oneMinusT = 1f - t; - return oneMinusT * oneMinusT * oneMinusT * sp + - 3f * oneMinusT * oneMinusT * t * p1 + - 3f * oneMinusT * t * t * p2 + - t * t * t * ep; - } - - public static Vector3 GetDire(float angle, bool isDegree = false) - { - angle = isDegree ? angle * Mathf.Deg2Rad : angle; - return new Vector3(Mathf.Sin(angle), Mathf.Cos(angle)); - } - - public static Vector3 GetVertialDire(Vector3 dire) - { - if (dire.x == 0) - return new Vector3(-1, 0, 0); - - if (dire.y == 0) - return new Vector3(0, -1, 0); - else - return new Vector3(-dire.y / dire.x, 1, 0).normalized; - } - - /// <summary> - /// 获得0-360的角度(12点钟方向为0度) - /// </summary> - /// <param name="from"></param> - /// <param name="to"></param> - /// <returns></returns> - public static float GetAngle360(Vector2 from, Vector2 to) - { - float angle; - - Vector3 cross = Vector3.Cross(from, to); - angle = Vector2.Angle(from, to); - angle = cross.z > 0 ? -angle : angle; - angle = (angle + 360) % 360; - return angle; - } - - public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false) - { - angle = isDegree ? angle * Mathf.Deg2Rad : angle; - return new Vector3(center.x + radius * Mathf.Sin(angle), - center.y + radius * Mathf.Cos(angle)); - } - - /// <summary> - /// 获得两直线的交点 - /// </summary> - /// <param name="p1">线段1起点</param> - /// <param name="p2">线段1终点</param> - /// <param name="p3">线段2起点</param> - /// <param name="p4">线段2终点</param> - /// <param name="intersection">相交点。当不想交时默认为 Vector3.zero </param> - /// <returns>相交则返回 true, 否则返回 false</returns> - public static bool GetIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, ref Vector3 intersection) - { - intersection = Vector3.zero; - - var d = (p2.x - p1.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p4.x - p3.x); - if (d == 0) - return false; - - var u = ((p3.x - p1.x) * (p4.y - p3.y) - (p3.y - p1.y) * (p4.x - p3.x)) / d; - var v = ((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / d; - if (u < 0 || u > 1 || v < 0 || v > 1) - return false; - - intersection.x = p1.x + u * (p2.x - p1.x); - intersection.y = p1.y + u * (p2.y - p1.y); - return true; - } - - /// <summary> - /// 三个点画线段所需要的六个关键点 - /// </summary> - /// <param name="lp">上一个点</param> - /// <param name="cp">当前点</param> - /// <param name="np">下一个点</param> - /// <param name="width">线段宽度</param> - /// <param name="ltp">上一个点的上角点</param> - /// <param name="lbp">上一个点的下角点</param> - /// <param name="ntp">下一个点的上角点</param> - /// <param name="nbp">下一个点的下角点</param> - /// <param name="itp">交汇点的上角点</param> - /// <param name="ibp">交汇点的下角点</param> - internal static void GetLinePoints(Vector3 lp, Vector3 cp, Vector3 np, float width, - ref Vector3 ltp, ref Vector3 lbp, - ref Vector3 ntp, ref Vector3 nbp, - ref Vector3 itp, ref Vector3 ibp, - ref Vector3 clp, ref Vector3 crp, - ref bool bitp, ref bool bibp, int debugIndex = 0) - { - var dir1 = (cp - lp).normalized; - var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * width; - ltp = lp - dir1v; - lbp = lp + dir1v; - if (debugIndex == 1 && cp == np) - { - ntp = np - dir1v; - nbp = np + dir1v; - clp = cp - dir1v; - crp = cp + dir1v; - return; - } - - var dir2 = (cp - np).normalized; - var dir2v = Vector3.Cross(dir2, Vector3.back).normalized * width; - ntp = np - dir2v; - nbp = np + dir2v; - clp = cp - dir2v; - crp = cp + dir2v; - - if (Vector3.Cross(dir1, dir2) == Vector3.zero && np != cp) - { - itp = ntp; - ibp = nbp; - return; - } - - var ldist = (Vector3.Distance(cp, lp) + 1) * dir1; - var rdist = (Vector3.Distance(cp, np) + 1) * dir2; - - bitp = true; - if (!UGLHelper.GetIntersection(ltp, ltp + ldist, ntp, ntp + rdist, ref itp)) - { - itp = cp - dir1v; - clp = cp - dir1v; - crp = cp - dir2v; - bitp = false; - } - bibp = true; - if (!UGLHelper.GetIntersection(lbp, lbp + ldist, nbp, nbp + rdist, ref ibp)) - { - ibp = cp + dir1v; - clp = cp + dir1v; - crp = cp + dir2v; - bibp = false; - } - if (bitp == false && bibp == false && cp == np) - { - ltp = cp - dir1v; - clp = cp + dir1v; - crp = cp + dir1v; - } - } - - public static bool IsPointInTriangle(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 check) - { - var dire1 = check - p1; - var dire2 = check - p2; - var dire3 = check - p3; - var c1 = dire1.x * dire2.y - dire1.y * dire2.x; - var c2 = dire2.x * dire3.y - dire2.y * dire3.x; - var c3 = dire3.x * dire1.y - dire3.y * dire1.x; - return c1 * c2 >= 0 && c1 * c3 >= 0; - } - - public static bool IsPointInPolygon(Vector3 p, List<Vector3> polyons) - { - if (polyons.Count == 0) return false; - var inside = false; - var j = polyons.Count - 1; - for (int i = 0; i < polyons.Count; j = i++) - { - var pi = polyons[i]; - var pj = polyons[j]; - if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) && - (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) - inside = !inside; - } - return inside; - } - public static bool IsPointInPolygon(Vector3 p, List<Vector2> polyons) - { - if (polyons.Count == 0) return false; - var inside = false; - var j = polyons.Count - 1; - for (int i = 0; i < polyons.Count; j = i++) - { - var pi = polyons[i]; - var pj = polyons[j]; - if (((pi.y <= p.y && p.y < pj.y) || (pj.y <= p.y && p.y < pi.y)) && - (p.x < (pj.x - pi.x) * (p.y - pi.y) / (pj.y - pi.y) + pi.x)) - inside = !inside; - } - return inside; - } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs.meta b/Assets/XCharts/Runtime/XUGL/UGLHelper.cs.meta deleted file mode 100644 index 2165db1..0000000 --- a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cc77f59a050d547caa3de82f4a9abd99 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/package.json b/Assets/XCharts/package.json deleted file mode 100644 index 5e21cef..0000000 --- a/Assets/XCharts/package.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "name": "com.monitor1394.xcharts", - "displayName": "XCharts", - "version": "3.0.1", - "date": "20220616", - "checkdate": "20220616", - "desc": "如果 XCharts 对您有帮助,希望您能在 Github 上点 Star 支持,非常感谢!", - "unity": "2018.3", - "description": "A charting and data visualization library for Unity.", - "keywords": [ - "chart", - "charts", - "graph", - "data-visualization" - ], - "category": "chart", - "repository": { - "type": "git", - "url": "git+https://github.com/XCharts-Team/XCharts.git" - }, - "author": "monitor1394", - "license": "MIT", - "bugs": { - "url": "https://github.com/XCharts-Team/XCharts/issues" - }, - "homepage": "https://github.com/XCharts-Team/XCharts" -} \ No newline at end of file diff --git a/Assets/XCharts/package.json.meta b/Assets/XCharts/package.json.meta deleted file mode 100644 index 9bc810b..0000000 --- a/Assets/XCharts/package.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: c4d5abd20b2304597ae3d0d57fd8986e -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Packages/manifest.json b/Packages/manifest.json index 7fc6dbe..4df3b2e 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,8 +1,9 @@ { "dependencies": { + "com.monitor1394.xcharts": "https://github.com/XCharts-Team/XCharts.git#3.0", "com.unity.collab-proxy": "1.9.0", "com.unity.ide.rider": "2.0.7", - "com.unity.ide.visualstudio": "2.0.11", + "com.unity.ide.visualstudio": "2.0.16", "com.unity.ide.vscode": "1.2.4", "com.unity.ml-agents": "2.0.1", "com.unity.test-framework": "1.1.29", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 8f73da3..80e0b37 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,5 +1,12 @@ { "dependencies": { + "com.monitor1394.xcharts": { + "version": "https://github.com/XCharts-Team/XCharts.git#3.0", + "depth": 0, + "source": "git", + "dependencies": {}, + "hash": "0e60a2633375d598adcf344730d6a971e6c590da" + }, "com.unity.barracuda": { "version": "2.0.0", "depth": 1, @@ -44,7 +51,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.11", + "version": "2.0.16", "depth": 0, "source": "registry", "dependencies": { diff --git a/UserSettings/EditorUserSettings.asset b/UserSettings/EditorUserSettings.asset index 7388c32..8308f19 100644 --- a/UserSettings/EditorUserSettings.asset +++ b/UserSettings/EditorUserSettings.asset @@ -12,6 +12,9 @@ EditorUserSettings: value: 22424703114646680e0b0227036c6c0417050c6439262f2434 flags: 0 RecentlyUsedScenePath-2: + value: 224247031146467d1f0b09041c3a7c111b120a2b630c233d22662e30e7ee312badc333e4e8742a323016f6 + flags: 0 + RecentlyUsedScenePath-3: value: 22424703114646680e0b0227036c761e3116152f623d28393930 flags: 0 vcSharedLogLevel:

- - - -