线形比赛积分增长或竞赛图|Highcharts企业图表代码示列

线形竞赛图(Line Chart)是一种常用的图表类型,用于显示数据随时间或其他连续变量的变化趋势。它通过将数据点连接成一条线,直观地展示数据的走势和模式。

特点:

  • 时间序列分析:线形竞赛图非常适合展示时间序列数据,例如股票价格、气温变化等。
  • 趋势识别:通过观察线条的上升或下降,可以快速识别数据的趋势。
  • 多系列比较:可以在同一图表中绘制多条线,以便比较不同数据集之间的关系。

竞赛图表

示例代码:

javascript 复制代码
const btn = document.getElementById('play-pause-button'),
    input = document.getElementById('play-range'),
    startRound = 0,
    endRound = 20,
    animationDuration = 1000;

// General helper functions
const arrToAssociative = arr => {
    const tmp = {};
    arr.forEach(item => {
        tmp[item[0]] = item[1];
    });

    return tmp;
};

const formatPoints = [];

const chart = Highcharts.chart('container', {
    chart: {
        type: 'line',
        marginRight: 110,
        animation: {
            duration: animationDuration,
            easing: t => t
        }
    },
    title: {
        text: 'F1 2012 Top Ten Drivers',
        floating: true,
        align: 'left',
        x: 70,
        y: 50
    },
    data: {
        csv: document.getElementById('csv').innerText,
        itemDelimiter: '\t',
        complete: function (options) {
            // Store the data for later use, and remove it from the series
            for (let i = 0; i < options.series.length; i++) {
                formatPoints[i] = arrToAssociative(options.series[i].data);
                options.series[i].data = null;
            }
        }
    },
    xAxis: {
        allowDecimals: false,
        min: startRound,
        max: endRound,
        title: {
            text: 'Round #',
            align: 'high',
            textAlign: 'left',
            x: 20,
            y: -20
        }
    },
    yAxis: {
        reversedStacks: false,
        max: 300,
        title: {
            text: 'Points'
        }
    },
    tooltip: {
        split: true,
        headerFormat: '<span style="font-size: 1.2em">{point.x}</span>',
        pointFormat: '{series.name}: {point.y} Points',
        crosshairs: true
    },
    plotOptions: {
        line: {
            animation: false,
            pointStart: startRound,
            marker: {
                enabled: false
            }
        }
    },
    annotations: [
        {
            crop: false,
            labelOptions: {
                borderWidth: 0,
                backgroundColor: undefined,
                align: 'left',
                verticalAlign: 'middle',
                overflow: 'allow',
                style: {
                    pointerEvents: 'none',
                    transition: 'opacity 0.5s'
                },
                x: -8,
                y: -1
            },
            labels: new Array(10).fill({
                text: 0,
                point: {
                    x: 0,
                    xAxis: 0,
                    y: 0,
                    yAxis: 0
                }
            })
        }
    ],

    responsive: {
        rules: [
            {
                condition: {
                    maxWidth: 500
                },
                chartOptions: {
                    chart: {
                        marginTop: 80
                    },
                    title: {
                        floating: false,
                        x: 0,
                        y: 20
                    },
                    yAxis: {
                        labels: {
                            align: 'left',
                            x: 0,
                            y: -3
                        },
                        tickLength: 0,
                        title: {
                            align: 'high',
                            reserveSpace: false,
                            rotation: 0,
                            textAlign: 'left',
                            y: -20
                        }
                    }
                }
            }
        ]
    }
});

function pause(button) {
    button.title = 'play';
    button.className = 'fa fa-play';
    clearTimeout(chart.sequenceTimer);
    chart.sequenceTimer = undefined;
}

function update(sliderClicked) {

    const series = chart.series,
        labels = chart.annotations[0].labels,
        yearIndex = input.value - startRound,
        dataLength = series[0].options.data.length;

    // If slider moved back in time
    if (yearIndex < dataLength - 1) {
        for (let i = 0; i < series.length; i++) {
            const seriesData = series[i].options.data.slice(0, yearIndex);
            series[i].setData(seriesData, false);
        }
    }

    // If slider moved forward in time
    if (yearIndex > dataLength - 1) {
        const remainingYears = yearIndex - dataLength;
        for (let i = 0; i < series.length; i++) {
            for (let j = input.value - remainingYears; j < input.value; j++) {
                series[i].addPoint([formatPoints[i][j]], false);
            }
        }
    }

    const nextnums = [];
    // Add current year if applicable, and update labels
    for (let i = 0; i < series.length; i++) {
        const newY = formatPoints[i][input.value];
        labels[i].options.point.x = yearIndex;
        labels[i].options.point.y = newY;

        if (yearIndex === 0) {
            labels[i].options.text =
                `<span style="color:${series[i].color}">●</span>
                ${series[i].name}</span>`;
        }
        nextnums.push(newY);
        if (series[i].options.data.length <= yearIndex) {
            series[i].addPoint(newY, false);
        }
    }

    if (sliderClicked) {
        chart.redraw(false);
    } else {
        chart.redraw();
    }

    input.value = parseInt(input.value, 10) + 1;

    if (input.value > endRound) {
        // Auto-pause
        pause(btn);
    }
}

function play(button) {
    // Reset slider at the end
    if (input.value > endRound) {
        input.value = startRound;
    }
    button.title = 'pause';
    button.className = 'fa fa-pause';
    chart.sequenceTimer = setInterval(function () {
        update(false);
    }, animationDuration);
}

btn.addEventListener('click', function () {
    if (chart.sequenceTimer) {
        pause(this);
    } else {
        play(this);
    }
});

update(true); // Move to initial position
update(false); // Animate to the first point immediately
play(btn); // Start the animation

// Trigger the update on the range bar click.
input.addEventListener('click', function () {
    update(true);
});
// Stop animation when clicking and dragging range bar
input.addEventListener('input', function () {
    pause(btn);
    update(true);
});
相关推荐
代码搬运媛1 小时前
Jest 测试框架详解与实现指南
前端
为何创造硅基生物2 小时前
C语言 结构体内存对齐规则(通俗易懂版)
c语言·开发语言
吃好睡好便好2 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
星寂樱易李2 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
counterxing2 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
仰泳之鹅2 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
wangqiaowq2 小时前
windows下nginx的安装
linux·服务器·前端
之歆3 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜3 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai108083 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly