JavaScript制作简单的框选图表

下面我来详细讲解一下如何使用JavaScript制作简单的框选图表。

1. 确定布局

首先,我们需要在HTML中确定图表的布局。可以使用<canvas>元素来绘制我们的图表,可以设置其宽度和高度,例如:

<canvas id="myChart" width="600" height="400"></canvas>

2. 获取数据

接下来,我们需要获取数据。可以使用XMLHttpRequest对象或fetch API从后台请求数据,或者直接将数据写死在JavaScript中,例如:

var data = [
    { label: "A", value: 10 },
    { label: "B", value: 20 },
    { label: "C", value: 30 },
    { label: "D", value: 40 },
    { label: "E", value: 50 },
];

3. 绘制图表

使用Canvas API来绘制图表,例如:

var ctx = document.getElementById("myChart").getContext("2d");

var x = 0;
var y = 0;
var width = 200;
var height = 200;

ctx.fillStyle = "lightgray";
ctx.fillRect(x, y, width, height);

for (var i = 0; i < data.length; i++) {
    var value = data[i].value;
    var label = data[i].label;

    ctx.fillStyle = "blue";
    ctx.fillRect(
        x,
        y + i * height / data.length,
        value * width / 100,
        height / data.length - 1
    );

    ctx.fillStyle = "black";
    ctx.fillText(label, x + 5, y + i * height / data.length + 15);
}

这段代码会绘制一个简单的柱状图,允许用户通过鼠标拖拽来框选某些柱子。

4. 实现框选功能

相信你已经注意到代码中的xywidthheight变量,是用来绘制柱状图的矩形范围。我们可以借助鼠标事件来获取用户所框选的区域:

var x1, y1, x2, y2;

document.getElementById("myChart").addEventListener("mousedown", function (e) {
    x1 = e.offsetX;
    y1 = e.offsetY;
});

document.getElementById("myChart").addEventListener("mouseup", function (e) {
    x2 = e.offsetX;
    y2 = e.offsetY;

    var rect = getSelectionRect(x1, y1, x2, y2);
    var selectedBars = getSelectedBars(rect, data);

    console.log(selectedBars);
});

function getSelectionRect(x1, y1, x2, y2) {
    var rect = {};

    rect.left = Math.min(x1, x2);
    rect.top = Math.min(y1, y2);
    rect.width = Math.abs(x2 - x1);
    rect.height = Math.abs(y2 - y1);

    return rect;
}

function getSelectedBars(rect, data) {
    var bars = [];

    for (var i = 0; i < data.length; i++) {
        var value = data[i].value;
        var label = data[i].label;

        var bar = {
            x: x,
            y: y + i * height / data.length,
            width: value * width / 100,
            height: height / data.length - 1,
            label: label,
        };

        if (bar.x + bar.width > rect.left && bar.x < rect.left + rect.width &&
            bar.y + bar.height > rect.top && bar.y < rect.top + rect.height) {
            bars.push(bar);
        }
    }

    return bars;
}

这段代码中,我们使用mousedownmouseup事件来获取用户的框选区域。然后,使用getSelectionRect函数来计算出矩形的左上角坐标、宽度和高度。接着,使用getSelectedBars函数来获取用户框选的柱子,如果柱子的矩形与用户框选的矩形有交集,则将其放入一个数组中,并返回该数组。

示例说明

下面是两个示例,展示如何使用框选图表实现不同的功能。

示例1:选择某个柱子

var data = [
    { label: "A", value: 10 },
    { label: "B", value: 20 },
    { label: "C", value: 30 },
    { label: "D", value: 40 },
    { label: "E", value: 50 },
];

var ctx = document.getElementById("myChart").getContext("2d");

var x = 0;
var y = 0;
var width = 200;
var height = 200;

ctx.fillStyle = "lightgray";
ctx.fillRect(x, y, width, height);

for (var i = 0; i < data.length; i++) {
    var value = data[i].value;
    var label = data[i].label;

    ctx.fillStyle = "blue";
    ctx.fillRect(
        x,
        y + i * height / data.length,
        value * width / 100,
        height / data.length - 1
    );

    ctx.fillStyle = "black";
    ctx.fillText(label, x + 5, y + i * height / data.length + 15);
}

document.getElementById("myChart").addEventListener("mouseup", function (e) {
    var x = e.offsetX;
    var y = e.offsetY;

    var bar = findBar(x, y, data);

    if (bar) {
        alert(bar.label + " is selected.");
    }
});

function findBar(x, y, data) {
    for (var i = 0; i < data.length; i++) {
        var value = data[i].value;
        var label = data[i].label;

        var bar = {
            x: x,
            y: y + i * height / data.length,
            width: value * width / 100,
            height: height / data.length - 1,
            label: label,
        };

        if (x > bar.x && x < bar.x + bar.width &&
            y > bar.y && y < bar.y + bar.height) {
            return bar;
        }
    }

    return null;
}

此示例中,我们在mouseup事件中查找鼠标所在的柱子,如果找到了某个柱子,则弹出提示框。这样就可以通过选择某个柱子来实现一些功能。

示例2:选择任意数量的柱子

var data = [
    { label: "A", value: 10 },
    { label: "B", value: 20 },
    { label: "C", value: 30 },
    { label: "D", value: 40 },
    { label: "E", value: 50 },
];

var ctx = document.getElementById("myChart").getContext("2d");

var x = 0;
var y = 0;
var width = 200;
var height = 200;

ctx.fillStyle = "lightgray";
ctx.fillRect(x, y, width, height);

for (var i = 0; i < data.length; i++) {
    var value = data[i].value;
    var label = data[i].label;

    ctx.fillStyle = "blue";
    ctx.fillRect(
        x,
        y + i * height / data.length,
        value * width / 100,
        height / data.length - 1
    );

    ctx.fillStyle = "black";
    ctx.fillText(label, x + 5, y + i * height / data.length + 15);
}

var selectedBars = [];

document.getElementById("myChart").addEventListener("mouseup", function (e) {
    var x = e.offsetX;
    var y = e.offsetY;

    var bar = findBar(x, y, data);

    if (bar) {
        var index = selectedBars.indexOf(bar);

        if (index >= 0) {
            selectedBars.splice(index, 1);
        } else {
            selectedBars.push(bar);
        }

        redrawChart(data, selectedBars);
    }
});

function findBar(x, y, data) {
    for (var i = 0; i < data.length; i++) {
        var value = data[i].value;
        var label = data[i].label;

        var bar = {
            x: x,
            y: y + i * height / data.length,
            width: value * width / 100,
            height: height / data.length - 1,
            label: label,
        };

        if (x > bar.x && x < bar.x + bar.width &&
            y > bar.y && y < bar.y + bar.height) {
            return bar;
        }
    }

    return null;
}

function redrawChart(data, selectedBars) {
    var ctx = document.getElementById("myChart").getContext("2d");

    var x = 0;
    var y = 0;
    var width = 200;
    var height = 200;

    ctx.fillStyle = "lightgray";
    ctx.fillRect(x, y, width, height);

    for (var i = 0; i < data.length; i++) {
        var value = data[i].value;
        var label = data[i].label;

        ctx.fillStyle = selectedBars.indexOf(label) >= 0 ? "green" : "blue";
        ctx.fillRect(
            x,
            y + i * height / data.length,
            value * width / 100,
            height / data.length - 1
        );

        ctx.fillStyle = "black";
        ctx.fillText(label, x + 5, y + i * height / data.length + 15);
    }
}

此示例中,我们使用selectedBars数组来保存用户选择的柱子。在mouseup事件中,如果点击到了某个柱子,则将其从selectedBars中移除,如果没有点击到某个柱子,则将其添加到selectedBars中。然后,调用redrawChart函数来重绘图表,并在柱子被选择时将其颜色设置为绿色。

这样就可以选择任意数量的柱子,并根据其被选择状态来调整柱子的颜色。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript制作简单的框选图表 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • js 判断当前时间是否处于某个一个时间段内

    要判断当前时间是否处于某个时间段内可以通过 JavaScript 中的 Date 对象来实现。以下是判断当前时间是否处于某个时间段内的完整攻略: 1. 获取当前时间 获取当前时间可以使用 Date 对象来实现,调用 Date 对象构造函数即可得到当前时间的 Date 实例。例如: const currentTime = new Date(); 2. 定义时间…

    JavaScript 2023年5月27日
    00
  • 地址栏传递中文参数乱码在js里用escape转码

    地址栏传递中文参数乱码是因为浏览器默认采用的编码方式是ASCII码(即英文字符的编码),而中文字符不在ASCII码的编码范围内,所以需要进行编码转换。其中一种解决方案是使用escape()函数对中文字符进行转码。 具体步骤如下: 在前端页面中,在传递中文参数的链接中使用escape()函数对参数进行转码。例如: <a href="exampl…

    JavaScript 2023年5月20日
    00
  • 原生js实现淘宝首页点击按钮缓慢回到顶部效果

    实现淘宝首页点击按钮缓慢回到顶部效果可以采用原生Javascript,下面是具体的实现步骤: 1. 获取回到顶部按钮以及页面滚动条 首先,在页面中添加“回到顶部”按钮,然后使用JS代码获取该按钮以及页面滚动条的对象: var scrollBtn = document.getElementById(‘scrollBtn’); var scrollTop = d…

    JavaScript 2023年6月10日
    00
  • js实现数组去重、判断数组以及对象中的内容是否相同

    数组去重的实现: 可以使用 Set 数据结构进行数组去重,因为 Set 对象只存储唯一的值。 let arr = [1, 1, 2, 2, 3, 3]; // 需要去重的数组 let arrUnique = […new Set(arr)]; // 使用 Set 数据结构进行去重 console.log(arrUnique); // 输出 [1, 2, 3…

    JavaScript 2023年5月27日
    00
  • javascript禁止访客复制网页内容的实现代码

    实现禁止访客复制网页内容的功能,可以使用javascript的一些方法来实现。下面是具体的实现攻略。 方案一:禁止复制内容 我们可以通过覆盖系统自带的复制事件的方式来实现禁止复制功能。具体步骤如下: 1. 绑定复制事件 使用Javascript绑定copy事件,添加事件回调函数。代码如下: document.addEventListener("co…

    JavaScript 2023年6月10日
    00
  • JS URL传中文参数引发的乱码问题

    当JS程序需要将中文参数作为URL请求的一部分时,往往会引发“乱码”的问题。 造成该问题的原因是:URL中只能包含某些预定义的字符,例如字母、数字和少数几个符号。如果我们需要处理的中文字符没有被编码成它们应该代表的URL编码序列,那么这些字符就可能不能被正确地识别和使用。 接下来,我们将提供两种针对此问题的攻略: 攻略1:使用encodeURI和decode…

    JavaScript 2023年5月20日
    00
  • JS中的算法与数据结构之队列(Queue)实例详解

    JS中的算法与数据结构之队列(Queue)实例详解 什么是队列? 队列是一种线性数据结构,它是一种先进先出的数据结构(FIFO),即最先进队列的元素也最先出队列。 队列有两个基本操作:入队和出队。入队将元素添加到队列的末尾,而出队则是从队列的前端删除元素。 队列的实现方式 我们可以用数组和链表来实现队列,这里我们介绍一下使用数组来实现队列的方式。 用数组实现…

    JavaScript 2023年5月27日
    00
  • JavaScript中日期函数的相关操作知识

    首先需要了解JavaScript中日期函数的基本操作知识,包括日期的创建、格式化和计算等。 创建日期对象 在JavaScript中,可以使用Date对象来创建一个日期。创建方式有多种,如下所示: 使用日期字符串创建 可以使用日期字符串来创建日期对象,字符串的格式为”YYYY/MM/DD”或者”MM/DD/YYYY”等,例如: var d = new Date…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部