当前位置: 首页 > Web前端 > vue.js

《D3.js》手绘分段折线图

时间:2023-03-31 19:26:28 vue.js

鍚勪綅鍕囨暍鐨勫皬浼欎即浠ぇ瀹跺ソ锛屾垜鏄綘浠殑鍢村己鐜嬪皬姝︼紝韬綋鍋ュ悍銆傛垜鏈変赴瀵岀殑鑴卞彂鎶€宸э紝鍙互璁╀綘鎴愪负璧勬繁鏄庢槦銆傜湅鍒板氨鍐欐槸鎴戠殑瀹楁棬锛屾寫鍓旀槸鎴戠殑鐗圭偣銆傛垜鐨勮唉閫婁腑閫忕潃涓€涓濆潥闊с€傛剼浜烘湁鎰氱锛屾槸鎴戞渶澶х殑瀹夋叞銆傛杩庢潵鍒板皬鍚撮殢绗旂郴鍒椼€奃3.js銆嬫墜缁樺垎娈垫姌绾垮浘銆傚弻鎵嬪啓鍦ㄥ墠闈紝鎻愪緵浠g爜閾炬帴Portal-ajun568锛屽弻鑴氭彁渚涙渶缁堟晥鏋滃浘銆備负浜嗙洰鐨勶紝鎵€鏈夎繃绋嬮兘涓虹粨鏋滄湇鍔★紝鑰屼笉鏄郴缁熷涔爏vg鍜孌3.js銆傛寚瀵拣煈哄皬浼欎即浠紝浣犱滑鏈夋病鏈夊拰鎴戜竴鏍风殑鍔熻兘闇€姹傦紝涓绘祦鐨勫浘琛ㄥ簱寰堥毦婊¤冻鎴戜滑鐨勯渶姹傦紱灏忎紮浼翠滑鏄笉鏄篃鍜屾垜涓€鏍锋€ヤ簬姹傛垚锛屾兂瑕佸湪鐭椂闂村唴瀹屾垚鐩稿簲鐨勫姛鑳藉紑鍙戙€傚鏋滀綘鍦ㄥ睆骞曞墠涔熸湁鍚屾牱鐨勬兂娉曪紝閭d箞D3鏄釜涓嶉敊鐨勯€夋嫨锛屽畠绠€鍗曟槗鐢紝鍙互鑷畾涔夌粯鍥俱€傜幇鍦ㄥ氨璁╂垜浠竴璧疯繘鍏ヨ繖涓骞荤殑鍥惧舰涓栫晫鍚р潡锔忓噯澶囧伐浣測arnaddd3灏嗗湪2021-03缁撴潫锛岀洰鍓嶆渶鏂扮増鏈琩3^6.6.0锛屾垜浠粠杩欎釜鐗堟湰寮€濮嬫垜浠殑鏃呯▼銆傚鏋滅増鏈湁鍙樺寲锛屽缓璁娇鐢ㄦ渶鏂扮増鏈€傪煑″缓璁殑瑙e墫鏁版嵁鏍煎紡濡備笅锛歞ataset=[{xValue:x杞存暟鎹畖Number,yValue:y杞存暟鎹畖Number,filled:鏄惁涓哄疄蹇冪偣|Boolean,},...[andsoon]]look馃憜pictureisavailable鎶婂畠鎷嗘垚浠ヤ笅鍑犱釜閮ㄥ垎锛歨over鏃舵寚鍚戝潗鏍囪酱璇磋SVG甯歌鍦烘櫙涓殑$d3.js$鏄?svg$鐨勮娉曠硸銆傛棦鐒舵暣绡囬兘瑕佸拰$svg$鎵撲氦閬擄紝鎬庝箞鑳戒笉璁よ瘑杩欎釜鍙埍鐨勫皬瀹朵紮鍛紵鎵€璋撶煡宸辩煡褰硷紝鐧炬垬涓嶆畣viewport=>width/height锛氭寚瀹氱敾甯冪殑瀹介珮viewBox=>(x,y,width,height):浠?(x,y)$鐐癸紝閫夋嫨瀹藉害涓?width$锛岄珮搴︿负$height$鐨勭煩褰紝鏀惧ぇ鍒扮敾甯冨ぇ灏忥紝姝f柟鍚戝鍥撅細鏉ュ嚑娈典唬鐮佹劅鍙椾笅馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔忓浘鐗囸煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="10,-150,400,300">馃鈥嶁檪锔忓浘鐗囪繖寮犲浘鍦?10,-150)浣嶇疆锛屾鏂瑰悜閫?00鉁栵笍300鐢诲竷鍜屾樉绀吼煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="-10,-10,40,30">馃鈥嶁檪锔忓浘鐗囪繖寮犲浘鐗囩浉褰撲簬閫夋嫨鑾峰彇鐨勫厓绱犳斁澶т簡20鍊嶃€傚父鐢ㄦ爣绛緍ect缁樺埗涓€涓煩褰params=>x,y,width,height,$x,y$鏄煩褰㈢殑鍋忕Щ閲忋€備互涓婇兘鏄煩褰㈢殑渚嬪瓙锛屾垜灏变笉璧樿堪浜嗐€俢ircle鐢讳竴涓渾馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">$tips:$fill濉厖棰滆壊馃鈥嶁檪锔廔mageellipse缁樺埗妞渾馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔廔magetext缁樺埗鏂囧瓧馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">鎴戝湪鐢绘枃瀛?/text>$tips:$stroke鎻忚竟棰滆壊鏍峰紡->text-anchoralignment,defaultmiddle,optionalstart,middle,end馃鈥嶁檪锔廔mageline鐢讳竴鏉$洿绾筐煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">$tips:$stroke-width绗旂敾瀹藉害馃鈥嶁檪锔廔magepolyline缁樺埗鎶樼嚎馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">$tips:$璁板緱濉负none锛屽惁鍒欒矾寰勪細琚~婊○煣熲€嶁檪锔廔magepath璺緞馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔廔mageg鍒嗙粍馃憠灏嗘爣绛惧垎缁勪互渚夸簬鍒嗙被鎴栬€呴噸澶嶄娇鐢ㄥ鍒娥煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔廔magedefs鑷畾涔夊浘褰煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔忓浘鍍忓眰娆$粨鏋勷煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔忓浘鐗団湇锔忕粯鍒剁敾甯冪殑鍓嶇疆鐭ヨ瘑宸笉澶氬噯澶囧ソ浜嗭紝灏忎紮浼翠滑锛岃繘鍏ユ棰樷潡锔?First$$of$$all$锛屾垜浠紑濮嬫瀯寤?html$缁撴瀯

$Secondly$锛屾垜浠湪杩欎釜div涓娇鐢╠3鏉ュ垱寤烘垜浠殑canvas锛屽楂橀兘鏄?00鉁栵笍800$d3$鏄摼鏉tructureselectselectelement(select$id$)selectAllselectallelements(selectelement,selectclass)appendappendelementattraddattributeconstwidth=800constheight=400d3.select('#line').append('svg').attr('width',width).attr('height',height)鉁嶏笍缁樺埗鍧愭爣杞村埢搴﹀湪寮€濮嬪埢搴︿箣鍓嶏紝鍏堢湅鍑犱釜鏈夌敤鐨勫嚱鏁帮細d3.max(arr)return$max$d3.min(arr)return$min$d3.extent(arr)return$[min,max]$鏈枃浣跨敤鐨勭嚎鎬ф瘮渚嬪昂鏄痵caleLinear鉂?what$$is$绾挎€ф瘮渚嬪昂馃憠灏嗕竴涓繛缁尯闂存槧灏勫埌鍙︿竴涓尯闂达紙domin鏄犲皠鍒皉ange)宕斿崕锛屼笂闈㈢殑浠g爜馃憠xScaled3.scaleLinear()//鍒涘缓涓€涓嚎鎬cale.domain([//domindata[x.min,x.max]d3.min(xData),d3.max(xData)])銆俽angeRound([0,width])//鑼冨洿鏁版嵁[0,width]x杞寸粯鍒舵帴涓嬫潵鎴戜滑浣跨敤axisBottom鍒涘缓涓€涓悜涓嬬殑鍧愭爣杞达紝閫氳繃scale璋冪敤璁剧疆鐨剆cale馃憠xAxisd3.axisBottom().scale(xScale)鐒跺悗锛岄€氳繃call鏂规硶鍦ㄧ敾甯冧笂濉厖svg銆俢all(xAxis)鑷虫绮楃暐缁樺埗浜唜杞达紝鐒跺悗鎾斁闊充箰璺宠垶銆傛湁娌℃湁鍙戠幇浠€涔堜笉瀵癸細鍙宠竟鐨?100$杞磋鎴幓鍗犳嵁浜嗘暣涓敾甯冿紝瀹屽叏娌℃湁缇庢劅鑰屼笖$x$杞翠笉搴旇鍦ㄥ簳閮ㄥ悧锛熷湪宸︿晶锛屽畠鐨勫ソ鏈嬪弸$y$涔熷簲璇ユ湁涓€涓┖鏍笺€?1,2$鐨勬牳蹇冮棶棰樻槸娌℃湁绌烘牸銆傛棦鐒惰鐣欑┖锛岄偅灏卞姞padding灏卞彲浠ヤ簡锛?3$鏄竴涓炕璇慶onstpadding={top:30,right:30,bottom:30,left:30}馃憠xScale-.rangeRound([0,width])+.rangeRound([0,width-padding.left-padding.right])馃憠svgsvg.append('g').attr('transform',`translate(${padding.left},${height-padding.bottom})`).call(xAxis)馃鈥嶁檪锔廔mageNo.1axis.tickValues([...arr])鐢ㄤ簬鎸囧畾鍧愭爣杞存樉绀虹殑鍊笺€俛xis.tickFormat()鏍煎紡鍖栧潗鏍囪酱鏁版嵁$eg:$鍧愭爣杞存暟鎹牸寮忓寲涓哄崈鍒嗕箣涓€axis.tickFormat(d3.format(",.0f"))锛屽叾涓?0f涓烘湭鏍煎紡鍖栫殑灏忔暟閮ㄥ垎No.2绗簩涓偣鍙互鐞嗚В涓哄湪宸﹀彸涓ょ娣诲姞涓€鏉℃暟鎹紝鐒跺悗灏嗕袱鐐硅繛鎺ヨ捣鏉ャ€傛坊鍔犳暟鎹紝闇€瑕佽ˉ澶氬皯锛屾垜浠紩鍏ヤ竴涓壇鏈暟鐨勬蹇碉紝瀹氫箟1涓壇鏈负鎬婚暱搴︾殑$1/dataset.length*2$锛屾渶灏忎负$1/10$.//鎷疯礉鏁拌绠?constlength=dataset.length*2+constpartDistance=(d3.max(xData)-d3.min(xData))/(length>10?10:length).domain([-d3.min(xData),-d3.max(xData)]).domain([+d3.min(xData,item=>{+returnitem-partDistance+}),+d3.max(xData,item=>{+returnitem+partDistance+})])No.3涓婇潰鐨勨€滄祬璋圫VG鈥濓紝鎴戜滑宸茬粡鍒嗗埆瑙i噴浜哾efs銆乬銆乸ath銆乽se銆傜繝鑺憋紝涓婇潰鐨勪唬鐮乧onstarrowPath='M4,4L20,12L4,20L8,12Z'constaxisColor='#fff'constarrowOffsetDistance=12svg.append('defs').append('g').attr('id','arrowX').append('path').attr('d',arrowPath).attr('fill',axisColor)svg.append('use').attr('href','#arrowX').attr('x',width-padding.right-arrowOffsetDistance).attr('y',height-padding.bottom-arrowOffsetDistance)M4,4L20,12L4,20L8,12Zd3.path()createpathpathmoveTo(x,y)MlineTo(x,y)LclosePath()涔熷彲浠ユ牴鎹柟娉曞姩鎬佺敓鎴怹letarrowPath=d3.path()//M4,4L20,12L4,20L8,12ZarrowPath.moveTo(4,4)arrowPath.lineTo(20,12)arrowPath.lineTo(4,20)arrowPath.lineTo(8,12)arrowPath.closePath()No.+鈭炰负浜嗚鍧愭爣杞存洿婕備寒锛岄殢渚跨偣鍑犵瑪锛屾渶缁堟晥鏋滃浘濡備笅锛?tip:$浣跨敤select/selectAll閫夋嫨鍏冪礌骞舵敼鍙樼浉搴旂殑灞炴€э紙鎴?style$鎴?svg$鍥惧舰灞炴€э級鏉ヨˉ鍏呭叾浠杇ood鍙?y$杞存€濆瘑杈炬爣璁扮敤浜庣粰鍥惧舰娣诲姞鍏冪礌锛屾垜浠殑鍧愭爣杞村緢绗﹀悎杩欎釜鐗规€arkerWidth/markerHeightwidth/heightrefX/refY$x/y$杞村亸绉籱arkerUNits鏄惁鍏佽marker璺熼殢鐩歌繛鍥惧舰鐨勭缉鏀撅紝榛樿strokeWidth锛堢缉鏀撅級锛屽彲閫塽serSpaceOnUse锛堜笉缂╂斁锛塷rient鏃嬭浆瑙掑害锛岄粯璁?auto$锛屽叿浣撴棆杞害鏁板彲浠ユ寚瀹氣潛濡備綍娣诲姞鍒扮粯鍒剁殑鍥惧舰馃憠鏄粰缁樺埗鐨勫浘褰㈡坊鍔犲涓嬪睘鎬э細marker-end="url(#id)",optional[marker-start,marker-mid,marker-end]鐗瑰埆娉ㄦ剰锛歮arker鍙互鐞嗚В涓轰綔鐢ㄤ簬鐐癸紝鎵€浠arker-mid瀵逛袱鐐硅繛鎺ユ病鏈夊奖鍝嶏紝鑷冲皯闇€瑕佷笁涓偣鎵嶈兘浜х敓鏁堟灉馃鈥嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔廔mage鐨勪袱绉嶅啓娉曞姣斿涓嬶細缁樺埗鍧愭爣鐐筩oordinatepoints鉂撶敾鍦堣瘏鍜掍綘锛堢敾鍦堬級绌哄績鐐光潛浜轰綋绗旂敾娉曪紙stroke-瀹藉害浣犲€煎緱鎷ユ湁锛夋槧灏勫埌鍧愭爣杞粹潛姣斾緥鐨勭偧閲戞湳锛堟寜姣斾緥鏄犲皠鍥炴潵锛夝煣熲€嶁檪锔忎唬鐮侌煣熲€嶁檪锔忓浘鍍忕粯鍒舵姌绾跨偣銆佺嚎銆侀潰锛屽苟涓庢垜浠紑濮嬭繛鎺ョ殑鐐广€傜敤浠€涔堬紵鎴戝缓璁ぇ瀹剁敤path锛堢敤娉曞湪鈥滅粯鍒跺潗鏍囪酱鈥濅腑鏈夎鏄庯級锛屼絾鎴戦€夋嫨鐢╨ine锛屾病鏈夌悊鐢憋紝灏辨槸浠绘€э紝涓嶆湇灏辨墦鎴戯紒馃捇鐭ヨ瘑鐐筪3.line().defined()褰撳墠鐐规槸鍚﹀搴旓紵鎶婄浉閭荤殑鐐硅繛璧锋潵鐢荤嚎锛屼絾鏄偣鐪熺殑瀹屾暣鍚楋紵鍦ㄥ瀛愮溂閲岋紝璧风偣鍦ㄥ摢閲岋紝缁堢偣鍦ㄥ摢閲岋紵鎴戜滑鏍规嵁鍓嶉潰璁$畻鍑虹殑浠芥暟琛ラ綈鏁版嵁锛岀劧鍚庣粯鍒躲€?/鎶樼嚎鏁版嵁澶勭悊letnewDataset=[]newDataset.push({xValue:dataset[0].xValue-partDistance,yValue:dataset[0].yValue,filled:true})newDataset.push(...dataset)newDataset.push({xValue:dataset[dataset.length-1].xValue+partDistance,yValue:dataset[dataset.length-1].yValue,filled:true})鐩寸嚎瑕嗙洊绌哄績鐐光潛鏍规嵁閲忓瓙鍔涘瀹氬緥-$svg$灞傚簭锛屽眰搴忓繀椤婚鍊掋€傛浛鎹唬鐮侀『搴忥紝瀹岀編瑙e喅銆?x$鍧愭爣鐩稿悓鐨勮繛鎺ョ嚎鉂撳ぇ瀹舵湁娌℃湁娉ㄦ剰鍒颁笂闈㈢殑瀹氫箟锛屼絾鏄垜涓嶆兂杩炴帴x鍧愭爣鐩稿悓鐨勭偣锛岃€屾槸娓呯┖杩欎釜鐐癸紝璁╁畠鍥炲綊鑷敱銆傚厠闅嗕竴涓紝Perfect锛屽畬缇庤В鍐充簡杩欎釜闂銆傝嚦浜巆lone鍝釜鐐癸紝闅忓績鎯呭氨濂斤紝浣犺鎴戜袱涓兘鎯宠锛屾嫋鍑烘潵鍓笅鏉ャ€?/Polyline鏁版嵁澶勭悊-newDataset.push(...dataset)+dataset.forEach(item=>item.filled?newDataset.push(item):newDataset.push(...[item,item]))馃鈥嶁檪锔忎唬鐮侌煣熲€嶁檪锔廔mage缁樺埗铏氱嚎stroke-dasharray:鐢ㄤ簬缁樺埗铏氱嚎锛屾瘡娆?x$缁樺埗鍍忕礌鍚庯紝灏嗗墿涓?y$涓儚绱狆煣熲€嶁檪锔忎唬鐮?svgwidth="400"height="300"viewBox="0,0,400,300">馃鈥嶁檪锔廔mage鎵句竴涓偣锛岃繛涓婄嚎锛屾垜浠殑铏氱嚎鐢荤俊缈犺姳锛屾斁閰歌彍馃鈥嶁檪锔廔mageTooltip鍦ㄦ瀯鎬漷ooltip涔嬪墠鎶涘嚭鍑犱釜闂鉂撳伐鍏锋彁绀烘樉绀轰粈涔堬紵瀵瑰簲鐐圭殑鍧愭爣鏄灏戯紵浠€涔堟槸鎮仠鍖哄煙锛焗over$鏄暣涓尯鍩燄煈変竴涓鐩栨暣涓潗鏍囪酱鐨?rect$锛岀劧鍚庢槸浜嬩欢澶勭悊$tooltip$馃憠褰?hover$鍦▁=c鍧愭爣涓婃壘鍒板搴旂偣鏃讹紝鍦ㄥ搴旂偣鏃佽竟鏄剧ず涓€涓皬鐨?div$锛屽皢铏氱嚎杩炴帴鍒?x$杞村拰$y$杞达紝骞跺湪璇ョ偣鏃佽竟鏄剧ず$tooltip$銆傜儲韬佺殑鏃跺€欙紝鍏堣拷鍔犱竴涓猺ect锛岀劧鍚庡榻愶紝杩涜浜嬩欢澶勭悊銆傚湪杩欓噷锛屾垜浠娇鐢ㄦ垜浠啛鎮夎€屾€ф劅鐨勮€佹湅鍙嬨€傚氨鏄繖鏍凤紝杩欐槸浠栦滑棣栨浜浉鐨勫湴鏂癸細svg.append('rect').attr('width',areaWidth).attr('height',areaHeight).style('fill','none').style('pointer-events','all').style('cursor','pointer').attr('transform',`translate(${padding.left},${padding.top})`).on('mouseover',mouseOver).on('mouseout',mouseOut).on('mousemove',mouseMove)鎺ヤ笅鏉ユ垜浠粯鍒?tooltip$鍙婂叾鎸囧悜$x$杞村拰$y$杞寸殑铏氱嚎銆傝繖鏃跺€欏氨浼氭湁杩欐牱鐨勭枒鎯戯紝鎴戣繕娌$畻濂戒綅缃紝鎬庝箞鐢诲憿锛屼笉鐢ㄧ潃鎬ワ紝璇风湅涓嬮潰鐨刴ouseMove锛岃繖涓皬瀹朵紮鍙互甯垜浠緱鍒扮偣鐨刼ffsetX锛岄偅涔堟眰鐐圭殑闂浼氬彉鎴愬凡鐭?x$姹?y$锛岀劧鍚庤浆鍖栦负姹傚叧鑱?x,y$鐨勫嚱鏁拌〃杈惧紡銆傚凡鐭ョ涓€娈靛拰鏈€鍚庝竴娈?y$鏄父閲?$y=c$)锛屼腑闂寸殑娈佃惤涓猴細$$(x-x1)*(y2-y1)=(x2-x1)*(y-y1)$$璇嗗瓧鎷胯捣鏈烘灙锛岀瀯鍑嗙洸鐐瑰厛鏉ヤ竴娉㈡壂涓€鎵玸caleLinear->invert锛氬弽鍚戞槧灏勶紙鏍规嵁鑼冨洿鍐呯殑缁欏畾鍊艰繑鍥炲煙涓搴旂殑鍊硷級constxInvert=xScale.invert(d.offsetX-padding.left)d3.bisector():Bisector瑕佺悊瑙h繖涓蹇碉紝鍏堣璇村畠鐨勪翰鎴歜isectLeft,bisectRightd3.bisectLeft(arr,x)鍏朵腑$arr$鏄鎻掑叆鐨勬暟缁勶紙寰呮帓搴忥級锛?x$鏄鎻掑叆鐨勫€硷紝return鍊兼槸鎻掑叆浣嶇疆銆傚鏋?x$宸茬粡鍦ㄦ暟缁勪腑锛屽畠灏嗚鎻掑叆鍒板悓涓€涓潯鐩殑鏈€宸﹁竟銆俢onstarr1=[2,3,5,6,7]d3.bisectLeft(arr1,4)//return2constarr1=[2,3,3,6,7]d3.bisectLeft(arr1,3)//return1鍏堣骞冲垎绾匡紝瀹冩槸浠€涔堬紝鍏跺疄鍜屼笂闈竴鏍凤紝鎴戜滑瀹為檯寮€鍙戝熀鏈兘鏄鏉傜殑Array缁撴瀯锛屾垜浠彲浠ユ牴鎹産isector.constbisect=d3.bisector(d=>d.xValue).rightconstxInvert=xScale.invert(d.offsetX-padding.left)consti=bisect(dealDataset)鎸囧畾涓?x$姣旇緝鐨勫€?xInvert)杩欐牱灏卞緱鍒颁簡褰撳墠鐐圭殑鍖洪棿锛岀劧鍚庢垜浠氨鐭ラ亾浣跨敤鍝釜鍑芥暟鏉ヨ幏鍙?y$getBoundingClientRect&getBBoxselection.node().getBoundingClientRect()鑾峰彇HTML鍏冪礌鐨勭浉鍏冲睘鎬ф潵鏄剧ず鏁版嵁濡備笅:selection.node().getBBox()鑾峰彇$svg$鍏冪礌鐨勭浉鍏冲睘鎬с€傛帴涓婃枃锛岀粰瀹氬嚱鏁板拰鐐?x$锛屽彲浠ユ壘鍒扮偣$y$锛岀劧鍚庢妸鐐圭敾鍒?x$杞村拰$y$杞寸殑铏氱嚎涓娿€傜劧鍚庢垜浠~鍏?tooltip$鐨勬樉绀哄唴瀹广€備负浜嗛槻姝㈣竟鐣岀偣瓒呭嚭鐢诲竷锛屾牴鎹?getBoundingClientRect$璋冩暣杈圭晫鍊肩殑浣嶇疆銆傚畬鏁翠唬鐮佽繛鎺ュ叆鍙ithub-ajun568鍙傝€凁煍楅摼鎺3瀹樼綉銆朚DN銆桽VG鍏冪礌鍙傝€冦€朣cottMurrayAn銆桽VG鍏ラ棬銆朢uanYifeng銆桽VG鍥惧儚浠嬬粛鏁欑▼銆朲hangXinxu銆楃悊瑙VG瑙嗗彛锛寁iewBox锛宲reserveAspectRatio缂╂斁銆朰anzi銆桵arker鐗瑰緛鍙傝€僲arker銆朤erry銆椾腑鍏冪礌D3锛氬钩鍒嗙嚎鏄粈涔堬紵