如何使 highchart图表标题文字可选择复制
highchart圖表的一個常見問題是不能復制文字
比如官網的某個圖表例子,文字不能選擇,也無法復制,有時產品會抓狂...
本文給出一個簡單的方案,包括一些解決的思路,希望能幫助到有需要的人
?
?
初期想了蠻久也搜了蠻多,沒搜到,找到的結論是圖表使用的是svg實現,必然無法選擇文字,似乎是個死問題,已經瀕臨放棄
不過后來又看到一篇討論,其實svg里面的文字是可以選擇復制的
頓時信心又來了,展開了新一輪思考
?
?
思考一:可能是姿勢不對
試試把標題配成 useHTML: true ,使用普通元素渲染,結果還是無法選
?
?
?
看看DOM結構,實際上已經和svg無關了
思考二:會不會是設置了某些樣式呢
跟選擇復制有關的也就這倆了,直接賦上去,還是無效
思考三:會不會是有事件影響,取消了點擊選擇效果呢
為了測試的簡便與純粹性,最好直接使用官方提供的簡單例子
查看元素對應的事件列表,有幾個需要關注
選擇highchart.js ,跳的不準呀,代碼混淆之后貌似chrome的跳轉一致都不太可靠了
思考四:什么js東西使得點擊選擇無效呢
可能是事件禁止了冒泡 stopPropagation,或者是取消了元素的事件默認處理機制 preventDefault
一搜,發現前者沒找到,而后者有多處
定位到一個 mouseDown事件觸發的位置,柳暗花明的感覺
試了一下可以發現,上下兩處是關鍵點,直接造成文字選擇功能失效了(當然這可能是作者的本意)
接下來就是驗證環節,把這文件下下來本地,改好后(注釋那倆地方)用Fiddler的文件映射功能,替換這個例子中的 highchart.js,妥妥的可以進行選擇復制
?
思考五:如何運用在業務代碼中?
在vue中使用的是npm的包管理,所以肯定不能直接改源代碼,可選的一個方案是覆蓋源代碼,即覆蓋這兩個方法
import Highcharts from "highcharts";// 重寫Highcharts事件處理,使得內容可選擇復制Highcharts.Pointer.prototype.onContainerMouseDown = function(a) {a = this.normalize(a);2 !== a.button && (this.zoomOption(a),// a.preventDefault && a.preventDefault(),this.dragStart(a))};Highcharts.Pointer.prototype.onContainerMouseMove = function(b) {// 整理變量let a = Highcharts;let B = Highcharts.charts;let q = function(a) {return "undefined" !== typeof a && null !== a};var c = this.chart;q(a.hoverChartIndex) && B[a.hoverChartIndex] && B[a.hoverChartIndex].mouseIsDown || (a.hoverChartIndex = c.index);b = this.normalize(b);// b.preventDefault || (b.returnValue = !1);"mousedown" === c.mouseIsDown && this.drag(b);!this.inClass(b.target, "highcharts-tracker") && !c.isInsidePlot(b.chartX - c.plotLeft, b.chartY - c.plotTop) || c.openMenu || this.runPointActions(b)};?
找到對象是誰,這一步可以斷點調試看this,或往上翻代碼,其實是個Pointer.?
通過分析可知,這個對象的Highcharts對象的一個子對象,我們也需要通過簡單的判斷來進行確認好
?需要注意的是,代碼中有一段用到了其他變量 q? B? a,所以在業務代碼中覆蓋的時候,我們需要另外提前賦值
q(a.hoverChartIndex) && B[a.hoverChartIndex] && B[a.hoverChartIndex].mouseIsDown || (a.hoverChartIndex = c.index);通過一系列分析和斷點查詢,以及確認值的一致,就能保證能覆蓋地正確
?
思考六:在vue中為何沒有生效
然鵝并不是順利的,在實際場景vue-highcharts中使用竟然沒啥變化,一輪調試下來也沒有走斷點,
無可奈何只好去看下它的實現,看有沒有什么突破口
源碼很少,就是一層包裝
但這里可以發現,如果沒有傳入highcharts,就會另外引入npm包來使用
所以很大可能是沒傳入這個屬性,致使覆蓋的Pointer并不是真正的圖表Pointer
仔細檢查代碼,才發現前人留個個坑,把大寫的屬性改成小寫之后,即可匹配上
?
當然,這個覆蓋的方式是挺暴力的,可以根據需求加些判斷處理,不過在現有業務中,不失為一個好辦法
?
轉載于:https://www.cnblogs.com/imwtr/p/11066595.html
總結
以上是生活随笔為你收集整理的如何使 highchart图表标题文字可选择复制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一切都是对象
- 下一篇: PHP 源码 —— is_array 函