/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.statistics;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import au.com.bytecode.opencsv.CSVWriter;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
/**
*
* @author kevinvandevelde at atmire.com
* Date: 21-jan-2009
* Time: 13:44:48
*
*/
public class Dataset {
private int nbRows;
private int nbCols;
/* The labels shown in our columns */
private List<String> colLabels;
/* The labels shown in our rows */
private List<String> rowLabels;
private String colTitle;
private String rowTitle;
/* The attributes for the colls */
private List<Map<String, String>> colLabelsAttrs;
/* The attributes for the rows */
private List<Map<String, String>> rowLabelsAttrs;
/* The data in a matrix */
private String[][]matrix;
/* The format in which we format our floats */
private String format = "0";
public Dataset(int rows, int cols){
matrix = new String[rows][cols];
nbRows = rows;
nbCols = cols;
initColumnLabels(cols);
initRowLabels(rows);
}
public Dataset(float[][] matrix){
this.matrix = (String[][]) ArrayUtils.clone(matrix);
nbRows = matrix.length;
if(0 < matrix.length && 0 < matrix[0].length)
{
nbCols = matrix[0].length;
}
initColumnLabels(nbCols);
initRowLabels(nbRows);
}
private void initRowLabels(int rows) {
rowLabels = new ArrayList<String>(rows);
rowLabelsAttrs = new ArrayList<Map<String, String>>();
for (int i = 0; i < rows; i++) {
rowLabels.add("Row " + (i+1));
rowLabelsAttrs.add(new HashMap<String, String>());
}
}
private void initColumnLabels(int nbCols) {
colLabels = new ArrayList<String>(nbCols);
colLabelsAttrs = new ArrayList<Map<String, String>>();
for (int i = 0; i < nbCols; i++) {
colLabels.add("Column " + (i+1));
colLabelsAttrs.add(new HashMap<String, String>());
}
}
public void setColLabel(int n, String label){
colLabels.set(n, label);
}
public void setRowLabel(int n, String label){
rowLabels.set(n, label);
}
public String getRowTitle() {
return rowTitle;
}
public String getColTitle() {
return colTitle;
}
public void setColTitle(String colTitle) {
this.colTitle = colTitle;
}
public void setRowTitle(String rowTitle) {
this.rowTitle = rowTitle;
}
public void setRowLabelAttr(int pos, String attrName, String attr){
Map<String, String> attrs = rowLabelsAttrs.get(pos);
attrs.put(attrName, attr);
rowLabelsAttrs.set(pos, attrs);
}
public void setRowLabelAttr(int pos, Map<String, String> attrMap){
rowLabelsAttrs.set(pos, attrMap);
}
public void setColLabelAttr(int pos, String attrName, String attr){
Map<String, String> attrs = colLabelsAttrs.get(pos);
attrs.put(attrName, attr);
colLabelsAttrs.set(pos, attrs);
}
public void setColLabelAttr(int pos, Map<String, String> attrMap) {
colLabelsAttrs.set(pos, attrMap);
}
public List<Map<String, String>> getColLabelsAttrs() {
return colLabelsAttrs;
}
public List<Map<String, String>> getRowLabelsAttrs() {
return rowLabelsAttrs;
}
public List<String> getColLabels() {
return colLabels;
}
public List<String> getRowLabels() {
return rowLabels;
}
public int getNbRows() {
return nbRows;
}
public int getNbCols() {
return nbCols;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public String[][] getMatrix(){
if (matrix.length == 0) {
return new String[0][0];
} else {
return matrix;
}
}
public void addValueToMatrix(int row, int coll, float value) {
DecimalFormat decimalFormat = new DecimalFormat(format);
matrix[row][coll] = decimalFormat.format(value);
}
public void addValueToMatrix(int row, int coll, String value) throws ParseException {
matrix[row][coll] = value;
}
/**
* Returns false if this dataset only contains zero's.
*/
public boolean containsNonZeroValues(){
if (matrix != null) {
for (String[] vector : matrix) {
for (String v : vector) {
if (StringUtils.isBlank(v) || v.equals("0"))
{
return true;
}
}
}
}
return false;
}
public void flipRowCols(){
//Lets make sure we at least have something to flip
if(0 < matrix.length && 0 < matrix[0].length){
//Flip the data first
String[][] newMatrix = new String[matrix[0].length][matrix.length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
newMatrix[j][i] = matrix[i][j];
}
}
//Flip the rows & column labels
List<String> backup = colLabels;
colLabels = rowLabels;
rowLabels = backup;
//Also flip the links
List<Map<String, String>> backList = colLabelsAttrs;
colLabelsAttrs = rowLabelsAttrs;
rowLabelsAttrs = backList;
matrix = newMatrix;
}
//Also flip these sizes
int backUp = nbRows;
nbRows = nbCols;
nbCols = backUp;
//Also flip the title's
String backup = rowTitle;
rowTitle = colTitle;
colTitle = backup;
}
public ByteArrayOutputStream exportAsCSV() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CSVWriter ecsvp = new CSVWriter(new OutputStreamWriter(baos), ';');
//Generate the item row
List<String> colLabels = getColLabels();
colLabels.add(0, "");
ecsvp.writeNext(colLabels.toArray(new String[colLabels.size()]));
List<String> rowLabels = getRowLabels();
String[][] matrix = getMatrix();
for (int i = 0; i < rowLabels.size(); i++) {
String rowLabel = rowLabels.get(i);
ecsvp.writeNext((String[]) ArrayUtils.addAll(new String[]{rowLabel}, matrix[i]));
}
ecsvp.flush();
ecsvp.close();
return baos;
}
}