D3 二维图表的绘制系列(十三)多符号散点图

Echarts 图表绘制:散点图 Echarts散点图是一种常用的数据可视化图表类型,用于展示两个或多个维度的数据分布情况。散点图通过在坐标系中绘制数据点的位置来表示数据的关系。Echarts散点图的特点如下:二维数据展示:散点图通常用于展示二维数据,其中每个数据点在坐标系中的位置表示了两个维度的数值关系。例如,可以用散点图展示身高和体重之间的关系,或者展示收入和教育程度之间的关系。明确的数据关系:散点图通过点的位置来展示数据的关系,可以清晰地看出数据之间的趋势、分布和相关性。 阅读详情

上一篇: 基础散点图 https://blog.youkuaiyun.com/zjw_python/article/details/98483109

下一篇: 气泡图 https://blog.youkuaiyun.com/zjw_python/article/details/98485368

代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/article/details/98182540

本图完整的源码地址: https://github.com/zjw666/D3_demo/tree/master/src/scatterChart/multiSymbolChart

1 图表效果

在这里插入图片描述

2 数据

x,y,x1,y1,x2,y2,x3,y3
24,12,95,45,35,75,32,85
39,20,74,62,82,24,34,46
78,15,14,64,3,75,64,19
15,80,32,67,45,62,84,39
36,70,10,68,36,10,38,49
7,11,67,2,67,14,34,20
36,13,31,47,95,9,74,73
34,89,34,75,5,98,3,2
9,95,74,69,31,47,32,20
72,35,26,65,16,36,99,65
46,78,85,42,32,14,43,12
73,95,8,6,81,62,10,95

3 关键代码

导入数据

d3.csv('./data.csv', function(d){
    return {
        x: +d.x,
        y: +d.y,
        x1: +d.x1,
        y1: +d.y1,
        x2: +d.x2,
        y2: +d.y2,
        x3: +d.x3,
        y3: +d.y3,
    };
}).then(function(data){
......

样式参数配置

const config = {
        margins: {top: 80, left: 80, bottom: 50, right: 80},
        textColor: 'black',
        gridColor: 'gray',
        ShowGridX: [10, 20, 30, 40, 50, 60, 70 ,80, 90, 100],
        ShowGridY: [10, 20, 30, 40, 50, 60, 70 ,80, 90, 100],
        title: '多符号散点图',
        pointSize: 100,
        hoverColor: 'white',
        animateDuration: 1000
    }

尺度转换,这里要注意,X和Y轴的最大值的计算

/* ----------------------------尺度转换------------------------  */
    chart.scaleX = d3.scaleLinear()
                    .domain([0, Math.ceil(d3.max(data, (d) => getMaxNum(d,'x'))/10)*10])
                    .range([0, chart.getBodyWidth()]);
    
    chart.scaleY = d3.scaleLinear()
                    .domain([0, Math.ceil(d3.max(data, (d) => getMaxNum(d,'y'))/10)*10])
                    .range([chart.getBodyHeight(), 0]);
    
    //获取数据行最大x值或y值
    function getMaxNum(d, type){
        const nums = [];
        Object.keys(d).forEach((key) => {
            if (key.indexOf(type) > -1) nums.push(d[key]);
        })
        return d3.max(nums);
    }

渲染数据点,为方便数据绑定,我们先转换了一下数据的结构,渲染步骤跟基础散点图类似,区别在于我们使用path元素,通过d3.symbol()指定不同的数据点形状

/* ----------------------------渲染数据点------------------------  */
    chart.renderPoints = function(){
        /*
            改变数据结构,方便渲染
            [
                [[x,y],[x,y],...],
                [[x1,y1],[x1,y1],...],
                [[x2,y2],[x2,y2],...],
                [[x3,y3],[x3,y3],...],
            ]
        */
        const tempData = data.map((d) => {
            const items = [];
            d3.permute(d, Object.keys(d)).forEach((item,i,array) => {
                if (i % 2 === 0){
                    items.push([array[i],array[i+1],i/2]);
                }
            });
            return items;
        });

        const multiData = d3.zip.apply(this,tempData);

        let groups = chart.body().selectAll('.g')
                        .data(multiData);

        let points = groups.enter()
                              .append('g')
                           .merge(groups)
                              .attr('class', (d,i) => 'g points-' + i)
                              .attr('fill', (d,i) => chart._colors(i))
                              .selectAll('.point')
                              .data((d) => d);
            
            groups.exit()
                    .remove();

            points.enter()
                    .append('path')
                    .classed('point', true)
                  .merge(points)
                    .attr('transform', (d) => 'translate(' + chart.scaleX(d[0]) + ',' + chart.scaleY(d[1]) + ')')
                    .attr('d', d3.symbol().type(function (d) {
                        return d3.symbols[d[2]];
                    }).size(1))
                    .transition().duration(config.animateDuration)
                    .attr('d', d3.symbol().type(function (d) {
                        return d3.symbols[d[2]];
                    }).size(config.pointSize));
                    
            
            points.exit()
                    .remove();
            
    }

接着就是渲染坐标轴、文本标签和网格线等

/* ----------------------------渲染坐标轴------------------------  */
    chart.renderX = function(){
        chart.svg().insert('g','.body')
                .attr('transform', 'translate(' + chart.bodyX() + ',' + (chart.bodyY() + chart.getBodyHeight()) + ')')
                .attr('class', 'xAxis')
                .call(d3.axisBottom(chart.scaleX));
    }

    chart.renderY = function(){
        chart.svg().insert('g','.body')
                .attr('transform', 'translate(' + chart.bodyX() + ',' + chart.bodyY() + ')')
                .attr('class', 'yAxis')
                .call(d3.axisLeft(chart.scaleY));
    }

    chart.renderAxis = function(){
        chart.renderX();
        chart.renderY();
    }

    /* ----------------------------渲染文本标签------------------------  */
    chart.renderText = function(){
        d3.select('.xAxis').append('text')
                            .attr('class', 'axisText')
                            .attr('x', chart.getBodyWidth())
                            .attr('y', 0)
                            .attr('fill', config.textColor)
                            .attr('dy', 30)
                            .text('X');

        d3.select('.yAxis').append('text')
                            .attr('class', 'axisText')
                            .attr('x', 0)
                            .attr('y', 0)
                            .attr('fill', config.textColor)
                            .attr('dx', '-30')
                            .attr('dy', '10')
                            .text('Y');
    }

    /* ----------------------------渲染网格线------------------------  */
    chart.renderGrid = function(){
        d3.selectAll('.yAxis .tick')
            .each(function(d, i){
                if (config.ShowGridY.indexOf(d) > -1){
                    d3.select(this).append('line')
                        .attr('class','grid')
                        .attr('stroke', config.gridColor)
                        .attr('x1', 0)
                        .attr('y1', 0)
                        .attr('x2', chart.getBodyWidth())
                        .attr('y2', 0);
                }
            });

        d3.selectAll('.xAxis .tick')
            .each(function(d, i){
                if (config.ShowGridX.indexOf(d) > -1){
                    d3.select(this).append('line')
                        .attr('class','grid')
                        .attr('stroke', config.gridColor)
                        .attr('x1', 0)
                        .attr('y1', 0)
                        .attr('x2', 0)
                        .attr('y2', -chart.getBodyHeight());
                }
            });
    }

添加鼠标交互事件,与基础散点图相似

/* ----------------------------绑定鼠标交互事件------------------------  */
    chart.addMouseOn = function(){
        //防抖函数
        function debounce(fn, time){
            let timeId = null;
            return function(){
                const context = this;
                const event = d3.event;
                timeId && clearTimeout(timeId)
                timeId = setTimeout(function(){
                    d3.event = event;
                    fn.apply(context, arguments);
                }, time);
            }
        }

        d3.selectAll('.point')
            .on('mouseover', function(d){
                const e = d3.event;
                const position = d3.mouse(chart.svg().node());
                e.target.style.cursor = 'hand'

                d3.select(e.target)
                    .attr('fill', config.hoverColor);
                
                chart.svg()
                    .append('text')
                    .classed('tip', true)
                    .attr('x', position[0]+5)
                    .attr('y', position[1])
                    .attr('fill', config.textColor)
                    .text('x: ' + d[0] + ', y: ' + d[1]);
            })
            .on('mouseleave', function(d){
                const e = d3.event;
                
                d3.select(e.target)
                    .attr('fill', chart._colors(d[2]));
                    
                d3.select('.tip').remove();
            })
            .on('mousemove', debounce(function(){
                    const position = d3.mouse(chart.svg().node());
                    d3.select('.tip')
                    .attr('x', position[0]+5)
                    .attr('y', position[1]-5);
                }, 6)
            );
    }

大功告成!!!


如果觉得这篇文章帮助了您,请打赏一个小红包鼓励作者继续创作哦!!!

在这里插入图片描述

D3 二维图表的绘制系列(一)介绍 1 介绍 D3 (或者叫 D3.js )是一个基于 web 标准的 JavaScript 可视化库. D3 可以借助 SVG, Canvas 以及HTML 将你的数据生动的展现出来. D3 结合了强大的可视化交互技术以及数据驱动 DOM 的技术,让你可以借助于现代浏览器的强大功能自由的对数据进行可视化 学习了d3一个多月,通过绘制一些简单的二维图表,总算入门了d3。强烈推荐《D3数据可视化实战... 阅读详情

相关推荐

D3 二维图表的绘制系列(十四)气泡图

上一篇: 多符号散点图 https://blog.youkuaiyun.com/zjw_python/article/details/98480632 下一篇: 雷达图 https://blog.youkuaiyun.com/zjw_python/article/details/98201470 代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/artic...

zjw_python的博客 3658

D3js 获取X,Y轴坐标

D3 就不多做介绍了,是一个非常强大的作图的工具。它到底怎么样,有多强大,看看官网d3js.org 就知道了. 参考地址: 1. http://www.pkuwwt.tk/d3-tutorial-cn/about.html 2. http://www.ourd3js.com/wordpress 3. www.d3js.org 要实现找到柱状图的X轴的坐标值,需要借助另外一个插

草原孤狼的专栏 8069

MATLAB作图

二维图形 1.曲线图 MATLAB是通过取点连线来作图的,所以我们在利用MATLAB作图时,需要先知道该图像上的一系列点的横坐标以及纵坐标。 具体方法有以下三个: plot(x,y,s) plot(x,y) plot(x1,y1,s1,x2,y2,s2,...,xn,yn,sn) 其中的s为限制线的因素: y 黄色 m 洋红色 c 蓝绿色 r ...

雨潇的博客 1189

java散点图_Java 创建 Excel 散点图

散点图是研究数据分布时常用的一种工具,通过观察散点图中坐标点的位置,可以帮助用户更加清晰直观的判断变量间是否存在关联关系。本文将介绍如何使用Free Spire.XLS for Java在Excel中创建散点图。JAR包导入:方法1:下载Free Spire.XLS forJava包并解压缩,然后将lib文件夹下的Spire.Xls.jar包作为依赖项导入到Java应用程序中。方法2: 直接通过...

weixin_42398629的博客 995

d3-render:声明式和可重复使用的D3。用一个功能替换选择,附加,数据等

D3渲染 声明式和可重复使用的D3。用一个功能替换select , append , data , join , enter , exit , transition等。 警告,目前处于高度试验阶段。 API将更改。 文章 。 有什么不同? 代替命令性代码: import * as d3 from &#39;d3&#39; ; // HTML file has an <svg> element const svg = d3 . select ( &#39;svg&#39; ) ; svg . append ( &#39;rect&#39; ) . attr ( &#39;fill&#39; , &#39;pink&#39; ) . attr ( &#39;x&#39; , 0 ) . attr ( &#39;width&#39; , 100 ) . attr ( &#39;height&#39; , 100 ) ; 编写这样的声明式样式: import render from &#39;d3-ren

从AT指令到万物互联:移远EG800K-CN模块的协议栈深度解析与实践指南

本文深度解析移远EG800K-CN 4G模块的协议栈架构与AT指令体系,涵盖MQTT云端集成、多协议配置优化及工业级故障排除指南。通过实战示例展示如何利用该模块构建稳定可靠的物联网连接方案,实现从设备到云端的万物互联。

jupyter5notebook的博客 362

使用D3绘制图表(3)--添加坐标轴和文本标签

使用D3绘制图表(3)--添加坐标轴和文本标签   上一篇是曲线的绘制,这样仅仅只是有一条线,完全先是不出数据想要表现的内容,于是我们要添加坐标系,添加坐标系和画线类似。   1.还是没有变化的html页面 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <link re

cxu123321的博客 3763

J1939协议实用指南与J1939数据记录方案

“没错,这是一份SAE J1939简单、实用指南。”—虹科 **开篇:**在这篇介绍中,我们介绍了J1939协议的基本知识,其中包括PGN和SPN。因为这是一篇偏向应用的简介,所以您还将会学习到如何通过DBC文件解码J1939数据、如何记录J1939、典型的应用案例和实用技巧。下面,来了解下这份简单易懂的J1939介绍吧~ 什么是J1939? 简而言之,SAE J1939其实是一套标准,重型车辆ECU间就是按照这套标准在CAN总线上进行通信的。当今大多数车辆都通过CAN(Controller Area Ne

1万+

群表示论之D3或S3的二次不可约表示

linux-0.11调试教程 4829

组建高效AI开发团队:角色、技能与协作

在当今科技飞速发展的时代,人工智能(AI)已经成为各个领域的核心驱动力。组建高效的AI开发团队对于企业和科研机构来说至关重要,它能够推动创新、提高竞争力、实现业务目标。本文的目的在于为那些希望组建或优化AI开发团队的管理者、技术负责人以及相关从业者提供全面的指导。范围涵盖了团队角色的定义、所需技能的分析、团队协作的策略,以及实际项目中的应用和相关资源的推荐。本文将首先介绍AI开发团队的核心概念与联系,包括团队角色、技能和协作之间的关系。接着阐述核心算法原理和具体操作步骤,结合数学模型和公式进行详细讲解。

2502_91592937的博客 995

Vue + ECharts:从零构建智慧农业数据监控大屏(附完整源码)」 「超实用!一步步实现智慧农业大屏,完整代码+讲解」 「前端新手友好:Vue + ECharts 打造炫酷农业数据大屏」 「

Vue + ECharts:从零构建智慧农业数据监控大屏(附完整源码)」 「超实用!一步步实现智慧农业大屏,完整代码+讲解」 「前端新手友好:Vue + ECharts 打造炫酷农业数据大屏」 「前端可视化项目实战:智慧农业监控大屏开发详解」 「农作物可视化监控:用 Vue 和 ECharts 构建大屏应用」 「从零开始开发一个智慧农业数据大屏(代码+图表展示)」 「前端新手也能实现!智慧农业监控大屏开发教程」 「用 Vue 和 ECharts 搭建动态数据大屏:详细图文教程」 「学习前端大屏开发:

sky10100100的博客 1535

D3 二维图表的绘制系列(十二)基础散点图

上一篇: 南丁格尔图 https://blog.youkuaiyun.com/zjw_python/article/details/98479641 下一篇: 多符号散点图 https://blog.youkuaiyun.com/zjw_python/article/details/98201470 代码结构和初始化画布的Chart对象介绍,请先看 https://blog.youkuaiyun.com/zjw_python/art...

zjw_python的博客 2545

GStreamer —— 2.1、Windows搭建GStreamer环境,Qt加载GStreamer库后运行 - “教程1:Hello world!“(附:完整源码)

GStreamer —— 2、Windows搭建GStreamer环境,Qt加载GStreamer库后运行"教程1:Hello world!"

797

MATLAB 之 绘制三维图形的基本函数、三维曲面和其他三维图形

【代码】MATLAB 之 绘制三维图形的基本函数、三维曲面和其他三维图形。

每天进步一点点! 2万+

2025年GESP12月认证C++一级真题解析

摘要 本文包含13道C++编程选择题,每题2分,涉及语法、运算符、循环、条件判断等知识点。题目考察了变量命名规则、运算符优先级、赋值语句、循环控制、格式化输出等内容。部分题目解析与标答存在差异,例如第4题逗号表达式输出应为5但标答为4,第6题赋值运算结果应为4 4但标答为3 4等。这些题目适合用于检验基础编程能力,但需注意部分标答可能存在争议,建议结合具体编译环境验证。最后一题考察"漂亮数"判断,要求填写数字某位能被3整除的条件表达式。

lan_in的博客 751

深度学习实战35-图卷积神经网络GCN模型的搭建与应用

大家好,我是微学AI,今天给大家介绍一下深度学习实战35-图卷积神经网络GCN模型的搭建与应用,GCN是一种用于处理图结构数据的深度学习模型,它可以捕捉节点之间的拓扑关系和局部特征,并进行图级别的预测和分类任务。下面将介绍如何搭建并应用GCN模型。

微学AI的博客 2226

d3.js 旋转图形_MATLAB二维图形

7.2 二维图形MATLAB提供了众多的二维图形绘图函数,这些函数的分类[R.D.1]如图7-3所示。可以看出,MATLAB基本的二维图形包括线型(line)、条型(bar)、区域型(area)、方向矢量型(direction)、辐射型(radial)、散点型(scatter)等多种类型,图中已经将各个函数所能够绘制图形的基本样式做了小的缩略图。本节介绍常用二维绘图函数的使用。至于其...

weixin_39603050的博客 430

AIGC算法工程师 面试八股文

1、简述DDPM的算法原理 2、什么是重参数化技巧?Diffusion Models和VAE中的重参数化技巧是如何使用的? VAE中的重参数化技巧 Diffusion Models中的重参数化技巧 3、什么是马尔可夫过程?DDPM中的马尔可夫链是如何定义的? 马尔可夫过程 DDPM马尔可夫链 4、为什么DDPM前向过程中前期加噪少,后期加噪多? 5、VAE和Diffusion Models中的变分推断是什么? 6、Negative Prompt实现的原理是什么?

沉迷单车的追风少年 1万+

二维图Matplotlib Pyplot

二维图Matplotlib Pyplot

herry57的博客 404

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

ECharts Map3D实战:如何巧妙解决散点图点击失效与多symbol共存问题

本文深入探讨了在ECharts Map3D中实现多symbol散点图时遇到的点击失效问题,并提供了基于分层渲染与事件代理的巧妙解决方案。通过分离视觉层与交互层,该方案不仅确保了点击事件的稳定触发,还完美支持了自定义图标(symbol)的多样化展示,有效提升了三维地理数据可视化的交互体验与开发效率。

weixin_28559803的博客 287

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

数学建模笔记 day-03

B站司守奎视频

m0_58321769的博客 645

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

python中matplotlib的使用(一)

需要导入matplotlib库 import matplotlib.pyplot as plt 或者 from matplotlib.pyplot import * 1、建立空白图 fig = plt.figure(figsize=(4,2)) # figsize = (4,2) 第一个数字表示大图中包含四个小图,第二个数字表示一行有几个小图 ax1 = fig.add_subplot(22...

jocker_775065019的博客 357

MATLAB常用画图命令汇总

2022.6.28更新了热力图,一时半会儿应该用不到matlab了,以后有缘再更 2023.7.1真想不到这个文章还有继续更新的一天,祝大家都读研快乐吧

User525600的博客 6万+

数学建模学习(7):Matlab绘图

最基础的二维图形绘制方法:plot-plot命令自动打开一个图形窗口Figure;用直线连接相邻两数据点来绘制图形-根据图形坐标大小自动缩扩坐标轴,将数据标尺及单位标注自动加到两个坐标轴上,可自定坐标轴,可把x, y 轴用对数坐标表示-如果已经存在一个图形窗口,plot命令则清除当前图形,绘制新图形可单窗口单曲线绘图;可单窗口多曲线绘图;可单窗口多曲线分图绘图;可多窗口绘图-可任意设定曲线颜色和线型;可给图形加坐标网线和图形加注功能y = sin(x);plot(x,y)

qq_60498436的博客 2612

数据可视化(matplotlib绘图)

基于Matplotlib模块的绘图 使用简单绘图语句,实现复杂绘图效果 以交互式操作实现渐趋精细的图形效果 使用嵌入式的Latex输出具有印刷级别的图表,科学表达式和符号文本 对图表的组成元素实现精细化控制 导入和画图准备 导入模块matplotlib.pyplot import matplotlib.pyplot as plt 在notebook中显示所绘图像 %matplotlib inl...

dongzixian的博客 425

matlab作图汇总

首先推荐一篇matlab绘图的博文:https://blog.youkuaiyun.com/sunyueqinghit/article/details/81905509 一.二维图 1.二维曲线图 程序 x = 0:0.25:12; y1 = x.^2; y2 = 12 - x; plot(x, y1, x, y2) xlabel('x');ylabel('y'); %产生图例 legend('y1...

马马也的个人博客 1019
上一篇: D3 二维图表的绘制系列(十二)基础散点图
下一篇: D3 二维图表的绘制系列(十一)南丁格尔图
PAT-python-zjw
博客等级 码龄10年 381粉丝 408原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值