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

仔细检查代码,才发现前人留个个坑,把大写的属性改成小写之后,即可匹配上

当然,这个覆盖的方式是挺暴力的,可以根据需求加些判断处理,不过在现有业务中,不失为一个好办法

最新文章

  1. Azure Backup (2) Azure备份服务
  2. JDK的安装和配置
  3. user_jj两条记录改成一条
  4. Hadoop数据类型介绍
  5. 1.1Linux 系统简介(学习过程)
  6. JAVA排序--[选择排序]
  7. 将秒格式化为时分秒的JS函数
  8. iis7以上版本权限控制
  9. Eclipse调试的一些小技巧
  10. 部署DNS服务
  11. 【转】open参数O_DIRECT的学习
  12. VS2015安装时问题汇总
  13. SDP(7):Cassandra- Cassandra-Engine:Streaming
  14. MongoDB分片群集的部署(用心描述,详细易懂)!!
  15. dijkstra算法解决单源最短路问题
  16. Mac 比较实用的软件
  17. 常见js面试题
  18. Scrapy学习篇(十)之下载器中间件(Downloader Middleware)
  19. Aimbat安装
  20. InnoDB Master Thread I/O Rate详解

热门文章

  1. 移动OA办公——Smobiler第一个开源应用解决方案,快来get吧
  2. HttpClient忽略SSL证书
  3. JDK10源码分析之HashMap
  4. ES 25 - Elasticsearch的分页查询及其深分页问题 (deep paging)
  5. 配置docker服务器支持远程连接
  6. 实时SSH网络吞吐量测试
  7. IDEA运行单个Java文件
  8. Django Form 内置字段
  9. 【BZOJ4816】[SDOI2017] 数字表格(莫比乌斯反演)
  10. QBXT模拟赛2