/**
* Clase que representa una gráfica
* @extends ControlPrimitive
*/
class BarChart extends ControlPrimitive {
#chart;
#data;
#initialized = false;
/**
* Crea una nueva gráfica
* @param {string} name Nombre de la gráfica
* @param {string} label Etiqueta que se mostrará
* @param {string} description Descripción que se mostrará
* @constructor
*/
constructor(name, label, description) {
super(name, label, description);
}
/**
* Retorna el html asociado a este control
* @returns Código html del control
*/
getHtmlCode() {
return '<div id="' + this.getName() + 'Div" class="chartDiv"></div>';
}
/**
* Inicia la gráfica
* @param {Array} dataset Array de datos
*/
initChart(dataset) {
var w = $("#" + this.getName() + "Div").width();
var h = $("#" + this.getName() + "Div").height();
this.#data = dataset;
var xScale = d3
.scaleBand()
.domain(d3.range(this.#data.length))
.rangeRound([0, w])
.paddingInner(0.05);
var yScale = d3
.scaleLinear()
.domain([0, d3.max(this.#data)])
.range([0, h]);
this.#chart = d3
.select("#" + this.getName() + "Div")
.append("svg")
.attr("width", w)
.attr("height", h);
var j = 0;
this.#chart
.selectAll("rect")
.data(this.#data)
.enter()
.append("rect")
.attr("x", function (d, i) {
return xScale(i);
})
.attr("y", function (d) {
return h - yScale(d);
})
.attr("width", xScale.bandwidth())
.attr("height", function (d) {
return yScale(d);
})
.attr("fill", function (d) {
return "rgb(0, 0, " + Math.floor(d * 30) + ")";
})
.attr("id", function () {
return "chartBar" + j++;
});
//Create labels
this.#chart
.selectAll("text")
.data(this.#data)
.enter()
.append("text")
.text(function (d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i) + xScale.bandwidth() / 2;
})
.attr("y", function (d) {
return h - yScale(d) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");
this.#initialized = true;
}
updateData() {
this.#chart.remove();
var w = $("#" + this.getName() + "Div").width();
var h = $("#" + this.getName() + "Div").height();
var xScale = d3
.scaleBand()
.domain(d3.range(this.#data.length))
.rangeRound([0, w])
.paddingInner(0.05);
var yScale = d3
.scaleLinear()
.domain([0, d3.max(this.#data)])
.range([0, h]);
this.#chart = d3
.select("#" + this.getName() + "Div")
.append("svg")
.attr("width", w)
.attr("height", h);
var j = 0;
this.#chart
.selectAll("rect")
.data(this.#data)
.enter()
.append("rect")
.attr("x", function (d, i) {
return xScale(i);
})
.attr("y", function (d) {
return h - yScale(d);
})
.attr("width", xScale.bandwidth())
.attr("height", function (d) {
return yScale(d);
})
.attr("fill", function (d) {
return "rgb(0, 0, " + Math.floor(d * 30) + ")";
})
.attr("id", function () {
return "chartBar" + j++;
});
//Create labels
this.#chart
.selectAll("text")
.data(this.#data)
.enter()
.append("text")
.text(function (d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function (d, i) {
return xScale(i) + xScale.bandwidth() / 2;
})
.attr("y", function (d) {
return h - yScale(d) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "11px")
.attr("fill", "white");
}
/**
* Establece los datos del gráfico
* @param {object[]} data Datos del gráfico
*/
setData(data) {
this.#data = data;
if (data != undefined) {
if (this.#initialized) {
this.updateData();
} else {
this.initChart();
}
}
}
/**
* Obtiene los datos del gráfico
* @returns Datos del gráfico
*/
getData() {
return this.#data;
}
/**
* Selecciona una barra
* @param {number} id Identificador de la barra
* @param {string} color Nombre del color del borde. Rojo por defecto
*/
selectBar(id, color = "red") {
this.setBarStyle(id, "outline: solid " + color + ";");
}
/**
* Setea el estilo de una barra
* @param {number} id Identificador de la barra
* @param {string} style Estilo que se quiere poner a la barra
*/
setBarStyle(id, style) {
if (Utilities.hasAttr("#chartBar" + id, "style")) {
this.removeBarStyle(id);
}
$("#chartBar" + id).attr("style", style);
}
/**
* Elimina el estilo de una barra
* @param {number} id Identificador de la barra
*/
removeBarStyle(id) {
$("#chartBar" + id).removeAttr("style");
}
/**
* Deselecciona una barra
* @param {number} id Identificador de la barra
*/
unselectBar(id) {
this.removeBarStyle(id);
}
/**
* Obtiene el estulo de una barra
* @param {number} id Identificador de la barra
* @returns El estilo de la barra en caso de existir
*/
getBarStyle(id) {
return $("#chartBar" + id).attr("style");
}
/**
* Setea el valor de una barra
* @param {number} id Identificador de la barra
* @param {number} value Valor de la barra
*/
setBarValue(id, value) {
this.#data[id] = value;
if (this.#initialized) {
this.updateData();
} else {
this.initChart();
}
}
/**
* Vacia la gráfica
*/
clearData() {
this.#data = null;
if (this.#initialized) {
this.#chart.remove();
}
}
}