d3 访问分组条形图中的嵌套数据

2024-01-08

我正在通过嵌套 .csv 文件构建分组条形图。该图表也可以作为折线图查看,因此我想要一个适合折线对象的嵌套结构。我原来的 .csv 看起来像这样:

Month,Actual,Forecast,Budget
Jul-14,200000,-,74073.86651
Aug-14,198426.57,-,155530.2499
Sep-14,290681.62,-,220881.4631
Oct-14,362974.9,-,314506.6437
Nov-14,397662.09,-,382407.67
Dec-14,512434.27,-,442192.1932
Jan-15,511470.25,511470.25,495847.6137
Feb-15,-,536472.5467,520849.9105
Mar-15,-,612579.9047,596957.2684
Apr-15,-,680936.5086,465313.8723
May-15,-,755526.7173,739904.081
Jun-15,-,811512.772,895890.1357

我的嵌套是这样的:

  d3.csv("data/net.csv", function(error, data) {
    if (error) throw error;

            var headers = d3.keys(data[0]).filter(function(head) {
            return head != "Month";
          });

                  data.forEach(function(d) {
                    d.month = parseDate(d.Month);
          });
            var categories = headers.map(function(name) { 

              return {
                name: name, // "name": the csv headers except month
                values: data.map(function(d) { 
                  return {
                    date: d.month, 
                    rate: +(d[name]),
                    };
                }),
              };

            });

构建我的图表的代码是:

  var bars = svg.selectAll(".barGroup")
        .data(data) // Select nested data and append to new svg group elements
        .enter()
        .append("g")
        .attr("class", "barGroup")   
        .attr("transform", function (d) { return "translate(" + xScale(d.month) + ",0)"; });

  bars.selectAll("rect")
        .data(categories)
        .enter()
        .append("rect")
        .attr("width", barWidth)
        .attr("x", function (d, i) { if (i < 2) {return 0;} else {return xScale.rangeBand() / 2;}})
        .attr("y", function (d) { return yScale(d.rate); })
        .attr("height", function (d) { return h - yScale(d.rate); })
        .attr("class", function (d) { return lineClass(d.name); });

g 元素很好,各个条形都映射到它们,并且正确应用了 x 值和类别。

我的问题在于访问条形高度和 y 值的“速率”数据。在上面的形式中,它给出一个 NaN。我还尝试使用类别数据附加 g 元素,然后附加矩形:

  .data(function(d) { return d.values })

这允许我访问汇率数据,但将所有 36 个条形图映射到每个范围带。

它在更扁平的数据结构中也可以很好地工作,但是当它嵌套两层时我似乎无法使用它,尽管查看了大量示例和问题。

如何访问费率数据?

为了响应 Cyril 的请求,以下是完整代码:

    var margin = {top: 20, right: 18, bottom: 80, left: 50},
        w = parseInt(d3.select("#bill").style("width")) - margin.left - margin.right,
        h = parseInt(d3.select("#bill").style("height")) - margin.top - margin.bottom;

    var customTimeFormat = d3.time.format.multi([
      [".%L", function(d) { return d.getMilliseconds(); }],
      [":%S", function(d) { return d.getSeconds(); }],
      ["%I:%M", function(d) { return d.getMinutes(); }],
      ["%I %p", function(d) { return d.getHours(); }],
      ["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
      ["%b %d", function(d) { return d.getDate() != 1; }],
      ["%b", function(d) { return d.getMonth(); }],
      ["%Y", function() { return true; }]
    ]);


    var parseDate = d3.time.format("%b-%y").parse;

    var displayDate = d3.time.format("%b %Y");

    var xScale = d3.scale.ordinal()
        .rangeRoundBands([0, w], .1);

    var xScale1 = d3.scale.linear()
          .domain([0, 2]);

    var yScale = d3.scale.linear()
         .range([h, 0])
         .nice();

    var xAxis = d3.svg.axis()
        .scale(xScale)
        .tickFormat(customTimeFormat)
        .orient("bottom");

    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left")
        .innerTickSize(-w)
        .outerTickSize(0);

    var svg = d3.select("#svgCont")
        .attr("width", w + margin.left + margin.right)
        .attr("height", h + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var thous = d3.format(",.0f")

    var lineClass = d3.scale.ordinal().range(["actual", "forecast", "budget"]);  

    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-10, 0])
      .html(function(d) {
        return "<p id='date'>" + displayDate(d.date) + "</p><p id='value'>$" + thous(d.rate);
      })

    d3.csv("data/net.csv", function(error, data) {
      if (error) throw error;

              var headers = d3.keys(data[0]).filter(function(head) {
              return head != "Month";
            });

                    data.forEach(function(d) {
                      d.month = parseDate(d.Month);
            });
              var categories = headers.map(function(name) { 

                return {
                  name: name, 
                  values: data.map(function(d) {
                    return {
                      date: d.month, 
                      rate: +(d[name]),
                      };
                  }),
                };

              });

    var min = d3.min(categories, function(d) {
                        return d3.min(d.values, function(d) {
                            return d.rate;
                        });
                    });



    var max = d3.max(categories, function(d) {
                        return d3.max(d.values, function(d) {
                            return d.rate;
                        });
                    });

    var minY = min < 0 ? min * 1.2 : min * 0.8;

                  xScale.domain(data.map(function(d) { return d.month; }));
                  yScale.domain([minY, (max * 1.1)]);

    var barWidth = headers.length > 2 ? xScale.rangeBand() / 2 : xScale.rangeBand() ;

    svg.call(tip);

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + h + ")")
        .call(xAxis);

    svg.append("g")
          .attr("class", "y axis")
          .call(yAxis);

    var bars = svg.selectAll(".barGroup")
          .data(data) 
          .enter()
          .append("g")
          .attr("class", "barGroup")   
          .attr("transform", function (d) { return "translate(" + xScale(d.month) + ",0)"; });

    bars.selectAll("rect")
          .data(categories)
          .enter()
          .append("rect")
          .attr("width", barWidth)
          .attr("x", function (d, i) { if (i < 2) {return 0;} else {return xScale.rangeBand() / 2;}})
          .attr("y", function (d) { return yScale(d.rate); })
          .attr("height", function (d) { return h - yScale(d.rate); })
          .attr("class", function (d) { return lineClass(d.name) + " bar"; });


    var legend = svg.selectAll(".legend")
          .data(headers) 
          .enter()
          .append("g")
          .attr("class", "legend");

    legend.append("line")
          .attr("class", function(d) { return lineClass(d); })
          .attr("x1", 0)
          .attr("x2", 40)
          .attr("y1", function(d, i) { return (h + 30) + (i *14); })
          .attr("y2", function(d, i) { return (h + 30) + (i *14); });

    legend.append("text")
        .attr("x", 50)
        .attr("y", function(d, i) { return (h + 32) + (i *14); })
        .text(function(d) { return d; });

    svg.selectAll(".bar")
       .on('mouseover', tip.show)
       .on('mouseout', tip.hide);

    });

2016 年 2 月 18 日更新。

看来我还没有充分解释我想要做什么。图表的折线图和条形图版本将单独显示,即用户可以根据对选择元素的输入查看任一版本。另请注意,我无法控制数据最初的输入方式。

I have 它在这里应该如何工作的一个版本。 http://lowercasen.com/dev/tests/barTransitions.html

当我还在解决这个问题时就提出了这个问题,但我从未解决这个问题 - 我使用了一种解决方法,即对数据进行两个单独的嵌套。


jsfiddle 链接:https://jsfiddle.net/sladav/rLh4qwyf/1/ https://jsfiddle.net/sladav/rLh4qwyf/1/

我认为问题的根源是您想要使用原始数据集中不明确存在的两个变量:(一)类别 and (2) Rate.

您的数据采用宽格式,因为每个类别都有自己的变量,并且比率值存在于月份和给定类别之一的十字路口。我认为您最终嵌套的方式是或至少应该解决这个问题,但我不清楚翻译中是否或在哪里丢失了某些内容。从概念上讲,我认为从一个与您想要实现的目标相匹配的组织开始更有意义。我重新格式化了原始数据并再次接近它 - 在概念层面上,嵌套似乎简单明了......

新专栏:

  • 月份:时间变量;映射到 X 轴
  • 类别:分类值[实际、预测、预算];用于分组/颜色
  • 比率:数值;映射到 Y 轴

重组 CSV(删除 NULL):

Month,Category,Rate
Jul-14,Actual,200000
Aug-14,Actual,198426.57
Sep-14,Actual,290681.62
Oct-14,Actual,362974.9
Nov-14,Actual,397662.09
Dec-14,Actual,512434.27
Jan-15,Actual,511470.25
Jan-15,Forecast,511470.25
Feb-15,Forecast,536472.5467
Mar-15,Forecast,612579.9047
Apr-15,Forecast,680936.5086
May-15,Forecast,755526.7173
Jun-15,Forecast,811512.772
Jul-14,Budget,74073.86651
Aug-14,Budget,155530.2499
Sep-14,Budget,220881.4631
Oct-14,Budget,314506.6437
Nov-14,Budget,382407.67
Dec-14,Budget,442192.1932
Jan-15,Budget,495847.6137
Feb-15,Budget,520849.9105
Mar-15,Budget,596957.2684
Apr-15,Budget,465313.8723
May-15,Budget,739904.081
Jun-15,Budget,895890.1357

对于新格式化的数据,您首先使用 d3.nest 使用 CATEGORY 变量显式对数据进行分组。现在您的数据存在于两层中。第一层有三组(每个类别一组)。第二层包含每条线/每组柱的汇率数据。您还必须嵌套数据选择 - 第一层用于绘制线条,第二层用于绘制条形。

嵌套您的数据:

var nestedData = d3.nest()
      .key(function(d) { return d.Category;})
      .entries(data)

为分组的第一层数据创建 svg 组:

d3.select(".plot-space").selectAll(".g-category")
    .data(nestedData)
    .enter().append("g")
    .attr("class", "g-category")

使用此数据添加您的线路/路径:

d3.selectAll(".g-category").append("path")
    .attr("class", "line")
    .attr("d", function(d){ return lineFunction(d.values);})
    .style("stroke", function(d) {return color(d.key);})

最后,“进入”第二层以添加条形/矩形:

d3.selectAll(".g-category").selectAll(".bars")
     .data(function(d) {return d.values;})
     .enter().append("rect")
        .attr("class", "bar")
        .attr("x", function(d) {return x(d.Month);})
        .attr("y", function(d) {return y(d.Rate);})
        .attr("width", 20)
        .attr("height", function(d) {return height - y(d.Rate)})
        .attr("fill", function(d) {return color(d.Category)})

这是一种简单的方法(至少对我来说),因为您一次只处理一个类别,使用分组数据绘制一条线,然后使用单个数据点绘制条形。

懒惰编辑:

并排显示类别栏

创建序数比例映射类别到 [1,nCategories]。使用它来动态偏移条形,例如

translate( newScale(category)*barWidth )

显示条形或线条(不是两者)

创建一个选择条形/线条并过渡/切换其可见性/不透明度的函数。当下拉输入更改时运行,并将下拉输入作为函数的输入。

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

d3 访问分组条形图中的嵌套数据 的相关文章

  • JavaScript onTouch 不工作

    谁能告诉我为什么这个 onTouch 处理程序没有触发 var myDiv document getElementById existingContent var myButton a href log out a myDiv append
  • 使用 vscode 调试器调试 next.js

    我已经使用安装了一个项目创建下一个应用程序 https github com segmentio create next app 我需要使用我的编辑器 vscode 调试服务器端渲染 所以我访问过vscode recipes 如何调试 ne
  • 主干视图 DOM 元素已删除

    我一直在阅读有关 Backbone js 僵尸 或内存泄漏 问题的信息 基本上 当您不再需要该元素时 您必须从 DOM 中解除绑定并删除该元素 以确保所有事件也被删除 现在 我有一个包含几个容器的单页应用程序 div div div div
  • TypeError: props.render 不是一个函数(React hook 形式)

    我将方法作为我用react hook form制作的形式的道具传递 当从react hook form添加控制器时 它给了我 TypeError props render不是一个函数 我在网上找不到任何解决方案 因此感谢任何帮助 impor
  • 使用 useReducers 调度函数发送多个操作?

    使用时是否可以通过调度函数发送多个动作useReducer挂钩反应 我尝试向它传递一组操作 但这会引发未处理的运行时异常 明确地说 通常会有一个初始状态对象和一个减速器 如下所示 const initialState message1 nu
  • 使用 JavaScript 使链接保持活动状态并在单击时显示悬停效果

    I am struggling to make this work I d like to make it where if O F is clicked the hover state stays active if another li
  • 使用 jQuery/JS 打开时使
    标签的内容具有动画效果

    我只想要 HTML5 的内容details标记为 滑行 动画打开 而不是仅仅弹出打开 立即出现 这可以用 jQuery Javascript 实现吗 Fiddle http jsfiddle net 9h4Hq HTML
  • 检查 JavaScript 字符串是否为 URL

    JavaScript 有没有办法检查字符串是否是 URL 正则表达式被排除在外 因为 URL 很可能是这样写的stackoverflow 也就是说它可能没有 com www or http 如果你想检查一个字符串是否是有效的 HTTP UR
  • 如何防止 Iframe 在与浏览器交互后弄乱浏览器的历史记录?

    因此 就我而言 我使用 Iframe 将 Grafana 附加到我的页面 这为我提供了漂亮且易于使用的图表 可以注意到 每次在图表上进行放大或缩小 使用鼠标单击 交互后 Grafana 的 Iframe 都会在我的 Angular 页面上触
  • 如何抑制窗口鼠标滚轮滚动...?

    我正在开发嵌入页面中的画布应用程序 我有它 因此您可以使用鼠标滚轮放大绘图 但不幸的是 这会滚动页面 因为它是文章的一部分 当我在 dom 元素上滚动鼠标滚轮时 是否可以阻止鼠标滚轮在窗口上滚动 附加鼠标滚轮 不是 Gecko DOMMou
  • 如何监听 jQuery AJAX 请求?

    以下两种实现 ajaxRequest 1 2 的方法应该是等效的 话说回来 为什么验证回调已执行的单元测试 3 在 1 中成功而在 2 中失败 我应该如何重写测试 3 来监视 2 中的成功回调 如果我尝试stub jQuery ajax使用
  • 从未用 @flow 标记的导入文件中获取类型定义

    TL DR我怎么告诉flow从未声明的导入模块导入类型定义 flow 加长版 流接缝能够从不使用流语法的文件中派生类型 请参阅示例 示例文件 flow js if Math random lt 0 5 var y hello else va
  • JavaScript 重定向到新窗口

    我有以下代码 它根据下拉列表的值重定向到页面 我如何使其在新窗口中打开 function goto form var index form select selectedIndex if form select options index
  • 在javascript中解析json - 长数字被四舍五入

    我需要解析一个包含长数字的 json 在 java servlet 中生成 问题是长数字被四舍五入 当执行这段代码时 var s x 6855337641038665531 var obj JSON parse s alert obj x
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • 条件在反应本机生产中失败,但在开发中有效

    我创建了一个反应本机应用程序 我需要通过它进行比较 如果属实 就会执行死刑 问题是 该条件适用于 React Native 开发模式 而不适用于 React Native 生产版本 我使用 firebase 作为数据库 也使用 redux
  • 如何更改此 jquery 插件的时区/时间戳?

    我正在使用这个名为 timeago 的插件 在这里找到 timeago yarp com 它工作得很好 只是它在似乎不同的时区运行 我住在美国东部 费城时区 当我将准确的 EST 时间放入 timeago 插件时 比如 2011 05 28
  • 如何仅在最后一个
  • 处给出透明六边形角度?
  • 我必须制作这样的菜单 替代文本 http shup com Shup 330421 1104422739 My Desktop png http shup com Shup 330421 1104422739 My Desktop png
  • 如何获取浏览器视口中当前显示的内容

    如何获取当前正在显示长文档的哪一部分的指示 例如 如果我的 html 包含 1 000 行 1 2 3 9991000 并且用户位于显示第 500 行的中间附近 那么我想得到 500 n501 n502 或类似的内容 显然 大多数场景都会比

随机推荐

  • 设置滚动条拇指大小

    我正在尝试计算与 WPF 滚动条拇指元素大小相关的算法 拇指元素的大小可以使用Scrollbar ViewportSize属性 但又与Scrollbar Minimum and Scrollbar Maximum价值观 到目前为止我发现的是
  • android 从加速度计读数中删除重力

    我正在开发一个 Android 应用程序 我需要从加速度计读数中消除重力 我已经阅读了关于这个问题的多个讨论 我还找到了一个算法here http developer android com reference android hardwa
  • pandas 中给定日期的季度天数

    我创建了一个日期数据框 如下所示 import pandas as pd timespan 366 df pd DataFrame Date pd date range pd datetime today periods timespan
  • 在 Keras 中实现 Rprop 算法

    我正在尝试为 Keras 实现弹性反向传播优化器 link http www inf fu berlin de lehre WS06 Musterererkennung Paper rprop pdf 但具有挑战性的部分是能够根据每个单独的
  • 何时使用 SortedList 而不是 SortedDictionary

    这可能看起来与此重复question https stackoverflow com questions 935621 whats the difference between sortedlist and sorteddictionary
  • 为结构字段分配默认值[重复]

    这个问题在这里已经有答案了 我想为 Go 中的结构字段分配默认值 我不确定是否可能 但在创建 初始化结构的对象时 如果我没有为该字段分配任何值 我希望它从默认值分配 知道如何实现它吗 type abc struct prop1 int pr
  • 从两个向量中采样唯一对

    给定两个向量 a and b a letters 1 6 b letters 7 11 目标是使用以下方法对两列矩阵进行采样a and b 第一列应包含以下元素a使得每个元素a重复两次 第二列应包含以下元素b使得每个元素b也重复至少两次 还
  • 如何将 pandas 数据框显示为数据表?

    我想显示一个表 这是一个 pandas 数据框 作为数据表 https datatables net examples data sources dom html 在下面的简化示例中 我读取了用户提供的两个数字 它们确定了表格的行号和列号
  • 如何在 CodeIgniter 中获取 show_error() 来加载视图?

    我需要在所有页面中加载头部视图和脚部视图 但show error使用自己的完整模板 它在加载此模板后停止执行 因此如果我愿意 页脚甚至不会加载 我应该重写这个方法还是有其他方法 所以 我就是这样做的 而且效果非常好 我延长了CI Excep
  • 为什么元胞数组中的尾随逗号是有效的 Matlab 语法?

    今天我很惊讶地发现 A 1 2 3 and B 1 2 3 都是 MATLAB 中的有效语法 我原以为第二个语句会产生错误 据我所知 它们产生相同的单元阵列 all A B 返回真 允许使用第二种语法有什么原因吗 这是解析器中的错误吗 是A
  • ggplot 抛出错误“找不到标签”,而“标签”显然在那里

    我可以绘制以下标签df using geom text df lt data frame x c 610 426 569 253 y c 226 276 364 185 label c accomplishments per week ho
  • private(set) 与 let 属性 - 'private(set)' 修饰符不能应用于只读属性

    我已经知道如何private set 作品 但下面的代码给出了编译时错误 class Person private set let name String Error private set let age Int Error init n
  • android 调试器不会在断点处停止

    我在控制台中看到调试语句 但调试器不会在任何断点处停止 我尝试清除所有断点并将它们添加回来 不确定这是如何发生的 但确实如此 对我有用的解决方案 Simply 卸载应用程序从设备 在设备上手动 并再次尝试调试
  • android 的 coredata 相当于什么

    我曾经为 iPhone 编程 但后来我想在 Android 中制作另一个类似的程序 那么 我应该使用类似 coredata 的框架吗 安卓有类似的东西吗 实际上你需要的是检查 Android 的 ORM 工具的持久性 并决定哪一个最适合你
  • 如何从安装程序获取路径以及如何在我的应用程序中设置?

    我正在编写一个 win 应用程序 现在我想为我的应用程序进行设置 我的代码是 Microsoft Win32 RegistryKey rk Microsoft Win32 Registry LocalMachine OpenSubKey S
  • 从 SwiftUI 按钮调用评估Javascript

    假设您有以下 WKWebView 实现 import Combine import SwiftUI import WebKit class WebViewData ObservableObject Published var parsedT
  • 如何在 Python 中对多元对数正态分布进行采样?

    使用 Python 如何从多元对数正态分布中采样数据 例如 对于多元正态分布 有两个选项 假设我们有一个 3 x 3 协方差矩阵和一个 3 维均值向量 mu Method 1 sample np random multivariate no
  • Internet Explorer 中的鼠标移动问题

    当事件目标位于鼠标上方时 Internet Explorer 不会触发 onmousemove 事件 img 元素 缺乏背景 但当目标有背景时 它确实会注册事件 有人对此有解释吗 我在 IE10 IE9 和 IE8 中也有同样的行为 在这里
  • sed,用该行的第一部分替换全局分隔符

    可以说我有以下几行 1 a b c 2 d e f 3 a b 4 a b c d e f 我如何使用 sed 或 perl 编辑它以便阅读 1a1b1c 2d2e2f 3a3b 4a4b4c4d4e4f 我已经用 awk 完成了这样的操作
  • d3 访问分组条形图中的嵌套数据

    我正在通过嵌套 csv 文件构建分组条形图 该图表也可以作为折线图查看 因此我想要一个适合折线对象的嵌套结构 我原来的 csv 看起来像这样 Month Actual Forecast Budget Jul 14 200000 74073