成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

highcharts: 如何解決「移動端將圖表旋轉(zhuǎn)90度,tooltip表現(xiàn)不正?!??

Yumenokanata / 3133人閱讀

摘要:背景在項(xiàng)目中使用是很容易的,移動端也適配的不錯,按照官網(wǎng)教程即可。修改完成后,發(fā)現(xiàn)的表現(xiàn)符合預(yù)期了。經(jīng)過測試圖表的其他基本功能正常。由于的功能太多,這樣的源碼修改功能對其他的功能有無影響,還不能完全確定。

背景

在項(xiàng)目中使用highcharts是很容易的,移動端也適配的不錯,按照官網(wǎng)教程即可。但是在移動端,由于手機(jī)端屏幕太小,需求方希望可以弄一個全屏圖,把手機(jī)橫過來觀察曲線。

正常:

豎過來:

很容易想到的一種實(shí)現(xiàn)方法:設(shè)置曲線container的寬為屏幕的高,高為屏幕的寬,然后給曲線的container加一個transform:rotate(90deg),就能夠?qū)崿F(xiàn)豎屏了。

這樣看起來沒問題,但是當(dāng)需要展現(xiàn)tooltip的時候,會發(fā)現(xiàn)tooltip不好使了。表現(xiàn)出來的現(xiàn)象是:當(dāng)用戶用手指延著曲線的x軸移動時,tooltip并不會跟著手指移動。
仔細(xì)觀察會發(fā)現(xiàn),tooltip的移動,還是根據(jù)手指在屏幕上移動時的【橫坐標(biāo)】來的。

開始嘗試解決問題

經(jīng)過查閱highcharts文檔,發(fā)現(xiàn)chart.inverted可以實(shí)現(xiàn)x軸和y軸的反轉(zhuǎn)。試了一下這個配置,發(fā)現(xiàn)并不是想象中那么理想,主要原因?yàn)椋?br>1、y軸在屏幕下方,但我們需要的是y軸在屏幕上方。而y軸的位置不那么好調(diào)整。
2、tooltip也需要我們多帶帶進(jìn)行旋轉(zhuǎn)。但是旋轉(zhuǎn)后,手指touchmove時,tooltip適配會出問題,有時候會跑到曲線外面去,無法控制。并且由于是svg畫圖,tooltip本身的transform-origin的選擇就是一個比較蛋疼的問題。

查閱了highcharts其他的api,并且上git搜了搜issue,但是并沒有這個問題的解決方法。本來想放棄highcharts, 轉(zhuǎn)投echarts的, 但在echarts的issue里發(fā)現(xiàn)很多人遇到了這個問題,但官方直接給列為了bug, 還不知道什么時候可以修復(fù)。最后還是考慮使用highcharts。

沒辦法,改源碼吧

由于大概知道問題產(chǎn)生的原因:圖表豎過來后,應(yīng)該用觸摸事件的縱坐標(biāo)而不是橫坐標(biāo)來作為表格內(nèi)的橫坐標(biāo)。改源碼應(yīng)該挺快的。

項(xiàng)目是用通過npm安裝的highcharts, 首先根據(jù)highcharts的package.json可以看到,引用的入口文件為:highcharts.js
這個文件是壓縮過的,它對應(yīng)的源代碼文件為:highcharts.src.js

結(jié)合源代碼文件和瀏覽器調(diào)試,發(fā)現(xiàn)在用戶滑動手指是,進(jìn)入了下面的邏輯:

            onContainerTouchStart: function(e) {
                this.zoomOption(e);
                this.touch(e, true);
            },

            onContainerTouchMove: function(e) {
                this.touch(e);
            },

一切都在這個touch函數(shù)里。繼續(xù)往下看:

/**
             * General touch handler shared by touchstart and touchmove.
             */
            touch: function(e, start) {
                var chart = this.chart,
                    hasMoved,
                    pinchDown,
                    isInside;

                if (chart.index !== H.hoverChartIndex) {
                    this.onContainerMouseLeave({
                        relatedTarget: true
                    });
                }
                H.hoverChartIndex = chart.index;
                
                // 這里判斷是是否是單觸
                if (e.touches.length === 1) {
                    
                    //  e為js的觸摸事件
                    e = this.normalize(e);

                    //  e.chartX ,e.chartY應(yīng)該就是觸摸時,在表格內(nèi)部的橫坐標(biāo)和縱坐標(biāo),這里的normalize應(yīng)該是對事件進(jìn)行了擴(kuò)展。
                    isInside = chart.isInsidePlot(
                        e.chartX - chart.plotLeft,
                        e.chartY - chart.plotTop
                    );
                    if (isInside && !chart.openMenu) {

                        // Run mouse events and display tooltip etc
                        if (start) {
                            this.runPointActions(e);
                        }

                        // Android fires touchmove events after the touchstart even if the
                        // finger hasn"t moved, or moved only a pixel or two. In iOS however,
                        // the touchmove doesn"t fire unless the finger moves more than ~4px.
                        // So we emulate this behaviour in Android by checking how much it
                        // moved, and cancelling on small distances. #3450.
                        if (e.type === "touchmove") {
                            pinchDown = this.pinchDown;
                            hasMoved = pinchDown[0] ? Math.sqrt( // #5266
                                Math.pow(pinchDown[0].chartX - e.chartX, 2) +
                                Math.pow(pinchDown[0].chartY - e.chartY, 2)
                            ) >= 4 : false;
                        }

                        if (pick(hasMoved, true)) {
                            this.pinch(e);
                        }

                    } else if (start) {
                        // Hide the tooltip on touching outside the plot area (#1203)
                        this.reset();
                    }

                } else if (e.touches.length === 2) {
                    this.pinch(e);
                }
            },

這里的normalize比較關(guān)鍵,因?yàn)楫a(chǎn)生tooltip表現(xiàn)不符合預(yù)期的原因應(yīng)該就是:旋轉(zhuǎn)時,由于圖被豎過來了,需要使用觸摸事件的縱坐標(biāo)來表示觸摸的【橫坐標(biāo)】,但highcharts依然采用了事件的橫坐標(biāo)。繼續(xù)看看normalize的內(nèi)容。

/**
             * Takes a browser event object and extends it with custom Highcharts
             * properties `chartX` and `chartY` in order to work on the internal 
             * coordinate system.
             * 
             * @param  {Object} e
             *         The event object in standard browsers.
             *
             * @return {PointerEvent}
             *         A browser event with extended properties `chartX` and `chartY`.
             */
            normalize: function(e, chartPosition) {
                var chartX,
                    chartY,
                    ePos;

                // IE normalizing
                e = e || win.event;
                if (!e.target) {
                    e.target = e.srcElement;
                }

                // iOS (#2757)
                ePos = e.touches ? (e.touches.length ? e.touches.item(0) : e.changedTouches[0]) : e;

                // Get mouse position
                if (!chartPosition) {
                    this.chartPosition = chartPosition = offset(this.chart.container);
                }

                // chartX and chartY
                // 這里是計算chartX和chartY,計算方法是用當(dāng)前觸摸(點(diǎn)擊)事件的橫坐標(biāo)減去圖表的橫坐標(biāo),縱坐標(biāo)減去圖表的縱坐標(biāo)。
                
                if (ePos.pageX === undefined) { // IE < 9. #886.
                    chartX = Math.max(e.x, e.clientX - chartPosition.left); // #2005, #2129: the second case is 
                    // for IE10 quirks mode within framesets
                    chartY = e.y;
                } else {
                    chartX = ePos.pageX - chartPosition.left;
                    chartY = ePos.pageY - chartPosition.top;
                }
                
                // 這里的chartX和chartY已經(jīng)是在表格內(nèi)部的坐標(biāo)了,后續(xù)的邏輯都是根據(jù)這個chartX和chartY來的,如果當(dāng)圖表被豎過來時,人為把這兩個值交換一下,是否就解決了tooltip的問題呢。
                if(豎屏) {
                    // 【豎屏】可以通過在配置表格的時候增加變量來判斷
                    return extend(e, {
                        chartX: Math.round(chartY),
                        chartY: Math.round(chartX)
                    });
                }
                
                return extend(e, {
                    chartX: Math.round(chartX),
                    chartY: Math.round(chartY)
                });
            },

按照這個思路,找到入口文件highcharts.js里對應(yīng)部分的代碼,進(jìn)行修改。修改完成后,發(fā)現(xiàn)tooltip的表現(xiàn)符合預(yù)期了。

經(jīng)過測試, 圖表的其他基本功能正常。之前還擔(dān)心這樣會不會影響lengends的點(diǎn)擊等。后來想了一下,由于是svg畫圖,所有點(diǎn)擊事件應(yīng)該都是直接綁定在元素上的,而不是像canvas一樣強(qiáng)依賴坐標(biāo),所以不會影響。這也是為什么在echarts下進(jìn)行rotate, lengends的交互也會受影響的原因。

由于highcharts的功能太多,這樣的源碼修改功能對其他的功能有無影響,還不能完全確定。待后續(xù)繼續(xù)補(bǔ)充。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95372.html

相關(guān)文章

  • echarts 與 highcharts

    摘要:渲染能力采用渲染除了對使用,一般來說,更適合繪制圖形元素數(shù)量非常大這一般是由數(shù)據(jù)量大導(dǎo)致的圖表如熱力圖地理坐標(biāo)系或平行坐標(biāo)系上的大規(guī)模線圖或散點(diǎn)圖等,也利于實(shí)現(xiàn)某些視覺特效如交通圖。 一.簡介 echartsecharts是百度公司前端開發(fā)的一個圖表庫,2013年發(fā)布第一版,主要采用canvas畫圖,目前版本3.8.4;完全免費(fèi); highcharthighcharts是國外的一家公司...

    王笑朝 評論0 收藏0
  • 螞蟻金服新一代數(shù)據(jù)可視化引擎 G2

    摘要:新公司已經(jīng)呆了一個多月,目前著手一個數(shù)據(jù)可視化的項(xiàng)目,數(shù)據(jù)可視化肯定要用到圖形庫如等,經(jīng)決定我的這個項(xiàng)目用阿里旗下螞蟻金服所開發(fā)的圖表庫。數(shù)據(jù)提示框內(nèi)提示的信息還可以通過格式化函數(shù)動態(tài)指定。 新公司已經(jīng)呆了一個多月,目前著手一個數(shù)據(jù)可視化的項(xiàng)目,數(shù)據(jù)可視化肯定要用到圖形庫如D3、Highcharts、ECharts、Chart等,經(jīng)決定我的這個項(xiàng)目用阿里旗下螞蟻金服所開發(fā)的G2圖表庫。...

    animabear 評論0 收藏0
  • Vue—Cli中使用動態(tài)Highcharts line圖表超初級教學(xué)

    摘要:開始讓動起來我會直接貼部分代碼加少量解釋,建議先看下官方給的動態(tài)實(shí)時刷新示意圖循環(huán)次,線從圖表右側(cè)開始出現(xiàn),軸會分為秒。 效果展示 社會你龍哥,人丑話不多,先來張圖!圖片傳不上去?。?!可能公司限制了,大家自己幻想下吧 highcharts環(huán)境搭配 由于技術(shù)現(xiàn)水平限制,需要用到兩個Highcharts,下面我會解釋,先上代碼 npm install --save highcharts ...

    stackvoid 評論0 收藏0
  • 玩轉(zhuǎn)CSS 3D -正八面體與正十二面體

    摘要:正八面體與正十二面體,這兩個正多面體雖然組合的面比較多,不過因?yàn)榫邆淞藢ΨQ性,所以只需要制作出一半的結(jié)構(gòu),另外一半再用反轉(zhuǎn)的方式接在一起即可。同樣的,旋轉(zhuǎn)讓整個正八面體旋轉(zhuǎn),看起來更有立體感。 正八面體與正十二面體,這兩個正多面體雖然組合的面比較多,不過因?yàn)榫邆淞藢ΨQ性,所以只需要制作出一半的結(jié)構(gòu),另外一半再用反轉(zhuǎn)的方式接在一起即可。 正八面體 正八面體可以想像成兩個金字塔疊合在一起,...

    Neilyo 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<