D3.js的V5版本-Vue框架中使用(第六章) ---交互式操作

本文介绍如何结合D3.js和Vue.js创建一个交互式的图表应用。通过具体的代码示例,展示了如何利用D3.js进行数据可视化,并利用Vue.js的组件化特性来增强图表的交互体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. Api使用

on("eventName",function);该函数是添加一个监听事件,它的第一个参数是事件类型,第二个参数是响应事件的内容

d3.select(this), 选择当前元素

   常见的事件类型

  • click:鼠标单击某元素时触发,相当于mousedown和mouseup的组合
  • mouseover:鼠标放在某元素上触发
  • mouseout:鼠标移出某元素时触发
  • mousemove:鼠标移动时触发
  • mousedown:鼠标按钮被按下时触发
  • mouseup:鼠标按钮被松开时触发
  • dblclick:鼠标双击时触发

当然还有很多,上面列出来的只是关于鼠标监听事件,还有键盘等的监听事件,在这里就不多讲了

二.Vue使用

<template lang='pug'>
    div.interactive-pane(:id="id")
        svg 
</template>

<script>
/**
 * 交互式操作
 */
import * as d3 from 'd3'
export default {
    name: '',
    data () {
        return {
            id: ''
        }
    },
    methods: {
        uuid () {
            function s4 () {
                return Math.floor((1 + Math.random()) * 0x10000)
                    .toString(16)
                    .substring(1)
            }
            return (
                s4() + s4() + '-' + s4() + '-' + s4() +  '-' + s4() + '-' + s4() + s4() + s4()
            )
        },
    },
    created () {
        this.id = this.uuid()
    },
    mounted () {
        //1.创建svg画布
        let marge = { top: 60, bottom: 60, left: 60, right: 60 }
        let width = document.getElementById(this.id).clientWidth
        let height = document.getElementById(this.id).clientHeight
        const svg = d3.select(this.$el).select('svg').attr('width', width).attr('height', height)
        let g = svg.append('g').attr('transform', 'translate(' + marge.top + ',' + marge.left + ')')
        //2.数据集
        let dataset = [10, 20, 30, 23, 13, 40, 27, 35, 20, 33];
        //3.坐标轴
        //x轴序数比例尺(d3.scaleBand()并不是一个连续性的比例尺,domain()中使用一个数组,不过range()需要是一个连续域)
        let ranges = d3.range(dataset.length)
        let xcale = d3.scaleBand().domain(ranges).range([0, width - marge.left - marge.right])
        let xAxis = d3.axisBottom(xcale)
        g.append('g')
            .attr('transform', 'translate(' + 0 + ',' + (height - marge.top - marge.bottom) + ')')
            .call(xAxis)
        //y轴线性比例尺
        let yscale = d3.scaleLinear().domain([0, d3.max(dataset)]).range([height - marge.top - marge.bottom, 0])
        let yAxis = d3.axisLeft(yscale)
        g.append('g')
            .attr('transform', 'translate(0, 0)')
            .call(yAxis)
        //4.为每个矩形和对应的文字创建一个分组<g>
        let gs = g.selectAll('rect')
            .data(dataset)
            .enter()
            .append('g')
        //5.绘制矩形
        //设置矩形之间的间隙
        let rectPadding = 20 
        gs.append('rect')
            .attr('x', function(d, i) {
                //xcale(i): 画布真实宽度(48)横坐标且从0开始, 0, 48, 96 ... 432
                return xcale(i) + rectPadding/2
            })
            .attr('width', function() {
                //xcale.step() 画布真实宽度(48):width-marge.left-marge.right/dataset.lenght
                return xcale.step() - rectPadding
            })
            .attr('y', function(d){
                return yscale(d)
            })
            .attr('height', function(d){
                return height - marge.top - marge.bottom - yscale(d)
            })
            .attr('fill', 'blue')
            .on("mouseover",function(){
                let rect = d3.select(this)
                    .transition()
                    .duration(1500)
                    .attr("fill","yellow");
            })
            .on("mouseout",function(){
                let rect = d3.select(this)
                    .transition()
                    .delay(1500)
                    .duration(1500)
                    .attr("fill","blue");
            })
        
        //6.绘制文字
        gs.append('text')
            .attr('x', function(d, i) {
                return xcale(i) + rectPadding/2
            })
            .attr('width', function() {
                return xcale.step() - rectPadding
            })
            .attr('y', function(d) {
                return yscale(d);
            })
    }
}
</script>

<style lang="scss" scoped>
.interactive-pane {
    width: 100%;
    height: 1000px;
}
</style>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值