D3 中的折线和图例间距

2024-03-05

我使用下面的示例,希望在饼图之外有图例,并且还具有文本的折线以及每个切片的计数和百分比。

使用当前代码,我在饼内有饼图,当我将鼠标悬停在切片上时,会显示文本和百分比。

非常感谢您的帮助。谢谢

有人可以帮忙吗,因为我无法继续前进。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <link rel="stylesheet" href="normalize.css">
    <style>
        #chart {
            height: 360px;
            margin: 0 auto; /* NEW */
            position: relative;
            width: 360px;
        }

        .tooltip {
            background: #eee;
            box-shadow: 0 0 5px #999999;
            color: #333;
            display: none;
            font-size: 12px;
            left: 130px;
            padding: 10px;
            position: absolute;
            text-align: center;
            top: 95px;
            width: 80px;
            z-index: 10;
        }

        .legend {
            font-size: 12px;
        }

        rect {
            cursor: pointer; /* NEW */
            stroke-width: 2;
        }

            rect.disabled { /* NEW */
                fill: transparent !important; /* NEW */
            }
        /* NEW */
        h1 { /* NEW */
            font-size: 14px; /* NEW */
            text-align: center; /* NEW */
        }
        /* NEW */
    </style>
</head>
<body>

    <div id="chart"></div>
    <script src="Scripts/d3.v3.min.js"></script>
    <script>
      (function(d3) {
        'use strict';

        var width = 360;
        var height = 360;
        var radius = Math.min(width, height) / 2;
        var donutWidth = 75;
        var legendRectSize = 18;
        var legendSpacing = 4;

        var color = d3.scale.category20(); //builtin range of colors

        var svg = d3.select('#chart')
          .append('svg')
          .attr('width', width)
          .attr('height', height)
          .append('g')
          .attr('transform', 'translate(' + (width / 2) +
            ',' + (height / 2) + ')');

        var arc = d3.svg.arc()
          .innerRadius(radius - donutWidth)
          .outerRadius(radius);

        var pie = d3.layout.pie()
          .value(function(d) { return d.count; })
          .sort(null);

        var tooltip = d3.select('#chart')
          .append('div')
          .attr('class', 'tooltip');

        tooltip.append('div')
          .attr('class', 'label');

        tooltip.append('div')
          .attr('class', 'count');

        tooltip.append('div')
          .attr('class', 'percent');

        d3.csv('weekdays.csv', function(error, dataset) {
          dataset.forEach(function(d) {
            d.count = +d.count;
            d.enabled = true;                                         // NEW
          });

          var path = svg.selectAll('path')
            .data(pie(dataset))
            .enter()
            .append('path')
            .attr('d', arc)
            .attr('fill', function(d, i) {
              return color(d.data.label);
            })                                                        // UPDATED (removed semicolon)
            .each(function(d) { this._current = d; });                // NEW

          path.on('mouseover', function(d) {
            var total = d3.sum(dataset.map(function(d) {
              return (d.enabled) ? d.count : 0;                       // UPDATED
            }));
            var percent = Math.round(1000 * d.data.count / total) / 10;
            tooltip.select('.label').html(d.data.label);
            tooltip.select('.count').html(d.data.count);
            tooltip.select('.percent').html(percent + '%');
            tooltip.style('display', 'block');
          });

          path.on('mouseout', function() {
            tooltip.style('display', 'none');
          });

          /* OPTIONAL
          path.on('mousemove', function(d) {
            tooltip.style('top', (d3.event.pageY + 10) + 'px')
              .style('left', (d3.event.pageX + 10) + 'px');
          });
          */

          var legend = svg.selectAll('.legend')
            .data(color.domain())
            .enter()
            .append('g')
            .attr('class', 'legend')
            .attr('transform', function(d, i) {
              var height = legendRectSize + legendSpacing;
              var offset =  height * color.domain().length / 2;
              var horz = -2 * legendRectSize;
              var vert = i * height - offset;
              return 'translate(' + horz + ',' + vert + ')';
            });

          legend.append('rect')
            .attr('width', legendRectSize)
            .attr('height', legendRectSize)
            .style('fill', color)
            .style('stroke', color)                                   // UPDATED (removed semicolon)
            .on('click', function(label) {                            // NEW
              var rect = d3.select(this);                             // NEW
              var enabled = true;                                     // NEW
              var totalEnabled = d3.sum(dataset.map(function(d) {     // NEW
                return (d.enabled) ? 1 : 0;                           // NEW
              }));                                                    // NEW

              if (rect.attr('class') === 'disabled') {                // NEW
                rect.attr('class', '');                               // NEW
              } else {                                                // NEW
                if (totalEnabled < 2) return;                         // NEW
                rect.attr('class', 'disabled');                       // NEW
                enabled = false;                                      // NEW
              }                                                       // NEW

              pie.value(function(d) {                                 // NEW
                if (d.label === label) d.enabled = enabled;           // NEW
                return (d.enabled) ? d.count : 0;                     // NEW
              });                                                     // NEW

              path = path.data(pie(dataset));                         // NEW

              path.transition()                                       // NEW
                .duration(750)                                        // NEW
                .attrTween('d', function(d) {                         // NEW
                  var interpolate = d3.interpolate(this._current, d); // NEW
                  this._current = interpolate(0);                     // NEW
                  return function(t) {                                // NEW
                    return arc(interpolate(t));                       // NEW
                  };                                                  // NEW
                });                                                   // NEW
            });                                                       // NEW

          legend.append('text')
            .attr('x', legendRectSize + legendSpacing)
            .attr('y', legendRectSize - legendSpacing)
            .text(function(d) { return d; });

        });

      })(window.d3);
    </script>
</body>
</html>

您可以将图例放在您想要的任何位置,方法是将图例分组并使用translate

首先制作 SVG:

  var s = d3.select('#chart')
    .append('svg')
    .attr('width', width)
    .attr('height', height);

现在创建一个图例组:

  var legend_group = s.append('g').attr('transform',
    'translate(' + (width / 3) + ',' + (height / 1.4) + ')');

使用将其翻译到您选择的位置。我已将其移至(width/3, height/1.4)

创建一个将在其中绘制饼图的组。

  var svg = s.append('g')
    .attr('transform', 'translate(' + (width / 2) +
      ',' + (radius) + ')');

让我们为每个切片制作一条折线: 此函数将生成与数据集长度一样多的折线。

function makePolyLines() {
  var polyline = svg.selectAll("polyline")
    .data(pie(dataset), key);

  polyline.enter()
    .append("polyline");
  //hide polyline for which value is 0, a case when legend is clicked.
  svg.selectAll("polyline").style("display", function(d) {
    if (d.value == 0) {
      return "none";
    } else {
      return "block";
    }
  });

  polyline.transition().duration(1000)
    .attrTween("points", function(d) {
      this._current = this._current || d;
      var interpolate = d3.interpolate(this._current, d);
      this._current = interpolate(0);
      return function(t) {
        var d2 = interpolate(t);
        var pos = outerArc.centroid(d2);
        pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
        return [arc.centroid(d2), outerArc.centroid(d2), pos];
      };
    });

  polyline.exit()
    .remove();
}

同样为标签制作文本。

function makeTexts() {
  var text = svg.selectAll(".labels")
    .data(pie(dataset), key);

  text.enter()
    .append("text")
    .attr("dy", ".35em")
    .classed("labels", true)
    .text(function(d) {
      return d.data.label + " (" + d.data.count + ")";
    });
  //hide text for which value is 0, a case when legend is clicked.
  svg.selectAll(".labels").style("display", function(d) {
    if (d.value == 0) {
      return "none";
    } else {
      return "block";
    }
  });

  text.transition().duration(1000)
    .attrTween("transform", function(d) {

      this._current = this._current || d;
      var interpolate = d3.interpolate(this._current, d);
      this._current = interpolate(0);
      return function(t) {
        var d2 = interpolate(t);
        var pos = outerArc.centroid(d2);
        pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
        return "translate(" + pos + ")";
      };
    })
    .styleTween("text-anchor", function(d) {
      this._current = this._current || d;
      var interpolate = d3.interpolate(this._current, d);
      this._current = interpolate(0);
      return function(t) {
        var d2 = interpolate(t);
        return midAngle(d2) < Math.PI ? "start" : "end";
      };
    });

  text.exit()
    .remove();
}

最后调用这两个函数。

1) 最初获取数据后。

2) 每当单击图例并且饼图更新时。

工作代码here http://plnkr.co/edit/sAbnep00GMRkx5Xey6gL?p=preview

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

D3 中的折线和图例间距 的相关文章

  • Facebook 自定义故事与大图像 - 使用 Javascript 打开图

    我正在尝试创建一个自定义故事 每次有人尝试发布它时都会有一个新图像 现在我创建了一个对象 以及将两者结合起来的动作和故事 我想要实现的是一个看起来像这样的故事https fbcdn dragon a akamaihd net hphotos
  • 尝试注册 RCTBridgeModule 类 RCTFileReaderModule

    尝试为名称 FileReaderModule 注册 RCTBridgeModule 类 RCTFileReaderModule 但该名称已由类 FileReaderModule 注册 尝试使用命令react native run ios在i
  • 如何翻转 Twitter Bootstrap 的工具提示

    我正在使用 Twitter 的 Bootstrap 来实现工具提示 目前 工具提示显示在链接上方 我希望工具提示出现在链接下方 我该怎么做呢 我正在触发工具提示 它明确指出 底部 但它不想为我工作 tooltip tooltip place
  • 未捕获的类型错误:无法读取未定义的属性“prop”

    我有 6 个输入复选框 如果选中的复选框超过 3 个 则最后一个复选框将被取消选中 为了更好地理解 请参阅我之前的question https stackoverflow com questions 35195235 if checkbox
  • Swift - 将图像插入 PDF 不再适用于 iOS 13

    目前正在开发在我的贷款计算器应用程序上导出 PDF 的功能 我有一个预览屏幕 可以在您保存 PDF 之前显示它 预览屏幕由带有 html 的 webView 组成 其中包含占位符 我能够成功地将图像插入到正确的占位符上 并将其显示在 PDF
  • 三.js环境光意想不到的效果

    在下面的代码中 我渲染了一些立方体并使用点光源和环境光照亮它们 然而 当设置为 0xffffff 时 AmbientLight 会将侧面的颜色更改为白色 无论其指定的颜色如何 奇怪的是 点光源按预期工作 我怎样才能使环境光表现得像点光 因为
  • Chrome JavaScript 日期构造函数获取 1884 年之前的日期似乎是错误的

    如果我将 1 1 1753 午夜 的 unix 毫秒时间戳值 6847786800000 传递给 Chrome 中的 JavaScript Date 构造函数 则 Chrome 给出的日期看起来非常奇怪 当我使用带有七个参数的 Date 构
  • 如何在美人鱼节点描述中添加链接?

    我想 如下图所示 div class mermaid graph TD A hello B an b important b link A gt B div 在下面添加实际链接link指向http google com 我尝试将相关节点修改
  • 动态更改 vuejs 2 中的选择输入选项

    如何动态更改选择下拉 v model 中的选项 我有 2 个选择输入 其中一个应该根据其他输入进行更改 例如 如果我选择 水果 则选择显示水果 如果我选择 蔬菜 则选择显示蔬菜 我不使用Vuejs 但查看文档后 var TypesArr F
  • 我可以在不同浏览器中获得一致的 CSS 颜色吗?

    我正在测试一个新网站 并且我有一个 div background color bbf6bb 这对我来说似乎无害 然而 在我的 MacBook Pro 上 Firefox 3 6 与 Safari 4 中的颜色看起来非常不同 在 Safari
  • 我们如何使用 thymeleaf 绑定对象列表的列表

    我有一个表单 用户可以在其中添加任意数量的内容表对象这也可以包含他想要的列对象 就像在 SQL 中构建表一样 我尝试了下面的代码 但没有任何效果 并且当我尝试绑定两个列表时 表单不再出现 控制器 ModelAttribute page pu
  • Onblur 事件在另一个 div 的 onclick 之前触发

    如上所述 我有一个按钮 单击该按钮将打开子菜单 对于子菜单中的每个选项 都有三个元素 我认为实际上还有更多元素 但为了简单起见 将其保留为 3 我将焦点放在子菜单的主 div 白色 框架 上 Onblur 这个 div 然后我隐藏子菜单 这
  • CSS:理解和调整字体的行距/行高

    有人问了一个非常相似的问题here https stackoverflow com questions 13701110 css remove line height leading on larger text但确实回答得足够了 CSS
  • CSS 动画自定义属性/变量

    一段时间以来我一直在努力让它发挥作用 关键是内部 div 将具有某种形状 并且可能会不止一个 这就是为什么我使用nth child选择器 这个内部 div 应该显示然后再次隐藏一段时间 问题是 我想在一个动画中为所有 后来的 多个内部 di
  • Babel/RequireJS + typeof“RangeError:超出最大调用堆栈大小”

    我有一个非常基本的 JS 错误 我很羞愧无法解决它 我正在使用 ES6 和 Babel 进行开发 并且正在做一些实验 请注意 我在 Babel 中使用了这些参数 presets es2015 plugins transform es2015
  • 有没有办法从画布上清除一个元素而不消除其他元素?

    我正在使用画布构建页面加载器 并使用 es6 类 虽然目前我无法使其正常工作 原因之一是我找不到清除画布的方法进展 到目前为止 这是我的代码 class Loader constructor width height this width
  • JsGrid 将嵌套对象加载到表中

    我正在 Django 中开发一个 Web 项目并使用 jsGrid 我遇到了问题并且找不到解决方案 我有一个嵌套的 JSON 数据 它是通过组合多个数据库表记录创建的 这是我的 JSON count 3 results personnel
  • Javascript/jQuery 外部高度()

    Does idOfLememt outerHeight 对所有浏览器产生相同的结果 IE7 有什么不同吗 只要去http api jquery com outerHeight http api jquery com outerHeight
  • Angular 2:使用正则表达式进行数字验证

    我正在尝试验证 IE 11 中的数字字段
  • JavaScript 中“键”的类型是什么?

    当我失去焦点并开始思考一个愚蠢的问题时 我遇到了这样的时刻 var a b value b 的类型是什么 我的意思不是 值 的类型 而是标记为 b 的实际键 背景 当我必须创建一个字符串键时 我开始想知道这一点 var a b value

随机推荐

  • 使用 compose 重新创建命名卷

    V renew anon volumes Recreate anonymous volumes instead of retrieving data from the previous containers Does docker comp
  • 如何在单击该图像的 onclick 事件时获取图像源路径

    当图像的 onclick 事件被触发时 我需要获取图像源 我尝试使用 document getElementById example src 但浏览器上的控制台显示 未捕获的类型错误 无法读取 null 的属性 src img src em
  • NamedPipeServerStream 接收 MAX=1024 字节,为什么?

    我正在使用 NamedPipeStream 客户端和服务器 我将数据从客户端发送到服务器 该数据是一个包含二进制数据的序列化对象 当服务器端接收数据时 它总是有最大1024大小 而客户端发送更多 因此 当尝试序列化数据时 这会导致以下异常
  • 可定制的字母替换器

    我一直在开发一个几乎可以替代字母的应用程序 所以你会有一封信和一个输入框 该字母代表将被替换的字母 您在输入框中写下您想要替换的内容 为此 我使用了正则表达式和对象 如果你像这样徘徊 匿名的 到底出了什么问题 julianavar 有什么不
  • 禁用 TabLayout 中的选项卡[重复]

    这个问题在这里已经有答案了 我用过TabLayout来自我的应用程序中最新的设计支持库 这些选项卡附加到一个视图分页器 该视图分页器加载每个选项卡的片段 我想禁用所有选项卡 直到视图页面加载用户选择的选项卡的片段 我无法禁用选项卡布局或使其
  • 使用 EPPlus 将 Excel 工作表格式化为表格

    我有一个 NET Core 应用程序 并且我不熟悉将 EPPlus 库与 C 一起使用 我有一个数据表 其中填充了我目前正在使用 EPPlus 将其插入到 Excel 工作表中的数据 我想知道是否有一种方法可以在将数据添加到工作表之后而不是
  • CUDA PTX 代码 %envreg<32> 特殊寄存器

    我尝试使用 CUDA 驱动程序 API 运行由 cl 内核生成的 PTX 汇编代码 我采取的步骤是这些 标准 opencl 程序 1 加载 cl内核 2 JIT编译 3 获取编译好的ptx代码并保存 到目前为止 一切都很好 我注意到 ptx
  • 在 Mobile Safari 上调试缓慢的 Angular-ui-router 状态更改

    我正在编写一个角度应用程序 使用 Angular ui router 来管理状态 路由 在桌面浏览器 Chrome Safari 上 这工作正常 然而 在 iPhone 4 上的 IOS 6 上的 Mobile Safari 上 以及 iP
  • 使用 WebBrowser .NET 控件放大网页

    IE7 中内置了 缩放 功能 显示在状态栏中 允许您放大至 400 我在演示 模拟应用程序中使用 WebBrowser NET 控件 并且需要放大网页 这是可能吗 我不想简单地拍摄页面照片并将其放大 因为我需要使用页面上的链接和按钮 如果重
  • Angular 6 - 无法解析AppComponent的所有参数

    我正在尝试使用 Angular 6 构建一个应用程序 但我仍在设置一切 但我的应用程序中的依赖注入似乎有问题 它无法解析任何构造函数参数 它们都导致Uncaught Error Can t resolve all parameters fo
  • Heroku 不支持 Neo4j?

    我正在尝试使用 Neo4j 数据库部署 Spring boot 应用程序 但是当我在 Heroku 中找到插件时 我看不到它 如何将 Neo4j 数据库推送到 Heroku 请帮我 先感谢您 This news https docs gra
  • JTable - 复合编辑器焦点

    我有一个由多个组件组成的自定义编辑器 就像是 class MyCellEditor extends AbstractCellEditor implements TableCellEditor JTextArea textArea JButt
  • 如何配置 Hibernate、Spring 和 Apache dbcp 进行连接池?

    我在集成 Spring Hibernate 和 Apache DBCP 时遇到问题 我已经用过DBCPConnectionProvider from here http wiki apache org commons DBCP Hibern
  • 西班牙 Windows 的字符集

    西班牙 Windows 的字符集是什么 Spanish es iso 8859 1 windows 1252
  • 有没有自动更新Javadoc的工具?

    我工作的代码库 很混乱 这种混乱的一方面是我们有大量方法 其签名不再与关联的 Javadoc 匹配 例如 param foo public void doFoo int bar 我不喜欢生成的 Javadoc 因为它几乎总是毫无价值 但我确
  • Android - Webview进度条

    我在网络视图上方添加了进度条 每当我单击链接时 我都会使进度条可见 我想让进度条覆盖在网络视图上 并且我想显示进度条的百分比 我知道css 但我不知道如何改变android中进度条的位置
  • 如何在 Perl 中刷新反引号中的输出?

    如果我有这个 Perl 应用程序 print someshellscript sh 它会打印一堆内容并且需要很长时间才能完成 我如何在 shell 脚本执行过程中打印该输出 看起来 Perl 只会在完成时打印 someshellscript
  • 如何将数据从一个视图控制器传递到另一个 SWIFT

    我正在制作一个应用程序 其中带有搜索栏和范围栏的表格视图必须连接到详细视图控制器 并且该详细视图控制器必须根据选择的单元格显示数据 我有一个数组 其中设置了用于排序和搜索项目的结构 我需要保留此功能 我的详细视图控制器有另一个 swift
  • 打印文本区域文本 - 全长(高度)?

    我有一个网络表单 我的客户希望用户能够打印出来 使用 CSS 进行一些样式设置就可以很好地工作 但是 我有几个textaear字段 如果用户键入的内容超过文本区域的高度 则打印时该类型将被截断 我努力了textarea height 100
  • D3 中的折线和图例间距

    我使用下面的示例 希望在饼图之外有图例 并且还具有文本的折线以及每个切片的计数和百分比 使用当前代码 我在饼内有饼图 当我将鼠标悬停在切片上时 会显示文本和百分比 非常感谢您的帮助 谢谢 有人可以帮忙吗 因为我无法继续前进