doevisualizations
Version:
Data Visualization Library based on RequireJS and D3.js (v4+)
1,011 lines (870 loc) • 47.9 kB
JavaScript
define(['jquery',
'underscore',
'jqueryuiwidget',
'handlebars',
'd3'
],
function($, _,ui, Handlebars, d3) {
$.widget("doe.doebar", {
// Options to be used as defaults
options: {},
_globalData: {},
_template: function() {
var arrHTML = [];
arrHTML.push('<div class="doebar">');
arrHTML.push('</div>');
return arrHTML.join('');
},
_create: function() {
this._fetchAndRender();
},
_fetchAndRender: function() {
this._compileTemplate();
// var p = $.get('4-yearGradRate.json');
// // var p = $.get('groupedBar.json');
// //var p = this.options.service.get();
// p.done($.proxy(function(data) {
// console.log(data);
// this.options.data = data;
// this._compileTemplate();
// }, this));
},
_compileTemplate: function() {
var compiled = Handlebars.compile(this._template());
this.element.html(compiled({}));
this.element.addClass('doebarcontainer');
this._bindEvents();
},
_generateRawTable: function() {
var arrHTML = [];
var data = this.options["Data"];
// console.log("raw table data: ", data);
if (data.length > 0) {
// arrHTML.push('<div style="display:none">');
arrHTML.push('<div class ="doehide">');
arrHTML.push('<table>');
arrHTML.push('<thead>');
arrHTML.push('<tr>');
for (p in data[1]) {
arrHTML.push('<th>');
arrHTML.push(p);
arrHTML.push('</th>');
}
arrHTML.push('</tr>');
for (var i = 0; i < data.length; i++) {
arrHTML.push('<tr>');
for (prop in data[i]) {
arrHTML.push('<td>');
arrHTML.push(data[i][prop]);
arrHTML.push('</td>');
}
arrHTML.push('</tr>');
}
arrHTML.push('</thead>');
arrHTML.push('</table>');
arrHTML.push('</div>');
}
this.element.append(arrHTML.join(''));
},
_bindEvents: function() {
var minWidth = 600, //set the minimum width and height
minHeight = 620,
widthTemp = this.element.width() < minWidth ? minWidth : this.element.width(),
heightTemp = this.element.height() < minHeight ? minHeight : this.element.height(),
maxSingleBarSize = 60,
maxGroupBarSize = 40,
// width = widthTemp * 0.65,
width = widthTemp * 0.8,
height = heightTemp * 0.6;
this._globalData.widthTemp = widthTemp;
this._globalData.heightTemp = heightTemp;
var formatComma = d3.format(","); // format large number with commas
var formatValue = d3.format(".2s");
var essaData = this.options;
//console.log(essaData);
var dataset = essaData["Data"];
var xField = essaData["XFields"];
var yField = essaData["YFields"];
var xTitle = essaData["XTitle"];
var yTitle = essaData["YTitle"];
var groupField = essaData["Groupings"];
var title = essaData["ChartTitle"]
var subTitle = essaData["ChartSubTitle"]
var tooltipTemplate = essaData["TooltipTemplate"]
var tooltipFields = essaData["TooltipFields"]
var showDataLabel = essaData["ShowDataLabel"];
var that = this;
var toolTipMasterTemplate = [];
var toolTipSuppressedTemplate = [];
toolTipMasterTemplate.push('<div class="tooltipprogress">');
toolTipMasterTemplate.push('<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>');
toolTipMasterTemplate.push('</div>');
toolTipMasterTemplate.push('<div class="tooltipcontent doehide">');
toolTipMasterTemplate.push(this.options["TooltipTemplate"]);
toolTipMasterTemplate.push('</div>');
toolTipSuppressedTemplate.push('<div class="tooltipprogress">');
toolTipSuppressedTemplate.push('<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>');
toolTipSuppressedTemplate.push('</div>');
toolTipSuppressedTemplate.push('<div class="tooltipcontent doehide">');
toolTipSuppressedTemplate.push("This data has been suppressed for student privacy.");
toolTipSuppressedTemplate.push('</div>');
var tooltipCompiled = Handlebars.compile(toolTipMasterTemplate.join(''));
var tooltipSuppressedCompiled = Handlebars.compile(toolTipSuppressedTemplate.join(''));
// dataset.forEach(function(d) {
// //console.log("###", typeof(d[yField]), d[yField]);
// for (var i = 0; i < tooltipFields.length; i++) {
// d[tooltipFields[i]] = formatComma(d[tooltipFields[i]]);
// }
// // console.log("###", typeof(d[yField]), d[yField]);
// // d[yField] = Number.parseInt(d[yField]);
// // console.log("###", typeof(d[yField]), d[yField]);
// a = d[tooltipFields[1]];
// a = a.replace(/\,/g, '');
// console.log("***", typeof(a), a);
// // d[yField] = +d[yField];
// // console.log("###", typeof(+d[yField]), +d[yField]);
// //d.CohortCount = +d.CohortCount;
// // console.log("###", typeof(d.YearGradCount), d.YearGradCount);
// // console.log("###", typeof(+d.YearGradCount), +d.YearGradCount);
// //d.YearGradCount = +d.YearGradCount;
// // console.log("###", typeof(d.SchoolYear));
// d.SchoolYear = +d.SchoolYear;
// // console.log("###", typeof(d.SchoolYear));
// // console.log(d.YearGradCount);
// });
//console.log("comma", dataset);
var tooltip = d3.select(this.element.find('.doebar').get(0))
.append('div')
.attr("class", "tooltip");
var svg = d3.select(this.element.find('.doebar').get(0))
.append("svg")
.attr('width', widthTemp)
.attr('height', heightTemp);
var g = svg.append('g')
.attr("transform",
"translate(" + widthTemp * 0.2 + "," + heightTemp * 0.15 + ")");
this._globalData.g = g;
var SuppressionFlag = false;
if (xField.length == 1) {
width = width * 0.9;
var dataSet = dataset;
maxValue = d3.max(dataSet, function(d) {
return parseFloat(d[yField]);
})
defaultvalue = maxValue > 0 ? maxValue : 100;
dataset.forEach(function(d) {
if (d[yField] === "*") {
d[yField] = -0.05 * defaultvalue;
SuppressionFlag = true;
}
});
if (dataSet.length < 4) { //check if the size of bars is less than 4
var xScale = d3.scaleBand()
// .range([0, width])
.range([0, Math.min(maxSingleBarSize * dataSet.length * 2, width)])
.padding(0.5);
var left = (width - widthTemp * 0.15 - Math.min(maxSingleBarSize * dataset.length * 2, width)) / 2;
} else {
var xScale = d3.scaleBand()
// .range([0, width])
.range([0, Math.min(maxSingleBarSize * dataSet.length * 1.5, width)]) //set the max bar size
.padding(0.3);
var left = (width - widthTemp * 0.15 - Math.min(maxSingleBarSize * dataset.length * 1.5, width)) / 2 + 40;
}
var yScale = d3.scaleLinear()
.range([height, 0]);
var color = d3.scaleOrdinal()
.range(this.options.ColorPalette);
xScale.domain(dataSet.map(function(d) { return d[xField]; }));
if (maxValue > 0) {
yScale.domain([0, d3.max(dataSet, function(d) {
return parseFloat(d[yField]);
})]).nice();
} else {
yScale.domain([0, 100]).nice();
}
var xAxis = d3.axisBottom(xScale);
// var yAxis = d3.axisLeft(yScale);
// var yAxis = d3.axisLeft(yScale).tickFormat(d3.format(".0s"));
//var yAxis = d3.axisLeft(yScale).tickFormat(function(d) { return formatValue(d) });
var yAxis = d3.axisLeft(yScale).ticks(10, "s");
var top = 20;
var bar = g.selectAll("rect")
.data(dataSet)
.enter()
.append("rect")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(" + left + "," + top + ")"; })
.attr("x", function(d) { return xScale(d[xField]); })
.attr("width", xScale.bandwidth())
.attr("fill", function(d) { return color(d); })
.attr("y", function(d) { return height; }) // animation effect
.attr("height", function(d) { return 0; });
bar.transition()
.delay(function(d, i) {
return i * 30;
})
.duration(1)
.ease(d3.easeLinear)
.attr("y", function(d) { return yScale(Math.abs(d[yField])); })
.attr("height", function(d) { return height - yScale(Math.abs(d[yField])); });
if (SuppressionFlag) {
var barText = g.selectAll("text")
.data(dataSet)
.enter()
.append("text")
// .text(function(d) { return d[yField] + '%'; })
// .attr("style", "font-family:FontAwesome;")
.style('font-family', 'FontAwesome')
.style('fill', "black")
.style('font-size', function(d) {
return 0.9 * Math.min(xScale.bandwidth(), height - yScale(Math.abs(d[yField])));
})
.text(function(d) {
if (parseFloat(d[yField]) < 0) {
return '\uf023'; // \uf023
} else {
if (showDataLabel == true) {
return formatComma(Math.abs(d[yField]));
} else {
return "";
}
}
})
.attr("class", "bartext notranslate")
.attr("transform", function(d) { return "translate(" + left + "," + top + ")"; })
.attr("text-anchor", "middle")
// .style("text-anchor", "middle")
.attr("x", function(d) { return xScale(d[xField]); })
// .attr("dy", ".8em");
.attr("dx", xScale.bandwidth() / 2)
.attr("dy", ".35em")
.attr("y", function(d) { return height; }); // animation effect
barText.transition()
.delay(function(d, i) {
return i * 30;
})
.duration(1)
.ease(d3.easeLinear)
.attr("y", function(d) {
return yScale(Math.abs(d[yField] / 2));
});
// barText.style("text-anchor", "middle");
} else {
var barText = g.selectAll("text")
.data(dataSet)
.enter()
.append("text")
// .text(function(d) { return d[yField] + '%'; })
.text(function(d) {
if (showDataLabel == true) {
return formatComma(d[yField]);
} else {
return "";
}
})
.attr("class", "bartext notranslate")
.attr("transform", function(d) { return "translate(" + left + "," + top + ")"; })
.attr("text-anchor", "middle")
// .style("text-anchor", "middle")
.attr("x", function(d) { return xScale(d[xField]); })
// .attr("dy", ".8em");
.attr("dx", xScale.bandwidth() / 2)
.attr("dy", function(d) {
return 15;
})
.attr("y", function(d) { return height; }); // animation effect
barText.transition()
.delay(function(d, i) {
return i * 30;
})
.duration(1)
.ease(d3.easeLinear)
.attr("y", function(d) {
return yScale(d[yField]);
});
}
dataSet.forEach(function(d) { //format tooltip
//console.log("###", typeof(d[yField]), d[yField]);
for (var i = 0; i < tooltipFields.length; i++) {
if (isNaN(parseFloat(d[tooltipFields[i]]))) {
d[tooltipFields[i]] = d[tooltipFields[i]];
} else {
d[tooltipFields[i]] = parseFloat(d[tooltipFields[i]]);
}
if (typeof(d[tooltipFields[i]]) === "number" && tooltipFields[i] !== "SchoolYear") {
d[tooltipFields[i]] = formatComma(d[tooltipFields[i]]);
}
}
});
bar.on('mouseover', function(d) {
g.selectAll("rect")
.transition()
.attr('opacity', 0.5);
d3.select(this)
.transition()
// .duration(300)
.attr('opacity', 1)
// .attr("x", function(d) { return xScale(d[xField]) - 5; })
// .attr("width", xScale.bandwidth() + 10);
.style("stroke", function(d) {
return color(d);
});
var temp = d[xField];
d3.selectAll(".axis text")
.filter(function(d) {
return d == temp
})
.classed("highlight", true);
// if (typeof(d[yField]) === "number") {
// y = d[yField];
// } else {
// var str1 = d[yField];
// var y = parseFloat(str1.replace(/,/g, "")); // parse large number with comma
// }
function helpCheck(param) {
if (typeof(param) === "number") {
result = param;
} else {
var str = param;
var result = parseFloat(str.replace(/,/g, "")); // parse large number with comma
}
return result;
}
if (parseFloat(d[yField]) > 0) {
var line = g.append('line')
.attr('id', 'limit')
.attr('x1', left)
.attr('y1', yScale(helpCheck(d[yField])) + top)
.attr('x2', xScale(d[xField]) + xScale.bandwidth() + left)
.attr('y2', yScale(helpCheck(d[yField])) + top)
// .attr("stroke-width", 2)
// .attr("stroke", "black");
}
if (parseFloat(d[yField]) < 0) {
tooltip
.style("left", (d3.event.layerX + 10) + "px")
.style("top", (d3.event.layerY + 10) + "px")
.style("display", "block")
.html(tooltipSuppressedCompiled);
} else {
if (tooltipTemplate) {
// var template = Handlebars.compile(tooltipTemplate);
// var tooltipCompiled = Handlebars.compile(toolTipMasterTemplate.join(''));
// for (var i = 0; i < tooltipFields.length; i++) {
// d[tooltipFields[i]] = formatComma(d[tooltipFields[i]]);
// }
var compiledTmpl = tooltipCompiled(d);
tooltip.html(compiledTmpl);
tooltip.style('top', (d3.event.layerY + 10) + 'px')
.style('left', (d3.event.layerX + 10) + 'px');
tooltip.style('display', 'block');
} else { tooltip.style('display', 'none'); }
}
that._trigger("tooltiprefreshed", null, {});
})
.on('mouseout', function(d) {
g.selectAll("rect")
.transition()
// .duration(300)
.attr('opacity', 1)
// .attr("x", function(d) { return xScale(d[xField]); })
// .attr("width", xScale.bandwidth());
.style("stroke", "none");
var temp = d[xField];
d3.selectAll(".axis text")
.filter(function(d) {
return d == temp
})
.classed("highlight", false);
g.selectAll('#limit').remove();
// g.selectAll('.divergence').remove();
tooltip.style("display", "none");
});
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + left + "," + (height + top) + ")")
.call(xAxis)
.selectAll("text")
// .attr("dx", "-.5em")
// .attr("dy", ".25em")
.attr("transform", "rotate(-25)")
.style("text-anchor", "end");
g.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + left + "," + top + ")")
.call(yAxis)
.append("text")
.attr("x", 2)
// .attr("y", yAxis(yAxis.ticks().pop()) + 0.5)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start");
// .text("Percetage (%)");
g.append("text")
.attr("class", "xLabel")
.attr("y", height * 1.2 + top)
.attr("x", (width - widthTemp * 0.15) / 2)
.attr("dy", "1em")
.style("text-anchor", "middle")
.text(xTitle);
g.append("text")
.attr("class", "yLabel")
.attr("transform", "rotate(-90)")
// .attr("y", 0 - 40)
// .attr("x", 0 - (height / 2))
.attr("y", -55 + left)
.attr("x", -height / 2)
// .attr("dy", "1em")
.style("text-anchor", "middle")
.text(yTitle);
g.append("text")
.attr('class', 'title')
.attr("x", (width - widthTemp * 0.15) / 2)
.attr("y", -height * 0.1)
.style("text-anchor", "middle")
.text(title);
g.append("text")
.attr('class', 'subTitle')
.attr("x", (width - widthTemp * 0.15) / 2)
.attr("y", -height * 0.03)
.style("text-anchor", "middle")
.text(subTitle);
if (SuppressionFlag) {
g.append("text")
.attr('class', 'lock notranslate')
.attr("x", -50)
.attr("y", height * 1.2 + 60)
.style('font-family', 'FontAwesome')
.style("text-anchor", "start")
.text("\uf023");
g.append("text")
.attr('class', 'note')
.attr("x", -36)
.attr("y", height * 1.2 + 60)
.style("text-anchor", "start")
.text("Some information may be protected for student privacy.");
}
this._trigger("complete", null, {});
} else if (xField.length > 1) {
width = width * 0.9;
this._globalData.width = width;
this._globalData.height = height;
var x0 = d3.scaleBand()
// .range([0, width])
.range([0, Math.min(maxGroupBarSize * dataset.length, width)])
.padding(0.2);
var x1 = d3.scaleBand()
.padding(0.05);
var y = d3.scaleLinear()
.range([height, 0]);
// var color = d3.scaleOrdinal(d3.schemeCategory10);
var color = d3.scaleOrdinal()
.range(this.options.ColorPalette);
this._globalData.color = color;
var xAxis = d3.axisBottom(x0);
var yAxis = d3.axisLeft(y).ticks(10, "s");
//var yAxis = d3.axisLeft(y).tickFormat(function(d) { return formatValue(d) }); //format Y axis
// raw data preprocessing
// note: Lodash 4.0 onwards, the .pairs function has been renamed to _.toPairs()
var formattedData = _.chain(dataset)
.groupBy(function(d) { return d[groupField] })
.pairs()
.map(function(currentItem) {
return _.object(_.zip(["groupItem", "values"], currentItem));
})
.value();
//console.log(formattedData);
// lodash 4.x version
// .chain(data).groupBy('color').toPairs().map(function (pair) { return _.zipObject(['Name', 'Suppliers'], air); }).value();
var data = formattedData;
maxValue = d3.max(data, function(d) {
return d3.max(d.values, function(d) { return parseFloat(d[yField]); });
})
defaultvalue = maxValue > 0 ? maxValue : 100;
data.forEach(function(d, i) { //handle *
_.each(d.values, function(d) {
if (d[yField] === "*") {
d[yField] = -0.05 * defaultvalue;
SuppressionFlag = true;
}
});
});
// var x0Param = data.map(function(d) { return d[groupField] });
var x0Param = data.map(function(d) { return d.groupItem });
var x1Param = data[0].values.map(function(d) { return d[xField[1]] });
x0.domain(x0Param);
x1.domain(x1Param).rangeRound([0, x0.bandwidth()]);
if (maxValue > 0) {
y.domain([0, d3.max(data, function(d) {
return d3.max(d.values, function(d) { return parseFloat(Math.abs(d[yField])); });
})]).nice();
} else {
y.domain([0, 100]).nice();
}
var left = (width - widthTemp * 0.08 - Math.min(maxGroupBarSize * dataset.length, width)) / 2 + 35;
var top = -height * 0.05;
var groupedBar = g.append("g")
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + x0(d.groupItem) + "," + top + ")"; })
.selectAll("rect")
.data(function(d) { return d.values; })
.enter().append("rect")
.attr("class", "bar")
.attr("transform", function(d) { return "translate(" + left + ",0)"; })
.attr("x", function(d) { return x1(d[xField[1]]); })
.attr("width", x1.bandwidth())
.attr("fill", function(d) { return color(d[xField[1]]); })
.attr("height", function(d) { return 0; })
.attr("y", function(d) { return height; });
groupedBar.transition()
.delay(function(d, i) {
return i * 100;
})
.duration(1)
.ease(d3.easeLinear)
.attr("height", function(d) { return height - y(Math.abs(d[yField])); })
.attr("y", function(d) { return y(Math.abs(d[yField])); });
if (SuppressionFlag) {
var barText = g.append("g")
.selectAll("g")
.data(data)
.enter().append("g")
//.attr("transform", function(d) { return "translate(" + x0(d.groupItem) + ",0)"; })
.attr("transform", function(d) { return "translate(" + x0(d.groupItem) + "," + top + ")"; })
.selectAll("text")
.data(function(d) { return d.values; })
.enter().append("text")
.style('font-family', 'FontAwesome')
.style('fill', 'black')
.style('font-size', function(d) {
return 0.9 * Math.min(x1.bandwidth(), height - y(Math.abs(d[yField])));
})
.text(function(d) {
if (parseFloat(d[yField]) < 0) {
return '\uf023'; // \uf023
} else {
// if (showDataLabel == true) {
// return formatComma(Math.abs(d[yField]));
// } else {
return "";
// }
}
})
.attr("class", "bartext notranslate")
.attr("text-anchor", "middle")
.attr("transform", function(d) { return "translate(" + left + ",0)"; })
.attr("x", function(d) { return x1(d[xField[1]]); })
.attr("dx", x1.bandwidth() / 2)
// .attr("dy", function(d) { return 8; })
.attr("dy", ".35em")
.attr("y", function(d) { return height; });
barText.transition()
.delay(function(d, i) {
return i * 100;
})
.duration(1)
.ease(d3.easeLinear)
.attr("y", function(d) { return y(Math.abs(d[yField]) / 2); });
}
dataset.forEach(function(d) { //format data for tooltip
for (var i = 0; i < tooltipFields.length; i++) {
if (isNaN(parseFloat(d[tooltipFields[i]]))) {
d[tooltipFields[i]] = d[tooltipFields[i]];
} else {
d[tooltipFields[i]] = parseFloat(d[tooltipFields[i]]);
}
if (typeof(d[tooltipFields[i]]) === "number" && tooltipFields[i] !== "SchoolYear") {
d[tooltipFields[i]] = formatComma(d[tooltipFields[i]]);
}
}
});
var tempData = _.chain(dataset)
.groupBy(function(d) { return d[groupField] })
.pairs()
.map(function(currentItem) {
return _.object(_.zip(["groupItem", "values"], currentItem));
})
.value();
//console.log("With Comma", formattedData);
data = tempData;
// function isInArray(value, array) {
// return array.indexOf(value) > -1;
// }
groupedBar.on('mouseover', function(d) {
g.selectAll(".bar")
.transition()
.attr('opacity', 0.5);
d3.select(this)
.transition()
// .duration(300)
.attr('opacity', 1)
.style("stroke", function(d) {
return color(d[xField[1]]);
});
if (parseFloat(d[yField]) < 0) {
tooltip
.style("left", (d3.event.layerX + 10) + "px")
.style("top", (d3.event.layerY + 10) + "px")
.style("display", "block")
.html(tooltipSuppressedCompiled);
} else {
if (tooltipTemplate) {
// var template = Handlebars.compile(tooltipTemplate);
var compiledTmpl = tooltipCompiled(d);
tooltip.html(compiledTmpl);
tooltip.style('top', (d3.event.layerY + 10) + 'px')
.style('left', (d3.event.layerX + 10) + 'px');
tooltip.style('display', 'block');
} else {
tooltip.style('display', 'none');
}
}
that._trigger("tooltiprefreshed", null, {});
var highlight = d[xField[0]];
d3.selectAll(".axis text")
.filter(function(d) {
return d == highlight
})
.classed("highlight", true);
var temp;
if (typeof(d[yField]) === "number") {
temp = d[yField];
} else {
var str = d[yField];
var temp = parseFloat(str.replace(/,/g, "")); // parse large number with comma
}
temp = Math.abs(temp);
if (parseFloat(d[yField]) > 0) {
var line = g.append('line')
.attr('id', 'limit')
.attr('x1', left)
.attr('y1', y(temp) + top)
.attr('x2', Math.min(maxGroupBarSize * dataset.length, width) + left) //d3.event.layerX
.attr('y2', y(temp) + top)
}
})
.on('mouseout', function(d) {
g.selectAll(".bar")
.transition()
// .duration(300)
.attr('opacity', 1)
.style("stroke", "none");
// g.selectAll(".bar").attr('opacity', 1.0);
var highlight = d[xField[0]];
d3.selectAll(".axis text")
.filter(function(d) {
return d == highlight
})
.classed("highlight", false);
g.selectAll('#limit').remove();
tooltip.style("display", "none");
});
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(" + left + "," + (height + top) + ")")
.call(xAxis)
.selectAll("text")
.attr("transform", "rotate(-25)")
.style("text-anchor", "end");
g.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + left + "," + top + ")")
.call(yAxis)
.append("text")
.attr("x", 2)
// .attr("y", yAxis(yAxis.ticks().pop()) + 0.5)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start");
// .text("Percetage (%)");
g.append("text")
.attr("class", "xLabel")
.attr("y", height * 1.1 + top + 20)
.attr("x", (width - widthTemp * 0.15) / 2)
.attr("dy", "1em")
.style("text-anchor", "middle")
.text(xTitle);
g.append("text")
.attr("class", "yLabel")
.attr("transform", "rotate(-90)")
// .attr("y", 0 - 40)
// .attr("x", 0 - (height / 2))
.attr("y", -50 + left)
.attr("x", 0 - height / 2 - top)
// .attr("dy", "1em")
.style("text-anchor", "middle")
.text(yTitle);
g.append("text")
.attr('class', 'title')
.attr("x", (width - widthTemp * 0.15) / 2)
.attr("y", -height * 0.15)
.style("text-anchor", "middle")
.text(title);
g.append("text")
.attr('class', 'subTitle')
.attr("x", (width - widthTemp * 0.15) / 2)
.attr("y", -height * 0.08)
.style("text-anchor", "middle")
.text(subTitle);
if (SuppressionFlag) {
g.append("text")
.attr('class', 'lock notranslate')
.attr("x", -50)
.attr("y", height * 1.2 + 65)
.style('font-family', 'FontAwesome')
.style("text-anchor", "start")
.text("\uf023");
g.append("text")
.attr('class', 'note')
.attr("x", -36)
.attr("y", height * 1.2 + 65)
.style("text-anchor", "start")
.text("Some information may be protected for student privacy.");
}
this._globalData.xField = xField;
var legendArr = x1Param;
// console.log("data", legendArr);
// var test = x1Param.reverse();
this._globalData.legendArr = legendArr;
// var test = ["150000000000", "160000000000", "170000000000"]
// console.log("reversed data", test);
this._drawLegend(legendArr);
this._trigger("complete", null, { "legendArr": legendArr });
// d3.select('.legendAll').selectAll('g').remove();
// this.setLegend(test);
}
this._generateRawTable();
},
destroy: function() {
},
_drawLegend: function(data) {
var color = d3.scaleOrdinal()
.range(this.options.ColorPalette);
// color = this._globalData.color;
widthTemp = this._globalData.widthTemp;
heightTemp = this._globalData.heightTemp;
width = this._globalData.width;
height = this._globalData.height;
g = this._globalData.g;
xField = this._globalData.xField;
dataOrigin = this._globalData.legendArr;
d3.select('.legendAll').remove();
// d3.select('.legendAll').selectAll('g').remove();
var legendAll = g.append('g')
.attr('class', 'legendAll');
var legend = g.select('.legendAll')
// .attr("font-family", "sans-serif")
// .attr("font-size", 8)
// .attr("text-anchor", "end")
.selectAll("g")
.data(data) //.reverse()
.enter().append("g");
legend.append("rect")
.attr("x", 0)
.attr("width", 20)
.attr("height", 20)
.attr("fill", color)
.on('mouseover', function(d, i) {
d3.select(this)
.style("stroke", "black");
var tem = i;
g.selectAll(".bar")
.filter(function(d, i) {
return dataOrigin.indexOf(d[xField[1]]) !== tem;
})
.attr('opacity', 0);
g.selectAll(".bartext")
.filter(function(d) {
return dataOrigin.indexOf(d[xField[1]]) !== tem;
})
.attr('opacity', 0);
})
.on('mouseout', function(d, i) {
d3.select(this)
.style("stroke", "none");
g.selectAll(".bar")
.attr('opacity', 1);
g.selectAll(".bartext")
.attr('opacity', 1);
});
legend.append("text")
.attr("x", 22)
.attr("y", 11)
.attr("dy", "0.32em")
.attr("class", "legend")
.style("text-anchor", "begin")
.text(function(d) { return d; })
.on('mouseover', function(d, i) {
d3.select(this)
.classed("highlight", true);
var temp = i;
g.selectAll(".bar")
.filter(function(d) {
return dataOrigin.indexOf(d[xField[1]]) !== temp
})
.attr('opacity', 0);
g.selectAll(".bartext")
.filter(function(d) {
return dataOrigin.indexOf(d[xField[1]]) !== temp;
})
.attr('opacity', 0);
})
.on('mouseout', function(d, i) {
d3.select(this)
.classed("highlight", false);
g.selectAll(".bar")
.attr('opacity', 1);
g.selectAll(".bartext")
.attr('opacity', 1);
});
var sum = 0;
var xPos = 0;
var yPos = height * 1.2;
legend
.attr(
"transform",
function(d, i) {
var ret = "translate(" + (xPos) + "," + yPos + ")";
xPos += this.getBBox().width + 10;
sum += this.getBBox().width + 10;
// xPos += d.length;
if (xPos > width - widthTemp * 0.15) {
xPos = 0;
yPos += 30;
}
return ret;
}
);
// .attr("transform", function(d, i) { return "translate(" + width / x1Param.length * i + "," + height * 1.2 + ")"; });
// legend.attr("transform", function(d, i) {
// if (x1Param.length > rowCount) {
// return "translate(" + (i % rowCount * ((width + 60) / rowCount) - 50) + "," + ((height * 1.2 + Math.floor(i / rowCount) * 25) + top + 20) + ")";
// } else {
// return "translate(" + (width / x1Param.length * i - 50) + "," + (height * 1.2 + top + 20) + ")";
// }
// });
var legendWidth = d3.select(this.element.find('.legendAll').get(0)).node().getBBox().width;
legendAll
.attr("transform", function(d, i) {
return "translate(" + (width - widthTemp * 0.15 - legendWidth) / 2 + "," + 0 + ")";
});
},
setLegend: function(data) {
// remove ();
this._drawLegend(data);
},
getLegend: function() {
},
_setOption: function(key, value) {
this._super(key, value);
},
_setOptions: function(options) {
this._super(options);
}
});
});