Javascript 在d3v4堆叠条形图中使用JSON

Javascript 在d3v4堆叠条形图中使用JSON,javascript,json,d3.js,dataset,bar-chart,Javascript,Json,D3.js,Dataset,Bar Chart,我找到了一个我想使用的d3v3,因为它使用json数据 还有一个d3v4,它加载并使用csv 我想制作一个d3v4堆叠条形图,但我想使用json数据来创建它,而不是从csv加载。我不知道如何升级v3版本或修改v4版本来实现这一点 这是我的数据结构: [{ "hospitalName": "hospital1", "category": "Injury & Poisoning", "Females": "0", "Males": "4

我找到了一个我想使用的d3v3,因为它使用json数据

还有一个d3v4,它加载并使用csv

我想制作一个d3v4堆叠条形图,但我想使用json数据来创建它,而不是从csv加载。我不知道如何升级v3版本或修改v4版本来实现这一点

这是我的数据结构:

[{
     "hospitalName": "hospital1",
     "category": "Injury & Poisoning",        
     "Females": "0",
     "Males": "4",
     "Unknown": "0",
     "count": "4"
},
{
    "hospitalName": "hospital1",
    "category": "Symptoms, Signs, & Ill-Defined Conditions",
    "Females": "1",
    "Males": "1",
    "Unknown": "0",
    "count": "2"
},
{
    "hospitalName": "hospital2",
    "category": "Mental Disorders",
    "Females": "0",
    "Males": "1",
    "Unknown": "0",
    "count": "1"
}]

如果有两个示例,我如何在d3v4堆叠条形图中使用此数据?

如果要在升级适合您的数据源类型的v3示例和修改v4示例以采用json而不是csv数据之间进行选择,则转换现有规范v4示例的选择应该获胜

d3.csv将csv文件转换为json。d3.csv创建的json看起来就像源csv中的json,该源csv的标题与数据项的属性相同。 因此,两个示例基本上使用相同的数据格式和结构。这就是为什么使用d3v4示例更简单的原因

要在v4示例中使用json数据而不是csv数据,您需要进行两项更改:

  • 获取正确的列数据:
  • 规范中的列使用
    var-keys=data.columns.slice(1)
    获取csv数据中应使用矩形打印的列
    columns
    是通过d3.csv添加到数据数组的属性,用于指定列标题。移除的值不会用矩形打印,但会标识堆栈,它可以是堆栈标签并用于x轴放置。由于columns属性是由d3.csv添加的,因此我们需要一种稍微不同的方法

    在您的案例中,我们希望得到数据中未知的男性、女性,您的每组结构如下所示:

    {
         "hospitalName": "hospital1",
         "category": "Injury & Poisoning",        
         "Females": "0",
         "Males": "4",
         "Unknown": "0",
         "count": "4"
    }
    
    因此,只需稍加修改即可获得关键点/属性(将用矩形绘制):

    var columns = d3.keys(data[0]);  // get the properties of the first item in the data array
    var keys = columns.slice(2,5); // extract keys with index 2,3,4. These will be the properties that are represented by rectangles in the chart.
    
  • 使用相同名称核算多个组/堆栈
  • 由于大多数示例的比例将使用组名,因此这些将不起作用。相反,我们需要为每个组提供唯一的索引,索引可以很好地工作:

    x.domain(data.map(function(d,i) { return i; }));
    
    您需要稍微格式化刻度,这样就不会将索引作为标签,比如:

    d3.axisBottom(x).tickFormat(function(d,i) { return data[i].hospitalName })
    
    用它将类别添加到勾号应该很容易

  • 修改total属性
  • 是的,我说了两个步骤,这太短了,不足以保证一个完整的项目,但列表最好有三个项目。原始规范使用d.total,数据使用d.count,这用于确定y标尺的域

    总共:

    
    .axis.domain{
    显示:无;
    }
    var svg=d3。选择(“svg”),
    边距={顶部:20,右侧:20,底部:30,左侧:40},
    宽度=+svg.attr(“宽度”)-margin.left-margin.right,
    高度=+svg.attr(“高度”)-margin.top-margin.bottom,
    g=svg.append(“g”).attr(“transform”、“translate”(+margin.left+)、“+margin.top+”);
    var x=d3.scaleBand()
    .rangeRound([0,宽度])
    .填塞器(0.05)
    .对齐(0.1);
    变量y=d3.scaleLinear()
    .rangeRound([高度,0]);
    var z=d3.scaleOrdinal()
    .范围([“98abc5”、“8a89a6”、“7b6888”、“6b486b”、“a05d56”、“d0743c”、“ff8c00”);
    风险值数据=[{
    “hospitalName”:“hospital1”,
    “类别”:“伤害和中毒”,
    “女性”:“0”,
    “男性”:“4”,
    “未知”:“0”,
    “计数”:“4”
    },
    {
    “hospitalName”:“hospital1”,
    “类别”:“症状、体征和定义不清的情况”,
    “女性”:“1”,
    “男性”:“1”,
    “未知”:“0”,
    “计数”:“2”
    },
    {
    “hospitalName”:“hospital2”,
    “类别”:“精神障碍”,
    “女性”:“0”,
    “男性”:“1”,
    “未知”:“0”,
    “计数”:“1”
    }]
    var columns=d3.keys(数据[0]);
    var key=columns.slice(2,5);
    sort(函数(a,b){返回b.total-a.total;});
    x、 域(data.map(函数(d,i){returni;}));
    y、 域([0,d3.max(数据,函数(d){return d.count;})]).nice();
    z、 域(密钥);
    g、 附加(“g”)
    .全选(“g”)
    .data(d3.stack().key(key)(数据))
    .enter().append(“g”)
    .attr(“fill”,函数(d){返回z(d.key);})
    .selectAll(“rect”)
    .data(函数(d){return d;})
    .enter().append(“rect”)
    .attr(“x”,函数(d,i){返回x(i);})
    .attr(“y”,函数(d){返回y(d[1]);})
    .attr(“height”,函数(d){返回y(d[0])-y(d[1]);})
    .attr(“宽度”,x.带宽());
    g、 附加(“g”)
    .attr(“类”、“轴”)
    .attr(“变换”、“平移(0)”、“高度+”)
    .call(d3.axisBottom(x).tickFormat(函数(d,i){返回数据[i].hospitalName}));
    g、 附加(“g”)
    .attr(“类”、“轴”)
    .call(d3.axisLeft(y).ticks(null,“s”))
    .append(“文本”)
    .attr(“x”,2)
    .attr(“y”,y(y.ticks().pop())+0.5)
    .attr(“dy”,“0.32em”)
    .attr(“填充”、“千”)
    .attr(“字体大小”、“粗体”)
    .attr(“文本锚定”、“开始”)
    .文本(“人口”);
    var图例=g.append(“g”)
    .attr(“字体系列”、“无衬线”)
    .attr(“字体大小”,10)
    .attr(“文本锚定”、“结束”)
    .全选(“g”)
    .data(key.slice().reverse())
    .enter().append(“g”)
    .attr(“transform”,函数(d,i){return“translate(0,+i*20+”);});
    图例。追加(“rect”)
    .attr(“x”,宽度-19)
    .attr(“宽度”,19)
    .attr(“高度”,19)
    .attr(“填充”,z);
    图例。追加(“文本”)
    .attr(“x”,宽度-24)
    .attr(“y”,9.5)
    .attr(“dy”,“0.32em”)
    .text(函数(d){return d;});
    
    这是标准的d3v4。虽然它使用d3.csv来加载数据,而不是使用内联数据,但这可以删除,并且您可以使用与示例中相同格式的json(*如果您在采用规范示例使用内联json*时遇到困难,可能会有所帮助)。那么,如果我改为使用外部json文件呢?那么您可以使用d3.json-抱歉,我原以为您指的是示例中的内联。使用d3.json将按原样加载json—这可能需要对规范进行一些更改。感谢