function (tag, help) { ////////////// vf-mvplot ////////////// NEED TO KNOW TAG NAME $(tag).each(function (index, element) { if(($(element).attr('rendered') == undefined || $(element).attr('rendered') == false)){ $(element).html(''); function renderPlot(outputs, element){ var data = outputs;//parse_data(outputs); // Size parameters. var n = data.variables.length; var padding = 19.5; var size = (($(element).parent().width() - (padding)) / n); // Position scales. var x = {}, y = {}; data.variables.forEach(function(variable) { var value = function(d) { return +d[variable]; }; var domain = [d3.min(data.values, value), d3.max(data.values, value)], range = [padding / 2, size - padding / 2]; x[variable] = d3.scale.linear() .domain(domain) .range(range); y[variable] = d3.scale.linear() .domain(domain) .range(range.slice().reverse()); }); // Axes. cell var axis = d3.svg.axis() .ticks(5) .tickSize(size * n); // Brush. var brush = d3.svg.brush() .on("brushstart", brushstart) .on("brush", brush) .on("brushend", brushend); // Root panel. var svg = d3.select('#'+$(element).attr('id')).append("svg") .attr("width", size * n + padding) .attr("height", size * n + padding); // X-axis. svg.selectAll("g.x.axis") .data(data.variables) .enter().append("g") .attr("class", "x axis") .attr("transform", function(d, i) { return "translate(" + i * size + ",0)"; }) .each(function(d) { d3.select(this).call(axis.scale(x[d]) .orient("bottom")); }); // Y-axis. svg.selectAll("g.y.axis") .data(data.variables) .enter().append("g") .attr("class", "y axis") .attr("transform", function(d, i) { return "translate(0," + i * size + ")"; }) .each(function(d) { d3.select(this).call(axis.scale(y[d]).orient("right")); }); // Cell and plot. var cell = svg.selectAll("g.cell") .data(cross(data.variables, data.variables)) .enter().append("g") .attr("class", "cell") .attr("transform", function(d) { return "translate(" + d.i * size + "," + d.j * size + ")"; }) .each(plot); // Titles for the diagonal. cell.filter(function(d) { return d.i == d.j; }).append("text") .attr("x", padding) .attr("y", padding) .attr("dy", ".71em") .text(function(d) { return data.labels[$.inArray(d.x,data.variables)];//d.x; }); function plot(p) { var cell = d3.select(this); // Plot frame. cell.append("rect") .attr("class", "frame") .attr("x", padding / 2) .attr("y", padding / 2) .attr("width", size - padding) .attr("height", size - padding); // Plot dots. cell.selectAll("circle") .data(data.values) .enter().append("circle") .on("mouseover", function(d) { cell.append("text") .attr("class", "designID") .attr("x", function(){ return x[p.x](d[p.x])+5; }) //mouse location (x) minus margin .attr("y", function(){ return y[p.y](d[p.y])-5; }) //mouse location (y) minus margin and some padding for better text display .attr("fill", "white") .text(d.designs); }) .on("mouseout", function(d) { //remove the text element added on the mouseover event when the mouseout event is triggered $("text.designID").remove(); }) //.attr("class", "selected") .attr("cx", function(d) { return x[p.x](d[p.x]); }) .attr("cy", function(d) { return y[p.y](d[p.y]); }) .attr("class", function(d) { if(!(d.designs == undefined)) { return "design " + d.cid + " selected"; //selected class is so all the points are shown bright upon initialization. Changes after brushing } else { return "design " + d.cid + " selected"; //selected class is so all the points are shown bright upon initialization. Changes after brushing } }) .attr("r", 3); // Plot brush. cell.call( brush.x(x[p.x]).y(y[p.y]) ); //Veritcal and Horizontal line thresholds... MJD /* var thresholds = {"power" : 5.25, "current" : 2.5, "voltage" : 4, "capacitance" : 0.8}; */ cell.append("g") .attr("class", "threshold vertical") //This is the class for the vertical line used by the 2Dscatter plot .append("line") .attr("x1", function(d) { return x[p.x](outputs.thresholds[p.x]); }) .attr("y1", padding / 2) .attr("x2", function(d){ return x[p.x](outputs.thresholds[p.x]); }) .attr("y2", size - padding / 2) .on("mouseover", function(d) { svg.append("text") .text(outputs.thresholds[p.x]) .attr("class", "objectiveLabel") .attr("x", function(){ return event.pageX - padding / 2 - 3; }) //mouse location (x) minus margin .attr("y", function(){ return event.pageY - padding / 2 + 3 - this.offsetTop; }) //mouse location (y) minus margin and some padding for better text display .attr("text-anchor", "start"); //.attr("fill", "green"); }) .on("mouseout", function(d) { $('text.objectiveLabel').remove(); }); cell.append("g") .attr("class", "threshold horizontal") //This is the class for the horizontal line used by the 2Dscatter plot .append("line") .attr("x1", padding / 2) .attr("y1", function(d) { return y[p.y](outputs.thresholds[p.y]); }) .attr("x2", size - padding / 2) .attr("y2", function(d){ return y[p.y](outputs.thresholds[p.y]); }) .on("mouseover", function(d) { svg.append("text") .text(outputs.thresholds[p.y]) .attr("class", "objectiveLabel") .attr("x", function(){ return event.pageX - padding; }) //mouse location (x) minus margin .attr("y", function(){ return event.pageY - padding + 5 - this.offsetTop; }) //mouse location (y) minus margin and some padding for better text display .attr("text-anchor", "middle") .attr("fill", "green"); }) .on("mouseout", function(d) { $('text.objectiveLabel').remove(); }); //Veritcal and Horizontal line objective... MJD /* var outputs.objectives = {"power" : 4.8, "current" : 3, "voltage" : 3.125, "capacitance" : 1.25}; */ cell.append("g") .attr("class", "objective vertical") //This is the class for the vertical line used by the 2Dscatter plot .append("line") .attr("x1", function(d) { return x[p.x](outputs.objectives[p.x]); }) .attr("y1", padding / 2) .attr("x2", function(d){ return x[p.x](outputs.objectives[p.x]); }) .attr("y2", size - padding / 2) .on("mouseover", function(d) { svg.append("text") .text(outputs.objectives[p.x]) .attr("class", "objectiveLabel") .attr("x", function(){ return event.pageX - padding / 2 - 3; }) //mouse location (x) minus margin .attr("y", function(){ return event.pageY - padding / 2 + 3 - this.offsetTop; }) //mouse location (y) minus margin and some padding for better text display .attr("text-anchor", "start") .attr("fill", "green"); }) .on("mouseout", function(d) { $('text.objectiveLabel').remove(); }); cell.append("g") .attr("class", "objective horizontal") //This is the class for the horizontal line used by the 2Dscatter plot .append("line") .attr("x1", padding / 2) .attr("y1", function(d) { return y[p.y](outputs.objectives[p.y]); }) .attr("x2", size - padding / 2) .attr("y2", function(d){ return y[p.y](outputs.objectives[p.y]); }) .on("mouseover", function(d) { svg.append("text") .text(outputs.objectives[p.y]) .attr("class", "objectiveLabel") .attr("x", function(){ return event.pageX - padding; }) //mouse location (x) minus margin .attr("y", function(){ return event.pageY - padding + 5 - this.offsetTop; }) //mouse location (y) minus margin and some padding for better text display .attr("text-anchor", "middle") .attr("fill", "green"); }) .on("mouseout", function(d) { $('text.objectiveLabel').remove(); }); } // Clear the previously-active brush, if any. function brushstart(p) { if (brush.data !== p) { cell.call(brush.clear()); brush.x(x[p.x]).y(y[p.y]).data = p; $(".design").addClass("selected"); //reselect all points if brush is cleared } } // Highlight only the brushed circles (conversely, deselect all non-brushed circles) function brush(p) { var e = brush.extent(); /*svg.selectAll("circle").attr("class", function(d) { return e[0][0] <= d[p.x] && d[p.x] <= e[1][0] && e[0][1] <= d[p.y] && d[p.y] <= e[1][1] ? "selected" : null; */ //globals cidSelected = []; cidNotSelected = []; svg.selectAll("circle").classed("selected", function(d) { if (e[0][0] <= d[p.x] && d[p.x] <= e[1][0] && e[0][1] <= d[p.y] && d[p.y] <= e[1][1]) { //link pplot to mvplot brushing if (jQuery.inArray($(this).attr("class").split(" ")[1], cidSelected) == -1) { cidSelected.push($(this).attr("class").split(" ")[1]); } //add the selected class from the mvplot element return true; } else { //link pplot to mvplot brushing if (jQuery.inArray($(this).attr("class").split(" ")[1], cidNotSelected) == -1) { cidNotSelected.push($(this).attr("class").split(" ")[1]); } //$("#pplot ." + cidSelected).removeClass("selected"); //remove the selected class from the mvplot element return false; } }); $("#pplot path.design").removeClass("selected"); if (!(cidSelected.length == 0)) { for (var i = 0; i < cidSelected.length; i++) { $("#pplot path." + cidSelected[i]).addClass("selected"); } } /* if (!(cidNotSelected.length == 0)) { for (var i = 0; i < cidNotSelected.length; i++) { $("path." + cidNotSelected[i]).removeClass("selected"); } } */ /* //"link" the mvplot with pplot $("#pplot path.design").each(function(){ var cidSelected = $(this).attr("class").split(" ")[2]; if (!(cidSelected == undefined)) { } }); */ } // If the brush is empty, select all circles. function brushend() { if (brush.empty()) { //if already selected, leave it selected. if not selected, select it. svg.selectAll("circle").classed("selected", true); } } function cross(a, b) { var c = [], n = a.length, m = b.length, i, j; for (i = -1; ++i < n;) for (j = -1; ++j < m;) c.push({x: a[i], i: i, y: b[j], j: j}); return c; } // fix negative signs in axis $('text').each(function(index,item){item.textContent = item.textContent.replace("-","-");}); } } if(!((typeof window[$(element).attr('data')]) == 'undefined')){ renderPlot(window[$(element).attr('data')].dataproviders.multiVariate(), element); $(element).attr('rendered','true'); } }); }