解决 jquery+highcharts xy轴反转画图时引起的series-label错位的问题

769 阅读7分钟

一、数据

已知一组画图的数据,x 轴数据 xAxisData 和 series 数据 seriesData 如下:  

    var xAxisData = [
        0.65,  0.835, 3.52, 6.32, 8.56, 10.61, 12.79, 14.59, 14.89, 15.19, 17.69, 20.49, 23.29, 26.09,
        28.89, 31.57, 33.18, 33.37, 33.56, 36.17, 38.97, 41.77, 44.57, 47.37, 50.17, 52.97, 55.77, 57.86,
        58.01, 58.16, 60.81, 63.61, 66.41, 69.21, 72.01, 74.81, 77.61, 80.41, 82.53, 82.65, 82.77, 85.35,
        88.02, 90.69, 93.36, 95.93, 98.23, 100.93, 103.63, 106.325, 107.175, 107.29, 107.65
    ]
        
    var seriesData = [
        {
            "data": [
                0.000085, 0.000088, 0.000163, 0.000269, 0.000372, 0.000481, 0.000611, 0.000728, 0.000748,
                0.000768, 0.000948, 0.001166, 0.001398, 0.001641, 0.001894, 0.00214, 0.002289, 0.002307,
                0.002324, 0.002565, 0.002821,  0.00307,  0.003308, 0.003533, 0.003739, 0.003925, 0.004085,
                0.004188, 0.004194, 0.004201, 0.004303, 0.004378, 0.004418, 0.00442, 0.004382, 0.004302,
                0.004178, 0.004008, 0.003848, 0.003838, 0.003829,  0.003593, 0.003306, 0.002973, 0.002594,
                0.002185,  0.001784, 0.001272, 0.000717, -0.000125, -0.000072,  -0.000097, -0.000178
            ],
            "name": "param1"
        },
        {
            "data": [
                0.000182, 0.00019, 0.000351, 0.000577, 0.000799, 0.001034, 0.001313, 0.001565, 0.001608,
                0.001651, 0.002038, 0.002506, 0.003006,  0.00353, 0.004072, 0.004603, 0.004924, 0.004961,
                0.004999, 0.005519, 0.00607, 0.006606, 0.007121, 0.007605, 0.008052, 0.008454, 0.008804,
                0.009027, 0.009042, 0.009056, 0.009281, 0.00945, 0.009545, 0.009559, 0.009488, 0.009329,
                0.009078, 0.008731, 0.008404, 0.008384, 0.008364, 0.007881, 0.007291, 0.006608, 0.005832,
                0.005, 0.004188, 0.003166, 0.002098, 0.001126, 0.00094,  0.000925, 0.000897
            ],
            "name": "param2"
        },
        {
            "data": [
                0, 0, -0.000001, -0.000001, -0.000002, -0.000003, -0.000004, -0.000004, -0.000005,
                -0.000005,-0.000006, -0.000007, -0.000009,  -0.000011, -0.000013, -0.000015, -0.000016,
                -0.000016,-0.000017, -0.000019, -0.000022, -0.000024, -0.000027, -0.00003, -0.000033,
                -0.000036, -0.000039, -0.000041, -0.000041, -0.000041, -0.000043, -0.000046, -0.000047,
                -0.000049, -0.00005, -0.000051, -0.000051, -0.000051, -0.00005, -0.00005, -0.00005,
                -0.000049, -0.000046, -0.000044, -0.00004, -0.000036,-0.000032, -0.000027,
                -0.000021, -0.000016, -0.000014, -0.000014, -0.000013
            ],
            "name": "param3"
        },
        {
            "data": [
                -0.000001, 0.000008, 0.00013, 0.000257,  0.000368, 0.000474, 0.00059, 0.000689, 0.000705,
                0.000722, 0.000859, 0.001019, 0.001186, 0.001361, 0.001545, 0.001729, 0.001845, 0.001859,
                0.001872, 0.00207, 0.00229, 0.002521, 0.002761, 0.003012, 0.003274, 0.003555, 0.003837,
                0.004056, 0.004072,  0.004088, 0.004377, 0.004697, 0.005031, 0.00538, 0.005746, 0.006129,
                0.006532, 0.006958, 0.007298, 0.007318, 0.007337, 0.007775, 0.008258, 0.008779, 0.00934,
                0.009919, 0.01045, 0.011107, 0.011804, 0.012531, 0.012621, 0.012634, 0.012672
            ],
            "name": "param4"
        },
        {
            "data": [
                0.001169, 0.001211, 0.001781, 0.002319, 0.002747, 0.003116, 0.00348, 0.00376, 0.003804,
                0.003847, 0.004177, 0.004497, 0.00476, 0.004966, 0.00511, 0.005186, 0.005202, 0.005202,
                0.005202, 0.00517, 0.005067, 0.004894, 0.004648, 0.00433, 0.003943, 0.003472, 0.002952,
                0.00252, 0.002488, 0.002456, 0.001854, 0.001164, -0.000429, -0.000379, -0.001202, -0.002068,
                -0.002967, -0.003899, -0.004626, -0.004666, -0.004707, -0.005608, -0.00656, -0.007532, -0.008517,
                -0.009465, -0.010272, -0.01119, -0.012066, -0.012879, -0.012971, -0.012983, -0.013021
            ],
            "name": "param5"
        },
        {
            "data": [
                0.002514, 0.002603, 0.00383, 0.004985, 0.005906, 0.006699, 0.007483, 0.008086, 0.00818,
                0.008273, 0.008983, 0.009671, 0.01024, 0.010685, 0.010997, 0.011163, 0.011199, 0.0112,
                0.011201, 0.011137, 0.010923, 0.010557, 0.010038, 0.009365, 0.008544, 0.007548, 0.006449,
                0.005537, 0.00547, 0.005403, 0.004136, 0.002695, 0.001215, 0.000839, -0.002424, -0.004218,
                -0.006094, -0.00804, -0.009555, -0.009639, -0.009723, -0.011596, -0.013567, -0.01557, -0.017588,
                -0.019513, -0.021139, -0.022968, -0.024688, -0.026249, -0.026423, -0.026446, -0.026517
            ],
            "name": "param6"
        }
    ]

二、 依赖

 <script src="https://code.hcharts.cn/10.3.2/highcharts.js"></script>
 <script src="https://code.hcharts.cn/10.3.2/modules/series-label.js"></script>
 <script src="https://code.hcharts.cn/10.3.2/modules/annotations.js"></script>

三、画图容器

  <div id="container" style="width: 760px; height: 650px"></div>

四、原始数据画图

4.1 代码

var chart = Highcharts.chart('container', {
	chart: {
      type: 'line',
      zoomType: 'x' //拖动鼠标可以缩放的维度
    },
	title: {
		text: 'test'
	},
	credits: {
      enabled: false
    },
	legend: {
      align: 'center', // 水平方向位置
      verticalAlign: 'top', // 垂直方向位置
      x: 0, // 距离 x 轴的距离
      y: -10 // 距离 Y 轴的距离
    },
	plotOptions: {
      line: {
        label: {
          enabled: true,
          minFontSize: 15,
          maxFontSize: 15
        },
        dataLabels: {
          // 开启数据标签
          enabled: false
        },
        uniqType: '1'
        // 关闭鼠标跟踪,对应的提示框、点击事件会失效
        // enableMouseTracking: false
      }
    },
	xAxis: {
      title: {
        text: 'X',
        style: {
          fontSize: 15
        }
      },
      categories: xAxisData
    },
	yAxis: {
		title: {
			text: 'Y'
		}
	},
	series: seriesData
});

4.2 效果

image.png

4.3 分析及思路

原始数据画图的效果如上图所示,该图没有满足需求。需求是需要将图逆时针旋转90度(x,y交换),并且 x 轴和 y 轴的数据从从小往大进行排序,思路如下:

  • 第一种思路是将整个图表容器进行旋转,但是效果上并不是特别好,不推荐。
  • 第二种思路是通过查阅官方文档,发现可以通过配置 inverted=true 来将 x 和 y 轴进行反转,效果如下图所示。

4.4 存在问题

我采用了第二种思路,画出的图如下: image.png

上图虽然解决了x 和 y 互换的问题,但仍然存在一些问题:

  1. x 轴从下往上数据没有按从小到大的顺序排列;
  2. x 轴数据和 y 轴数据不匹配,正常情况下是:x=0.65,y=-0.03为一组,以此类推;
  3. 图的形状需要是开口向上的,而不是向下的;
  4. series-label 标签没有对应到每一条线上。

只要把上面几个问题解决了,就能到达最终的效果了。

五、优化画图

针对第一个问题,我将 x 轴的数据进行了反转(添加了 reverse() 方法)。 image.png

表面上看起来似乎第二个问题好像也解决了,其实不是的,在反转 x 轴数据的同时,对应的每一组 series 数据也需要反转,否则数据就对不上了。 image.png

到这一步,可以看见我们已经解决了问题1、2、3了。

关于问题4,我也费了老大劲,花了好多时间查资料都没能解决 series-label 的问题,目前看来既没有人遇见过这个问题,官方也没有解决的办法。

但是值得庆幸的是,在查资料的过程中,我发现了另外一种办法,就是通过配置 annotations 可以达到类似的效果,所以我干脆弃用 series-label,选择使用 annotations 了。

要使用 annotations,那我们的 series 数据的数据结构就需要改变一下,每个 series 都需要增加 keys = ['y', 'id'] 参数,并且 data 的结构改为二维数据 [[点1的值, 点1的id], [点2的值, 点2的id], ...],为了使 annotations 标签与对应的 series 颜色保持一致,还可以设置 color,lineColor 等 。

在配置 annotations.labels 时,我们只需要配置标签显示的位置为某个点的位置(data 中 的 第二个参数),标签显示的文本等。

代码如下:

var colors = {
   'param1': 'rgb(124, 181, 236)',
   'param2': 'black',
   'param3': 'rgb(144, 237, 125)',
   'param4': 'rgb(247, 163, 92)',
   'param5': 'rgb(128, 133, 233)',
   'param6': 'rgb(241, 92, 128)'
}

var xAxisData = [
    0.65, 0.835, 3.52, 6.32, 8.56, 10.61, 12.79, 14.59, 14.89, 15.19, 17.69, 20.49,
    23.29, 26.09, 28.89, 31.57, 33.18, 33.37, 33.56, 36.17, 38.97, 41.77, 44.57, 47.37,
    50.17, 52.97, 55.77, 57.86, 58.01, 58.16, 60.81, 63.61, 66.41, 69.21, 72.01, 74.81,
    77.61, 80.41, 82.53, 82.65, 82.77, 85.35, 88.02, 90.69, 93.36, 95.93, 98.23, 100.93,
    103.63, 106.325, 107.175, 107.29, 107.65
].reverse()
    
var seriesData = [
  {
    keys: ['y', 'id'],
    data: [
      [0.000085, 'param10'], [0.000088, 'param11'], [0.000163, 'param12'],
      [0.000269, 'param13'], [0.000372, 'param14'], [0.000481, 'param15'],
      [0.000611, 'param16'], [0.000728, 'param17'], [0.000748, 'param18'],
      [0.000768, 'param19'], [0.000948, 'param110'], [0.001166, 'param111'],
      [0.001398, 'param112'], [0.001641, 'param113'], [0.001894, 'param114'],
      [0.00214, 'param115'], [0.002289, 'param116'], [0.002307, 'param117'],
      [0.002324, 'param118'], [0.002565, 'param119'], [0.002821, 'param120'],
      [0.00307, 'param121'], [0.003308, 'param122'], [0.003533, 'param123'],
      [0.003739, 'param124'], [0.003925, 'param125'], [0.004085, 'param126'],
      [0.004188, 'param127'], [0.004194, 'param128'], [0.004201, 'param129'],
      [0.004303, 'param130'], [0.004378, 'param131'], [0.004418, 'param132'],
      [0.00442, 'param133'], [0.004382, 'param134'], [0.004302, 'param135'],
      [0.004178, 'param136'], [0.004008, 'param137'], [0.003848, 'param138'],
      [0.003838, 'param139'], [0.003829, 'param140'], [0.003593, 'param141'],
      [0.003306, 'param142'], [0.002973, 'param143'], [0.002594, 'param144'],
      [0.002185, 'param145'], [0.001784, 'param146'], [0.001272, 'param147'],
      [0.000717, 'param148'], [-0.000125, 'param149'], [-0.000072, 'param150'],
      [-0.000097, 'param151'], [-0.000178, 'param152']
    ].reverse(),
    lineColor: 'rgb(124, 181, 236)',
    color: 'rgb(124, 181, 236)',
    name: 'param1'
  },
  {
    keys: ['y', 'id'],
    data: [
      [0.000182, 'param20'], [0.00019, 'param21'], [0.000351, 'param22'],
      [0.000577, 'param23'], [0.000799, 'param24'], [0.001034, 'param25'],
      [0.001313, 'param26'], [0.001565, 'param27'], [0.001608, 'param28'],
      [0.001651, 'param29'], [0.002038, 'param210'], [0.002506, 'param211'],
      [0.003006, 'param212'], [0.00353, 'param213'], [0.004072, 'param214'],
      [0.004603, 'param215'], [0.004924, 'param216'], [0.004961, 'param217'],
      [0.004999, 'param218'], [0.005519, 'param219'], [0.00607, 'param220'],
      [0.006606, 'param221'], [0.007121, 'param222'], [0.007605, 'param223'],
      [0.008052, 'param224'], [0.008454, 'param225'], [0.008804, 'param226'],
      [0.009027, 'param227'], [0.009042, 'param228'], [0.009056, 'param229'],
      [0.009281, 'param230'], [0.00945, 'param231'], [0.009545, 'param232'],
      [0.009559, 'param233'], [0.009488, 'param234'], [0.009329, 'param235'],
      [0.009078, 'param236'], [0.008731, 'param237'], [0.008404, 'param238'],
      [0.008384, 'param239'], [0.008364, 'param240'], [0.007881, 'param241'],
      [0.007291, 'param242'], [0.006608, 'param243'], [0.005832, 'param244'],
      [0.005, 'param245'], [0.004188, 'param246'], [0.003166, 'param247'],
      [0.002098, 'param248'], [0.001126, 'param249'], [0.00094, 'param250'],
      [0.000925, 'param251'], [0.000897, 'param252']
    ].reverse(),
    lineColor: 'black',
    color: 'black',
    name: 'param2'
  },
  {
    keys: ['y', 'id'],
    data: [
      [0, 'param30'], [0, 'param31'],
      [-0.000001, 'param32'], [-0.000001, 'param33'], [-0.000002, 'param34'],
      [-0.000003, 'param35'], [-0.000004, 'param36'], [-0.000004, 'param37'],
      [-0.000005, 'param38'], [-0.000005, 'param39'], [-0.000006, 'param310'],
      [-0.000007, 'param311'], [-0.000009, 'param312'], [-0.000011, 'param313'],
      [-0.000013, 'param314'], [-0.000015, 'param315'], [-0.000016, 'param316'],
      [-0.000016, 'param317'], [-0.000017, 'param318'], [-0.000019, 'param319'],
      [-0.000022, 'param320'], [-0.000024, 'param321'], [-0.000027, 'param322'],
      [-0.00003, 'param323'], [-0.000033, 'param324'], [-0.000036, 'param325'],
      [-0.000039, 'param326'], [-0.000041, 'param327'], [-0.000041, 'param328'],
      [-0.000041, 'param329'], [-0.000043, 'param330'], [-0.000046, 'param331'],
      [-0.000047, 'param332'], [-0.000049, 'param333'], [-0.00005, 'param334'],
      [-0.000051, 'param335'], [-0.000051, 'param336'], [-0.000051, 'param337'],
      [-0.00005, 'param338'], [-0.00005, 'param339'], [-0.00005, 'param340'],
      [-0.000049, 'param341'], [-0.000046, 'param342'], [-0.000044, 'param343'],
      [-0.00004, 'param344'], [-0.000036, 'param345'], [-0.000032, 'param346'],
      [-0.000027, 'param347'], [-0.000021, 'param348'], [-0.000016, 'param349'],
      [-0.000014, 'param350'], [-0.000014, 'param351'], [-0.000013, 'param352']
    ].reverse(),
    lineColor: 'rgb(144, 237, 125)',
    color: 'rgb(144, 237, 125)',
    name: 'param3'
  },
  {
    keys: ['y', 'id'],
    data: [
      [-0.000001, 'param40'], [0.000008, 'param41'], [0.00013, 'param42'],
      [0.000257, 'param43'], [0.000368, 'param44'], [0.000474, 'param45'],
      [0.00059, 'param46'], [0.000689, 'param47'], [0.000705, 'param48'],
      [0.000722, 'param49'], [0.000859, 'param410'], [0.001019, 'param411'],
      [0.001186, 'param412'], [0.001361, 'param413'], [0.001545, 'param414'],
      [0.001729, 'param415'], [0.001845, 'param416'], [0.001859, 'param417'],
      [0.001872, 'param418'], [0.00207, 'param419'], [0.00229, 'param420'],
      [0.002521, 'param421'], [0.002761, 'param422'], [0.003012, 'param423'],
      [0.003274, 'param424'], [0.003555, 'param425'], [0.003837, 'param426'],
      [0.004056, 'param427'], [0.004072, 'param428'], [0.004088, 'param429'],
      [0.004377, 'param430'], [0.004697, 'param431'], [0.005031, 'param432'],
      [0.00538, 'param433'], [0.005746, 'param434'], [0.006129, 'param435'],
      [0.006532, 'param436'], [0.006958, 'param437'], [0.007298, 'param438'],
      [0.007318, 'param439'], [0.007337, 'param440'], [0.007775, 'param441'],
      [0.008258, 'param442'], [0.008779, 'param443'], [0.00934, 'param444'],
      [0.009919, 'param445'], [0.01045, 'param446'], [0.011107, 'param447'],
      [0.011804, 'param448'], [0.012531, 'param449'], [0.012621, 'param450'],
      [0.012634, 'param451'], [0.012672, 'param452']
    ].reverse(),
    lineColor: 'rgb(247, 163, 92)',
    color: 'rgb(247, 163, 92)',
    name: 'param4'
  },
  {
    keys: ['y', 'id'],
    data: [
      [0.001169, 'param50'], [0.001211, 'param51'], [0.001781, 'param52'],
      [0.002319, 'param53'], [0.002747, 'param54'], [0.003116, 'param55'],
      [0.00348, 'param56'], [0.00376, 'param57'], [0.003804, 'param58'],
      [0.003847, 'param59'], [0.004177, 'param510'], [0.004497, 'param511'],
      [0.00476, 'param512'], [0.004966, 'param513'], [0.00511, 'param514'],
      [0.005186, 'param515'], [0.005202, 'param516'], [0.005202, 'param517'],
      [0.005202, 'param518'], [0.00517, 'param519'], [0.005067, 'param520'],
      [0.004894, 'param521'], [0.004648, 'param522'], [0.00433, 'param523'],
      [0.003943, 'param524'], [0.003472, 'param525'], [0.002952, 'param526'],
      [0.00252, 'param527'], [0.002488, 'param528'], [0.002456, 'param529'],
      [0.001854, 'param530'], [0.001164, 'param531'], [-0.000429, 'param532'],
      [-0.000379, 'param533'], [-0.001202, 'param534'], [-0.002068, 'param535'],
      [-0.002967, 'param536'], [-0.003899, 'param537'], [-0.004626, 'param538'],
      [-0.004666, 'param539'], [-0.004707, 'param540'], [-0.005608, 'param541'],
      [-0.00656, 'param542'], [-0.007532, 'param543'], [-0.008517, 'param544'],
      [-0.009465, 'param545'], [-0.010272, 'param546'], [-0.01119, 'param547'],
      [-0.012066, 'param548'], [-0.012879, 'param549'], [-0.012971, 'param550'],
      [-0.012983, 'param551'], [-0.013021, 'param552']
    ].reverse(),
    lineColor: 'rgb(128, 133, 233)',
    color: 'rgb(128, 133, 233)',
    name: 'param5'
  },
  {
    keys: ['y', 'id'],
    data: [
      [0.002514, 'param60'], [0.002603, 'param61'], [0.00383, 'param62'],
      [0.004985, 'param63'], [0.005906, 'param64'], [0.006699, 'param65'],
      [0.007483, 'param66'], [0.008086, 'param67'], [0.00818, 'param68'],
      [0.008273, 'param69'], [0.008983, 'param610'], [0.009671, 'param611'],
      [0.01024, 'param612'], [0.010685, 'param613'], [0.010997, 'param614'],
      [0.011163, 'param615'], [0.011199, 'param616'], [0.0112, 'param617'],
      [0.011201, 'param618'], [0.011137, 'param619'], [0.010923, 'param620'],
      [0.010557, 'param621'], [0.010038, 'param622'], [0.009365, 'param623'],
      [0.008544, 'param624'], [0.007548, 'param625'], [0.006449, 'param626'],
      [0.005537, 'param627'], [0.00547, 'param628'], [0.005403, 'param629'],
      [0.004136, 'param630'], [0.002695, 'param631'], [0.001215, 'param632'],
      [0.000839, 'param633'], [-0.002424, 'param634'], [-0.004218, 'param635'],
      [-0.006094, 'param636'], [-0.00804, 'param637'], [-0.009555, 'param638'],
      [-0.009639, 'param639'], [-0.009723, 'param640'], [-0.011596, 'param641'],
      [-0.013567, 'param642'], [-0.01557, 'param643'], [-0.017588, 'param644'],
      [-0.019513, 'param645'], [-0.021139, 'param646'], [-0.022968, 'param647'],
      [-0.024688, 'param648'], [-0.026249, 'param649'], [-0.026423, 'param650'],
      [-0.026446, 'param651'], [-0.026517, 'param652']
    ].reverse(),
    lineColor: 'rgb(241, 92, 128)',
    color: 'rgb(241, 92, 128)',
    name: 'param6'
  }
]

Highcharts.chart('container', {
	chart: {
      type: 'line',
      zoomType: 'x',
      inverted: true
    },
    credits: {
      enabled: false
    },
	title: {
		text: 'test'
	},
	tooltip: {
		enabled: true
	},
	xAxis: {
      title: {
        text: 'X',
        style: {
          fontSize: 15
        }
      },
      categories: xAxisData
    },
    yAxis: {
      title: {
        text: 'Y',
        style: {
          fontSize: 15
        }
      },
      labels: {
        style: {
          fontSize: 15
        },
        formatter: function () {
          return this.value
        }
      }
    },
    annotations: [{
	labels: [{
	  point: 'param142',
	  text: 'param1',
	  backgroundColor: colors['param1']
	}, {
	  point: 'param232',
	  text: 'param2',
	  backgroundColor: colors['param2']
	}, {
	  point: 'param326',
	  text: 'param3',
	  backgroundColor: colors['param3']
	}, {
	  point: 'param447',
	  text: 'param4',
	  backgroundColor: colors['param4']
	}, {
	  point: 'param547',
	  text: 'param5',
	  backgroundColor: colors['param5']
	}, {
	  point: 'param647',
	  text: 'param6',
	  backgroundColor: colors['param6']
	}],
	labelOptions: {
	  x: 50, y: -10
	}
    }],
    series: seriesData,
});

效果如下: image.png

六、总结

作为程序员,我能理解那种遇到技术难点,又找不到解决办法的焦躁感,特别是没有参考,没有帮助的时候真的很难受,所以如果我的文章能帮您解决类似的问题,那么请您点个赞,感谢大家!!!