mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
JKQTPbarVerticalGraph and JKQTPbarHoricontalGraph now draw bars with the proper width, even if data is not sorted
This commit is contained in:
parent
8dc6b57f9c
commit
34631fb66f
@ -57,14 +57,10 @@ QVector<double> JKQTPcolumn::copyData()
|
||||
QVector<double> d;
|
||||
copyData(d);
|
||||
return d;
|
||||
};
|
||||
}
|
||||
|
||||
/** \brief reads the \a n'th value from the column
|
||||
*
|
||||
* This method accesses the datastore and returns the double value stored in the \a n'th row of the according
|
||||
* column.
|
||||
*/
|
||||
double JKQTPcolumn::getValue(unsigned long long n) const {
|
||||
double JKQTPcolumn::getValue(unsigned long long n) const
|
||||
{
|
||||
if (!datastore) return 0;
|
||||
if (!datastore->getItem(datastoreItem)) return 0;
|
||||
return datastore->getItem(datastoreItem)->get(datastoreOffset, n);
|
||||
@ -75,19 +71,18 @@ double *JKQTPcolumn::getPointer(unsigned long long n) const
|
||||
if (!datastore) return 0;
|
||||
if (!datastore->getItem(datastoreItem)) return 0;
|
||||
return datastore->getItem(datastoreItem)->getPointer(datastoreOffset, n);
|
||||
};
|
||||
}
|
||||
|
||||
/** \brief sets the \a n'th value from the column
|
||||
*
|
||||
* This method accesses the datastore and returns the double value stored in the \a n'th row of the according
|
||||
* column.
|
||||
*/
|
||||
void JKQTPcolumn::setValue(unsigned long long n, double val) {
|
||||
void JKQTPcolumn::setValue(unsigned long long n, double val)
|
||||
{
|
||||
if (!datastore) return ;
|
||||
if (!datastore->getItem(datastoreItem)) return;
|
||||
datastore->getItem(datastoreItem)->set(datastoreOffset, n, val);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void JKQTPcolumn::copy(double* data, unsigned long long N, unsigned long long offset) {
|
||||
if (!datastore) return ;
|
||||
JKQTPdatastoreItem* it=datastore->getItem(datastoreItem);
|
||||
@ -308,6 +303,11 @@ size_t JKQTPdatastore::ensureColumnNum(QString name) {
|
||||
return addColumn(0, name);
|
||||
}
|
||||
|
||||
JKQTPcolumn JKQTPdatastore::getColumn(size_t i) const
|
||||
{
|
||||
return columns.value(i);
|
||||
}
|
||||
|
||||
size_t JKQTPdatastore::addCopiedItem(JKQTPdatastoreItemFormat dataformat, double* data, size_t columnsnum, unsigned long long rows) {
|
||||
JKQTPdatastoreItem* it=NULL;
|
||||
if ((dataformat==JKQTPsingleColumn)||(columnsnum==1)) {
|
||||
@ -1042,19 +1042,77 @@ size_t JKQTPdatastore::addLinearColumn(unsigned long long rows, double start, do
|
||||
}
|
||||
|
||||
/** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
|
||||
double JKQTPdatastore::get(size_t column, unsigned long long row) {
|
||||
double JKQTPdatastore::get(size_t column, unsigned long long row) const {
|
||||
return columns[column].getValue(row);
|
||||
};
|
||||
}
|
||||
|
||||
/** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
|
||||
void JKQTPdatastore::set(size_t column, unsigned long long row, double value) {
|
||||
long long JKQTPdatastore::getNextLowerIndex(size_t column, unsigned long long row, long long start, long long end) const
|
||||
{
|
||||
const JKQTPcolumn& col=columns[column];
|
||||
if (start<0 && end>=0) return getNextLowerIndex(column, row, 0, end);
|
||||
else if (start>=0 && end<0) return getNextLowerIndex(column, row, start, col.getRows()-1);
|
||||
else if (start<0 && end<0) return getNextLowerIndex(column, row, 0, col.getRows()-1);
|
||||
else {
|
||||
double d=0;
|
||||
const double v=col.getValue(row);
|
||||
long long res=-1;
|
||||
for ( long long i=start; i<=end; i++) {
|
||||
if (i!=(long long)row) {
|
||||
const double v1=col.getValue(i);
|
||||
const double dd=v1-v;
|
||||
if ((dd<0) && ((fabs(dd)<d)||(d==0.0))) {
|
||||
res=i;
|
||||
d=fabs(dd);
|
||||
//std::cout<<" getNextLowerIndex("<<column<<", "<<row<<", "<<start<<", "<<end<<"): i="<<i<<": OK res="<<res<<" d="<<d<<"\n";
|
||||
} /*else {
|
||||
std::cout<<" getNextLowerIndex("<<column<<", "<<row<<", "<<start<<", "<<end<<"): i="<<i<<": FAIL res="<<res<<" dd="<<dd<<" v1="<<v1<<" v="<<v<<"\n";
|
||||
}*/
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
long long JKQTPdatastore::getNextLowerIndex(size_t column, unsigned long long row) const
|
||||
{
|
||||
return getNextLowerIndex(column, row, 0, columns[column].getRows()-1);
|
||||
}
|
||||
|
||||
long long JKQTPdatastore::getNextHigherIndex(size_t column, unsigned long long row, long long start, long long end) const
|
||||
{
|
||||
const JKQTPcolumn& col=columns[column];
|
||||
if (start<0 && end>=0) return getNextHigherIndex(column, row, 0, end);
|
||||
else if (start>=0 && end<0) return getNextHigherIndex(column, row, start, col.getRows()-1);
|
||||
else if (start<0 && end<0) return getNextHigherIndex(column, row, 0, col.getRows()-1);
|
||||
else {
|
||||
double d=0;
|
||||
const double v=col.getValue(row);
|
||||
long long res=-1;
|
||||
for ( long long i=start; i<=end; i++) {
|
||||
if (i!=(long long)row) {
|
||||
const double v1=col.getValue(i);
|
||||
const double dd=v1-v;
|
||||
if ((dd>0) && ((fabs(dd)<d)||(d==0.0))) {
|
||||
res=i;
|
||||
d=fabs(dd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
long long JKQTPdatastore::getNextHigherIndex(size_t column, unsigned long long row) const
|
||||
{
|
||||
return getNextHigherIndex(column, row, 0, columns[column].getRows()-1);
|
||||
}
|
||||
|
||||
void JKQTPdatastore::set(size_t column, unsigned long long row, double value)
|
||||
{
|
||||
columns[column].setValue(row, value);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
JKQTPcolumn JKQTPdatastore::getColumn(size_t i) {
|
||||
//std::cout<<"datastore->getColumn("<<i<<")\n";
|
||||
return columns.value(i);
|
||||
};
|
||||
|
||||
unsigned long long JKQTPdatastore::getMaxRows() {
|
||||
unsigned long long res=0;
|
||||
|
@ -204,7 +204,15 @@ class LIB_EXPORT JKQTPdatastore{
|
||||
|
||||
|
||||
/** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
|
||||
double get(size_t column, unsigned long long row);
|
||||
double get(size_t column, unsigned long long row) const;
|
||||
/** \brief gets the of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/
|
||||
long long getNextLowerIndex(size_t column, unsigned long long row, long long start, long long end) const;
|
||||
/** \brief gets the of the datapoint with the nearest, but lower value in the column */
|
||||
long long getNextLowerIndex(size_t column, unsigned long long row) const;
|
||||
/** \brief gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column) */
|
||||
long long getNextHigherIndex(size_t column, unsigned long long row, long long start, long long end) const;
|
||||
/** \brief gets the index of the datapoint with the nearest, but higher value in the column */
|
||||
long long getNextHigherIndex(size_t column, unsigned long long row) const;
|
||||
|
||||
/** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
|
||||
void set(size_t column, unsigned long long row, double value);
|
||||
@ -772,7 +780,7 @@ class LIB_EXPORT JKQTPdatastore{
|
||||
size_t ensureColumnNum(QString name);
|
||||
|
||||
/** \brief returns the JKQTPcolumn object for the \a i -th column in the store */
|
||||
JKQTPcolumn getColumn(size_t i);
|
||||
JKQTPcolumn getColumn(size_t i) const;
|
||||
|
||||
/** \brief returns the maximum number of rows in all columns */
|
||||
unsigned long long getMaxRows();
|
||||
@ -918,14 +926,14 @@ class LIB_EXPORT JKQTPcolumn {
|
||||
double getValue(unsigned long long n) const;
|
||||
/** \brief gets a pointer to the n-th value in the column
|
||||
*/
|
||||
double* getPointer(unsigned long long n=0) const;
|
||||
double* getPointer(unsigned long long n=0) const ;
|
||||
|
||||
/** \brief sets the \a n'th value from the column
|
||||
*
|
||||
* This method accesses the datastore and returns the double value stored in the \a n'th row of the according
|
||||
* column.
|
||||
*/
|
||||
void setValue(unsigned long long n, double val);
|
||||
void setValue(unsigned long long n, double val) ;
|
||||
|
||||
/** \brief returns a pointer to the datastore item representing this column */
|
||||
inline JKQTPdatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); }
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "jkqtpbaseplotter.h"
|
||||
#include <stdlib.h>
|
||||
#include <QDebug>
|
||||
#include <iostream>
|
||||
#include "jkqtptools.h"
|
||||
#include "jkqtpimageelements.h"
|
||||
#include "jkqtpbaseelements.h"
|
||||
@ -4311,18 +4312,32 @@ void JKQTPbarHorizontalGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
for (int iii=imin; iii<imax; iii++) {
|
||||
int i=qBound(imin, getDataIndex(iii), imax);
|
||||
double xv=datastore->get(xColumn,i);
|
||||
long long sr=datastore->getNextLowerIndex(xColumn, i, datarange_start, datarange_end);
|
||||
long long lr=datastore->getNextHigherIndex(xColumn, i, datarange_start, datarange_end);
|
||||
double yv=datastore->get(yColumn,i);
|
||||
if (imin==imax) { // only one x-value
|
||||
// if (imin==imax) { // only one x-value
|
||||
// deltam=0.5;
|
||||
// deltap=0.5;
|
||||
// } else if (i==imax-1) { // the right-most x-value
|
||||
// deltap=deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
// } else if (i==imin) { // the left-most x-value
|
||||
// deltam=deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
// } else {
|
||||
// deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
// deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
// }
|
||||
if (sr<0 && lr<0) { // only one x-value
|
||||
deltam=0.5;
|
||||
deltap=0.5;
|
||||
} else if (i==imax-1) { // the right-most x-value
|
||||
deltap=deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
} else if (i==imin) { // the left-most x-value
|
||||
deltam=deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
} else if (lr<0) { // the right-most x-value
|
||||
deltap=deltam=fabs(xv-datastore->get(xColumn,sr))/2.0;
|
||||
} else if (sr<0) { // the left-most x-value
|
||||
deltam=deltap=fabs(datastore->get(xColumn,lr)-xv)/2.0;
|
||||
} else {
|
||||
deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
deltam=fabs(xv-datastore->get(xColumn,sr))/2.0;
|
||||
deltap=fabs(datastore->get(xColumn,lr)-xv)/2.0;
|
||||
}
|
||||
//std::cout<<iii<<", \t"<<i<<", \t"<<sr<<", \t"<<lr<<", \t"<<deltam<<", \t"<<deltap<<"\n\n";
|
||||
delta=deltap+deltam;
|
||||
|
||||
if (JKQTPIsOKFloat(xv) && JKQTPIsOKFloat(yv)) {
|
||||
@ -4375,17 +4390,31 @@ bool JKQTPbarHorizontalGraph::getXMinMax(double& minx, double& maxx, double& sma
|
||||
|
||||
for (int i=imin; i<imax; i++) {
|
||||
double xv=datastore->get(xColumn,i);
|
||||
long long sr=datastore->getNextLowerIndex(xColumn, i, datarange_start, datarange_end);
|
||||
long long lr=datastore->getNextHigherIndex(xColumn, i, datarange_start, datarange_end);
|
||||
double delta, deltap, deltam;
|
||||
if (imin==imax) { // only one x-value
|
||||
// if (imin==imax) { // only one x-value
|
||||
// deltam=0.5;
|
||||
// deltap=0.5;
|
||||
// } else if (i==imax-1) { // the right-most x-value
|
||||
// deltap=deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
// } else if (i==imin) { // the left-most x-value
|
||||
// deltam=deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
// } else {
|
||||
// deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
// deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
// }
|
||||
|
||||
if (sr<0 && lr<0) { // only one x-value
|
||||
deltam=0.5;
|
||||
deltap=0.5;
|
||||
} else if (i==imax-1) { // the right-most x-value
|
||||
deltap=deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
} else if (i==imin) { // the left-most x-value
|
||||
deltam=deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
} else if (lr<0) { // the right-most x-value
|
||||
deltap=deltam=fabs(xv-datastore->get(xColumn,sr))/2.0;
|
||||
} else if (sr<0) { // the left-most x-value
|
||||
deltam=deltap=fabs(datastore->get(xColumn,lr)-xv)/2.0;
|
||||
} else {
|
||||
deltam=fabs(xv-datastore->get(xColumn,i-1))/2.0;
|
||||
deltap=fabs(datastore->get(xColumn,i+1)-xv)/2.0;
|
||||
deltam=fabs(xv-datastore->get(xColumn,sr))/2.0;
|
||||
deltap=fabs(datastore->get(xColumn,lr)-xv)/2.0;
|
||||
}
|
||||
delta=deltap+deltam;
|
||||
|
||||
@ -4546,16 +4575,30 @@ void JKQTPbarVerticalGraph::draw(JKQTPEnhancedPainter& painter) {
|
||||
int i=qBound(imin, getDataIndex(iii), imax);
|
||||
double xv=datastore->get(xColumn,i);
|
||||
double yv=datastore->get(yColumn,i);
|
||||
if (imin==imax) { // only one x-value
|
||||
long long sr=datastore->getNextLowerIndex(yColumn, i, datarange_start, datarange_end);
|
||||
long long lr=datastore->getNextHigherIndex(yColumn, i, datarange_start, datarange_end);
|
||||
// if (imin==imax) { // only one x-value
|
||||
// deltam=0.5;
|
||||
// deltap=0.5;
|
||||
// } else if (i==imax-1) { // the right-most x-value
|
||||
// deltap=deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
// } else if (i==imin) { // the left-most x-value
|
||||
// deltam=deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
// } else {
|
||||
// deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
// deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
// }
|
||||
|
||||
if (sr<0 && lr<0) { // only one y-value
|
||||
deltam=0.5;
|
||||
deltap=0.5;
|
||||
} else if (i==imax-1) { // the right-most x-value
|
||||
deltap=deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
} else if (i==imin) { // the left-most x-value
|
||||
deltam=deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
} else if (lr<0) { // the right-most y-value
|
||||
deltap=deltam=fabs(yv-datastore->get(yColumn,sr))/2.0;
|
||||
} else if (sr<0) { // the left-most y-value
|
||||
deltam=deltap=fabs(datastore->get(yColumn,lr)-yv)/2.0;
|
||||
} else {
|
||||
deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
deltam=fabs(yv-datastore->get(yColumn,sr))/2.0;
|
||||
deltap=fabs(datastore->get(yColumn,lr)-yv)/2.0;
|
||||
}
|
||||
delta=deltap+deltam;
|
||||
|
||||
@ -4659,16 +4702,30 @@ bool JKQTPbarVerticalGraph::getYMinMax(double& miny, double& maxy, double& small
|
||||
for (int i=imin; i<imax; i++) {
|
||||
double yv=datastore->get(yColumn,i);
|
||||
double delta, deltap, deltam;
|
||||
if (imin==imax) { // only one x-value
|
||||
long long sr=datastore->getNextLowerIndex(yColumn, i, datarange_start, datarange_end);
|
||||
long long lr=datastore->getNextHigherIndex(yColumn, i, datarange_start, datarange_end);
|
||||
// if (imin==imax) { // only one x-value
|
||||
// deltam=0.5;
|
||||
// deltap=0.5;
|
||||
// } else if (i==imax-1) { // the right-most x-value
|
||||
// deltap=deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
// } else if (i==imin) { // the left-most x-value
|
||||
// deltam=deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
// } else {
|
||||
// deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
// deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
// }
|
||||
|
||||
if (sr<0 && lr<0) { // only one y-value
|
||||
deltam=0.5;
|
||||
deltap=0.5;
|
||||
} else if (i==imax-1) { // the right-most x-value
|
||||
deltap=deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
} else if (i==imin) { // the left-most x-value
|
||||
deltam=deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
} else if (lr<0) { // the right-most y-value
|
||||
deltap=deltam=fabs(yv-datastore->get(yColumn,sr))/2.0;
|
||||
} else if (sr<0) { // the left-most y-value
|
||||
deltam=deltap=fabs(datastore->get(yColumn,lr)-yv)/2.0;
|
||||
} else {
|
||||
deltam=fabs(yv-datastore->get(yColumn,i-1))/2.0;
|
||||
deltap=fabs(datastore->get(yColumn,i+1)-yv)/2.0;
|
||||
deltam=fabs(yv-datastore->get(yColumn,sr))/2.0;
|
||||
deltap=fabs(datastore->get(yColumn,lr)-yv)/2.0;
|
||||
}
|
||||
delta=deltap+deltam;
|
||||
if (JKQTPIsOKFloat(yv) && JKQTPIsOKFloat(delta) ) {
|
||||
|
@ -14,8 +14,10 @@ int main(int argc, char* argv[])
|
||||
JKQTPdatastore* ds=plot.getDatastore();
|
||||
|
||||
// 2. now we create data for three simple barchart
|
||||
QString L[Ndata]={ "cat. A", "cat. B", "cat. C", "cat. D", "other"};
|
||||
double X[Ndata]={ 1, 2, 3, 4, 5};
|
||||
QString L[Ndata]={ "cat. A", "cat. C", "cat. B", "cat. D", "other"};
|
||||
double X[Ndata]={ 1, 3, 2, 4, 5};
|
||||
//QString L[Ndata]={ "cat. A", "cat. B", "cat. C", "cat. D", "other"}; // correctly sorted data!
|
||||
//double X[Ndata]={ 1, 2, 3, 4, 5};
|
||||
double Y1[Ndata]={ 5, 4, 3, 4, 5};
|
||||
double Y2[Ndata]={ -5, -3, 1, 3, 6};
|
||||
double Y3[Ndata]={ 6, 2, 5, 3, 6};
|
||||
|
Loading…
Reference in New Issue
Block a user