mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-18 09:24:42 -04:00
in csv export the selected number format is preserved, see #349
This commit is contained in:
parent
957aea4a24
commit
8718bb9a65
@ -182,6 +182,13 @@ public final class Signal implements Comparable<Signal> {
|
||||
return bidirectionalReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the format to be used to visualize the signal values
|
||||
*/
|
||||
public IntFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter interface to set a value
|
||||
*/
|
||||
|
@ -5,10 +5,12 @@
|
||||
*/
|
||||
package de.neemann.digital.data;
|
||||
|
||||
import de.neemann.digital.core.IntFormat;
|
||||
import de.neemann.digital.core.Observable;
|
||||
import de.neemann.digital.testing.parser.TestRow;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
@ -198,7 +200,18 @@ public class ValueTable extends Observable implements Iterable<TestRow> {
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public void saveCSV(File file) throws IOException {
|
||||
saveCSV(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")));
|
||||
saveCSV(file, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the data in csv file
|
||||
*
|
||||
* @param file the file
|
||||
* @param columnInfo information of how to format the values, maybe null
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public void saveCSV(File file, ColumnInfo[] columnInfo) throws IOException {
|
||||
saveCSV(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)), columnInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -208,6 +221,10 @@ public class ValueTable extends Observable implements Iterable<TestRow> {
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
public void saveCSV(BufferedWriter w) throws IOException {
|
||||
saveCSV(w, null);
|
||||
}
|
||||
|
||||
void saveCSV(BufferedWriter w, ColumnInfo[] columnInfo) throws IOException {
|
||||
try {
|
||||
w.write("\"step\"");
|
||||
for (String s : names)
|
||||
@ -216,7 +233,14 @@ public class ValueTable extends Observable implements Iterable<TestRow> {
|
||||
int row = 0;
|
||||
for (TestRow s : this) {
|
||||
w.write("\"" + (row++) + "\"");
|
||||
for (Value value : s.getValues()) w.write(",\"" + value + "\"");
|
||||
if (columnInfo == null) {
|
||||
for (Value value : s.getValues())
|
||||
w.write(",\"" + value + "\"");
|
||||
} else {
|
||||
int i = 0;
|
||||
for (Value value : s.getValues())
|
||||
w.write(",\"" + columnInfo[i++].format(value) + "\"");
|
||||
}
|
||||
w.write("\n");
|
||||
}
|
||||
} finally {
|
||||
@ -266,4 +290,36 @@ public class ValueTable extends Observable implements Iterable<TestRow> {
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns formatting information
|
||||
*/
|
||||
public static final class ColumnInfo {
|
||||
private int bits;
|
||||
private IntFormat format;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param format the format to use
|
||||
* @param bits the number of bits to output
|
||||
*/
|
||||
public ColumnInfo(IntFormat format, int bits) {
|
||||
this.format = format;
|
||||
this.bits = bits;
|
||||
}
|
||||
|
||||
private String format(Value value) {
|
||||
switch (value.getType()) {
|
||||
case HIGHZ:
|
||||
return "Z";
|
||||
case DONTCARE:
|
||||
return "X";
|
||||
case CLOCK:
|
||||
return "C";
|
||||
default:
|
||||
return format.formatToEdit(new de.neemann.digital.core.Value(value.getValue(), bits));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ public class GraphDialog extends JDialog implements Observer {
|
||||
private static final Icon ICON_ZOOM_IN = IconCreator.create("View-zoom-in.png");
|
||||
private static final Icon ICON_ZOOM_OUT = IconCreator.create("View-zoom-out.png");
|
||||
|
||||
private ValueTable.ColumnInfo[] columnInfo;
|
||||
|
||||
/**
|
||||
* Creates a instance prepared for "live logging"
|
||||
*
|
||||
@ -66,9 +68,11 @@ public class GraphDialog extends JDialog implements Observer {
|
||||
}
|
||||
}.order(signals);
|
||||
|
||||
|
||||
ValueTableObserver valueTableObserver = new ValueTableObserver(microStep, signals, MAX_SAMPLE_SIZE);
|
||||
|
||||
GraphDialog graphDialog = new GraphDialog(owner, title, valueTableObserver.getLogData(), model);
|
||||
GraphDialog graphDialog = new GraphDialog(owner, title, valueTableObserver.getLogData(), model)
|
||||
.setColumnInfo(createColumnsInfo(signals));
|
||||
|
||||
graphDialog.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
@ -85,6 +89,15 @@ public class GraphDialog extends JDialog implements Observer {
|
||||
return graphDialog;
|
||||
}
|
||||
|
||||
private static ValueTable.ColumnInfo[] createColumnsInfo(ArrayList<Signal> signals) {
|
||||
ValueTable.ColumnInfo[] info = new ValueTable.ColumnInfo[signals.size()];
|
||||
for (int i = 0; i < signals.size(); i++) {
|
||||
Signal s = signals.get(i);
|
||||
info[i] = new ValueTable.ColumnInfo(s.getFormat(), s.getValue().getBits());
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
@ -163,7 +176,7 @@ public class GraphDialog extends JDialog implements Observer {
|
||||
JFileChooser fileChooser = new MyFileChooser();
|
||||
fileChooser.setFileFilter(new FileNameExtensionFilter("Comma Separated Values", "csv"));
|
||||
new SaveAsHelper(GraphDialog.this, fileChooser, "csv")
|
||||
.checkOverwrite(logData::saveCSV);
|
||||
.checkOverwrite(file -> logData.saveCSV(file, columnInfo));
|
||||
}
|
||||
}.setToolTip(Lang.get("menu_saveData_tt")).createJMenuItem());
|
||||
file.add(new ExportAction(Lang.get("menu_exportSVG"), GraphicSVG::new).createJMenuItem());
|
||||
@ -181,6 +194,11 @@ public class GraphDialog extends JDialog implements Observer {
|
||||
setLocationRelativeTo(owner);
|
||||
}
|
||||
|
||||
private GraphDialog setColumnInfo(ValueTable.ColumnInfo[] columnInfo) {
|
||||
this.columnInfo = columnInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
private final AtomicBoolean paintPending = new AtomicBoolean();
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
package de.neemann.digital.data;
|
||||
|
||||
import de.neemann.digital.core.IntFormat;
|
||||
import de.neemann.digital.testing.parser.TestRow;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@ -40,6 +41,19 @@ public class ValueTableTest extends TestCase {
|
||||
"\"1\",\"0\",\"1\",\"Z\"\n", sw.toString());
|
||||
}
|
||||
|
||||
public void testCSV2() throws Exception {
|
||||
StringWriter sw = new StringWriter();
|
||||
ValueTable.ColumnInfo[] infos = new ValueTable.ColumnInfo[]{
|
||||
new ValueTable.ColumnInfo(IntFormat.hex, 4),
|
||||
new ValueTable.ColumnInfo(IntFormat.oct, 4),
|
||||
new ValueTable.ColumnInfo(IntFormat.bin, 4),
|
||||
};
|
||||
t.saveCSV(new BufferedWriter(sw), infos);
|
||||
assertEquals("\"step\",\"A\",\"B\",\"C\"\n" +
|
||||
"\"0\",\"0x0\",\"000\",\"0b0000\"\n" +
|
||||
"\"1\",\"0x0\",\"001\",\"Z\"\n", sw.toString());
|
||||
}
|
||||
|
||||
public void testMax() {
|
||||
ValueTable t = new ValueTable("A", "B", "C")
|
||||
.add(new TestRow(new Value(0), new Value(4), new Value(1)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user