Мне нужно отобразить общее значение поверх диаграммы с накоплением, я использую гистограмму с накоплением D3 с Angular 7.
Я пытался реализовать, но получаю сообщение об ошибке ОШИБКА TypeError: Не удается прочитать свойство «домен» неопределенного
Дайте мне знать, что не так с текущей реализацией, или благодарю вас всех за предоставление некоторых ссылок.
// Get Stacked chart data
let stackedJsonData = this.getStackChartData.data;
var data = Array();
// Loop to iterate the JSON to fetch stacked chart data
for (let k = 0; k < stackedJsonData.length; k++) {
var objItem = {};
var key_name = Object.keys(stackedJsonData[k])[0];
objItem["State"] = key_name;
var objArray = stackedJsonData[k][key_name];
for (var i = 0; i < objArray.length; i++) {
var keyNm = "id" + (i + 1);
objItem[keyNm.toString()] = objArray[i];
}
data.push(objItem);
}
let keys = Object.getOwnPropertyNames(data[0]).slice(1);
data = data.map(v => {
v.total = keys.map(key => v[key]).reduce((a, b) => a + b, 0);
return v;
});
data.sort((a: any, b: any) => b.total - a.total);
this.x.domain(data.map((d: any) => d.State));
this.y.domain([0, d3Array.max(data, (d: any) => d.total)]).nice();
this.z.domain(keys);
this.g
.append("g")
.selectAll("g")
.data(d3Shape.stack().keys(keys)(data))
.enter()
.append("g")
.attr("fill", d => this.z(d.key))
.selectAll("rect")
.data(d => d)
.enter()
.append("rect")
.attr("x", d => this.x(d.data.State))
.attr("y", d => this.y(d[1]))
.attr("height", d => this.y(d[0]) - this.y(d[1]))
.attr("width", this.x.bandwidth());
// Draw stacked chart x-axis
this.g
.append("g")
.attr("class", "axis")
.attr("transform", "translate(18," + this.height + ")")
.attr("color", "#ebecf5")
.call(d3Axis.axisBottom(this.x));
//Draw stacked chart y-axis
this.g
.append("g")
.attr("class", "axis")
.attr("color", "#ebecf5")
.call(d3Axis.axisLeft(this.y).ticks(null, "s"))
.append("text")
.attr("x", 2)
.attr("y", this.y(this.y.ticks().pop()) + 0.5);
// Display total value on top of stacked bar
this.g
.selectAll("g")
.data(d3Shape.stack().keys(keys)(data))
.enter()
.attr("fill", d => this.z(d.key))
.append("text")
.data(d => d)
.attr("class", "yAxis-label")
.attr("fill", "#70747a")
.attr("text-anchor", "middle")
.attr("x", d => this.x(d.data.State))
.attr("y", d => this.y(d[1]) - 5)
.text(d => d.data.State);
Как говорится в сообщении об ошибке, this.x
, this.y
или this.z
не определены. Вы их где-то создаете, например, в конструкторе?
Да, но это не то же самое, что их создание. Вам нужно присвоить их переменной следующим образом: this.x = d3.scaleLinear(); this.y = d3.scaleLinear();
. Возможно, вам понадобятся разные шкалы для разных осей, например scaleOrdinal
для цветов. Посмотрите tutorialspoint.com/d3js/d3js_scales_api.htm для получения дополнительной информации.
Нет, это глобальные переменные, определенные как private x: any; частный у: любой; частный z: любой;