JavaScript制作简单的框选图表

yizhihongxing

下面我来详细讲解一下如何使用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日

相关文章

  • JQuery的ajax的用法在asp中使用$.ajax()实现

    下面我来详细讲解“JQuery的ajax的用法在asp中使用$.ajax()实现”的完整攻略。 什么是jQuery的ajax jQuery的ajax是一种用于发送和接收异步请求的技术,可以通过ajax向服务器发送请求并在不刷新页面的情况下更新数据。它可以使用多种HTTP请求方法,例如GET、POST等,并支持跨域请求和JSONP等功能。 如何在ASP中使用$…

    JavaScript 2023年6月11日
    00
  • js如何查找json数据中的最大值和最小值方法

    当需要在 JSON 数据中查找最大值和最小值时,可以使用 JavaScript 中的 Math.max() 和 Math.min() 函数,结合遍历 JSON 数据实现。 具体步骤如下: 读取 JSON 数据 首先需要将 JSON 数据读入到 JavaScript 中,可以使用 XMLHttpRequest 对象读取远程 JSON 文件,也可以直接将 JSO…

    JavaScript 2023年5月27日
    00
  • Javascript基础知识(二)事件

    Javascript基础知识(二)事件 一、事件的定义和使用 事件是指在操作网页时所产生的一系列动作,例如鼠标点击、键盘输入、窗口滚动等等。通过事件,我们可以给网页绑定相应的响应函数,实现网页的交互功能。 在Javascript中,事件通常被定义为对象的一种,可以使用addEventListener()方法来绑定事件函数。示例代码如下: document.g…

    JavaScript 2023年6月10日
    00
  • 深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例

    深入分析escape()、encodeURI()、encodeURIComponent()的区别及示例 在JavaScript中,编码与解码字符串是非常常见的操作。对于URL、HTML等特殊字符的处理,我们通常会使用escape()、encodeURI()、encodeURIComponent()这几个函数,它们虽然都是编码函数,但是处理的范围和方式各不相同…

    JavaScript 2023年5月19日
    00
  • JavaScript 实现生命游戏

    JavaScript 实现生命游戏攻略 生命游戏是一个经典的细胞自动机,它是由英国数学家约翰·何顿·康威于1970年发明的。该游戏规则虽然简单,但是可玩性极高,主要涉及到生死、繁衍和群体规律等内容。 本文主要介绍了如何使用 JavaScript 实现生命游戏,分别从实现规则和游戏界面两个方面进行阐述。 实现规则 生命游戏的规则和初始状态都是在网格上的,它主要…

    JavaScript 2023年5月28日
    00
  • vue-router两种模式区别及使用注意事项详解

    Vue-router两种模式区别及使用注意事项详解 前言 在学习Vue时,经常会使用Vue-router来实现前端路由。Vue-router有两种模式:history模式和hash模式。本篇文章将详细讲解这两种模式的区别,并给出使用注意事项。 区别 Hash模式 默认模式是hash模式,即地址栏的URL格式是以#/开头,比如: http://localhos…

    JavaScript 2023年6月11日
    00
  • JavaScript 浏览器兼容性总结及常用浏览器兼容性分析

    JavaScript 浏览器兼容性总结及常用浏览器兼容性分析 什么是浏览器兼容性? 浏览器兼容性指的是不同的浏览器(如 Chrome、Safari、Firefox、Edge 等)在对同一段代码的解释和运行方式上存在差异的情况。 由于各个浏览器采取的内核和标准不同,所以同一段 JavaScript 代码在不同的浏览器上的表现可能完全不同。因此,在开发网站或应用…

    JavaScript 2023年6月10日
    00
  • js代码规范之Eslint安装与配置详解

    下面详细讲解“js代码规范之Eslint安装与配置详解”的完整攻略。 1. 什么是eslint Eslint 是一个 JavaScript 代码检查工具,它的作用是用来检查代码是否符合规范,发现问题并提醒开发者。它支持很多不同的规则集合,不但可以检查常规错误,还可以发现潜在的问题。 2. Eslint的安装 可以使用npm进行全局安装,可以使用以下命令行进行…

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