我正在创建分组的条形图,但是我的分组大小不一样。我的所有数据都有一个对象数组(array1)。
我正在创建一张地图,每组的大小与这篇文章相同:Making a grouped bar chart when my groups are varied sizes?
创建栏时遇到很多麻烦,我无法使用发布代码。
我还需要创建x和y线并将数字放在小节上方,这对我来说非常困难,因为我对node.js和d3.js不满意,如果有人可以帮助我,我将不胜感激我。
(注意:我不会说英语,所以我使用了谷歌翻译器)
这是我的数组:
const array1 = [
{name: 'john', lastName: 'smith', amount: 2},
{name: 'john', lastName: 'white', amount: 1},
{name: 'mark', lastName: 'smith', amount: 1},
{name: 'mary', lastName: 'brown', amount: 1}
]
这是我的代码:
//My variables
const d3 = require('d3')
const jsdom = require("jsdom")
const { JSDOM } = jsdom
var fs = require('fs')
const groupKey = 'name'
const keys = ['smith', 'white', 'brown']
const width=800
const margin = {top: 10, right: 10, bottom: 20, left: 40}
const height = 600
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d3.max(keys, key => d[key]))]).nice()
.rangeRound([height - margin.bottom, margin.top])
const x1 = d3.scaleBand()
.domain(keys)
.rangeRound([0, x0.bandwidth()])
.padding(0.05)
const x0 = d3.scaleBand()
.domain(data.map(d => d[groupKey]))
.rangeRound([margin.left, width - margin.right])
.paddingInner(0.1)
const color = d3.scaleOrdinal()
.range(["#054a7f", "#0f527f", "#347180", "#5e9381", "#72a381", "#89b581", "#ff8c00"])
const xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x0).tickSizeOuter(0))
.call(g => g.select(".domain").remove())
const yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(null, "s"))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 3)
.attr("text-anchor", "start")
.attr("font-weight", "bold"))
const legend = svg => {
const g = svg
.attr("transform", `translate(${width*1.2},0)`)
.attr("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", 13)
.selectAll("g")
.data(color.domain().slice().reverse())
.join("g")
.attr("transform", (d, i) => `translate(0,${i * 20})`);
g.append("rect")
.attr("x", 19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", color);
g.append("text")
.attr("x", 0)
.attr("y", 9.5)
.attr("dy", "0.35em")
.text(d => d);
}
//Here is the map of groups
var x1s = d3.nest()
.key(function(d) { return d[groupKey] })
.rollup(function(d){
return d3.scaleBand()
.domain(d.map(function(c){return c.sobrenome}), console.log(d.map(function(c){return c.sobrenome})))
.rangeRound([0, x0.bandwidth()])
.padding(0.05)
}).map(data)
//My document
const window = (new JSDOM(`<html><head></head><body></body></html>`, { pretendToBeVisual: false })).window;
window.d3 = d3.select(window.document)
//My svg object
var svg = window.d3.select('body')
.append('div').attr('class', 'container')
.append('svg')
.attr('xmlns', 'http://www.w3.org/2000/svg')
.attr('width', width+200)
.attr('height', height)
.attr('transform', 'translate(' + 20 + ',' + 20 + ')')'
//Here is where i create the bars
svg.append("g")
.selectAll("g")
.data(data)
.join("g")
.attr("transform", d => `translate(${x0(d[groupKey])},0)`)
.selectAll("rect")
.data(d => keys.map(key => ({key, value: d[key]})))
.join("rect")
.attr("x", d => x1(d.key))
.attr("y", d => y(d.value))
.attr("width", x1.bandwidth())
.attr("height", d => y(0) - y(d.value))
.attr("fill", d => color(d.key))
//My last try
// svg.append("g")
// .selectAll("g")
// .data(data)
// .join("g")
// .attr("transform", d => `translate(${x0(d[groupKey])},0)`)
// .enter().append("rect")
// .style("fill", function(d, i) {
// return color(d.name);
// })
// .attr("x", 0)
// .attr("y", function(d) {
// return x0(d.name) + x1s["$"+d.name](d.lastName);
// })
// .attr("height", function(d) {
// return x1s["$"+d.name].bandwidth();
// })
// .attr("width", function(d) {
// return x0(d.amount);
// });
//And others
svg.append("g")
.call(xAxis)
svg.append("g")
.call(yAxis)
svg.append("g")
.call(legend)
const xmlserializer = require('xmlserializer')
console.log('*** SVG ***')
console.log(xmlserializer.serializeToString(svg.node()))
const chartComplete = xmlserializer.serializeToString(svg.node())
fs.writeFile('chart.svg', chartComplete, function(erro) {
if(erro) {
throw erro
}
console.log("OK!");
})
}