From bd4702ebe0eb07734e3e9a53885e23770f0ad1a1 Mon Sep 17 00:00:00 2001 From: hyunjuna Date: Fri, 16 Dec 2022 14:11:01 -0800 Subject: [PATCH] add proto type of interactive and responsive confusion matrix --- .../index copy later.jsx | 563 +++++++++++++++ .../ConfusionMatrixJSONRender/index copy.jsx | 434 ++++++++++++ .../ConfusionMatrixJSONRender/index.jsx | 640 ++++++++++++++++++ .../components/ConfusionMatrixJSON/index.jsx | 108 +-- lab/webapp/src/components/Results/index.jsx | 29 +- 5 files changed, 1689 insertions(+), 85 deletions(-) create mode 100644 lab/webapp/src/components/ConfusionMatrixJSONRender/index copy later.jsx create mode 100644 lab/webapp/src/components/ConfusionMatrixJSONRender/index copy.jsx create mode 100644 lab/webapp/src/components/ConfusionMatrixJSONRender/index.jsx diff --git a/lab/webapp/src/components/ConfusionMatrixJSONRender/index copy later.jsx b/lab/webapp/src/components/ConfusionMatrixJSONRender/index copy later.jsx new file mode 100644 index 000000000..2c0d45d47 --- /dev/null +++ b/lab/webapp/src/components/ConfusionMatrixJSONRender/index copy later.jsx @@ -0,0 +1,563 @@ +/* ~This file is part of the Aliro library~ + +Copyright (C) 2017 Epistasis Lab, University of Pennsylvania + +Aliro is maintained by: + - Heather Williams (hwilli@upenn.edu) + - Weixuan Fu (weixuanf@upenn.edu) + - William La Cava (lacava@upenn.edu) + - Michael Stauffer (stauffer@upenn.edu) + - and many other generous open source contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +(Autogenerated header, do not modify) + +*/ +import React, { Component } from 'react'; + +import c3 from 'c3'; + +import d3 from 'd3'; + + + +// working version +// class TestLineChart extends Component { + + +// // train_sizes={train_sizes} +// // train_scores={train_scores} +// // test_scores={test_scores} +// // chartKey={chartKey} +// // chartColor={chartColor} +// // min={0.5} +// // max={1.0} + +// componentDidMount() { +// const { train_sizes, train_scores, test_scores, chartKey, chartColor, min, max } = this.props; +// train_sizes && train_scores && test_scores && this.renderChart(train_sizes, train_scores, test_scores, chartKey, chartColor, min, max); +// } +// /* +// colors: { +// 'test_score': '#0072b2', ---- light blue +// 'train_score': '#f0e442' ---- light yellow +// '#55D6BE' ----- light sea green +// } + +// use anonymous function to 'disable' interaction +// look here - https://github.com/c3js/c3/issues/493#issuecomment-456686654 +// */ + +// // renderChart(expList, chartKey, chartColor, min, max) { +// renderChart(train_sizes, train_scores, test_scores, chartKey, chartColor, min, max) { + +// window.console.log('here in renderChart for TestLineChart'); +// // window.console.log('train_sizes: ', train_sizes); +// // window.console.log('train_scores.length: ', train_scores.length); +// // window.console.log('train_scores: ', train_scores); +// // window.console.log('test_scores: ', test_scores); + +// // // +// // min = 0; +// // // max is last element in train_sizes +// max = train_sizes[train_sizes.length - 1]; +// max = max + 0.1 * max; + +// window.console.log('max: ', max); +// var total_train_scores=[]; +// var total_test_scores=[]; +// for (var i = 0; i < train_scores.length; i++) { + +// // calculate averge of train_sizes[i] +// // divide by train_scores[i].length + +// var sum_train_scores = 0; +// var sum_test_scores = 0; +// for (var j = 0; j < train_scores[i].length; j++) { +// sum_train_scores += train_scores[i][j]; +// sum_test_scores += test_scores[i][j]; +// } +// var avg_sum_train_scores = sum_train_scores / train_scores[i].length; +// var avg_sum_test_scores = sum_test_scores / test_scores[i].length; + +// total_train_scores.push(avg_sum_train_scores); +// total_test_scores.push(avg_sum_test_scores); + + +// } + + +// var json = []; +// for (var i = 0; i < train_sizes.length; i++) { +// json.push({x: train_sizes[i], Training_score: total_train_scores[i], Cross_validation_score: total_test_scores[i]}); +// } + +// // window.console.log('json: ', json); + +// // window.console.log('chartKey: ', chartKey); + +// var chart = c3.generate({ +// bindto: `.${chartKey}`, + +// data: { +// json: json, + +// keys: { +// x: 'x', +// value: ['Training_score', 'Cross_validation_score'], +// } + +// }, +// axis: { +// y: { +// min: 0, +// max: 1, +// label: 'Score' + +// }, +// x: { +// min: 0, +// max: max, +// label: 'Training examples', +// tick: { +// multiline:false, +// culling: false // <-- THIS! +// } + +// } +// }, +// grid: { +// y: { +// show: true, +// color : '#fff!important' +// }, +// x: { +// show: true, +// color : '#fff!important' +// } +// }, + +// tooltip: { +// format: { +// title: function (d) { return 'Training examples: ' + d; } +// } +// } + + + + + +// }); + +// // if document element has testuser text, then make it unvisiable + + + + + + +// } + +// render() { +// return ( +//
+// ); +// } +// } + +// TestLineChart.defaultProps = { +// chartColor: '#60B044' +// }; + +// export default TestLineChart; + + + + + + + + + + + +// test version +class TestLineChart extends Component { + componentDidMount() { + console.log("hello"); + // train_sizes={train_sizes} + // train_scores={train_scores} + // test_scores={test_scores} + // chartKey={chartKey} + // chartColor={chartColor} + // min={0.5} + // max={1.0} + const { train_sizes,train_scores,test_scores, cnf_data,chartKey, chartColor, min, max } = this.props; + this.renderChart(train_sizes,train_scores,test_scores,cnf_data, chartKey, chartColor, min, max); + } + + +/* +colors: { + 'test_score': '#0072b2', ---- light blue + 'train_score': '#f0e442' ---- light yellow + '#55D6BE' ----- light sea green +} + +use anonymous function to 'disable' interaction +look here - https://github.com/c3js/c3/issues/493#issuecomment-456686654 +*/ + + renderChart(train_sizes,train_scores,test_scores,cnf_data, chartKey, chartColor, min, max) { + console.log('here in renderChart for TestLineChart'); + + + var margin = {top: 50, right: 50, bottom: 100, left: 100}; + + function Matrix(options) { + var width = 250, + height = 250, + data = options.data, + container = options.container, + labelsData = options.labels, + startColor = options.start_color, + endColor = options.end_color; + + var widthLegend = 100; + + if(!data){ + throw new Error('Please pass data'); + } + + if(!Array.isArray(data) || !data.length || !Array.isArray(data[0])){ + throw new Error('It should be a 2-D array'); + } + + var maxValue = d3.max(data, function(layer) { return d3.max(layer, function(d) { return d; }); }); + var minValue = d3.min(data, function(layer) { return d3.min(layer, function(d) { return d; }); }); + + var numrows = data.length; + var numcols = data[0].length; + var svg = d3.select(`.${chartKey}`).append("svg") + // var svg = d3.select(container).append("svg") + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + + var background = svg.append("rect") + .style("stroke", "black") + .style("stroke-width", "2px") + .attr("width", width) + .attr("height", height); + + var x = d3.scaleBand() + .domain(d3.range(numcols)) + .range([0, width]); + + var y = d3.scaleBand() + .domain(d3.range(numrows)) + .range([0, height]); + + var colorMap = d3.scaleLinear() + .domain([minValue,maxValue]) + .range([startColor, endColor]); + + var row = svg.selectAll(".row") + .data(data) + .enter().append("g") + .attr("class", "row") + .attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; }); + + var cell = row.selectAll(".cell") + .data(function(d) { return d; }) + .enter().append("g") + .attr("class", "cell") + .attr("transform", function(d, i) { return "translate(" + x(i) + ", 0)"; }); + + cell.append('rect') + .attr("width", x.bandwidth()) + .attr("height", y.bandwidth()) + .style("stroke-width", 0); + + cell.append("text") + .attr("dy", ".32em") + .attr("x", x.bandwidth() / 2) + .attr("y", y.bandwidth() / 2) + .attr("text-anchor", "middle") + .style("fill", function(d, i) { return d >= maxValue/2 ? 'white' : 'black'; }) + .text(function(d, i) { return d; }); + + row.selectAll(".cell") + .data(function(d, i) { return data[i]; }) + .style("fill", colorMap); + + var labels = svg.append('g') + .attr('class', "labels"); + + var columnLabels = labels.selectAll(".column-label") + .data(labelsData) + .enter().append("g") + .attr("class", "column-label") + .attr("transform", function(d, i) { return "translate(" + x(i) + "," + height + ")"; }); + + columnLabels.append("line") + .style("stroke", "black") + .style("stroke-width", "1px") + .attr("x1", x.bandwidth() / 2) + .attr("x2", x.bandwidth() / 2) + .attr("y1", 0) + .attr("y2", 5); + + columnLabels.append("text") + .attr("x", 30) + .attr("y", y.bandwidth() / 2) + .attr("dy", ".22em") + .attr("text-anchor", "end") + .attr("transform", "rotate(-60)") + .text(function(d, i) { return d; }); + + var rowLabels = labels.selectAll(".row-label") + .data(labelsData) + .enter().append("g") + .attr("class", "row-label") + .attr("transform", function(d, i) { return "translate(" + 0 + "," + y(i) + ")"; }); + + rowLabels.append("line") + .style("stroke", "black") + .style("stroke-width", "1px") + .attr("x1", 0) + .attr("x2", -5) + .attr("y1", y.bandwidth() / 2) + .attr("y2", y.bandwidth() / 2); + + rowLabels.append("text") + .attr("x", -8) + .attr("y", y.bandwidth() / 2) + .attr("dy", ".32em") + .attr("text-anchor", "end") + .text(function(d, i) { return d; }); + + var key = d3.select("#legend") + .append("svg") + .attr("width", widthLegend) + .attr("height", height + margin.top + margin.bottom); + + var legend = key + .append("defs") + .append("svg:linearGradient") + .attr("id", "gradient") + .attr("x1", "100%") + .attr("y1", "0%") + .attr("x2", "100%") + .attr("y2", "100%") + .attr("spreadMethod", "pad"); + + legend + .append("stop") + .attr("offset", "0%") + .attr("stop-color", endColor) + .attr("stop-opacity", 1); + + legend + .append("stop") + .attr("offset", "100%") + .attr("stop-color", startColor) + .attr("stop-opacity", 1); + + key.append("rect") + .attr("width", widthLegend/2-10) + .attr("height", height) + .style("fill", "url(#gradient)") + .attr("transform", "translate(0," + margin.top + ")"); + + var y = d3.scaleLinear() + .range([height, 0]) + .domain([minValue, maxValue]); + + var yAxis = d3.axisRight(y); + + key.append("g") + .attr("class", "y axis") + .attr("transform", "translate(41," + margin.top + ")") + .call(yAxis) + + } + function testMatrix(){ + console.log("testMatrix"); + } + var matrix = cnf_data; + + console.log("cnf_data in line",cnf_data); + + + + // print curreht class name + window.console.log('TestLine current class name: ', `.${chartKey}`); + + + + var div = d3.select(`.${chartKey}`) + // add svg to div + + var svg = div.append("svg") + // make viewbox to make svg responsive + .attr("viewBox", "0 0 600 400") + .attr("preserveAspectRatio", "xMinYMin meet") + .append("g") + .attr("transform", "translate(50,50)"); + + + // var matrix = [[10,20],[30,40]]; + + + // var matrix = [[10,20],[30,40]]; + + + + var tempcount=0; + + + + // var rect = svg.selectAll("rect") + // .data(matrix) + // .enter() + // .append("rect") + // .attr("width", 100) + // .attr("height", 100) + // // make width and height related to current div size + // // .attr("width", function(d, i) { + // // return d3.select(`.${chartKey}`).node().getBoundingClientRect().width/10; + // // }) + // // .attr("height", function(d, i) { + // // return d3.select(`.${chartKey}`).node().getBoundingClientRect().height/10; + // // }) + // .attr("x", function(d, i) { + // console.log('d: ', d); + + // console.log('d[0][0]: ', d[0]); + // console.log('d[0][1]: ', d[1]); + // // loop based on size of d + // for (var i = 0; i < d.length; i++) { + // // console.log('d[i]: ', d[i]); + // // make 1 row 2 column + // tempcount+=1; + // console.log('tempcount', tempcount); + // } + + // return i * 100; + + // } ) + // .attr("y", function(d, i) { + + // return i * 100; + // } + // ) + // .attr('id', function(d, i) { + // return 'rect_' + d; + // } + // ) + // .attr('fill', function(d, i) { + + // console.log('fill_d: ', d); + // // choose color based on value d + + // if (d > 150) { + // return 'green'; + // } + // return 'red'; + // } + // ) + // // make it show more than background color + // .attr('opacity', 0.5) + // // add mouseover event + // // .on("mouseover", function(d, i) { + // // // change color + // // d3.select(this).attr('fill', 'blue'); + // // console.log('number',d) + // // // show this d as string on the rect + // // d3.select(this).text(d); + // // // make the text color white + // // d3.select(this).attr('fill', 'white'); + + // // d3.select(this).text('This is some information about whatever') + // // .attr('x', 50) + // // .attr('y', 150) + // // .attr('fill', 'white') + + // // }) + // .append('text').text('test'); + + + // need to generalize this to work for any size matrix + + var tp = matrix[0][0]; + var fn = matrix[0][1]; + var fp = matrix[1][0]; + var tn = matrix[1][1]; + + var p = tp + fn; + var n = fp + tn; + + var accuracy = (tp+tn)/(p+n); + var f1 = 2*tp/(2*tp+fp+fn); + var precision = tp/(tp+fp); + var recall = tp/(tp+fn); + + accuracy = Math.round(accuracy * 100) / 100 + f1 = Math.round(f1 * 100) / 100 + precision = Math.round(precision * 100) / 100 + recall = Math.round(recall * 100) / 100 + + var computedData = []; + computedData.push({"F1":f1, "PRECISION":precision,"RECALL":recall,"ACCURACY":accuracy}); + + var labels = ['Class A', 'Class B']; + Matrix({ + container : '#container', + chartKey : chartKey, + data : matrix, + labels : labels, + start_color : '#ffffff', + end_color : '#e67e22' + }); + // testMatrix(); + + // rendering the table + // var table = tabulate(computedData, ["F1", "PRECISION","RECALL","ACCURACY"]); + + + + } + + render() { + return ( +
+ ); + } +} + +TestLineChart.defaultProps = { + chartColor: '#60B044' +}; + +export default TestLineChart; + + + + + + + diff --git a/lab/webapp/src/components/ConfusionMatrixJSONRender/index copy.jsx b/lab/webapp/src/components/ConfusionMatrixJSONRender/index copy.jsx new file mode 100644 index 000000000..979e00edc --- /dev/null +++ b/lab/webapp/src/components/ConfusionMatrixJSONRender/index copy.jsx @@ -0,0 +1,434 @@ +/* ~This file is part of the Aliro library~ + +Copyright (C) 2017 Epistasis Lab, University of Pennsylvania + +Aliro is maintained by: + - Heather Williams (hwilli@upenn.edu) + - Weixuan Fu (weixuanf@upenn.edu) + - William La Cava (lacava@upenn.edu) + - Michael Stauffer (stauffer@upenn.edu) + - and many other generous open source contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +(Autogenerated header, do not modify) + +*/ +import React, { Component } from 'react'; + +import c3 from 'c3'; + +import d3 from 'd3'; + + + +// working version +// class TestLineChart extends Component { + + +// // train_sizes={train_sizes} +// // train_scores={train_scores} +// // test_scores={test_scores} +// // chartKey={chartKey} +// // chartColor={chartColor} +// // min={0.5} +// // max={1.0} + +// componentDidMount() { +// const { train_sizes, train_scores, test_scores, chartKey, chartColor, min, max } = this.props; +// train_sizes && train_scores && test_scores && this.renderChart(train_sizes, train_scores, test_scores, chartKey, chartColor, min, max); +// } +// /* +// colors: { +// 'test_score': '#0072b2', ---- light blue +// 'train_score': '#f0e442' ---- light yellow +// '#55D6BE' ----- light sea green +// } + +// use anonymous function to 'disable' interaction +// look here - https://github.com/c3js/c3/issues/493#issuecomment-456686654 +// */ + +// // renderChart(expList, chartKey, chartColor, min, max) { +// renderChart(train_sizes, train_scores, test_scores, chartKey, chartColor, min, max) { + +// window.console.log('here in renderChart for TestLineChart'); +// // window.console.log('train_sizes: ', train_sizes); +// // window.console.log('train_scores.length: ', train_scores.length); +// // window.console.log('train_scores: ', train_scores); +// // window.console.log('test_scores: ', test_scores); + +// // // +// // min = 0; +// // // max is last element in train_sizes +// max = train_sizes[train_sizes.length - 1]; +// max = max + 0.1 * max; + +// window.console.log('max: ', max); +// var total_train_scores=[]; +// var total_test_scores=[]; +// for (var i = 0; i < train_scores.length; i++) { + +// // calculate averge of train_sizes[i] +// // divide by train_scores[i].length + +// var sum_train_scores = 0; +// var sum_test_scores = 0; +// for (var j = 0; j < train_scores[i].length; j++) { +// sum_train_scores += train_scores[i][j]; +// sum_test_scores += test_scores[i][j]; +// } +// var avg_sum_train_scores = sum_train_scores / train_scores[i].length; +// var avg_sum_test_scores = sum_test_scores / test_scores[i].length; + +// total_train_scores.push(avg_sum_train_scores); +// total_test_scores.push(avg_sum_test_scores); + + +// } + + +// var json = []; +// for (var i = 0; i < train_sizes.length; i++) { +// json.push({x: train_sizes[i], Training_score: total_train_scores[i], Cross_validation_score: total_test_scores[i]}); +// } + +// // window.console.log('json: ', json); + +// // window.console.log('chartKey: ', chartKey); + +// var chart = c3.generate({ +// bindto: `.${chartKey}`, + +// data: { +// json: json, + +// keys: { +// x: 'x', +// value: ['Training_score', 'Cross_validation_score'], +// } + +// }, +// axis: { +// y: { +// min: 0, +// max: 1, +// label: 'Score' + +// }, +// x: { +// min: 0, +// max: max, +// label: 'Training examples', +// tick: { +// multiline:false, +// culling: false // <-- THIS! +// } + +// } +// }, +// grid: { +// y: { +// show: true, +// color : '#fff!important' +// }, +// x: { +// show: true, +// color : '#fff!important' +// } +// }, + +// tooltip: { +// format: { +// title: function (d) { return 'Training examples: ' + d; } +// } +// } + + + + + +// }); + +// // if document element has testuser text, then make it unvisiable + + + + + + +// } + +// render() { +// return ( +//
+// ); +// } +// } + +// TestLineChart.defaultProps = { +// chartColor: '#60B044' +// }; + +// export default TestLineChart; + + + + + + + + + + + +// test version +class TestLineChart extends Component { + componentDidMount() { + console.log("hello"); + // train_sizes={train_sizes} + // train_scores={train_scores} + // test_scores={test_scores} + // chartKey={chartKey} + // chartColor={chartColor} + // min={0.5} + // max={1.0} + const { train_sizes,train_scores,test_scores, cnf_data,chartKey, chartColor, min, max } = this.props; + this.renderChart(train_sizes,train_scores,test_scores,cnf_data, chartKey, chartColor, min, max); + } + + +/* +colors: { + 'test_score': '#0072b2', ---- light blue + 'train_score': '#f0e442' ---- light yellow + '#55D6BE' ----- light sea green +} + +use anonymous function to 'disable' interaction +look here - https://github.com/c3js/c3/issues/493#issuecomment-456686654 +*/ + + renderChart(train_sizes,train_scores,test_scores,cnf_data, chartKey, chartColor, min, max) { + console.log('here in renderChart for TestLineChart'); + // window.console.log('exp list: '); + // window.console.log('exp list: ', expList); + // print d3 version + // window.console.log('d3 version: ', d3.version); + // // print c3 version + // window.console.log('c3 version: ', c3.version); + + + + // // make expList like[['1',0.2],['2',0.3],['3',0.5]] + // // expList = [['1',0.2],['2',0.3],['3',0.5]]; + + // // print expList + // window.console.log('expList: ', expList); + + // // print chartKey + // window.console.log('chartKey: ', chartKey); + + // var chart = c3.generate({ + // bindto: `.${chartKey}`, + // data: { + + + // columns:expList + // , + + // type : 'TestLineChart', + // // colors: { + // // columns[0][0]: '#ff0000', + // // columns[1][0]: '#00ff00' + // // } + // // , + // onclick: function (d, i) { console.log("onclick", d, i); }, + // onmouseover: function (d, i) { console.log("onmouseover", d, i); }, + // onmouseout: function (d, i) { console.log("onmouseout", d, i); } + // }, + // TestLineChart: { + // // title: "Iris Petal Width" + // title: "" + // // title: expList + // } + // }); + + + + + // make confusion matrix [[10,20],[30,40]] using d3.js + // var matrix = [[10,20],[30,40]]; + + var matrix = cnf_data; + + console.log("cnf_data in line",cnf_data); + + + + // print curreht class name + window.console.log('TestLine current class name: ', `.${chartKey}`); + + + + var div = d3.select(`.${chartKey}`) + // add svg to div + + var svg = div.append("svg") + // make viewbox to make svg responsive + .attr("viewBox", "0 0 600 400") + .attr("preserveAspectRatio", "xMinYMin meet") + .append("g") + .attr("transform", "translate(50,50)"); + + + // var matrix = [[10,20],[30,40]]; + + + // var matrix = [[10,20],[30,40]]; + + + + var tempcount=0; + + + + // var rect = svg.selectAll("rect") + // .data(matrix) + // .enter() + // .append("rect") + // .attr("width", 100) + // .attr("height", 100) + // // make width and height related to current div size + // // .attr("width", function(d, i) { + // // return d3.select(`.${chartKey}`).node().getBoundingClientRect().width/10; + // // }) + // // .attr("height", function(d, i) { + // // return d3.select(`.${chartKey}`).node().getBoundingClientRect().height/10; + // // }) + // .attr("x", function(d, i) { + // console.log('d: ', d); + + // console.log('d[0][0]: ', d[0]); + // console.log('d[0][1]: ', d[1]); + // // loop based on size of d + // for (var i = 0; i < d.length; i++) { + // // console.log('d[i]: ', d[i]); + // // make 1 row 2 column + // tempcount+=1; + // console.log('tempcount', tempcount); + // } + + // return i * 100; + + // } ) + // .attr("y", function(d, i) { + + // return i * 100; + // } + // ) + // .attr('id', function(d, i) { + // return 'rect_' + d; + // } + // ) + // .attr('fill', function(d, i) { + + // console.log('fill_d: ', d); + // // choose color based on value d + + // if (d > 150) { + // return 'green'; + // } + // return 'red'; + // } + // ) + // // make it show more than background color + // .attr('opacity', 0.5) + // // add mouseover event + // // .on("mouseover", function(d, i) { + // // // change color + // // d3.select(this).attr('fill', 'blue'); + // // console.log('number',d) + // // // show this d as string on the rect + // // d3.select(this).text(d); + // // // make the text color white + // // d3.select(this).attr('fill', 'white'); + + // // d3.select(this).text('This is some information about whatever') + // // .attr('x', 50) + // // .attr('y', 150) + // // .attr('fill', 'white') + + // // }) + // .append('text').text('test'); + + + // need to generalize this to work for any size matrix + + var tp = matrix[0][0]; + var fn = matrix[0][1]; + var fp = matrix[1][0]; + var tn = matrix[1][1]; + + var p = tp + fn; + var n = fp + tn; + + var accuracy = (tp+tn)/(p+n); + var f1 = 2*tp/(2*tp+fp+fn); + var precision = tp/(tp+fp); + var recall = tp/(tp+fn); + + accuracy = Math.round(accuracy * 100) / 100 + f1 = Math.round(f1 * 100) / 100 + precision = Math.round(precision * 100) / 100 + recall = Math.round(recall * 100) / 100 + + var computedData = []; + computedData.push({"F1":f1, "PRECISION":precision,"RECALL":recall,"ACCURACY":accuracy}); + + var labels = ['Class A', 'Class B']; + Matrix({ + container : '#container', + data : confusionMatrix, + labels : labels, + start_color : '#ffffff', + end_color : '#e67e22' + }); + + // rendering the table + // var table = tabulate(computedData, ["F1", "PRECISION","RECALL","ACCURACY"]); + + + + } + + render() { + return ( +
+ ); + } +} + +TestLineChart.defaultProps = { + chartColor: '#60B044' +}; + +export default TestLineChart; + + + + + + + diff --git a/lab/webapp/src/components/ConfusionMatrixJSONRender/index.jsx b/lab/webapp/src/components/ConfusionMatrixJSONRender/index.jsx new file mode 100644 index 000000000..20591da8e --- /dev/null +++ b/lab/webapp/src/components/ConfusionMatrixJSONRender/index.jsx @@ -0,0 +1,640 @@ +/* ~This file is part of the Aliro library~ + +Copyright (C) 2017 Epistasis Lab, University of Pennsylvania + +Aliro is maintained by: + - Hyunjun Choi (hyunjun.choi@cshs.org) + - + - Heather Williams (hwilli@upenn.edu) + - Weixuan Fu (weixuanf@upenn.edu) + - William La Cava (lacava@upenn.edu) + - Michael Stauffer (stauffer@upenn.edu) + - and many other generous open source contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +(Autogenerated header, do not modify) + +*/ +import React, { Component } from 'react'; + +// import c3 from 'c3'; + +import d3 from 'd3'; + + + +// working version +// class ConfusionMatrixJSONRender extends Component { + + +// // train_sizes={train_sizes} +// // train_scores={train_scores} +// // test_scores={test_scores} +// // chartKey={chartKey} +// // chartColor={chartColor} +// // min={0.5} +// // max={1.0} + +// componentDidMount() { +// const { train_sizes, train_scores, test_scores, chartKey, chartColor, min, max } = this.props; +// train_sizes && train_scores && test_scores && this.renderChart(train_sizes, train_scores, test_scores, chartKey, chartColor, min, max); +// } +// /* +// colors: { +// 'test_score': '#0072b2', ---- light blue +// 'train_score': '#f0e442' ---- light yellow +// '#55D6BE' ----- light sea green +// } + +// use anonymous function to 'disable' interaction +// look here - https://github.com/c3js/c3/issues/493#issuecomment-456686654 +// */ + +// // renderChart(expList, chartKey, chartColor, min, max) { +// renderChart(train_sizes, train_scores, test_scores, chartKey, chartColor, min, max) { + +// window.console.log('here in renderChart for ConfusionMatrixJSONRender'); +// // window.console.log('train_sizes: ', train_sizes); +// // window.console.log('train_scores.length: ', train_scores.length); +// // window.console.log('train_scores: ', train_scores); +// // window.console.log('test_scores: ', test_scores); + +// // // +// // min = 0; +// // // max is last element in train_sizes +// max = train_sizes[train_sizes.length - 1]; +// max = max + 0.1 * max; + +// window.console.log('max: ', max); +// var total_train_scores=[]; +// var total_test_scores=[]; +// for (var i = 0; i < train_scores.length; i++) { + +// // calculate averge of train_sizes[i] +// // divide by train_scores[i].length + +// var sum_train_scores = 0; +// var sum_test_scores = 0; +// for (var j = 0; j < train_scores[i].length; j++) { +// sum_train_scores += train_scores[i][j]; +// sum_test_scores += test_scores[i][j]; +// } +// var avg_sum_train_scores = sum_train_scores / train_scores[i].length; +// var avg_sum_test_scores = sum_test_scores / test_scores[i].length; + +// total_train_scores.push(avg_sum_train_scores); +// total_test_scores.push(avg_sum_test_scores); + + +// } + + +// var json = []; +// for (var i = 0; i < train_sizes.length; i++) { +// json.push({x: train_sizes[i], Training_score: total_train_scores[i], Cross_validation_score: total_test_scores[i]}); +// } + +// // window.console.log('json: ', json); + +// // window.console.log('chartKey: ', chartKey); + +// var chart = c3.generate({ +// bindto: `.${chartKey}`, + +// data: { +// json: json, + +// keys: { +// x: 'x', +// value: ['Training_score', 'Cross_validation_score'], +// } + +// }, +// axis: { +// y: { +// min: 0, +// max: 1, +// label: 'Score' + +// }, +// x: { +// min: 0, +// max: max, +// label: 'Training examples', +// tick: { +// multiline:false, +// culling: false // <-- THIS! +// } + +// } +// }, +// grid: { +// y: { +// show: true, +// color : '#fff!important' +// }, +// x: { +// show: true, +// color : '#fff!important' +// } +// }, + +// tooltip: { +// format: { +// title: function (d) { return 'Training examples: ' + d; } +// } +// } + + + + + +// }); + +// // if document element has testuser text, then make it unvisiable + + + + + + +// } + +// render() { +// return ( +//
+// ); +// } +// } + +// ConfusionMatrixJSONRender.defaultProps = { +// chartColor: '#60B044' +// }; + +// export default ConfusionMatrixJSONRender; + + + + + + + + + + + +// test version +class ConfusionMatrixJSONRender extends Component { + componentDidMount() { + console.log("hello"); + + const { cnf_data,chartKey, chartColor, min, max } = this.props; + this.renderChart(cnf_data, chartKey, chartColor, min, max); + } + + +/* +colors: { + 'test_score': '#0072b2', ---- light blue + 'train_score': '#f0e442' ---- light yellow + '#55D6BE' ----- light sea green +} + +use anonymous function to 'disable' interaction +look here - https://github.com/c3js/c3/issues/493#issuecomment-456686654 +*/ + + renderChart(cnf_data, chartKey, chartColor, min, max) { + // console.log('here in renderChart for ConfusionMatrixJSONRender'); + + + + + + + function Matrix_ver3(options) { + + // var margin = {top: 100, right: 100, bottom: 100, left: 100}, + // var margin = {top: 50, right: 50, bottom: 50, left: 50}, + var margin = {top: 200, right: 200, bottom: 200, left: 200}, + width = 250, + height = 250, + svg = options.svg, + data = options.data, + // container = options.container, + labelsData = options.labels, + numrows, + numcols; + + if(!data){ + throw new Error('No data passed.'); + } + + if(!Array.isArray(data) || !data.length || !Array.isArray(data[0])){ + throw new Error('Data type should be two-dimensional Array.'); + } + + numrows = data.length; + numcols = data[0].length; + + // sum all the values in the matrix + var sum = 0; + for (var i = 0; i < numrows; i++) { + for (var j = 0; j < numcols; j++) { + sum += data[i][j]; + } + } + + var max = 0; + // find max value in the matrix + for (var i = 0; i < numrows; i++) { + for (var j = 0; j < numcols; j++) { + if (data[i][j] > max) { + max = data[i][j]; + } + } + } + + var min = 0; + // find min value in the matrix + for (var i = 0; i < numrows; i++) { + for (var j = 0; j < numcols; j++) { + if (data[i][j] < min) { + min = data[i][j]; + } + } + } + + // console.log("sum",sum); + + + // var svg = d3.select(container).append("svg") + svg + .attr("width", width + margin.left + margin.right) + .attr("height", height + margin.top + margin.bottom) + .append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + // .attr("transform", "translate(" + 500 + "," + 500 + ")"); + + var background = svg.append("rect") + .style("stroke", "black") + .style("stroke-width", "2px") + .attr("width", width) + .attr("height", height); + + + var x = d3.scale.ordinal() + .domain(d3.range(numcols)) + .rangeBands([0, width]); + + var y = d3.scale.ordinal() + .domain(d3.range(numrows)) + .rangeBands([0, height]); + + var colorMap = d3.scale.linear() + // .domain([0, sum]) + // .domain([0, max]) + .domain([min, max]) + // make + // .range(["red", "blue"]); + // .range(["white", "red", "green"]); + // .range(["white", "blue"]); + // use dark red and dark blue + .range(["#afacbd", "#092180"]); + // .range(["white", "#55D6BE"]); + // .range() + + + var row = svg.selectAll(".row") + .data(data) + .enter().append("g") + .attr("class", "row") + .attr("transform", function(d, i) { return "translate(0," + y(i) + ")"; }); + + var cell = row.selectAll(".cell") + .data(function(d) { return d; }) + .enter().append("g") + .attr("class", "cell") + .attr("transform", function(d, i) { return "translate(" + x(i) + ", 0)"; }); + + cell.append('rect') + .attr("width", x.rangeBand()) + .attr("height", y.rangeBand()) + .style("stroke-width", 0.5) + .style("stroke", "white") + // when user mouseover, change the stroke-width to 1 + .on("mouseover", function(d) { + + + // apply opacity to the background color + d3.select(this).style("opacity", 0.5); + + + + + }) + // when user mouseout, change the stroke-width to 0.5 + .on("mouseout", function(d) { + + + // apply opacity to the background color + d3.select(this).style("opacity", 1); + + }) + + + + + cell.append("text") + .attr("dy", ".32em") + .attr("x", x.rangeBand() / 2) + .attr("y", y.rangeBand() / 2) + .attr("text-anchor", "middle") + .style("fill", function(d, i) { return d >= 0.5 ? 'white' : 'black'; }) + .text(function(d, i) { return d; }); + + row.selectAll(".cell") + .data(function(d, i) { return (data[i]) ; }) + .style("fill", colorMap); + + var labels = svg.append('g') + .attr('class', "labels"); + + var columnLabels = labels.selectAll(".column-label") + .data(labelsData) + .enter().append("g") + .attr("class", "column-label") + .attr("transform", function(d, i) { return "translate(" + x(i) + "," + height + ")"; }); + + columnLabels.append("line") + .style("stroke", "black") + .style("stroke-width", "1px") + .attr("x1", x.rangeBand() / 2) + .attr("x2", x.rangeBand() / 2) + .attr("y1", 0) + .attr("y2", 5); + + columnLabels.append("text") + .attr("x", 6) + .attr("y", y.rangeBand() / 2) + .attr("dy", ".32em") + .attr("text-anchor", "end") + .attr("transform", "rotate(-60)") + .text(function(d, i) { return d; }); + + + svg.append("text") + .attr("x", 170) + // .attr("y", y.rangeBand() / 1.5) + .attr("y", 330) + // .attr("dy", ".32em") + .attr("text-anchor", "end") + // .attr("transform", "rotate(-60)") + .text("Predicted label") + // mouseover, change the text size to 20 + .on("mouseover", function(d) { + d3.select(this).style("font-size", 20); + }) + // mouseout, change the text size to 10 + .on("mouseout", function(d) { + d3.select(this).style("font-size", 10); + }) + ; + + + var rowLabels = labels.selectAll(".row-label") + .data(labelsData) + .enter().append("g") + .attr("class", "row-label") + .attr("transform", function(d, i) { return "translate(" + 0 + "," + y(i) + ")"; }); + + rowLabels.append("line") + .style("stroke", "black") + .style("stroke-width", "1px") + .attr("x1", 0) + .attr("x2", -5) + .attr("y1", y.rangeBand() / 2) + .attr("y2", y.rangeBand() / 2); + + rowLabels.append("text") + .attr("x", -8) + .attr("y", y.rangeBand() / 2) + .attr("dy", ".32em") + .attr("text-anchor", "end") + .text(function(d, i) { return d; }); + + + svg.append("text") + .attr("x", -85) + // .attr("y", y.rangeBand() / 1.5) + .attr("y", -60) + // .attr("dy", ".32em") + .attr("text-anchor", "end") + .attr("transform", "rotate(-90)") + .text("True label") + .attr("id", "true_label") + // mouseover, change the text size to 20 + .on("mouseover", function(d) { + d3.select(this).style("font-size", 20); + }) + // mouseout, change the text size to 10 + .on("mouseout", function(d) { + d3.select(this).style("font-size", 10); + }) + ; + + + + + + } + + var matrix = cnf_data; + + // console.log("cnf_data in line",cnf_data); + + + + // print curreht class name + // window.console.log('TestLine current class name: ', `.${chartKey}`); + + + + var div = d3.select(`.${chartKey}`) + // add svg to div + + var svg = div.append("svg") + // make viewbox to make svg responsive + .attr("viewBox", "0 0 600 400") + .attr("preserveAspectRatio", "xMinYMin meet") + .append("g") + // transform to center svg + .attr("transform", "translate(180,50)"); + + // var matrix = [[10,20],[30,40]]; + + + // var matrix = [[10,20],[30,40]]; + + + + var tempcount=0; + + + + // var rect = svg.selectAll("rect") + // .data(matrix) + // .enter() + // .append("rect") + // .attr("width", 100) + // .attr("height", 100) + // // make width and height related to current div size + // // .attr("width", function(d, i) { + // // return d3.select(`.${chartKey}`).node().getBoundingClientRect().width/10; + // // }) + // // .attr("height", function(d, i) { + // // return d3.select(`.${chartKey}`).node().getBoundingClientRect().height/10; + // // }) + // .attr("x", function(d, i) { + // console.log('d: ', d); + + // console.log('d[0][0]: ', d[0]); + // console.log('d[0][1]: ', d[1]); + // // loop based on size of d + // for (var i = 0; i < d.length; i++) { + // // console.log('d[i]: ', d[i]); + // // make 1 row 2 column + // tempcount+=1; + // console.log('tempcount', tempcount); + // } + + // return i * 100; + + // } ) + // .attr("y", function(d, i) { + + // return i * 100; + // } + // ) + // .attr('id', function(d, i) { + // return 'rect_' + d; + // } + // ) + // .attr('fill', function(d, i) { + + // console.log('fill_d: ', d); + // // choose color based on value d + + // if (d > 150) { + // return 'green'; + // } + // return 'red'; + // } + // ) + // // make it show more than background color + // .attr('opacity', 0.5) + // // add mouseover event + // // .on("mouseover", function(d, i) { + // // // change color + // // d3.select(this).attr('fill', 'blue'); + // // console.log('number',d) + // // // show this d as string on the rect + // // d3.select(this).text(d); + // // // make the text color white + // // d3.select(this).attr('fill', 'white'); + + // // d3.select(this).text('This is some information about whatever') + // // .attr('x', 50) + // // .attr('y', 150) + // // .attr('fill', 'white') + + // // }) + // .append('text').text('test'); + + + // need to generalize this to work for any size matrix + + // var tp = matrix[0][0]; + // var fn = matrix[0][1]; + // var fp = matrix[1][0]; + // var tn = matrix[1][1]; + + // var p = tp + fn; + // var n = fp + tn; + + // var accuracy = (tp+tn)/(p+n); + // var f1 = 2*tp/(2*tp+fp+fn); + // var precision = tp/(tp+fp); + // var recall = tp/(tp+fn); + + // accuracy = Math.round(accuracy * 100) / 100 + // f1 = Math.round(f1 * 100) / 100 + // precision = Math.round(precision * 100) / 100 + // recall = Math.round(recall * 100) / 100 + + // var computedData = []; + // computedData.push({"F1":f1, "PRECISION":precision,"RECALL":recall,"ACCURACY":accuracy}); + + + // get length of matrix + var matrixLength = matrix.length; + console.log('matrixLength: ', matrixLength); + + // make the classes based on the length of matrix + var classes = []; + for (var i = 0; i < matrixLength; i++) { + classes.push("Class_"+i); + } + console.log('classes: ', classes); + // var labels = ['Class A', 'Class B']; + var labels = classes; + + Matrix_ver3({ + svg : svg, + + chartKey : chartKey, + data : matrix, + labels : labels, + start_color : '#ffffff', + end_color : '#e67e22' + }); + // testMatrix(); + + // rendering the table + // var table = tabulate(computedData, ["F1", "PRECISION","RECALL","ACCURACY"]); + + + + } + + render() { + return ( +
+ ); + } +} + +ConfusionMatrixJSONRender.defaultProps = { + chartColor: '#60B044' +}; + +export default ConfusionMatrixJSONRender; + + + + + + + diff --git a/lab/webapp/src/components/Results/components/ConfusionMatrixJSON/index.jsx b/lab/webapp/src/components/Results/components/ConfusionMatrixJSON/index.jsx index 8a997b2f2..4b7933233 100644 --- a/lab/webapp/src/components/Results/components/ConfusionMatrixJSON/index.jsx +++ b/lab/webapp/src/components/Results/components/ConfusionMatrixJSON/index.jsx @@ -30,8 +30,9 @@ import PropTypes from 'prop-types'; import InvertedCard from '../../../InvertedCard'; import Gauge from '../../../Gauge'; import GaugeAll from '../../../GaugeAll'; -import DonutChart from '../../../DonutChart'; -import BarChart from '../../../BarChart'; +// import DonutChart from '../../../DonutChart'; +// import LineChart from '../../../LineChart'; +import ConfusionMatrixJSONRender from '../../../ConfusionMatrixJSONRender'; import BarPlot from '../../../BarPlot'; import { Header, Icon, Popup} from 'semantic-ui-react'; /** @@ -56,84 +57,47 @@ function foldcheck(fold) { return [iconname, iconcolor, iconmsg]; } -function NoScore({ scoreName, scoreValueList, featureList, chartKey, chartColor, type }) { - - console.log('scoreName',scoreName); - console.log('scoreValueList',scoreValueList); - console.log('type',type); - - +function NoScore({ scoreName, cnf_data,chartKey, chartColor, type }) { const getCardContent = () => { - if(typeof(scoreValue) !== 'number' && !scoreValueList.length) { - if (scoreName.includes('AUC') ) { - return ( -
- ); - } else { - return ( -
- ); - } - } else if (scoreValueList && type == "classification") { - - console.log("scoreValueList && type == classification") + // if(typeof(scoreValue) !== 'number' && !scoreValueList.length) + // { + // if (scoreName.includes('AUC') ) { + // return ( + //
+ // ); + // } else { + // return ( + //
+ // ); + // } + // } + + if (type == "classification") { + + console.log("i am here in no score ConfusionMatrixJSONRender"); return ( - // - - // - - + + ); - } else if (scoreValueList && type == "r2_or_vaf") { - return ( - - ); - } else if (scoreValueList && type == "pearsonr") { - return ( - - ); - } + } + }; - if(typeof(scoreValue) !== 'number' && !scoreValueList.length){ + if(typeof(scoreValue) !== 'number' ){ return ( ); } else { - let fold = scoreValueList[0][1]/scoreValueList[1][1]; + let fold = train_scores[0][1]/train_scores[1][1]; var icons = foldcheck(fold); let headericon = ( + - {/* */} + @@ -384,7 +384,14 @@ class Results extends Component { /> {/* */} - {/* */} + {/* This TestChart is for interactive and responsive confusion matrix */} +