如何使 highchart圖表標題文字可選擇複製

highchart圖表的一個常見問題是不能複製文字php

好比官網的某個圖表例子,文字不能選擇,也沒法複製,有時產品會抓狂...vue

本文給出一個簡單的方案,包括一些解決的思路,但願能幫助到有須要的人web

 

 

初期想了蠻久也搜了蠻多,沒搜到,找到的結論是圖表使用的是svg實現,必然沒法選擇文字,彷佛是個死問題,已經瀕臨放棄chrome

不事後來又看到一篇討論,其實svg裏面的文字是能夠選擇複製的npm

頓時信心又來了,展開了新一輪思考ide

 

 

思考一:多是姿式不對svg

試試把標題配成 useHTML: true ,使用普通元素渲染,結果仍是沒法選測試

 

 

 

看看DOM結構,實際上已經和svg無關了this

思考二:會不會是設置了某些樣式呢spa

跟選擇複製有關的也就這倆了,直接賦上去,仍是無效

思考三:會不會是有事件影響,取消了點擊選擇效果呢

爲了測試的簡便與純粹性,最好直接使用官方提供的簡單例子

查看元素對應的事件列表,有幾個須要關注

選擇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

仔細檢查代碼,才發現前人留個個坑,把大寫的屬性改爲小寫以後,便可匹配上

 

固然,這個覆蓋的方式是挺暴力的,能夠根據需求加些判斷處理,不過在現有業務中,不失爲一個好辦法

相關文章
相關標籤/搜索