Minsky
minsky::CSVDialog Class Reference

#include <CSVDialog.h>

Inheritance diagram for minsky::CSVDialog:
Inheritance graph
Collaboration diagram for minsky::CSVDialog:
Collaboration graph

Public Member Functions

double tableWidth () const
 width of table (in pixels) More...
 
void loadFile ()
 loads an initial sequence of lines from url. If fname contains "://", is is treated as a URL, and downloaded from the web. More...
 
void guessSpecAndLoadFile ()
 guess the spec, then load an initial sequence of like loadFile() More...
 
void loadFileFromName (const std::string &fname)
 common implementation of loading the initial sequence of lines More...
 
void reportFromFile (const std::string &input, const std::string &output) const
 
void requestRedraw ()
 
std::size_t columnOver (double x) const
 return column mouse is over More...
 
std::size_t rowOver (double y) const
 return row mouse is over More...
 
std::vector< std::vector< std::string > > parseLines (size_t maxColumn=std::numeric_limits< size_t >::max())
 
void populateHeaders ()
 populate all column names from the headers row More...
 
void populateHeader (size_t col)
 populate the name of column col with the data from the header row More...
 
void classifyColumns ()
 try to classify axis,data,ignore columns based on read in data More...
 
std::vector< size_t > correctedUniqueValues ()
 unique values in each column, ignoring initial header lines could slightly underestimate the value, and is never less than 1, even for empty columns More...
 
- Public Member Functions inherited from minsky::RenderNativeWindow
const RenderFrameArgsframeArgs () const
 
 ~RenderNativeWindow () override
 
virtual void init ()
 perform any initialisation of any subclasses of this More...
 
void renderFrame (const RenderFrameArgs &args)
 
void destroyFrame ()
 
void draw ()
 
void requestRedraw ()
 
void macOSXRedraw ()
 
RenderNativeWindowoperator= (const RenderNativeWindow &x)
 
 RenderNativeWindow ()=default
 
 RenderNativeWindow (const RenderNativeWindow &)=default
 
virtual bool hasScrollBars () const
 return whether this window has scrollbars (needed for MacOSX). More...
 
- Public Member Functions inherited from minsky::EventInterface
virtual void mouseDown (float x, float y)
 
virtual void controlMouseDown (float x, float y)
 
virtual void mouseUp (float x, float y)
 
virtual void mouseMove (float x, float y)
 
virtual void zoom (double x, double y, double z)
 
virtual void moveTo (float x, float y)
 move this so that (x,y) is centred More...
 
virtual std::vector< float > position () const
 current centre coordinates More...
 
virtual double zoomFactor () const
 
virtual bool keyPress (const KeyPressArgs &)
 handle key press over current itemFocus, More...
 
virtual bool getItemAt (float x, float y)
 item or wire obtained by get*At() calls More...
 
virtual bool getWireAt (float x, float y)
 item or wire obtained by get*At() calls More...
 

Public Attributes

double xoffs =80
 
double colWidth =50
 
bool flashNameRow =false
 
DataSpec spec
 
std::string url
 filename, or web url More...
 
- Public Attributes inherited from minsky::EventInterface
ItemPtr item
 item or wire obtained by get*At() calls More...
 
WirePtr wire
 item or wire obtained by get*At() calls More...
 

Static Public Attributes

static const unsigned numInitialLines =100
 
- Static Public Attributes inherited from minsky::RenderNativeWindow
static ecolab::cairo::Colour backgroundColour {0.8,0.8,0.8,1}
 

Private Member Functions

 CLASSDESC_ACCESS (DataSpec)
 
bool redraw (int, int, int width, int height) override
 

Private Attributes

std::vector< std::string > initialLines
 initial lines of file More...
 
double rowHeight =0
 
double m_tableWidth
 

Additional Inherited Members

- Static Public Member Functions inherited from minsky::RenderNativeWindow
static double scaleFactor ()
 

Detailed Description

Definition at line 35 of file CSVDialog.h.

Member Function Documentation

◆ CLASSDESC_ACCESS()

minsky::CSVDialog::CLASSDESC_ACCESS ( DataSpec  )
private

◆ classifyColumns()

void CSVDialog::classifyColumns ( )

try to classify axis,data,ignore columns based on read in data

Definition at line 344 of file CSVDialog.cc.

References minsky::isNumerical(), and parseLines().

345 {
346  auto parsedLines=parseLines();
347  spec.dimensionCols.clear();
348  spec.dataCols.clear();
349  spec.dimensions.resize(min(spec.numCols,spec.maxColumn));
350  for (size_t col=0; col<spec.numCols; ++col)
351  {
352  bool entryFound=false, timeFound=true, numberFound=true;
353  for (size_t row=spec.nRowAxes(); row<parsedLines.size(); ++row)
354  if (col<parsedLines[row].size() && !parsedLines[row][col].empty())
355  {
356  entryFound=true;
357  if (numberFound && !isNumerical(parsedLines[row][col]))
358  numberFound=false;
359  static const AnyVal any(Dimension(Dimension::time,""));
360  if (timeFound)
361  try
362  {any(parsedLines[row][col]);}
363  catch (...)
364  {timeFound=false;}
365  }
366  if (entryFound && col<spec.maxColumn)
367  {
368  if (numberFound)
369  spec.dataCols.insert(col);
370  else
371  {
372  spec.dimensionCols.insert(col);
373  if (timeFound)
374  spec.dimensions[col].type=Dimension::time;
375  else
376  spec.dimensions[col].type=Dimension::string;
377  spec.dimensions[col].units.clear();
378  }
379  }
380  else if (col>=spec.nColAxes() && col<spec.maxColumn)
381  spec.dataCols.insert(col);
382  }
383 }
std::size_t nColAxes() const
start column of the data area
Definition: CSVParser.h:48
std::vector< std::vector< std::string > > parseLines(size_t maxColumn=std::numeric_limits< size_t >::max())
Definition: CSVDialog.cc:300
std::size_t numCols
number of columns in CSV. Must be > dataColOffset
std::vector< civita::Dimension > dimensions
bool isNumerical(const std::string &s)
Definition: CSVParser.cc:338
DataSpec spec
Definition: CSVDialog.h:48
std::size_t maxColumn
maximum number of columns that can be configured independently. Columns after this limit are treated ...
Definition: CSVParser.h:43
std::size_t nRowAxes() const
start row of the data area
Definition: CSVParser.h:46
std::set< unsigned > dataCols
std::set< unsigned > dimensionCols
rows and columns that are comment lines to be ignored
Here is the call graph for this function:

◆ columnOver()

size_t CSVDialog::columnOver ( double  x) const

return column mouse is over

Definition at line 290 of file CSVDialog.cc.

291 {
292  return size_t((x-xoffs)/(colWidth+5));
293 }

◆ correctedUniqueValues()

std::vector< size_t > CSVDialog::correctedUniqueValues ( )

unique values in each column, ignoring initial header lines could slightly underestimate the value, and is never less than 1, even for empty columns

Definition at line 385 of file CSVDialog.cc.

References parseLines().

386 {
387  auto r=spec.uniqueValues();
388  // apply a correction by removing the values in the header rows
389  vector<set<size_t>> correction(r.size());
390  auto parsedLines=parseLines();
391  const hash<string> h;
392  for (size_t row=0; row<parsedLines.size() && row<spec.nRowAxes(); ++row)
393  for (size_t col=0; col<correction.size() && col<parsedLines[row].size(); ++col)
394  correction[col].insert(h(parsedLines[row][col]));
395  for (size_t i=0; i<r.size(); ++i)
396  if (r[i]>correction[i].size())
397  r[i]-=correction[i].size();
398  else
399  r[i]=1;
400  return r;
401 }
std::vector< std::vector< std::string > > parseLines(size_t maxColumn=std::numeric_limits< size_t >::max())
Definition: CSVDialog.cc:300
const std::vector< size_t > & uniqueValues() const
number of unique values in each column corrected for header row, so may be slightly inaccurate if hea...
Definition: CSVParser.h:92
DataSpec spec
Definition: CSVDialog.h:48
std::size_t nRowAxes() const
start row of the data area
Definition: CSVParser.h:46
Here is the call graph for this function:

◆ guessSpecAndLoadFile()

void CSVDialog::guessSpecAndLoadFile ( )

guess the spec, then load an initial sequence of like loadFile()

Definition at line 102 of file CSVDialog.cc.

103 {
104  spec=DataSpec();
107  populateHeaders();
108  classifyColumns();
109 }
void guessFromFile(const std::string &fileName)
initial stab at dataspec from examining file
Definition: CSVParser.h:80
void classifyColumns()
try to classify axis,data,ignore columns based on read in data
Definition: CSVDialog.cc:344
void populateHeaders()
populate all column names from the headers row
Definition: CSVDialog.cc:327
std::string url
filename, or web url
Definition: CSVDialog.h:50
DataSpec spec
Definition: CSVDialog.h:48
void loadFileFromName(const std::string &fname)
common implementation of loading the initial sequence of lines
Definition: CSVDialog.cc:111

◆ loadFile()

void CSVDialog::loadFile ( )

loads an initial sequence of lines from url. If fname contains "://", is is treated as a URL, and downloaded from the web.

Definition at line 97 of file CSVDialog.cc.

98 {
100 }
std::string url
filename, or web url
Definition: CSVDialog.h:50
void loadFileFromName(const std::string &fname)
common implementation of loading the initial sequence of lines
Definition: CSVDialog.cc:111

◆ loadFileFromName()

void CSVDialog::loadFileFromName ( const std::string &  fname)

common implementation of loading the initial sequence of lines

Definition at line 111 of file CSVDialog.cc.

References minsky::stripByteOrderingMarker().

112 {
113  ifstream is(fname);
115  initialLines.clear();
116  for (size_t i=0; i<numInitialLines && is; ++i)
117  {
118  initialLines.emplace_back();
119  getline(is, initialLines.back());
120  // chomp any final '\r' character (DOS files)
121  if (!initialLines.back().empty() && initialLines.back().back()=='\r')
122  initialLines.back().erase(initialLines.back().end()-1);
123  }
124  // Ensure dimensions.size() is the same as nColAxes() upon first load of a CSV file. For ticket 974.
126 }
std::size_t nColAxes() const
start column of the data area
Definition: CSVParser.h:48
std::vector< civita::Dimension > dimensions
DataSpec spec
Definition: CSVDialog.h:48
std::size_t nRowAxes() const
start row of the data area
Definition: CSVParser.h:46
void stripByteOrderingMarker(std::istream &s)
checks if the input stream has the UTF-8 byte ordering marker, and removes it if present ...
Definition: str.h:147
std::vector< std::string > initialLines
initial lines of file
Definition: CSVDialog.h:37
static const unsigned numInitialLines
Definition: CSVDialog.h:44
void setDataArea(std::size_t row, std::size_t col)
set top left cell of the data area
Definition: CSVParser.cc:370
Here is the call graph for this function:

◆ parseLines()

std::vector< std::vector< std::string > > CSVDialog::parseLines ( size_t  maxColumn = std::numeric_limits<size_t>::max())

Definition at line 300 of file CSVDialog.cc.

References parseLines().

301 {
302  vector<vector<string>> parsedLines;
303  if (spec.mergeDelimiters)
304  if (spec.separator==' ')
305  parsedLines=::parseLines(boost::char_separator<char>(), initialLines, maxColumn);
306  else
307  {
308  char separators[]={spec.separator,'\0'};
309  parsedLines=::parseLines
310  (boost::char_separator<char>(separators,""),initialLines, maxColumn);
311  }
312  else
313  parsedLines=::parseLines
314  (boost::escaped_list_separator<char>(spec.escape,spec.separator,spec.quote),
315  initialLines, maxColumn);
316 
317  // update numCols iff maxColumn unrestricted
318  if (maxColumn==numeric_limits<size_t>::max())
319  {
320  spec.numCols=0;
321  for (auto& i: parsedLines)
322  spec.numCols=std::max(spec.numCols, i.size());
323  }
324  return parsedLines;
325 }
std::vector< std::vector< std::string > > parseLines(size_t maxColumn=std::numeric_limits< size_t >::max())
Definition: CSVDialog.cc:300
std::size_t numCols
number of columns in CSV. Must be > dataColOffset
DataSpec spec
Definition: CSVDialog.h:48
std::vector< std::string > initialLines
initial lines of file
Definition: CSVDialog.h:37
Here is the call graph for this function:

◆ populateHeader()

void CSVDialog::populateHeader ( size_t  col)

populate the name of column col with the data from the header row

Definition at line 335 of file CSVDialog.cc.

References parseLines().

336 {
337  auto parsedLines=parseLines();
338  if (spec.headerRow>=parsedLines.size()) return;
339  auto& headers=parsedLines[spec.headerRow];
340  if (col<headers.size() && col<spec.maxColumn)
341  spec.dimensionNames[col]=headers[col];
342 }
std::vector< std::vector< std::string > > parseLines(size_t maxColumn=std::numeric_limits< size_t >::max())
Definition: CSVDialog.cc:300
DataSpec spec
Definition: CSVDialog.h:48
std::size_t headerRow
number of header rows
std::vector< std::string > dimensionNames
std::size_t maxColumn
maximum number of columns that can be configured independently. Columns after this limit are treated ...
Definition: CSVParser.h:43
Here is the call graph for this function:

◆ populateHeaders()

void CSVDialog::populateHeaders ( )

populate all column names from the headers row

Definition at line 327 of file CSVDialog.cc.

References parseLines().

328 {
329  auto parsedLines=parseLines();
330  if (spec.headerRow>=parsedLines.size()) return;
331  auto& hr=parsedLines[spec.headerRow];
332  spec.dimensionNames={hr.begin(), min(hr.end(), hr.begin()+spec.maxColumn)};
333 }
std::vector< std::vector< std::string > > parseLines(size_t maxColumn=std::numeric_limits< size_t >::max())
Definition: CSVDialog.cc:300
DataSpec spec
Definition: CSVDialog.h:48
std::size_t headerRow
number of header rows
std::vector< std::string > dimensionNames
std::size_t maxColumn
maximum number of columns that can be configured independently. Columns after this limit are treated ...
Definition: CSVParser.h:43
Here is the call graph for this function:

◆ redraw()

bool CSVDialog::redraw ( int  ,
int  ,
int  width,
int  height 
)
overrideprivate

Definition at line 168 of file CSVDialog.cc.

References parseLines().

169 {
170  cairo_t* cairo=surface->cairo();
171  rowHeight=15;
172  vector<vector<string>> parsedLines=parseLines();
173 
174  // LHS row labels
175  {
176  Pango pango(cairo);
177  pango.setText("Dimension");
178  cairo_move_to(cairo,xoffs-pango.width()-5,0);
179  pango.show();
180  pango.setText("Type");
181  cairo_move_to(cairo,xoffs-pango.width()-5,rowHeight);
182  pango.show();
183  pango.setText("Format");
184  cairo_move_to(cairo,xoffs-pango.width()-5,2*rowHeight);
185  pango.show();
186  if (flashNameRow)
187  pango.setMarkup("<b>Name</b>");
188  else
189  pango.setText("Name");
190  cairo_move_to(cairo,xoffs-pango.width()-5,3*rowHeight);
191  pango.show();
192  pango.setText("Header");
193  cairo_move_to(cairo,xoffs-pango.width()-5,(4+spec.headerRow)*rowHeight);
194  pango.show();
195 
196  }
197 
198  CroppedPango pango(cairo, colWidth);
199  pango.setFontSize(0.8*rowHeight);
200 
201  set<size_t> done;
202  double x=xoffs, y=0;
203  size_t col=0;
204  for (; done.size()<parsedLines.size(); ++col)
205  {
206  if (col<spec.nColAxes())
207  {// dimension check boxes
208  const CairoSave cs(cairo);
209  const double cbsz=5;
210  cairo_set_line_width(cairo,1);
211  cairo_translate(cairo,x+0.5*colWidth,y+0.5*rowHeight);
212  cairo_rectangle(cairo,-cbsz,-cbsz,2*cbsz,2*cbsz);
213  if (spec.dimensionCols.contains(col))
214  {
215  cairo_move_to(cairo,-cbsz,-cbsz);
216  cairo_line_to(cairo,cbsz,cbsz);
217  cairo_move_to(cairo,cbsz,-cbsz);
218  cairo_line_to(cairo,-cbsz,cbsz);
219  }
220  cairo_stroke(cairo);
221  }
222  y+=rowHeight;
223  // type
224  if (spec.dimensionCols.contains(col) && col<spec.dimensions.size() && col<spec.nColAxes())
225  {
226  pango.setText(classdesc::enumKey<Dimension::Type>(spec.dimensions[col].type));
227  pango.setxy(x,y);
228  pango.show();
229  }
230  y+=rowHeight;
231  if (spec.dimensionCols.contains(col) && col<spec.dimensions.size() && col<spec.nColAxes())
232  {
233  pango.setText(spec.dimensions[col].units);
234  pango.setxy(x,y);
235  pango.show();
236  }
237  y+=rowHeight;
238  if (spec.dimensionCols.contains(col) && col<spec.dimensionNames.size() && col<spec.nColAxes())
239  {
240  pango.setText(spec.dimensionNames[col]);
241  pango.setxy(x,y);
242  pango.show();
243  }
244  y+=rowHeight;
245  for (size_t row=0; row<parsedLines.size(); ++row)
246  {
247  auto& line=parsedLines[row];
248  if (col<line.size())
249  {
250  const CairoSave cs(cairo);
251  pango.setText(line[col]);
252  pango.setxy(x, y);
253  if (row==spec.headerRow)
254  if (col<spec.nColAxes())
255  cairo_set_source_rgb(surface->cairo(),0,0.7,0);
256  else
257  cairo_set_source_rgb(surface->cairo(),0,0,1);
258  else if (row<spec.nRowAxes() || (col<spec.nColAxes() && !spec.dimensionCols.contains(col)))
259  cairo_set_source_rgb(surface->cairo(),1,0,0);
260  else if (col<spec.nColAxes())
261  cairo_set_source_rgb(surface->cairo(),0,0,1);
262  pango.show();
263  }
264  else
265  done.insert(row);
266  y+=rowHeight;
267  }
268  {
269  const CairoSave cs(cairo);
270  cairo_set_source_rgb(cairo,.5,.5,.5);
271  cairo_move_to(cairo,x-2.5,0);
272  cairo_rel_line_to(cairo,0,(parsedLines.size()+4)*rowHeight);
273  cairo_stroke(cairo);
274  }
275  x+=colWidth+5;
276  y=0;
277  }
278  m_tableWidth=(col-1)*(colWidth+5);
279  for (size_t row=0; row<parsedLines.size()+5; ++row)
280  {
281  const CairoSave cs(cairo);
282  cairo_set_source_rgb(cairo,.5,.5,.5);
283  cairo_move_to(cairo,xoffs-2.5,row*rowHeight);
284  cairo_rel_line_to(cairo,m_tableWidth,0);
285  cairo_stroke(cairo);
286  }
287  return true;
288 }
std::size_t nColAxes() const
start column of the data area
Definition: CSVParser.h:48
std::vector< std::vector< std::string > > parseLines(size_t maxColumn=std::numeric_limits< size_t >::max())
Definition: CSVDialog.cc:300
double rowHeight
Definition: CSVDialog.h:38
std::vector< civita::Dimension > dimensions
DataSpec spec
Definition: CSVDialog.h:48
std::size_t headerRow
number of header rows
std::vector< std::string > dimensionNames
std::size_t nRowAxes() const
start row of the data area
Definition: CSVParser.h:46
double m_tableWidth
Definition: CSVDialog.h:39
std::set< unsigned > dimensionCols
rows and columns that are comment lines to be ignored
Here is the call graph for this function:

◆ reportFromFile()

void CSVDialog::reportFromFile ( const std::string &  input,
const std::string &  output 
) const

Definition at line 50 of file CSVDialog.cc.

References minsky::reportFromCSVFile(), and minsky::stripByteOrderingMarker().

51 {
52  ifstream is(input);
54  ofstream of(output);
55  reportFromCSVFile(is,of,spec,file_size(input));
56 }
void reportFromCSVFile(istream &input, ostream &output, const DataSpec &spec, uintmax_t fileSize)
creates a report CSV file from input, with errors sorted at begining of file, with a column for error...
Definition: CSVParser.cc:1161
Definition: input.py:1
DataSpec spec
Definition: CSVDialog.h:48
void stripByteOrderingMarker(std::istream &s)
checks if the input stream has the UTF-8 byte ordering marker, and removes it if present ...
Definition: str.h:147
Here is the call graph for this function:

◆ requestRedraw()

void minsky::CSVDialog::requestRedraw ( )
inline

Definition at line 63 of file CSVDialog.h.

63 {if (surface.get()) surface->requestRedraw();}

◆ rowOver()

size_t CSVDialog::rowOver ( double  y) const

return row mouse is over

Definition at line 295 of file CSVDialog.cc.

296 {
297  return size_t(y/rowHeight);
298 }
double rowHeight
Definition: CSVDialog.h:38

◆ tableWidth()

double minsky::CSVDialog::tableWidth ( ) const
inline

width of table (in pixels)

Definition at line 52 of file CSVDialog.h.

References m_tableWidth.

52 {return m_tableWidth;}
double m_tableWidth
Definition: CSVDialog.h:39

Member Data Documentation

◆ colWidth

double minsky::CSVDialog::colWidth =50

Definition at line 46 of file CSVDialog.h.

◆ flashNameRow

bool minsky::CSVDialog::flashNameRow =false

Definition at line 47 of file CSVDialog.h.

◆ initialLines

std::vector<std::string> minsky::CSVDialog::initialLines
private

initial lines of file

Definition at line 37 of file CSVDialog.h.

◆ m_tableWidth

double minsky::CSVDialog::m_tableWidth
private

Definition at line 39 of file CSVDialog.h.

Referenced by tableWidth().

◆ numInitialLines

const unsigned CSVDialog::numInitialLines =100
static

◆ rowHeight

double minsky::CSVDialog::rowHeight =0
private

Definition at line 38 of file CSVDialog.h.

◆ spec

DataSpec minsky::CSVDialog::spec

Definition at line 48 of file CSVDialog.h.

◆ url

std::string minsky::CSVDialog::url

filename, or web url

Definition at line 50 of file CSVDialog.h.

◆ xoffs

double minsky::CSVDialog::xoffs =80

Definition at line 45 of file CSVDialog.h.


The documentation for this class was generated from the following files: