目前使用Highcharts是开发手机端的一些图表页面,相对于交互的要求,这边在开发的过程中遇到了一些问题。目前总结一些问题和解决方法。
1、Highcharts封装
由于Highcharts开发会多处用到,所以我这边进行了封装,目前我还是用的angularJs1.0系列,这边直接贴代码。
<div id="container1" style="min-width: 310px; height: 400px; margin: 0 auto;margin-top: 20px;"></div> <div chart-dean data-id="containerId1" data-chart="chart" data-x="5" data-y="15" data-chart-type="chartType" data-y-axis="yAxis1" data-options="plotOptions" data-stack="true" data-series="series1" data-callback="getBudgetExecution"></div>
.directive("chartDean", [function () { return { restrict: 'EA', scope: { x: "=", id: "=", y: "=", series: "=", callback: "=", stack: "=", chartType:"=", legendEnabled: "=", footerFormat: "=", headerFormat: "=", options: "=", verticalAlign: "=", yAxis: "=" }, template: "", link: function ($scope, element, attributes) { $(function () { $scope.chart = Highcharts.chart($scope.id, { credits: { enabled: false }, chart:{ type:$scope.chartType, marginTop:"40", zoomType: 'x', panning:true }, title: { text: null }, exporting: { enabled: false }, xAxis: [{ labels: { style: { color: "#222", "font-size": "10px", whiteSpace: 'inherit', textOverflow: 'none' } }, categories: [], gridLineDashStyle: "Solid", gridLineWidth: "0.5px", gridLineColor: '#ddd' }], yAxis: $scope.yAxis, tooltip: { formatter: function () { var s = ""; if($scope.footerFormat){ s = $scope.footerFormat(this); }else{ angular.forEach(this.points, function (item) { s += item.series.name + ':' + item.y + '<br/>'; }); } return s; }, backgroundColor: "white", borderWidth: 1, borderRadius: 10, shared: true, followTouchMove:false, style: { "color": "#222", "cursor": "default" }, borderColor: "#ddd" }, plotOptions: $scope.options ? $scope.options : { column: { stacking: $scope.stack ? null : 'normal' } }, legend: { enabled:!$scope.legendEnabled, align: 'center', verticalAlign: $scope.verticalAlign ? $scope.verticalAlign : 'bottom', borderRadius: 0, itemStyle: {color: '#222',"font-size": "12px","font-weight": "normal",lineHeight: '20px'}, itemMarginTop: 5, itemMarginBottom: 10, symbolRadius: 0, shadow: false }, series: $scope.series }); $scope.callback($scope.chart); }); } }; }])
以上封装可接受的传参可以进行去Highcharts官网去查询API。
附送地址:https://api.hcharts.cn/highcharts#chart.width
接下来进入正题。
2、在开发的过程中,页面初始化后,第一次点击图表没有弹出提示框,但是点击第二次开始之后会正常。后来发现是使用了老版本的Highcharts。更新Highcharts版本之后不再有问题。
3、在开发的过程中,交互需要提示框的形状是这样的,但是Highcharts可以在一个表中多条数据不共享的情况下允许你选择弹出框的样式。但是一旦数据共享只会显示长方形框(即tooltip中的shared属性为true),无法显示上述图中的提示框。后来使用Highcharts的useHtml属性去自己写,但是会出现一个问题,手机屏幕太小,数据太多,因还需根据不同的位置,提示框显示在不同的地方,防止最后一条数据的提示框显示在屏幕之外,所以跟交互沟通,决定使用Highcharts自带的提示框,修改其样式,尽量保持一致。(我认为开发的过程中,如果因为一些小的东西,但是会增加很多工作量,这样是可以跟交互进行沟通,但是一些工作量比较小的,虽然需要去研究一下,可以去尽力的跟交互保持一致,毕竟我认为前端是直接面向客户,能尽量跟交互保持一致,尽量保持一致)。
4、以上在开中,我遇到两个难解决的问题。
4.1、如何让B线做到像Highcharts标识线一样,从最左端到最右端,因为如果用数据去塞给B,例如,给B的数据都是一样的,这样可以弄出一条线,但是起点和终点都是在aa的中间到gg的中间,无法做到从最左端到最右端,所以想出了一个办法,在series中加入B,但是不往B里塞数据,只是在Y轴上画一条标识线,如果在提示框中也需要展示其数据,可以自己定义tooltip展示的内容。
4.2、如何让这一条标识的刻度值显示在Y轴
一开始想的是,展示一条线,然后把这条线的刻度值,在获取数据之后,获取Y轴的所有刻度值,然后往刻度数组中push进标识线的值,然后进行排序,这样就OK了,但是有一个问题,当标识线的刻度值于其中一个刻度值很接近的时候,是会造成重叠的,所以这个是有问题的,后来相除一个办法,当相邻的两个刻度值小于刻度间值得1/5的时候,把标识线相邻的刻度减小或者增大,这样可以接近问题,但是用户体验感不好,被一些人否定。
最后的解决方案是:不在刻度上展示,只是在标识线上展示text,然后调整样式,使他像在Y轴的刻度,如果被遮挡,刻度根据两个刻度值小于刻度间值得1/5的时候,调整text的Y进行移动(官网有API,查看一下就可以了解),目前亲测是1/5以下会重叠,以上不会重叠,所以1/5以上不会进行处理,这样就完美的解决问题。
5、平移功能
目前Highcharts只支持在初始化图的时候,进行放大才能进行平移,平移也分两个手指平移和单个手指平移,由于放大是两个手指进行操作,所以我建议移动是单个手指去操作。HighchartsApi中的
zoomType: 'x', panning:true
以上是目前所遇到的一些问题,以后继续开发中会遇到的问题会及时的更新到博客中。