vue中使用raphael.js实现地图绘制

一、效果图

二、在vue中引入raphael.js

npm i raphael -S

三、封装一个名为StreetMap的组件,代码如下

  1 <template>
  2   <div>
  3     <div id='streetMap'>
  4       <div class="tips" v-show="tipsShow" :style="tipsStyle">
  5         <span v-html="tipsContent"></span>
  6       </div>
  7     </div>
  8   </div>
  9 </template>
 10 
 11 <script>
 12 import Raphael from 'raphael'
 13 export default {
 14   name: 'StreetMap',
 15   props: {
 16     // 格式:{'街道的拼音':数量}
 17     mapData: {
 18       type: Object,
 19       required: true
 20     },
 21      {
 22       type: String,
 23       default: '100%'
 24     },
 25     height: {
 26       type: String,
 27       default: '100%'
 28     }
 29   },
 30   data () {
 31     return {
 32       district: [],
 33       R: null, // Raphael对象
 34       // 设置每一个街道svg图片的属性
 35       pathAttr: {
 36         'fill': '#97d6f5', // 区地图颜色渐变色
 37         'stroke': '#eee', // 区地图描边颜色
 38         'stroke-width': 1, // 区地图描边宽度
 39         'stroke-linejoin': 'round', // 画笔转折处连接点的画风
 40         'cursor': 'pointer' // 鼠标经过svg图片的时候,鼠标样式
 41       },
 42       // 街道名称字体的属性
 43       textAttr: {
 44         'fill': '#000',
 45         'font-size': '20px',
 46         'cursor': 'pointer'
 47       },
 48       tipsShow: false, // 用于控制提示信息是否显示
 49       tipsContent: '', // 提示的信息内容
 50       leftPosition: 0, // 鼠标在svg图片上滑动过的OffsetX
 51       topPosition: 0 // 鼠标在svg图片上滑动过的OffsetY
 52     }
 53   },
 54   computed: {
 55     tipsStyle () {
 56       return {
 57         left: `${this.leftPosition}px`,
 58         top: `${this.topPosition}px`
 59       }
 60     }
 61   },
 62   mounted () {
 63     // 设置整体svg图片的高宽
 64     this.R = Raphael('streetMap', 408, 262)
 65     // 设置svg的视图
 66     this.R.setViewBox(0, 0, 600, 500)
 67 
 68     // 调用绘制地图方法
 69     this.paintMap(this.R)
 70     for (let state in this.district) {
 71       // 获取每一个svg路径的颜色
 72       this.district[state]['path'].color = Raphael.getColor(0.9)
 73       // 处理每一个svg路径的呈现的文字和事件
 74       this.processPath(this.district[state]['path'], state)
 75     }
 76   },
 77   beforeDestroy () {
 78   },
 79   methods: {
 80     paintMap (R) {
 81       this.district.fucheng = {
 82         name: '福城',
 83         path: R.path('M180 228L174 221L170 218L169 216L176 205L177 202L175 198L173 195L170 192L170 186L169 181L168 178L164 177L160 178L156 177L154 177L150 178L146 176C146 176 145 174 145 173C145 172 142 170 142 170L140 170L136 170L132 170L129 168L130 166L131 163L131 159L128 158L126 160L124 161L122 159L120 156L118 156L114 157L110 157L108 154L112 147L114 143L118 142L129 130L134 127L137 122L141 121L144 118L148 113L151 114L154 114L156 115L156 112L157 109L156 104L159 100L158 96L154 94L148 88L152 82L150 79L147 78L147 80L144 80L141 78L138 75L133 72L132 75C131 75 128 74 128 74L124 73L127 70L126 66L129 65L132 65L136 63L140 58L144 55L150 53L152 54L156 58L160 59L162 57L164 59L167 60L170 61L173 61L176 62L178 60L182 60L184 58L187 62L186 66L186 70L187 74C189 74 190 74 190 74L192 72L194 70L195 71L194 74L193 76C195 77 195 79 195 79L196 82C198 83 197 85 197 85C195 85 194 88 194 88L194 91L190 90L189 94L190 96L192 98L190 101L187 103L187 105L187 107L186 110L182 113L183 115L187 115L188 116L188 120L192 120L193 122L194 127L196 130L200 132L204 135L202 140L203 144L204 148L206 150C206 150 210 150 211 150C212 150 215 150 215 150L218 150L219 152L220 155L223 155L224 158L227 159L229 157L231 157L232 160L234 163L236 167L234 170L235 172L232 175L230 180L230 182L227 183L225 185L224 190L227 192L231 192L232 196L232 200L230 202L227 200L224 201L223 204L224 208L222 212L222 217L224 218L226 218L228 220L227 224L228 227L227 233L229 236L232 240L233 243L234 246L232 249L229 248C227 247 222 246 222 246L220 243L217 242L215 244L212 246L211 250L209 253L208 256C208 256 206 256 205 256C204 256 202 252 202 252L194 243L190 240L187 240L184 240L180 236L178 232C178 232 179 228 180 228Z').attr(this.pathAttr)
 84       }
 85       this.district.dalang = {
 86         name: '大浪',
 87         path: R.path('M147 340L147 338L172 320L174 318L174 315L171 311L171 307L169 304L166 300L164 297L162 295L160 294L160 291L157 290L155 288L154 285L152 282L151 278L151 275L150 274C148 273 148 270 148 270L145 266L144 263C144 263 144 262 145 261L148 259C149 259 152 258 153 258C154 257 158 256 158 256L162 254L167 253L172 252L175 251L180 251L184 251L186 250L182 247L182 244L180 240L177 237L176 234L177 230L172 224L167 220L166 216L169 210L174 202L172 198C172 198 168 195 168 194C168 194 167 191 167 190L167 185L167 182L165 180L162 180L158 181L155 180L150 182L148 180L144 179L143 176L142 174C142 173 139 173 139 173C139 173 137 174 136 174L132 174L129 172L127 170L126 168L128 166L128 162L126 164L124 165C122 165 120 162 120 162L118 159L114 160L110 160L108 158L106 156L104 157L102 159L100 159L98 161L96 165L92 166L93 170L92 175C91 175 90 180 90 180L88 184L86 186C84 186 83 189 83 189L86 188L88 188C88 189 88 191 88 191L89 193L85 194L84 197C85 197 88 195 88 195L90 194L93 196L94 197L96 198L96 202L94 204L92 203L90 201L88 202L86 204L86 205L88 206L91 206L92 208C92 208 91 209 90 210C90 210 88 210 87 210C86 210 84 208 84 208L84 211L86 214L84 216L85 218L85 222L83 224L86 226L87 230L84 234L84 238L83 240L80 240L74 242L76 244L72 246L72 250L70 253L71 260L75 264L78 271L81 275L80 279L80 284L78 288L80 290L76 294L75 298L73 301L69 302C69 302 68 305 68 306L69 310L70 314L71 320L66 324L66 328L71 327L75 330L78 335L82 336L86 334C87 334 92 334 92 334C92 334 95 334 96 334C97 334 101 337 101 337L106 337L110 339L114 342L116 347L120 350L120 353L119 356L146 346L148 344L147 340ZM235 334').attr(this.pathAttr)
 88       }
 89       this.district.longhua = {
 90         name: '龙华',
 91         path: R.path('M1397 504M209 328L196 322L190 321L186 321L181 319L178 317L177 314L176 311L174 306L173 303L170 300L168 295C168 295 165 294 164 294C164 293 164 289 164 289L159 288L158 285L155 281L155 277L154 274L152 272L150 268L147 264C147 264 149 261 150 261L155 260L159 259L164 256C164 256 167 256 168 256C169 255 175 254 175 254C176 254 184 253 184 253L188 252L191 251L187 248L185 246L185 244L188 243L191 245L193 247L196 250L200 254L202 257L203 260L208 260L211 258L212 254L215 248L218 246L220 249L226 250L229 253L235 252C235 252 237 250 237 249L238 246L236 242L236 238L242 241L247 244L252 245L256 245L257 248L259 251L261 252L264 250C264 250 266 252 267 252L271 252L271 248L273 250L273 254L273 256L274 259L272 261L269 259L269 256L267 258L264 261L264 265L265 268L260 275L257 275C256 274 254 275 254 275L250 274L247 273L247 276L247 278L251 280L252 283C252 283 252 285 252 286C251 286 249 288 249 288L248 290L248 311L248 314L245 311C243 310 241 309 241 309L240 313L238 317L241 316L244 314L246 317L249 319L248 322L250 325L249 328L246 331L248 337L250 341L249 344L245 343L243 343L242 346L244 351L245 354L242 356L228 353L228 349L229 346L224 341C224 340 225 336 225 336L225 333L217 331L212 329C212 329 208 328 209 328Z').attr(this.pathAttr)
 92       }
 93       this.district.minzhi = {
 94         name: '民治',
 95         path: R.path('M151 348L122 358L120 359C121 360 124 359 124 359L124 360L127 360L130 362L132 362L136 362C138 362 139 364 139 364L139 366L140 368L140 370L142 372L143 374L144 376L147 377C149 378 149 379 149 379L149 380L151 383L152 385L152 388L152 392L154 394L154 396C156 396 157 396 157 396L158 398C158 398 158 399 158 400L159 402C160 403 159 405 159 405L160 406L163 406L164 408L166 410L166 412L167 414L170 413L172 414L174 416C176 415 178 414 178 414L180 415L181 418L182 422L183 426L182 430L183 434L186 438L188 441L188 445L186 448L184 452L183 454L184 457L182 461L185 460C187 460 192 461 192 461L194 463L196 462C198 462 199 460 199 460L200 458L203 460L205 457L208 458L211 459L214 458C214 458 216 457 216 456C217 456 221 458 221 458L226 456L231 461L236 460L238 461L241 462L243 460L243 456L246 454L250 451L252 452L255 450L260 452L264 454L269 454L270 451L272 449L273 447L276 444L279 442L281 440L277 438L277 434L274 431L272 431L270 432L268 430L266 427L265 424L262 424L259 420L254 416L256 411L256 409L256 404L256 401L254 399L256 395L249 390L252 385L250 382L251 378L249 373L247 371L245 370L244 368L245 366L241 364L240 361L239 357L234 356L229 355L226 354L225 349L226 347L222 341L222 335L215 333L208 330L195 324L186 324L177 320L174 323L169 326L152 338L150 340C150 340 152 348 151 348Z').attr(this.pathAttr)
 96       }
 97       this.district.guanhu = {
 98         name: '观湖',
 99         path: R.path('M294 253L292 255L290 258L285 258L282 256L279 254L277 256L276 259L275 254L274 248L271 244C269 244 269 246 269 246L269 250L264 247L261 249L260 246L257 242L250 241L245 239L240 236C239 236 236 234 236 234L234 240L230 234L230 230L231 227L230 222L231 219L227 215L224 215L225 213L226 209L228 207L226 204L230 205L233 204L234 202L234 199L234 192L233 189L229 189L228 186C230 185 233 184 233 184L232 180L236 174L238 172L238 170L242 169L248 167L256 161L261 156L265 153L270 152L271 150C272 149 275 147 275 147L276 146L278 146L280 144L282 146L283 148C285 148 288 147 288 147L288 150L284 151L288 154L292 154L293 162L296 166L300 168L305 170L311 172L310 177L316 181L324 177L326 174L328 176L331 180L339 175L344 179L343 183L344 186C345 186 348 186 348 186L348 190L344 189L340 189L330 199L330 204L331 208L332 212L334 214L336 217L340 221L343 222L346 222C346 223 348 225 348 225L346 226L343 225L339 226L334 230L333 233L334 238C334 238 336 242 336 243C336 244 338 247 338 247L341 250L341 253L343 258L342 262L342 266L344 269C342 270 339 270 339 270L336 268L336 270L334 272L335 274L337 275L335 277L332 277L330 279L326 282C324 283 325 285 325 285L323 287L321 289L320 292L318 290L315 288L313 283L313 279L308 277L307 272L305 269L304 265L304 262L301 258L299 255L296 253C296 253 294 254 294 253Z').attr(this.pathAttr)
100       }
101       this.district.guanlan = {
102         name: '观澜',
103         path: R.path('M264 150L257 156L254 160L252 160L249 163L246 165L238 167L238 164L234 156L231 153L228 154L227 156L225 154C224 154 223 152 223 152L221 149L220 147L212 147L206 147L205 139L206 135L206 133L198 127C198 127 196 124 196 123L194 119L192 117L190 117L190 114L188 113L189 111L190 109L190 105L192 102L195 100L194 96L192 93L196 94L197 92L197 89L198 86L201 84L200 81L198 79L198 76L197 72L197 68C195 67 193 68 193 68L191 70C189 71 188 66 188 66L190 63L189 59L187 56L192 55L194 51L194 48L197 47L200 50L201 54L202 52L204 50L207 48L212 47L214 49L216 52L220 53L223 52L226 49L230 46L235 44L235 42C235 42 233 40 234 40C235 39 237 37 237 37C238 36 242 36 242 36C242 36 242 39 242 40C243 40 241 44 241 44L240 46L242 52L245 53L246 56L247 60L245 62L242 64L240 68L242 72L245 71L248 72C248 72 253 71 254 71L258 75L261 77L264 74L266 77C266 77 267 74 268 74L271 72L273 73L272 77L273 80L271 84L269 86L269 89L272 89L274 90L278 90L281 88L283 92L282 95L280 99L284 98C284 98 287 97 288 97L289 100L289 104L292 106L297 105L300 102L304 100L308 98L308 93L309 89L314 86L319 89L325 88L329 90L331 92L329 94L331 97L334 94L339 94L342 96L344 93L344 98L343 102L343 104L347 107L348 114L347 118L344 119L345 122L349 123L349 128C349 128 352 130 353 130L356 130C357 130 357 134 357 134C357 135 359 138 359 138L360 147L364 150C364 150 368 150 369 150C370 150 372 152 372 152L371 157L369 158L366 162L366 167L366 170L365 174L360 174L359 176L360 180L360 182L356 180L354 184L353 187L350 184L347 183L347 178L340 171L333 175L326 168L325 171L323 173L319 176L315 176L314 171L310 168L304 166L299 162L297 157L296 152L291 150L290 144L285 144L282 142L278 140L275 142L272 144L269 146C269 146 264 151 264 150Z').attr(this.pathAttr)
104       }
105     },
106     handlerMouseOver () {},
107     handlerMouseOut () {},
108     initEvent () {},
109     processPath (svgPath, itemName) {
110       // 获取当前图形的中心坐标
111       let xx = svgPath.getBBox().x + (svgPath.getBBox().width / 2)
112       let yy = svgPath.getBBox().y + (svgPath.getBBox().height / 2)
113 
114       // 修改部分地图文字偏移坐标
115       switch (this.district[itemName].name) {
116         case '大浪':
117           xx -= 35
118           // yy -= 10
119           break
120         case '龙华':
121           xx -= 565
122           yy -= 80
123           break
124         case '观湖':
125           yy -= 10
126           break
127         case '观澜':
128           yy += 10
129           break
130         case '玉塘':
131           xx -= 20
132           break
133         case '光明':
134           yy -= 20
135           break
136         case '公明':
137           xx -= 10
138           break
139         default:
140       }
141       // 写入文字
142       this.district[itemName]['text'] = this.R.text(xx, yy, this.district[itemName]['name']).attr(this.textAttr)
143       // 绑定事件
144       svgPath[0].addEventListener('mouseover', () => {
145         svgPath.animate({fill: svgPath.color, stroke: '#eee'}, 500)
146         this.district[itemName]['text'].toFront()
147         // 设置tips要显示的内容
148         this.tipsContent = `${this.district[itemName].name}:<br>残疾人数:${this.mapData[itemName]}人`
149         // 显示提示框
150         this.tipsShow = true
151       })
152       svgPath[0].addEventListener('mouseout', () => {
153         svgPath.animate({fill: '#97d6f5', stroke: '#eee'}, 500)
154         this.district[itemName]['text'].toFront()
155         // 隐藏提示框
156         this.tipsShow = false
157       })
158       svgPath[0].addEventListener('mousemove', (e) => {
159         // 设置提示信息跟随鼠标移动
160         this.leftPosition = e.offsetX + 40
161         this.topPosition = e.offsetX + 30
162       })
163     }
164   }
165 }
166 </script>
167 
168 <style scoped>
169 #streetMap{
170   position: relative;
171 }
172 .tips{
173   padding: 5px;
174   border-radius: 5px;
175   position: absolute;
176   left: 0;
177   top: 0;
178   color: #FFF;
179   font-size: 14px;
180   background-color: rgba(0, 0, 0, 0.7);
181 }
182 </style>

四、参考网站

1、https://www.cnblogs.com/stephenykk/p/3553690.html  raphael矢量图API

2、https://www.cnblogs.com/pangguoming/p/6542281.html svg图片路径的绘制

原文地址:https://www.cnblogs.com/llcdxh/p/9390379.html