PortaleOrdiniGruppo/PortalStudio/chart/objects/ZtChartFunnel.js
2025-03-24 15:28:26 +01:00

280 lines
11 KiB
JavaScript

function ZtFunnelChart() {
StdChart.apply(this, ["FUNNEL", "f071"]);
this.multiSVG = true;
this.multiMargins = {};
this.borderItem = [];
this.byCount = (this.type == "FUNNEL");
}
ZtFunnelChart.prototype = Object.create(ZtPieChart.prototype);
ZtFunnelChart.prototype.constructor = ZtFunnelChart;
ZtFunnelChart.prototype._SetChartSettingsJSON = function () {
this.defSettings.funnel = this.chartConfig.graphSettings.extends.funnel;
this.defSettings.shape = this.chartConfig.graphSettings.shape;
this.defSettings.shape.onlyHover = false;
this.defSettings.shape.figureTypes = ["circle", "square", "triangle", "cross", "diamond", "star", "wye"];
if (!this.defSettings.shape.draw) {
this.defSettings.shape.onlyHover = true;
this.defSettings.shape.size = 2;
this.defSettings.shape.type = "percent";
}
this.funnelColor = Empty(this.chartConfig.graphSettings.gauge.fillColor) ? "#A3A3A3" : this.chartConfig.graphSettings.gauge.fillColor;
this.defSettings.fillTransparency = this.chartConfig.graphSettings.fillTransparency;
}
ZtFunnelChart.prototype._SetScales = function () {
this.scaleY = {};
for (var i = 0; i < this.valueFields.length; i++) {
this.scaleY[this.valueFields[i]] = {};
this.scaleY[this.valueFields[i]].left = d3.scaleLinear();
this.scaleY[this.valueFields[i]].right = d3.scaleLinear();
}
}
ZtFunnelChart.prototype._SetScaleParameters = function (scaleY, type, min, max, width, hrel) {
var offset = 4,
sRadius = 2 * this.GetShapesRadius();
scaleY[type].domain([min, max]);
if (type == "left")
scaleY[type].range([width/2, 0]);
else
scaleY[type].range([width/2, width]);
var newmin = min,
newmax = max;
if(this.defSettings.funnel.type != 'shapes'){ //blocks, bottom, middle
newmin = scaleY.left.invert(scaleY.left(min) + offset);
if(this.defSettings.funnel.type =='middle'){
newmax = scaleY.left.invert(scaleY.left(max) - (hrel/2));
}
}
else{ //shapes
newmax = scaleY.left.invert(scaleY.left(newmax) - sRadius);
}
scaleY[type].domain([newmin, newmax]);
}
ZtFunnelChart.prototype._DrawChartElements = function () {
var parentGroup = this.renderer.append("g")
.attr("id", this.chartId + this.type + "_svgGroup")
.attr("transform", "translate(" + [this.margin.left, this.margin.top] + ")");
var positions = this.GetRendererSubdivisionsSizes(this._GetDivisor()),
yIndex = -1,
id = "",
group,
groupS,
dList = this._GetOppositeDrawingList(),
_this = this,
mvalues = [],
scaleY,
min,
max;
for (var i = 0; i < positions.length; i++) {
yIndex = this.propertyName.indexOf(dList[i]);
scaleY = this.scaleY[dList[i]];
id = this.chartId + i + "_";
this._DrawMultiSVGPlot(id, parentGroup, positions[i].x, positions[i].y, positions[i].width, positions[i].height);
group = this.renderer.append("g")
.attr("id", id + this.type + "_elementGroup")
groupS = this.renderer.append("g")
.attr("id", id + this.type + "_shapesGroup")
mvalues = this.dataSet.map( function(rec) { return [rec[_this.xIndex], rec[yIndex]] });
min = d3.min(mvalues.map(function(record) { return record[1]; }));
max = d3.max(mvalues.map(function(record) { return record[1]; }));
this._SetScaleParameters(scaleY, "left", min, max, positions[i].width, positions[i].height/mvalues.length);
this._SetScaleParameters(scaleY, "right", min, max, positions[i].width, positions[i].height/mvalues.length);
this.DrawFunnel(group, mvalues, i, 1, scaleY, positions[i].height);
if (this.defSettings.funnel.type == "shapes")
this.DrawShapes(groupS, mvalues, i, this.xIndex, 1, {scaleY: scaleY, dataLen: mvalues.length, gHeight: positions[i].height, valueField: dList[i]});
if (this.seriesList.length > 1)
this.DrawDomainLabel(i, positions[i], this.seriesList[this.valueFields.indexOf(dList[i])]);
}
this.svg = d3.select("#" + this.chartId + "d3ChartPlot");
this.renderer = d3.select("#" + this.chartId + "d3Renderer");
}
ZtFunnelChart.prototype._GetShapeCX = function (d, dataIndex, xIndex, yIndex, recIndex, cobj) {
return cobj.scaleY.right(d[yIndex]);
}
ZtFunnelChart.prototype._GetShapeCY = function (d, dataIndex, xIndex, yIndex, recIndex, cobj) {
return recIndex * (cobj.gHeight / cobj.dataLen) + (2 * this.GetShapesRadius());
}
ZtFunnelChart.prototype._SetElementsColor = function () {
this.SetColorSet();
var idx = -1,
gradID,
colD,
i;
for (i = 0; i < this.items.length; i++) {
if (this.defSettings.funnel.type == "shapes") {
d3.select(this.items[i].itm)
.style("fill", this.funnelColor);
if (this.defSettings.fillTransparency)
d3.select(this.items[i].itm).style("fill-opacity", 0.6);
}
else {
idx = this.categoryList.indexOf(this.items[i].category);
if (idx >= 0) {
this.items[i].idx = idx;
this.items[i].sidx = this.valueFields.indexOf(this.items[i].valueField);
this.items[i].color = this.colorSet[idx];
if (this.defSettings.useColorSeriesForEach)
this.items[i].color = this.colorSet[i];
if (this.defSettings.reuseColorSeries)
this.items[i].color = this.colorSet[i % this.colorSet.length];
var styleObj = {};
gradID = this.chartId + this.type + "_" + idx + "Gradient";
if (!Empty(this.items[i].color.color) && Empty(this.items[i].color.gradient) || this.items[i].color.color.toLowerCase() == this.items[i].color.gradient.toLowerCase())
colD = this.items[i].color.color;
else if (Empty(this.items[i].color.color) && !Empty(this.items[i].color.gradient))
colD = this.items[i].color.gradient;
else {
this.CreateGradient(this.items[i].color.color, this.items[i].color.gradient, gradID, "element");
colD = "url(" + document.URL + "#" + gradID + ")";
}
styleObj.fill = colD;
styleObj.stroke = colD;
d3.select(this.items[i].itm).attr("style", makeStyleHTMLString(styleObj, d3.select(this.items[i].itm).attr("style")));
}
}
}
for (i = 0; i < this.borderItem.length; i++) {
this.borderItem[i].style("stroke", "none");
}
}
ZtFunnelChart.prototype._IsNotExcludedDomainShapes = function (text) {
return this.categoryList.hasElement(text) >= 0;
}
ZtFunnelChart.prototype._GetItems = function () {
if (this.defSettings.funnel.type == "shapes")
return this.shapes;
return this.items;
}
ZtFunnelChart.prototype._SetShapesColor = function () {
for (var i = 0; i < this.shapes.length; i++) {
var idx = this.categoryList.indexOf(this.shapes[i].category);
if (idx >= 0) {
this.shapes[i].idx = idx;
this.shapes[i].sidx = this.orgCategoryList.indexOf(this.shapes[i].category);
if (!Empty(this.objConfig.keyField))
this.shapes[i].sidx = this.orgCategoryList.indexOf(this.shapes[i].keyField);
this.shapes[i].color = { color: this.colorSet[idx].color, gradient: this.colorSet[idx].gradient };
if (this.defSettings.useColorSeriesForEach)
this.shapes[i].color = { color: this.colorSet[i].color, gradient: this.colorSet[i].gradient };
var styleObj = {};
styleObj.fill = this.GetChartBackground().color;
styleObj.stroke9width = (this.defSettings.shape.stroke || 1) + "px";
if (!this.defSettings.shape.onlyHover) {
styleObj.stroke = this.shapes[i].color.color;
if (this.defSettings.shape.colorSeries[idx])
styleObj.stroke = this.defSettings.shape.colorSeries[idx].color;
if (this.defSettings.shape.customFill && !Empty(this.defSettings.shape.fillColorSeries)) {
if (this.defSettings.shape.fillColorSeries[idx])
styleObj.fill = this.defSettings.shape.fillColorSeries[idx].color;
else {
if (this.defSettings.shape.fill)
styleObj.fill = this.shapes[i].color.color;
else
styleObj.fill = "url(#" + this.chartId + "rendererGradient)";
}
}
else {
if (this.defSettings.shape.fill)
styleObj.fill = this.shapes[i].color.color;
else
styleObj.fill = "url(#" + this.chartId + "rendererGradient)";
}
}
else {
styleObj.stroke = "transparent";
styleObj.fill = "transparent";
}
this.shapes[i].colorApplied = this.shapes[i].color.color;
d3.select(this.shapes[i].itm).attr("style", makeStyleHTMLString(styleObj, d3.select(this.shapes[i].itm).attr("style")));
}
}
}
ZtFunnelChart.prototype._ApplyMouseOver = function (item, itemObj) {
if (this.defSettings.funnel.type == "shapes") {
var _this = this,
mRefChart = this._ZtChart.StdChart;
this.RemoveAllHovers();
if (item) {
var itemObject = itemObj || this._GetItems()[d3.select(item).attr("item-index")],
clone = this._GetItemClone(item);
mRefChart._hoverItem = itemObject;
d3.select(clone)
.attr("item-type", "hover")
.attr("d", d3.symbol()
.size( function () { return 5 * Math.pow(_this.GetShapesRadius(), 2); })
.type( function () {
if (_this.defSettings.shape.differSeries) {
var index = itemObject.idx,
fig = _this.defSettings.shape.figureTypes[index];
if (Empty(fig) || index > _this.defSettings.shape.figureTypes.length)
fig = _this.defSettings.shape.figureTypes[index % _this.defSettings.shape.figureTypes.length];
return d3["symbol" + fig.charAt(0).toUpperCase() + fig.slice(1)];
}
return d3["symbol" + _this.defSettings.shape.figure.charAt(0).toUpperCase() + _this.defSettings.shape.figure.slice(1)];
})
)
.style("stroke-opacity", 1)
.style("fill", "transparent")
.style("stroke", itemObject.color.color)
.style("stroke-width", 2 + "px")
.style("cursor", function() {
if (!_this._ZtChart.enableClick)
return "default";
return "pointer";
})
.on("mousemove", function() {
mRefChart.ClearHoverTimeout();
})
.on("mouseout", function() {
mRefChart.RemoveHoverTimeout();
delete mRefChart._hoverItem;
})
.on("click", function () {
_this._ApplyClick(itemObject, d3.mouse(this));
});
mRefChart._d3mouse = d3.mouse(item);
mRefChart._d3event = d3.event;
setTimeout(function(mRefChart, item, itemObject, clone){
if (mRefChart._hoverItem) {
if (mRefChart._CheckIdentityItem(mRefChart._hoverItem, itemObject)) {
item.parentNode.appendChild(clone);
_this.ShowTooltip(mRefChart, item, itemObject);
}
}
}, 50, mRefChart, item, itemObject, clone);
}
}
else
ZtPieChart.prototype._ApplyMouseOver.call(this, item, itemObj);
}
ZtFunnelChart.prototype._GetDefaultAnimateFunction = function (item, lastValueObj, duration) {
ZtLinesChart.prototype._GetDefaultAnimateFunction.call(this, item, lastValueObj, duration);
}