MPAndroidChart 折线图 时间轴 折线图横轴时间_类目

根据项目中使用的折线图,整理可配置属性:

/**
 * 折线图
 * demo https://echarts.apache.org/examples/zh/editor.html?c=dynamic-data2
 * 文档 https://echarts.apache.org/zh/option.html#title
 */
import { Pieces } from "./share/pieces";

export class LineChartDynamic {
    data = [];
    now = new Date(1997, 9, 3);
    oneDay = 24 * 3600 * 1000;
    value = Math.random() * 1000;

    constructor(myChart) {
        // 绘制图表,初始化绘图数据
        myChart.setOption(this.getOptions(this.data = (() => {
            let data = [];
            for (let i = 0; i < 1000; i++) {
                data.push(this.randomData(this));
            }
            return data;
        })()));
        // 随机数据
        this.setDynamicData(myChart);
    }

    /**
     * 设置数据更新展示
     * @param myChart
     */
    setDynamicData(myChart) {
        let self = this;
        // 设置数据显示
        setInterval(function () {
            for (let i = 0; i < 5; i++) {
                // 出一个进一个,保持数组个数稳定;只入不出则为项目趋势图效果
                self.data.shift();
                self.data.push(self.randomData(self));
            }
            myChart.setOption({
                series: [
                    {
                        data: self.data
                    }
                ]
            });
        }, 1000);
    }

    /**
     * 生成单条数据
     * @param self
     * @returns {{name: string, value: (string|number)[]}}
     */
    randomData(self) {
        self.now = new Date(+self.now + self.oneDay);
        self.value = self.value + Math.random() * 21 - 10;
        // return {  // 1
        //     name: self.now.toString(),
        //     value: [
        //         [ self.now.getFullYear(), self.now.getMonth() + 1, self.now.getDate() ].join('/'),
        //         Math.round(self.value)
        //     ]
        // };
        // return [ // 2
        //     self.now,
        //     Math.round(self.value),
        // ];
        return [ // 3
            [self.now.getFullYear(), self.now.getMonth() + 1, self.now.getDate() ].join('/'),
            Math.round(self.value),
        ];
    }

    /**
     * 配置项
     * @param data
     * @returns Object
     */
    getOptions(data) {
        return {
            title: {
                show: true, // 是否显示标题组件。
                text: 'Dynamic Data & Time Axis', // 主标题文本,支持使用 \n 换行。
                link: 'https://echarts.apache.org/examples/zh/editor.html?c=dynamic-data2', // 主标题文本超链接。
                target: 'blank', // 指定窗口打开主标题超链接。self | blank
                textStyle: {
                    color: '#333',
                    fontStyle: 'normal', // 主标题文字字体的风格。normal | italic | oblique
                    fontWeight: 'bolder', // 主标题文字字体的风格。normal | bold | bolder | lighter
                    // 等字体相关配置...
                },
                subtext: 'Line Chart', // 副标题文本,支持使用 \n 换行。
                sublink: 'https://echarts.apache.org/examples/zh/index.html#chart-type-line', // 副标题文本超链接。
                subtarget: 'blank', // 指定窗口打开副标题超链接。self | blank
                subtextStyle: {}, // 类似主标题样式配置
                textAlign: 'auto', // 整体(包括 text 和 subtext)的水平对齐。auto | left | right | center
                textVerticalAlign: 'auto', // 整体(包括 text 和 subtext)的水平对齐。auto | top | bottom | middle
                /**
                 * 标题内边距,单位px,默认各方向内边距为5,接受数组分别设定上右下左边距。
                 * padding: 5 - 设置内边距为 5
                 * padding: [5, 10] - 设置上下的内边距为 5,左右的内边距为 10
                 * padding: [5, 10, 5, 10] - 分别设置四个方向的内边距,上右下左
                 */
                padding: 5,
                itemGap: 10, // 主副标题之间的间距。
            },
            // backgroundColor: Pieces.getColor(), // 背景色
            legend: { // 图例组件。位置相关配置可调整,配置项较多
                show: true,
                type: 'plain', // 默认 plain 普通图例;scroll 可滚动翻页的图例。当图例数量较多时可以使用
                /**
                 * 项目中图例显示位置:
                 * 上 top: 20, left: 'center'
                 * 下 bottom: 20, left: 'center'
                 * 左 top: 'middle', left: 20,
                 * 右 top: 'middle', right: 20,
                 * 分项设置时,其余时可赋值 'auto'
                 */
                top: '20', // 图例组件离容器上侧的距离。 20具体像素值 | 20%高宽的百分比 | top | middle | bottom
                left: 'center', // 图例组件离容器左侧的距离。 20具体像素值 | 20%高宽的百分比 | left | center | right
                right: 'auto', // 图例组件离容器右侧的距离。 20具体像素值 | 20%高宽的百分比
                bottom: 'auto', // 图例组件离容器下侧的距离。 20具体像素值 | 20%高宽的百分比
                // orient: 'horizontal', // 图例列表的布局朝向。horizontal | vertical
                textStyle: {
                    color: Pieces.getColor(), // 文字的颜色。
                    fontStyle: 'italic', // 文字字体的风格。normal | italic | oblique
                    fontWeight: 'bold', // 文字字体的粗细。normal | bold | bolder | lighter
                    fontFamily: 'sans-serif', // 文字的字体系列。还可以是 'serif' , 'monospace', 'Arial', 'Courier New', 'Microsoft YaHei', ...
                    fontSize: 12, // 文字的字体大小。
                },
            },
            grid: { // 直角坐标系内绘图网格,待研究
                show: true,
                containLabel: true,
            },
            xAxis: { // 直角坐标系 grid 中的 x 轴
                show: true, // 是否显示 x 轴。
                /**
                 * 坐标轴类型。
                 * 'value' 数值轴,适用于连续数据。
                 * 'category' 类目轴,适用于离散的类目数据。为该类型时类目数据可自动从 series.data 或 dataset.source 中取,或者可通过 xAxis.data 设置类目数据。
                 * 'time' 时间轴,适用于连续的时序数据,与数值轴相比时间轴带有时间的格式化,在刻度计算上也有所不同,例如会根据跨度的范围来决定使用月,星期,日还是小时范围的刻度。
                 * 'log' 对数轴。适用于对数数据。
                 */
                type: 'time',
                // name: 'xxx', // 坐标轴名称。
                // nameLocation: 'end', // 坐标轴名称显示位置。start | middle | center | end
                // nameTextStyle: {}, // 坐标轴名称的文字样式。
                // nameGap: 15, // 坐标轴名称与轴线之间的距离。
                // nameRotate: 15, // 坐标轴名字旋转,角度值。
                // inverse: true, // 是否是反向坐标轴。
                /**
                 * 坐标轴刻度最小值。
                 * 可以设置成特殊值 'dataMin',此时取数据在该轴上的最小值作为最小刻度。
                 * 不设置时会自动计算最小值保证坐标轴刻度的均匀分布。
                 * 当设置成 function 形式时,可以根据计算得出的数据最大最小值设定坐标轴的最小值。如:
                 * min: function (value) {
                 *     return value.min - 20;
                 * }
                 * 其中 value 是一个包含 min 和 max 的对象,分别表示数据的最大最小值,这个函数可返回坐标轴的最小值,
                 * 也可返回 null/undefined 来表示“自动计算最小值”(返回 null/undefined 从 v4.8.0 开始支持)。
                 */
                // min: 'dataMin',
                /**
                 * 坐标轴刻度最大值。
                 * 可以设置成特殊值 'dataMax',此时取数据在该轴上的最大值作为最大刻度。
                 * 不设置时会自动计算最大值保证坐标轴刻度的均匀分布。
                 * 同 min
                 */
                // max: 'dataMax',
                /**
                 * 只在数值轴中(type: 'value')有效。
                 * 是否是脱离 0 值比例。设置成 true 后坐标刻度不会强制包含零刻度。在双数值轴的散点图中比较有用。
                 * 在设置 min 和 max 之后该配置项无效。
                 */
                // scale: true,
                /**
                 * 坐标轴的分割段数,需要注意的是这个分割段数只是个预估值,最后实际显示的段数会在这个基础上根据分割后坐标轴刻度显示的易读程度作调整。
                 * 在类目轴中无效。
                 */
                // splitNumber: 5,
                axisLine: { // 坐标轴轴线相关设置。
                    show: true,
                    lineStyle: { // { color , width , type , dashOffset , cap , join , miterLimit , shadowBlur , shadowColor , shadowOffsetX , shadowOffsetY , opacity }
                        color: Pieces.getColor(),
                    }
                },
                axisTick: { // 坐标轴刻度相关设置。
                    show: true,
                    inside: false, // 坐标轴刻度是否朝内,默认朝外。
                    length: 5, // 坐标轴刻度的长度。
                    lineStyle: {}, // { color , width , type , dashOffset , cap , join , miterLimit , shadowBlur , shadowColor , shadowOffsetX , shadowOffsetY , opacity }
                },
                axisLabel: { // 坐标轴刻度标签的相关设置。
                    show: true,
                    /**
                     * 坐标轴刻度标签的显示间隔,在类目轴中有效。
                     * 默认会采用标签不重叠的策略间隔显示标签。
                     * 可以设置成 0 强制显示所有标签。
                     * 如果设置为 1,表示『隔一个标签显示一个标签』,如果值为 2,表示隔两个标签显示一个标签,以此类推。
                     * 可以用数值表示间隔的数据,也可以通过回调函数控制。回调函数格式如下:
                     * (index:number, value: string) => boolean
                     * 第一个参数是类目的 index,第二个值是类目名称,如果跳过则返回 false。
                     */
                    interval: 'auto',
                    inside: false, // 刻度标签是否朝内,默认朝外。
                    rotate: 0, // 刻度标签旋转的角度,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠。旋转的角度从 -90 度到 90 度。
                    margin: 8, // 刻度标签与轴线之间的距离。
                    // formatter: function (value, index) { return value; } // 刻度标签的内容格式器,支持字符串模板和回调函数两种形式。
                    // 文本颜色,字体样式等
                    color: 'inherit', // 设置字体颜色,防止设置轴线颜色后字体颜色默认同步
                    fontStyle: 'italic', // 文字字体的风格。normal | italic | oblique
                    fontWeight: 'bold', // 文字字体的粗细。normal | bold | bolder | lighter
                    fontFamily: 'sans-serif', // 文字的字体系列。还可以是 'serif' , 'monospace', 'Arial', 'Courier New', 'Microsoft YaHei', ...
                    fontSize: 12, // 文字的字体大小。
                },
                splitLine: { // 坐标轴在 grid 区域中的分隔线。
                    show: true, // 是否显示分隔线。默认数值轴显示,类目轴不显示。
                    interval: 'auto', // 坐标轴分隔线的显示间隔,在类目轴中有效。默认同 axisLabel.interval 一样。
                    lineStyle: {} // { color , width , type , dashOffset , cap , join , miterLimit , shadowBlur , shadowColor , shadowOffsetX , shadowOffsetY , opacity }
                },
                // axisPointer: { // 坐标轴指示器配置项。
                //     /**
                //      * 默认不显示。但是如果 tooltip.trigger 设置为 'axis' 或者 tooltip.axisPointer.type 设置为 'cross',则自动显示 axisPointer。
                //      * 坐标系会自动选择显示显示哪个轴的 axisPointer,也可以使用 tooltip.axisPointer.axis 改变这种选择。
                //      */
                //     show: true,
                //     type: 'line', // 指示器类型。line | shadow | none
                //     snap: true, // 坐标轴指示器是否自动吸附到点上。默认自动判断。这个功能在数值轴和时间轴上比较有意义,可以自动寻找细小的数值点。
                //     label: { // 坐标轴指示器的文本标签。一大堆样式
                //     },
                //     lineStyle: {}, // axisPointer.type 为 'line' 时有效。
                //     shadowStyle: {}, // axisPointer.type 为 'shadow' 时有效。
                // },
            },
            yAxis: { // 直角坐标系 grid 中的 y 轴,配置类似 x轴
                type: 'value',
                /**
                 * 坐标轴两边留白策略,类目轴和非类目轴的设置和表现不一样。
                 * 类目轴中 boundaryGap 可以配置为 true 和 false。默认为 true,这时候刻度只是作为分隔线,标签和数据点都会在两个刻度之间的带(band)中间。
                 * 非类目轴,包括时间,数值,对数轴,boundaryGap是一个两个值的数组,分别表示数据最小值和最大值的延伸范围,可以直接设置数值或者相对的百分比,在设置 min 和 max 后无效。 示例:
                 * boundaryGap: ['20%', '20%']
                 */
                boundaryGap: [ 0, '100%' ],
                splitLine: {
                    show: true,
                }
            },
            tooltip: {
                trigger: 'axis',
                alwaysShowContent: false, // 是否永远显示提示框内容,默认情况下在移出可触发提示框区域后 一定时间 后隐藏,设置为 true 可以保证一直显示提示框内容。
                show: true,
                formatter: function (params) {
                    console.log(params);
                    params = params[0];
                    // let date = new Date(params.name); // 1
                    // let date = new Date(params.value[0]); // 2
                    // return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() + ' : ' + params.value[1]; // 1 2
                    return params.value[0] + ':' + params.value[1];
                },
                /**
                 * 浮层的渲染模式, html | richText
                 * 默认以 'html 即额外的 DOM 节点展示 tooltip;
                 * 此外还可以设置为 'richText' 表示以富文本的形式渲染,
                 * 渲染的结果在图表对应的 Canvas 中(目前 SVG 尚未支持富文本),这对于一些没有 DOM 的环境(如微信小程序)有更好的支持。
                 */
                renderMode: 'richText',
                // appendToBody: true, // 配合 renderMode 为 html 使用;本地测试气泡位置有问题,先用 richText 方式
                // className: 'tooltip', // 指定 tooltip 的 DOM 节点的 CSS 类。(只在 html 模式下生效)。
                axisPointer: {},
                backgroundColor: Pieces.getColor(), // 提示框浮层的背景颜色。
                borderColor: Pieces.getColor(), // 提示框浮层的边框颜色。
                borderWidth: 1, // 提示框浮层的边框宽。
                padding: [ 5, 10 ], // 提示框浮层内边距,单位px,默认各方向内边距为5,接受数组分别设定上右下左边距。
                textStyle: {}, // 提示框浮层的文本样式。
            },
            series: [
                { // series-line 折线/面积图
                    name: 'Fake Data', // 系列名称,用于tooltip的显示,legend 的图例筛选,在 setOption 更新数据和配置项时用于指定对应的系列。
                    type: 'line',
                    /**
                     * 从调色盘 option.color 中取色的策略,可取值为:
                     * 'series':按照系列分配调色盘中的颜色,同一系列中的所有数据都是用相同的颜色;
                     * 'data':按照数据项分配调色盘中的颜色,每个数据项都使用不同的颜色。
                     */
                    colorBy: 'series',
                    /**
                     * 标记的图形。
                     * ECharts 提供的标记类型包括
                     * 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
                     */
                    symbol: 'emptyCircle',
                    symbolSize: 10, // 标记的大小,可以设置成诸如 10 这样单一的数字,也可以用数组分开表示宽和高,例如 [20, 10] 表示标记宽为20,高为10。
                    showSymbol: false, // 是否显示 symbol, 如果 false 则只有在 tooltip hover 的时候显示。过于密集不宜展示
                    label: { // 图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
                        show: true,
                        /**
                         * 标签的位置。
                         * 支持:top / left / right / bottom / inside / insideLeft / insideRight / insideTop / insideBottom / insideTopLeft /
                         * insideBottomLeft / insideTopRight / insideBottomRight
                         * 也可以用一个数组表示相对的百分比或者绝对像素值表示标签相对于图形包围盒左上角的位置。
                         * // 绝对的像素值
                         * position: [10, 10],
                         * // 相对的百分比
                         * position: ['50%', '50%']
                         */
                        // position: 'top',
                        // distance: 5, // 距离图形元素的距离。当 position 为字符描述值(如 'top'、'insideRight')时候有效。
                        // rotate、formatter、color、font相关、border、bgcolor、shadow等
                    },
                    endLabel: {}, // 折线端点的标签。 类似 label 配置
                    areaStyle: { // 区域填充样式。设置后显示成区域面积图。
                        color: Pieces.getColor()
                    },
                    /**
                     * 系列中的数据内容数组。数组项通常为具体的数据项。
                     * 注意,如果系列没有指定 data,并且 option 有 dataset,那么默认使用第一个 dataset。如果指定了 data,则不会再使用 dataset。
                     * 可以使用 series.datasetIndex 指定其他的 dataset。
                     * 通常来说,数据用一个二维数组表示。如下,每一列被称为一个『维度』。
                     *  data: [
                     *         // 维度X   维度Y   其他维度 ...
                     *         [  3.4,    4.5,   15,   43],
                     *         [  4.2,    2.3,   20,   91],
                     *         [  10.8,   9.5,   30,   18],
                     *         [  7.2,    8.8,   18,   57]
                     *     ]
                     */
                    data: data
                }
            ]
        };
    }
}

data 数据大体结构都是二位数组,将必要信息整理成 二维数组即能显示折线图,tooltip 则根据传入数据处理显示即可。

 tooltip formatter 回调函数打印数据:

MPAndroidChart 折线图 时间轴 折线图横轴时间_类目_02

 由此可见,节点的值存储在 value 属性上,根据传入数据的结构,能很好的解析出来用于气泡显示。 

调试效果:

MPAndroidChart 折线图 时间轴 折线图横轴时间_类目_03

 

踩坑:

MPAndroidChart 折线图 时间轴 折线图横轴时间_图例_04