├── .gitattributes ├── .gitignore ├── LikeEchartsMap.sln ├── LikeEchartsMap ├── App.config ├── App.xaml ├── App.xaml.cs ├── LikeEchartsMap.csproj ├── MainWindow.xaml ├── MainWindow.xaml.cs └── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | -------------------------------------------------------------------------------- /LikeEchartsMap.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LikeEchartsMap", "LikeEchartsMap\LikeEchartsMap.csproj", "{3E8869CA-C1AE-40CB-9BCD-50DD9CE662DD}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3E8869CA-C1AE-40CB-9BCD-50DD9CE662DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3E8869CA-C1AE-40CB-9BCD-50DD9CE662DD}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3E8869CA-C1AE-40CB-9BCD-50DD9CE662DD}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3E8869CA-C1AE-40CB-9BCD-50DD9CE662DD}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LikeEchartsMap/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LikeEchartsMap/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /LikeEchartsMap/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace LikeEchartsMap 10 | { 11 | /// 12 | /// App.xaml 的交互逻辑 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LikeEchartsMap/LikeEchartsMap.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3E8869CA-C1AE-40CB-9BCD-50DD9CE662DD} 8 | WinExe 9 | Properties 10 | LikeEchartsMap 11 | LikeEchartsMap 12 | v4.5 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 4.0 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | MSBuild:Compile 54 | Designer 55 | 56 | 57 | MSBuild:Compile 58 | Designer 59 | 60 | 61 | App.xaml 62 | Code 63 | 64 | 65 | MainWindow.xaml 66 | Code 67 | 68 | 69 | 70 | 71 | Code 72 | 73 | 74 | True 75 | True 76 | Resources.resx 77 | 78 | 79 | True 80 | Settings.settings 81 | True 82 | 83 | 84 | ResXFileCodeGenerator 85 | Resources.Designer.cs 86 | 87 | 88 | SettingsSingleFileGenerator 89 | Settings.Designer.cs 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | -------------------------------------------------------------------------------- /LikeEchartsMap/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 18 | 19 | 27 | 28 | 45 | 46 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 86 | 93 | 106 | 113 | 115 | 120 | 127 | 134 | 141 | 153 | 169 | 174 | 179 | 186 | 193 | 200 | 206 | 214 | 225 | 230 | 235 | 239 | 249 | 266 | 292 | 295 | 301 | 310 | 324 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | -------------------------------------------------------------------------------- /LikeEchartsMap/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Animation; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Navigation; 15 | using System.Windows.Shapes; 16 | 17 | namespace LikeEchartsMap 18 | { 19 | /// 20 | /// MainWindow.xaml 的交互逻辑 21 | /// 22 | public partial class MainWindow : Window 23 | { 24 | public MainWindow() 25 | { 26 | InitializeComponent(); 27 | } 28 | 29 | //所有的动画 都在这个方法里 AddPointToStoryboard 30 | 31 | #region 成员变量 32 | /// 33 | /// 跑动的点里的Path的Data 34 | /// 35 | private string m_PointData; 36 | /// 37 | /// 点的运动速度 单位距离/秒 38 | /// 39 | private double m_Speed; 40 | /// 41 | /// 运动轨迹弧线的正弦角度 42 | /// 43 | private double m_Angle; 44 | /// 45 | /// 数据源 46 | /// 47 | private List m_Source; 48 | /// 49 | /// 故事版 50 | /// 51 | private Storyboard m_Sb = new Storyboard(); 52 | #endregion 53 | 54 | #region 事件 55 | #region loaded 56 | /// 57 | /// loaded 58 | /// 59 | private void Window_Loaded(object sender, RoutedEventArgs e) 60 | { 61 | //参数设置部分 62 | m_PointData = "M244.5,98.5 L273.25,93.75 C278.03113,96.916667 277.52785,100.08333 273.25,103.25 z"; 63 | m_Speed = 50; 64 | m_Angle = 15; 65 | 66 | MakeData(); 67 | InitRadioButton(); 68 | AddAnimation(m_Source[0]); 69 | } 70 | #endregion 71 | #region RadioButton点击 72 | /// 73 | /// RadioButton点击 74 | /// 75 | void rbtn_Click(object sender, RoutedEventArgs e) 76 | { 77 | RadioButton rbtn = (RadioButton)sender; 78 | if (rbtn.IsChecked == true) 79 | { 80 | foreach (MapItem item in m_Source) 81 | { 82 | if ((string)rbtn.Content == item.From.ToString()) 83 | { 84 | AddAnimation(item); 85 | return; 86 | } 87 | } 88 | } 89 | } 90 | #endregion 91 | #endregion 92 | 93 | #region 方法 94 | #region 做数据 95 | /// 96 | /// 做数据 97 | /// 98 | private void MakeData() 99 | { 100 | Random rd = new Random(); 101 | List list = new List(); 102 | List toList = new List(); 103 | toList.Add(new MapToItem() { To = ProvincialCapital.成都, Diameter = rd.Next(10, 51) }); 104 | toList.Add(new MapToItem() { To = ProvincialCapital.西宁, Diameter = rd.Next(10, 51) }); 105 | toList.Add(new MapToItem() { To = ProvincialCapital.哈尔滨, Diameter = rd.Next(10, 51) }); 106 | toList.Add(new MapToItem() { To = ProvincialCapital.海口, Diameter = rd.Next(10, 51), Tip = "美丽的大海" }); 107 | toList.Add(new MapToItem() { To = ProvincialCapital.呼和浩特, Diameter = rd.Next(10, 51) }); 108 | toList.Add(new MapToItem() { To = ProvincialCapital.重庆, Diameter = 50, Tip = "山鸡大神在这" }); 109 | toList.Add(new MapToItem() { To = ProvincialCapital.台北, Diameter = rd.Next(10, 51) }); 110 | toList.Add(new MapToItem() { To = ProvincialCapital.乌鲁木齐, Diameter = rd.Next(10, 51) }); 111 | toList.Add(new MapToItem() { To = ProvincialCapital.广州, Diameter = rd.Next(10, 51) }); 112 | toList.Add(new MapToItem() { To = ProvincialCapital.上海, Diameter = 50, Tip = "雷叔的地盘!" }); 113 | list.Add(new MapItem() { From = ProvincialCapital.北京, To = toList }); 114 | list.Add(new MapItem() { From = ProvincialCapital.西安, To = toList }); 115 | list.Add(new MapItem() { From = ProvincialCapital.拉萨, To = toList }); 116 | m_Source = list; 117 | } 118 | #endregion 119 | #region 加载菜单RadioButton 120 | /// 121 | /// 加载RadioButton 122 | /// 123 | private void InitRadioButton() 124 | { 125 | Random rd = new Random(); 126 | for (int i = 0; i < m_Source.Count; i++) 127 | { 128 | byte r = (byte)rd.Next(0, 256); 129 | byte g = (byte)rd.Next(0, 256); 130 | byte b = (byte)rd.Next(0, 256); 131 | RadioButton rbtn = new RadioButton(); 132 | rbtn.Content = m_Source[i].From.ToString(); 133 | rbtn.Margin = new Thickness(0, 20, 0, 0); 134 | rbtn.Background = new SolidColorBrush(Color.FromArgb(200, r, g, b)); 135 | rbtn.BorderBrush = new SolidColorBrush(Color.FromArgb(255, r, g, b)); 136 | if (i == 0) 137 | rbtn.IsChecked = true; 138 | else 139 | rbtn.IsChecked = false; 140 | rbtn.Click += rbtn_Click; 141 | spnl_Radio.Children.Add(rbtn); 142 | } 143 | } 144 | #endregion 145 | #region 添加控件和动画到容器 146 | /// 147 | /// 添加控件和动画到容器 148 | /// 149 | /// 数据项 150 | private void AddAnimation(MapItem item) 151 | { 152 | grid_Animation.Children.Clear(); 153 | m_Sb.Children.Clear(); 154 | Random rd = new Random(); 155 | foreach (MapToItem toItem in item.To) 156 | { 157 | if (item.From == toItem.To) 158 | continue; 159 | 160 | //颜色 161 | byte[] rgb = new byte[] { (byte)rd.Next(0, 255), (byte)rd.Next(0, 255), (byte)rd.Next(0, 255) }; 162 | 163 | //运动轨迹 164 | double l = 0; 165 | Path particlePath = GetParticlePath(item.From, toItem, rgb, out l); 166 | grid_Animation.Children.Add(particlePath); 167 | // 跑动的点 168 | Grid grid = GetRunPoint(rgb); 169 | //到达城市的圆 170 | Ellipse ell = GetToEllipse(toItem, rgb); 171 | AddPointToStoryboard(grid, ell, m_Sb, particlePath, l, item.From, toItem); 172 | grid_Animation.Children.Add(grid); 173 | grid_Animation.Children.Add(ell); 174 | 175 | m_Sb.Begin(this); 176 | } 177 | } 178 | #endregion 179 | #region 获取省会,直辖市,特别行政区的坐标 180 | /// 181 | /// 获取省会,直辖市,特别行政区的坐标 182 | /// 183 | /// 城市 184 | /// Point(Left,Top) 185 | private Point GetProvincialCapitalPoint(ProvincialCapital city) 186 | { 187 | Point point = new Point(0, 0); 188 | switch (city) 189 | { 190 | case ProvincialCapital.北京: 191 | point.X = 625.71145; 192 | point.Y = 265.20515; 193 | break; 194 | case ProvincialCapital.天津: 195 | point.X = 646.648895; 196 | point.Y = 277.719215; 197 | break; 198 | case ProvincialCapital.上海: 199 | point.X = 730.844; 200 | point.Y = 425.208; 201 | break; 202 | case ProvincialCapital.重庆: 203 | point.X = 487.123; 204 | point.Y = 469.796; 205 | break; 206 | case ProvincialCapital.石家庄: 207 | point.X = 605.527; 208 | point.Y = 300.853; 209 | break; 210 | case ProvincialCapital.太原: 211 | point.X = 575.685; 212 | point.Y = 310.961; 213 | break; 214 | case ProvincialCapital.沈阳: 215 | point.X = 725.375; 216 | point.Y = 214.217; 217 | break; 218 | case ProvincialCapital.长春: 219 | point.X = 742.702; 220 | point.Y = 173.786; 221 | break; 222 | case ProvincialCapital.哈尔滨: 223 | point.X = 751.847; 224 | point.Y = 137.687; 225 | break; 226 | case ProvincialCapital.南京: 227 | point.X = 691.682; 228 | point.Y = 418.295; 229 | break; 230 | case ProvincialCapital.杭州: 231 | point.X = 706.603; 232 | point.Y = 446.211; 233 | break; 234 | case ProvincialCapital.合肥: 235 | point.X = 661.841; 236 | point.Y = 418.295; 237 | break; 238 | case ProvincialCapital.福州: 239 | point.X = 706.603; 240 | point.Y = 528.516; 241 | break; 242 | case ProvincialCapital.南昌: 243 | point.X = 646.439; 244 | point.Y = 486.16; 245 | break; 246 | case ProvincialCapital.济南: 247 | point.X = 648.845; 248 | point.Y = 327.807; 249 | break; 250 | case ProvincialCapital.郑州: 251 | point.X = 596.382; 252 | point.Y = 371.126; 253 | break; 254 | case ProvincialCapital.武汉: 255 | point.X = 617.078; 256 | point.Y = 451.506; 257 | break; 258 | case ProvincialCapital.长沙: 259 | point.X = 593.975; 260 | point.Y = 497.231; 261 | break; 262 | case ProvincialCapital.广州: 263 | point.X = 611.303; 264 | point.Y = 592.531; 265 | break; 266 | case ProvincialCapital.海口: 267 | point.X = 553.545; 268 | point.Y = 663.766; 269 | break; 270 | case ProvincialCapital.成都: 271 | point.X = 445.73; 272 | point.Y = 453.912; 273 | break; 274 | case ProvincialCapital.贵阳: 275 | point.X = 492.417; 276 | point.Y = 533.811; 277 | break; 278 | case ProvincialCapital.昆明: 279 | point.X = 420.22; 280 | point.Y = 563.171; 281 | break; 282 | case ProvincialCapital.西安: 283 | point.X = 522.259; 284 | point.Y = 384.121; 285 | break; 286 | case ProvincialCapital.兰州: 287 | point.X = 442.842; 288 | point.Y = 354.28; 289 | break; 290 | case ProvincialCapital.西宁: 291 | point.X = 408.668; 292 | point.Y = 340.321; 293 | break; 294 | case ProvincialCapital.拉萨: 295 | point.X = 235.394; 296 | point.Y = 452.949; 297 | break; 298 | case ProvincialCapital.南宁: 299 | point.X = 520.815; 300 | point.Y = 605.046; 301 | break; 302 | case ProvincialCapital.呼和浩特: 303 | point.X = 557.877; 304 | point.Y = 255.128; 305 | break; 306 | case ProvincialCapital.银川: 307 | point.X = 479.422; 308 | point.Y = 299.891; 309 | break; 310 | case ProvincialCapital.乌鲁木齐: 311 | point.X = 220.474; 312 | point.Y = 179.562; 313 | break; 314 | case ProvincialCapital.香港: 315 | point.X = 623.817; 316 | point.Y = 611.784; 317 | break; 318 | case ProvincialCapital.澳门: 319 | point.X = 600.714; 320 | point.Y = 615.634; 321 | break; 322 | case ProvincialCapital.台北: 323 | point.X = 747.515; 324 | point.Y = 545.844; 325 | break; 326 | } 327 | return point; 328 | } 329 | #endregion 330 | #region 获取运动轨迹 331 | /// 332 | /// 获取运动轨迹 333 | /// 334 | /// 来自 335 | /// 去 336 | /// 颜色:r,g,b 337 | /// 两点间的直线距离 338 | /// Path 339 | private Path GetParticlePath(ProvincialCapital from, MapToItem toItem, byte[] rgb, out double l) 340 | { 341 | Point startPoint = GetProvincialCapitalPoint(from); 342 | Point endPoint = GetProvincialCapitalPoint(toItem.To); 343 | 344 | Path path = new Path(); 345 | Style style = (Style)FindResource("ParticlePathStyle"); 346 | path.Style = style; 347 | PathGeometry pg = new PathGeometry(); 348 | PathFigure pf = new PathFigure(); 349 | pf.StartPoint = startPoint; 350 | ArcSegment arc = new ArcSegment(); 351 | arc.SweepDirection = SweepDirection.Clockwise;//顺时针弧 352 | arc.Point = endPoint; 353 | //半径 正弦定理a/sinA=2r r=a/2sinA 其中a指的是两个城市点之间的距离 角A指a边的对角 354 | double sinA = Math.Sin(Math.PI * m_Angle / 180.0); 355 | //计算距离 勾股定理 356 | double x = startPoint.X - endPoint.X; 357 | double y = startPoint.Y - endPoint.Y; 358 | double aa = x * x + y * y; 359 | l = Math.Sqrt(aa); 360 | double r = l / (sinA * 2); 361 | arc.Size = new Size(r, r); 362 | pf.Segments.Add(arc); 363 | pg.Figures.Add(pf); 364 | path.Data = pg; 365 | path.Stroke = new SolidColorBrush(Color.FromArgb(255, rgb[0], rgb[1], rgb[2])); 366 | path.Stretch = Stretch.None; 367 | path.ToolTip = string.Format("{0}=>{1}", from.ToString(), toItem.To.ToString()); 368 | 369 | return path; 370 | } 371 | #endregion 372 | #region 获取跑动的点 373 | /// 374 | /// 获取跑动的点 375 | /// 376 | /// 颜色:r,g,b 377 | /// Grid 378 | private Grid GetRunPoint(byte[] rgb) 379 | { 380 | //一个Grid里包含一个椭圆 一个Path 椭圆做阴影 381 | //Grid 382 | Grid grid = new Grid(); 383 | grid.IsHitTestVisible = false;//不参与命中测试 384 | grid.HorizontalAlignment = HorizontalAlignment.Left; 385 | grid.VerticalAlignment = VerticalAlignment.Top; 386 | grid.Width = 40; 387 | grid.Height = 15; 388 | grid.RenderTransformOrigin = new Point(0.5, 0.5); 389 | //Ellipse 390 | Ellipse ell = new Ellipse(); 391 | ell.Width = 40; 392 | ell.Height = 15; 393 | ell.Fill = new SolidColorBrush(Color.FromArgb(255, rgb[0], rgb[1], rgb[2])); 394 | RadialGradientBrush rgbrush = new RadialGradientBrush(); 395 | rgbrush.GradientOrigin = new Point(0.8, 0.5); 396 | rgbrush.GradientStops.Add(new GradientStop(Color.FromArgb(255, 0, 0, 0), 0)); 397 | rgbrush.GradientStops.Add(new GradientStop(Color.FromArgb(22, 0, 0, 0), 1)); 398 | ell.OpacityMask = rgbrush; 399 | grid.Children.Add(ell); 400 | //Path 401 | Path path = new Path(); 402 | path.Data = Geometry.Parse(m_PointData); 403 | path.Width = 30; 404 | path.Height = 4; 405 | LinearGradientBrush lgb = new LinearGradientBrush(); 406 | lgb.StartPoint = new Point(0, 0); 407 | lgb.EndPoint = new Point(1, 0); 408 | lgb.GradientStops.Add(new GradientStop(Color.FromArgb(88, rgb[0], rgb[1], rgb[2]), 0)); 409 | lgb.GradientStops.Add(new GradientStop(Color.FromArgb(255, 255, 255, 255), 1)); 410 | path.Fill = lgb; 411 | path.Stretch = Stretch.Fill; 412 | grid.Children.Add(path); 413 | return grid; 414 | } 415 | #endregion 416 | #region 获取到达城市的圆 417 | /// 418 | /// 获取到达城市的圆 419 | /// 420 | /// 数据项 421 | /// 颜色 422 | /// Ellipse 423 | private Ellipse GetToEllipse(MapToItem toItem, byte[] rgb) 424 | { 425 | Ellipse ell = new Ellipse(); 426 | ell.HorizontalAlignment = HorizontalAlignment.Left; 427 | ell.VerticalAlignment = VerticalAlignment.Top; 428 | ell.Width = toItem.Diameter; 429 | ell.Height = toItem.Diameter; 430 | ell.Fill = new SolidColorBrush(Color.FromArgb(255, rgb[0], rgb[1], rgb[2])); 431 | Point toPos = GetProvincialCapitalPoint(toItem.To); 432 | TranslateTransform ttf = new TranslateTransform(toPos.X - ell.Width / 2, toPos.Y - ell.Height / 2);//定位到城市所在的点 433 | ell.RenderTransform = ttf; 434 | ell.ToolTip = string.Format("{0} {1}", toItem.To.ToString(), toItem.Tip); 435 | ell.Opacity = 0; 436 | return ell; 437 | } 438 | #endregion 439 | #region 将点加入到动画故事版 440 | /// 441 | /// 将点加入到动画故事版 442 | /// 443 | /// 运动的点 444 | /// 达到城市的圆 445 | /// 故事版 446 | /// 运动轨迹 447 | /// 运动轨迹的直线距离 448 | /// 来自 449 | /// 去 450 | private void AddPointToStoryboard(Grid runPoint, Ellipse toEll, Storyboard sb, Path particlePath, double l, ProvincialCapital from, MapToItem toItem) 451 | { 452 | double pointTime = l / m_Speed;//点运动所需的时间 453 | double particleTime = pointTime / 2;//轨迹呈现所需时间(跑的比点快两倍) 454 | 455 | #region 运动的点 456 | TransformGroup tfg = new TransformGroup(); 457 | MatrixTransform mtf = new MatrixTransform(); 458 | tfg.Children.Add(mtf); 459 | TranslateTransform ttf = new TranslateTransform(-runPoint.Width / 2, -runPoint.Height / 2);//纠正最上角沿path运动到中心沿path运动 460 | tfg.Children.Add(ttf); 461 | runPoint.RenderTransform = tfg; 462 | 463 | MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath(); 464 | maup.PathGeometry = particlePath.Data.GetFlattenedPathGeometry(); 465 | maup.Duration = new Duration(TimeSpan.FromSeconds(pointTime)); 466 | maup.RepeatBehavior = RepeatBehavior.Forever; 467 | maup.AutoReverse = false; 468 | maup.IsOffsetCumulative = false; 469 | maup.DoesRotateWithTangent = true; 470 | Storyboard.SetTarget(maup, runPoint); 471 | Storyboard.SetTargetProperty(maup, new PropertyPath("(Grid.RenderTransform).Children[0].(MatrixTransform.Matrix)")); 472 | sb.Children.Add(maup); 473 | #endregion 474 | 475 | #region 达到城市的圆 476 | //轨迹到达圆时 圆呈现 477 | DoubleAnimation ellda = new DoubleAnimation(); 478 | ellda.From = 0.2;//此处值设置0-1会有不同的呈现效果 479 | ellda.To = 1; 480 | ellda.Duration = new Duration(TimeSpan.FromSeconds(particleTime)); 481 | ellda.BeginTime = TimeSpan.FromSeconds(particleTime);//推迟动画开始时间 等轨迹连接到圆时 开始播放圆的呈现动画 482 | ellda.FillBehavior = FillBehavior.HoldEnd; 483 | Storyboard.SetTarget(ellda, toEll); 484 | Storyboard.SetTargetProperty(ellda, new PropertyPath(Ellipse.OpacityProperty)); 485 | sb.Children.Add(ellda); 486 | //圆呈放射状 487 | RadialGradientBrush rgBrush = new RadialGradientBrush(); 488 | GradientStop gStop0 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0); 489 | //此为控制点 color的a值设为0 off值走0-1 透明部分向外放射 初始设为255是为了初始化效果 开始不呈放射状 等跑动的点运动到城市的圆后 color的a值才设为0开始呈现放射动画 490 | GradientStop gStopT = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0); 491 | GradientStop gStop1 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 1); 492 | rgBrush.GradientStops.Add(gStop0); 493 | rgBrush.GradientStops.Add(gStopT); 494 | rgBrush.GradientStops.Add(gStop1); 495 | toEll.OpacityMask = rgBrush; 496 | //跑动的点达到城市的圆时 控制点由不透明变为透明 color的a值设为0 动画时间为0 497 | ColorAnimation ca = new ColorAnimation(); 498 | ca.To = Color.FromArgb(0, 0, 0, 0); 499 | ca.Duration = new Duration(TimeSpan.FromSeconds(0)); 500 | ca.BeginTime = TimeSpan.FromSeconds(pointTime); 501 | ca.FillBehavior = FillBehavior.HoldEnd; 502 | Storyboard.SetTarget(ca, toEll); 503 | Storyboard.SetTargetProperty(ca, new PropertyPath("(Ellipse.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Color)")); 504 | sb.Children.Add(ca); 505 | //点达到城市的圆时 呈现放射状动画 控制点的off值走0-1 透明部分向外放射 506 | DoubleAnimation eda = new DoubleAnimation(); 507 | eda.To = 1; 508 | eda.Duration = new Duration(TimeSpan.FromSeconds(2)); 509 | eda.RepeatBehavior = RepeatBehavior.Forever; 510 | eda.BeginTime = TimeSpan.FromSeconds(particleTime); 511 | Storyboard.SetTarget(eda, toEll); 512 | Storyboard.SetTargetProperty(eda, new PropertyPath("(Ellipse.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Offset)")); 513 | sb.Children.Add(eda); 514 | #endregion 515 | 516 | #region 运动轨迹 517 | //找到渐变的起点和终点 518 | Point startPoint = GetProvincialCapitalPoint(from); 519 | Point endPoint = GetProvincialCapitalPoint(toItem.To); 520 | Point start = new Point(0, 0); 521 | Point end = new Point(1, 1); 522 | if (startPoint.X > endPoint.X) 523 | { 524 | start.X = 1; 525 | end.X = 0; 526 | } 527 | if (startPoint.Y > endPoint.Y) 528 | { 529 | start.Y = 1; 530 | end.Y = 0; 531 | } 532 | LinearGradientBrush lgBrush = new LinearGradientBrush(); 533 | lgBrush.StartPoint = start; 534 | lgBrush.EndPoint = end; 535 | GradientStop lgStop0 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0); 536 | GradientStop lgStop1 = new GradientStop(Color.FromArgb(0, 0, 0, 0), 0); 537 | lgBrush.GradientStops.Add(lgStop0); 538 | lgBrush.GradientStops.Add(lgStop1); 539 | particlePath.OpacityMask = lgBrush; 540 | //运动轨迹呈现 541 | DoubleAnimation pda0 = new DoubleAnimation(); 542 | pda0.To = 1; 543 | pda0.Duration = new Duration(TimeSpan.FromSeconds(particleTime)); 544 | pda0.FillBehavior = FillBehavior.HoldEnd; 545 | Storyboard.SetTarget(pda0, particlePath); 546 | Storyboard.SetTargetProperty(pda0, new PropertyPath("(Path.OpacityMask).(GradientBrush.GradientStops)[0].(GradientStop.Offset)")); 547 | sb.Children.Add(pda0); 548 | DoubleAnimation pda1 = new DoubleAnimation(); 549 | //pda1.From = 0.5; //此处解开注释 值设为0-1 会有不同的轨迹呈现效果 550 | pda1.To = 1; 551 | pda1.Duration = new Duration(TimeSpan.FromSeconds(particleTime)); 552 | pda1.FillBehavior = FillBehavior.HoldEnd; 553 | Storyboard.SetTarget(pda1, particlePath); 554 | Storyboard.SetTargetProperty(pda1, new PropertyPath("(Path.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Offset)")); 555 | sb.Children.Add(pda1); 556 | #endregion 557 | } 558 | #endregion 559 | #endregion 560 | } 561 | /// 562 | /// 省会,直辖市,特别行政区 563 | /// 564 | public enum ProvincialCapital 565 | { 566 | 北京, 567 | 天津, 568 | 上海, 569 | 重庆, 570 | 石家庄, 571 | 太原, 572 | 沈阳, 573 | 长春, 574 | 哈尔滨, 575 | 南京, 576 | 杭州, 577 | 合肥, 578 | 福州, 579 | 南昌, 580 | 济南, 581 | 郑州, 582 | 武汉, 583 | 长沙, 584 | 广州, 585 | 海口, 586 | 成都, 587 | 贵阳, 588 | 昆明, 589 | 西安, 590 | 兰州, 591 | 西宁, 592 | 拉萨, 593 | 南宁, 594 | 呼和浩特, 595 | 银川, 596 | 乌鲁木齐, 597 | 香港, 598 | 澳门, 599 | 台北 600 | } 601 | /// 602 | /// 地图数据项 603 | /// 604 | public class MapItem 605 | { 606 | /// 607 | /// 出发城市 608 | /// 609 | public ProvincialCapital From { get; set; } 610 | /// 611 | /// 到达城市 612 | /// 613 | public List To { get; set; } 614 | } 615 | /// 616 | /// 地图到达城市数据项 617 | /// 618 | public class MapToItem 619 | { 620 | /// 621 | /// 到达城市 622 | /// 623 | public ProvincialCapital To { get; set; } 624 | /// 625 | /// 到达城市圆点的直径 626 | /// 627 | public double Diameter { get; set; } 628 | /// 629 | /// 提示的值 630 | /// 631 | public string Tip { get; set; } 632 | } 633 | } 634 | -------------------------------------------------------------------------------- /LikeEchartsMap/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // 有关程序集的常规信息通过以下 8 | // 特性集控制。更改这些特性值可修改 9 | // 与程序集关联的信息。 10 | [assembly: AssemblyTitle("LikeEchartsMap")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("LikeEchartsMap")] 15 | [assembly: AssemblyCopyright("Copyright © 2016")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // 将 ComVisible 设置为 false 使此程序集中的类型 20 | // 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, 21 | // 则将该类型上的 ComVisible 特性设置为 true。 22 | [assembly: ComVisible(false)] 23 | 24 | //若要开始生成可本地化的应用程序,请在 25 | // 中的 .csproj 文件中 26 | //设置 CultureYouAreCodingWith。 例如,如果您在源文件中 27 | //使用的是美国英语,请将 设置为 en-US。 然后取消 28 | //对以下 NeutralResourceLanguage 特性的注释。 更新 29 | //以下行中的“en-US”以匹配项目文件中的 UICulture 设置。 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //主题特定资源词典所处位置 36 | //(在页面或应用程序资源词典中 37 | // 未找到某个资源的情况下使用) 38 | ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 39 | //(在页面、应用程序或任何主题特定资源词典中 40 | // 未找到某个资源的情况下使用) 41 | )] 42 | 43 | 44 | // 程序集的版本信息由下面四个值组成: 45 | // 46 | // 主版本 47 | // 次版本 48 | // 生成号 49 | // 修订号 50 | // 51 | // 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, 52 | // 方法是按如下所示使用“*”: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /LikeEchartsMap/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本: 4.0.30319.34209 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace LikeEchartsMap.Properties 12 | { 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// 返回此类使用的、缓存的 ResourceManager 实例。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LikeEchartsMap.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 为所有资源查找重写当前线程的 CurrentUICulture 属性, 56 | /// 方法是使用此强类型资源类。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /LikeEchartsMap/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /LikeEchartsMap/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace LikeEchartsMap.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /LikeEchartsMap/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 博客地址:http://www.cnblogs.com/tsliwei/p/5616381.html 2 | --------------------------------------------------------------------------------