D3 二维图表的绘制系列(十六)矩形树状图

上一篇: 雷达图 https://blog.csdn.net/zjw_python/article/details/98486655

下一篇: 树图 https://blog.csdn.net/zjw_python/article/details/98492510

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

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

1 图表效果

在这里插入图片描述

2 数据

树图类的数据不再是csv格式,而是json

{
    "name": "grandfather",
    "children": [
        {
            "name": "father",
            "children": [
                {
                    "name": "son",
                    "children": [
                        {"name": "grandson1", "house": 2},
                        {"name": "grandson2", "house": 3},
                        {"name": "grandson3", "house": 4}

                    ]
                }
            ]
        },
        {
            "name": "mother1",
            "children": [
                {
                    "name": "daughter1",
                    "children": [
                        {"name": "granddaughter1", "house": 4},
                        {"name": "granddaughter2", "house": 2}
                    ]
                },
                {
                    "name": "daughter2",
                    "children": [
                        {"name": "granddaughter3", "house": 4}
                    ]
                }
            ]
        },
        {
            "name": "mother2",
            "children": [
                {
                    "name": "son1",
                    "children": [
                        {"name": "grandson4", "house": 6},
                        {"name": "granddaughter4", "house": 1}
                    ]
                },
                {
                    
                    "name": "son2",
                    "children": [
                        {"name": "granddaughter5", "house": 2},
                        {"name": "grandson5", "house": 3},
                        {"name": "granddaughter5", "house": 2}
                    ]
                    
                }
            ]
        }

    ]
}

3 关键代码

导入数据

d3.json('./data.json').then(function(data){
....

一些样式配置参数

const config = {
        margins: {top: 80, left: 80, bottom: 50, right: 80},
        textColor: 'black',
        title: '矩形树图',
        hoverColor: 'white',
        animateDuration: 1000
    }

数据转换,树图是层次型的数据结构,首选使用d3.hierarchy构造节点,接着将生成root节点传入d3.treemap布局函数中,返回具有布局信息的节点,每个节点都具有x0,x1,y0,y1

/* ----------------------------数据转换------------------------  */
    const root = d3.hierarchy(data)
                    .sum((d) => d.house)
                    .sort((a,b) => a.value - b.value);

    const generateTreeMap = d3.treemap()
                    .size([chart.getBodyWidth(), chart.getBodyHeight()])
                    .round(true)
                    .padding(1);
    
    generateTreeMap(root);

直接绑定具有布局信息的节点数组,然后运用渲染矩形,非常简单

/* ----------------------------渲染矩形------------------------  */
    chart.renderRect = function(){
        const cells = chart.body().selectAll('.cell')
                                    .data(root.leaves());
                
              cells.enter()
                     .append('g')
                     .attr('class', (d, i) => 'cell cell-' + i)
                     .append('rect')
                   .merge(cells)
                     .attr('x', (d) => d.x0)
                     .attr('y', (d) => d.y0)
                     .attr('width', (d) => d.x1 - d.x0)
                     .attr('height', (d) => d.y1 - d.y0)
                     .attr('fill', (d,i) => chart._colors(i % 10));
            
              cells.exit()
                    .remove();     
    }

渲染文本标签,注意限制文本的长度不要超过矩形的宽度

/* ----------------------------渲染文本标签------------------------  */
    chart.renderText = function(){

        const texts = d3.selectAll('.cell')
                            .append('text');
              texts
                .attr('class', 'cell-text')
                .attr('transform', (d) => 'translate(' + (d.x0+d.x1)/2 + ',' + (d.y0+d.y1)/2 + ')' )
                .text((d) => d.data.name)
                .attr('stroke', config.textColor)
                .attr('fill', config.textColor)
                .attr('text-anchor', 'middle')
                .text( function(d){
                    if (textWidthIsOk(d, this)){
                        return d.data.name;
                    }else{
                        return '...';
                    }
                })
        
        // 检测文本长度是否合适
        function textWidthIsOk(d, text){
            const textWidth = text.getBBox().width;
            if ((d.x1-d.x0) >= textWidth) return true;
            return false;
        }

    }

最后绑定鼠标交互事件,鼠标悬停时矩形变色

/* ----------------------------绑定鼠标交互事件------------------------  */
    chart.addMouseOn = function(){

        d3.selectAll('.cell rect')
            .on('mouseover', function(){
                const e = d3.event;
                e.target.style.cursor = 'hand'

                d3.select(e.target)
                    .attr('fill', config.hoverColor);
                
            })
            .on('mouseleave', function(d,i){
                const e = d3.event;
                
                d3.select(e.target)
                    .attr('fill', chart._colors(i % 10));
            });
    }

大功告成!!!


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

在这里插入图片描述

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
下面是使用Direct3D 11绘制一个矩形的代码示例: ``` // 定义矩形的顶点数据 struct Vertex { XMFLOAT3 position; XMFLOAT4 color; }; Vertex vertices[] = { { XMFLOAT3(-1.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, // 左上顶点,红色 { XMFLOAT3( 1.0f, 1.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) }, // 右上顶点,绿色 { XMFLOAT3( 1.0f, -1.0f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, // 右下顶点,蓝色 { XMFLOAT3(-1.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) } // 左下顶点,白色 }; // 定义矩形的索引数据 WORD indices[] = { 0, 1, 2, // 第一个三角形 0, 2, 3 // 第二个三角形 }; // 创建顶点缓冲区 D3D11_BUFFER_DESC vertexBufferDesc = {}; vertexBufferDesc.ByteWidth = sizeof(Vertex) * 4; vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA vertexBufferData = {}; vertexBufferData.pSysMem = vertices; vertexBufferData.SysMemPitch = 0; vertexBufferData.SysMemSlicePitch = 0; ID3D11Buffer* vertexBuffer = nullptr; device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &vertexBuffer); // 创建索引缓冲区 D3D11_BUFFER_DESC indexBufferDesc = {}; indexBufferDesc.ByteWidth = sizeof(WORD) * 6; indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA indexBufferData = {}; indexBufferData.pSysMem = indices; indexBufferData.SysMemPitch = 0; indexBufferData.SysMemSlicePitch = 0; ID3D11Buffer* indexBuffer = nullptr; device->CreateBuffer(&indexBufferDesc, &indexBufferData, &indexBuffer); // 设置顶点缓冲区和索引缓冲区 UINT stride = sizeof(Vertex); UINT offset = 0; context->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset); context->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0); // 设置输入布局和顶点着色器 context->IASetInputLayout(inputLayout); context->VSSetShader(vertexShader, nullptr, 0); // 设置渲染管线状态 context->OMSetRenderTargets(1, &renderTargetView, depthStencilView); context->RSSetState(rasterizerState); context->RSSetViewports(1, &viewport); context->OMSetDepthStencilState(depthStencilState, 0); // 绘制矩形 context->DrawIndexed(6, 0, 0); ``` 上述代码中,我们首先定义了一个 `Vertex` 结构体来表示顶点的位置和颜色信息。然后定义了一个包含 4 个顶点和 6 个索引的矩形。接着创建了顶点缓冲区和索引缓冲区,并将顶点数据和索引数据拷贝到缓冲区中。最后设置渲染管线的状态并调用 `DrawIndexed` 函数来绘制矩形
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值