Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Label and levels improvement #5700

Merged
merged 3 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions CommonData/column.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ std::map<double, Label*> Column::replaceDoubleWithLabel(doublevec dbls)
return doubleLabelMap;
}

Label *Column::replaceDoublesTillLabelsRowWithLabels(size_t row)
Label *Column::replaceDoublesTillLabelsRowWithLabels(size_t row, double returnForDbl)
{
JASPTIMER_SCOPE(Column::replaceDoublesTillLabelsRowWithLabels);

Expand All @@ -1301,8 +1301,9 @@ Label *Column::replaceDoublesTillLabelsRowWithLabels(size_t row)
else
throw std::runtime_error("replaceDoublesTillLabelsRowWithLabels choked on a temp-label that cant be converted to double???"); //Should never ever occur because it starts from _labels.size!

//the last dbl is the one we want so use it to get the right label from the map:
Label * label = replaceDoubleWithLabel(dbls)[dbl];
//the last dbl is the one we want so use it to get the right label from the map
auto labelPerDbl = replaceDoubleWithLabel(dbls);
Label * label = labelPerDbl[std::isnan(returnForDbl) || labelPerDbl.count(returnForDbl) == 0 ? dbl : returnForDbl];

return label;
}
Expand Down Expand Up @@ -1730,7 +1731,8 @@ void Column::labelsOrderByValue(bool doDbUpdateEtc)
replaceDoublesTillLabelsRowWithLabels(labelsTempCount());

doublevec asc = valuesNumericOrdered();
size_t curMax = asc.size()+1;
auto alpha = valuesAlphabeticalOffsets();
size_t ascMax = asc.size()+1;
std::map<double, int> orderMap;

for(size_t i=0; i<asc.size(); i++)
Expand All @@ -1746,7 +1748,7 @@ void Column::labelsOrderByValue(bool doDbUpdateEtc)
else
ColumnUtils::getDoubleValue(label->originalValueAsString(), aValue);

label->setOrder(!std::isnan(aValue) ? orderMap[aValue] : curMax++);
label->setOrder(!std::isnan(aValue) ? orderMap[aValue] : alpha[label] + ascMax);
}

_sortLabelsByOrder();
Expand Down Expand Up @@ -1775,6 +1777,26 @@ doublevec Column::valuesNumericOrdered()
return doublevec(values.begin(), values.end());
}

std::map<Label*, size_t> Column::valuesAlphabeticalOffsets()
{
std::map<Label*, size_t> labelMap;
Labels alphaLabels;

for(Label * label : _labels)
if(!label->originalValue().isDouble())
alphaLabels.push_back(label);

std::sort(alphaLabels.begin(), alphaLabels.end(), [](const Label * l, const Label * r)
{
return l->originalValueAsString() < r->originalValueAsString();
});

for(size_t l=0; l<alphaLabels.size(); l++)
labelMap[alphaLabels[l]] = l;

return labelMap;
}

void Column::valuesReverse()
{
JASPTIMER_SCOPE(Column::valuesReverse);
Expand Down
5 changes: 3 additions & 2 deletions CommonData/column.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ class Column : public DataSetBaseNode

std::map<double,Label*> replaceDoubleWithLabel(doublevec dbls);
Label * replaceDoubleWithLabel(double dbl);
Label * replaceDoublesTillLabelsRowWithLabels(size_t row);
Label * replaceDoublesTillLabelsRowWithLabels(size_t row, double returnForDbl = NAN);
bool replaceDoubleLabelFromRowWithDouble(size_t row, double dbl); ///< Returns true if succes

void labelValueChanged(Label * label, double aDouble, const Json::Value & previousOriginal); ///< Pass NaN for non-convertible values
Expand Down Expand Up @@ -232,7 +232,7 @@ class Column : public DataSetBaseNode

static void setAutoSortByValuesByDefault(bool autoSort);
static bool autoSortByValuesByDefault();

protected:
void _checkForDependencyLoop(stringset foundNames, std::list<std::string> loopList);
void _dbUpdateLabelOrder(bool noIncRevisionWhenBatchedPlease = false); ///< Sets the order of the _labels to label.order and in DB
Expand All @@ -243,6 +243,7 @@ class Column : public DataSetBaseNode
void _convertVectorIntToDouble(intvec & intValues, doublevec & doubleValues);
void _resetLabelValueMap();
doublevec valuesNumericOrdered();
std::map<Label*,size_t> valuesAlphabeticalOffsets();

private:
DataSet * const _data;
Expand Down
32 changes: 16 additions & 16 deletions Desktop/components/JASP/Widgets/LabelEditorWindow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ FocusScope
target: columnModel
function onChosenColumnChanged()
{
levelsTableView.lastRow = -1;
levelsTableView.selectedRow = -1;
}
}

property real filterColWidth: 60 * jaspTheme.uiScale
property real remainingWidth: width - filterColWidth
property real valueColWidth: Math.min(columnModel.valueMaxWidth + 10, remainingWidth * 0.5) * jaspTheme.uiScale
property real labelColWidth: Math.min(columnModel.labelMaxWidth + 10, remainingWidth * 0.5) * jaspTheme.uiScale
property int lastRow: -1
property int selectedRow: -1


columnHeaderDelegate: Item
Expand Down Expand Up @@ -129,7 +129,7 @@ FocusScope
{
id: backgroundItem

onActiveFocusChanged: if(activeFocus) levelsTableView.lastRow = rowIndex
onActiveFocusChanged: if(activeFocus) levelsTableView.selectedRow = rowIndex

MouseArea
{
Expand Down Expand Up @@ -440,7 +440,7 @@ FocusScope
iconSource: jaspTheme.iconPath + "menu-column-order-by-values.svg"
onClicked: { forceActiveFocus(); columnModel.toggleAutoSortByValues(); }

toolTip: qsTr("Automatically order labels by their numeric value")
toolTip: qsTr("Automatically order labels by their value")

height: buttonColumnVariablesWindow.buttonHeight
implicitHeight: buttonColumnVariablesWindow.buttonHeight
Expand All @@ -458,49 +458,49 @@ FocusScope
height: buttonColumnVariablesWindow.buttonHeight
implicitHeight: buttonColumnVariablesWindow.buttonHeight
width: height
visible: !columnModel.autoSort || columnModel.firstNonNumericRow > 1 //if there are at least 2 numerics we have something to reverse
visible: columnModel.hasSeveralNumericValues //if there are at least 2 numerics we have something to reverse
}

RoundedButton
{
iconSource: jaspTheme.iconPath + "arrow-reverse.png"
onClicked: { forceActiveFocus(); columnModel.reverse(); }

toolTip: columnModel.autoSort ? qsTr("Reverse order of the labels with non-numeric values") : qsTr("Reverse order of all labels")
toolTip: qsTr("Reverse order of all labels")

height: buttonColumnVariablesWindow.buttonHeight
implicitHeight: buttonColumnVariablesWindow.buttonHeight
width: height
visible: !columnModel.autoSort || columnModel.rowsTotal - columnModel.firstNonNumericRow > 1 //If there are at least 2 non numerics there is something to reverse

visible: !columnModel.autoSort
enabled: columnModel.rowsTotal > 1
}

RoundedButton
{
iconSource: jaspTheme.iconPath + "arrow-up.png"

onClicked: { forceActiveFocus(); columnModel.moveSelectionUp(); levelsTableView.lastRow--; }
toolTip: columnModel.autoSort ? qsTr("Move selected non-numeric labels up") : qsTr("Move selected labels up")
onClicked: { forceActiveFocus(); columnModel.moveSelectionUp(); levelsTableView.selectedRow--; }
toolTip: qsTr("Move selected labels up")

height: buttonColumnVariablesWindow.buttonHeight
implicitHeight: buttonColumnVariablesWindow.buttonHeight
width: height
enabled: levelsTableView.lastRow == -1 ? false : columnModel.firstNonNumericRow < levelsTableView.lastRow
visible: !columnModel.autoSort || columnModel.rowsTotal - columnModel.firstNonNumericRow > 1 //If there are at least 2 non numerics there is something to move up
enabled: levelsTableView.selectedRow > 0
visible: !columnModel.autoSort
}

RoundedButton
{
iconSource: jaspTheme.iconPath + "arrow-down.png"

onClicked: { forceActiveFocus(); columnModel.moveSelectionDown(); levelsTableView.lastRow++; }
toolTip: columnModel.autoSort ? qsTr("Move selected non-numeric labels down") : qsTr("Move selected labels down")
onClicked: { forceActiveFocus(); columnModel.moveSelectionDown(); levelsTableView.selectedRow++; }
toolTip: qsTr("Move selected labels down")

height: buttonColumnVariablesWindow.buttonHeight
implicitHeight: buttonColumnVariablesWindow.buttonHeight
width: height
enabled: levelsTableView.lastRow == -1 ? false : ((columnModel.firstNonNumericRow <= levelsTableView.lastRow) && ( levelsTableView.lastRow < columnModel.rowsTotal - 1 ))
visible: !columnModel.autoSort || columnModel.rowsTotal - columnModel.firstNonNumericRow > 1 //If there are at least 2 non numerics there is something to move down
enabled: levelsTableView.selectedRow >= 0 && levelsTableView.selectedRow < columnModel.rowCount() - 1
visible: !columnModel.autoSort
}

RoundedButton
Expand Down
25 changes: 11 additions & 14 deletions Desktop/data/columnmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,27 +187,25 @@ int ColumnModel::rowsTotal() const
return rowCount();
}

int ColumnModel::firstNonNumericRow() const
bool ColumnModel::hasSeveralNumericValues() const
{
if(!column() || !column()->autoSortByValue())
return 0;
if(!column())
return false;

int nonEmptyNonNumerics = 0;
int numberOfNumericalValues = 0;
for(Label * label : column()->labels())
if(!label->isEmptyValue())
{
static double dummy;

if(!(label->originalValue().isDouble() || ColumnUtils::getDoubleValue(label->originalValueAsString(), dummy)))
return nonEmptyNonNumerics;
nonEmptyNonNumerics++;
if(label->originalValue().isDouble() && ColumnUtils::getDoubleValue(label->originalValueAsString(), dummy))
numberOfNumericalValues++;

if (numberOfNumericalValues > 1)
return true;
}

//If we have more temporary labels then normal ones then those afterwards are all numeric (or something wouldve been replaced/sorted) so we can return labelsTempCount()
if(column()->labelsTempCount() > nonEmptyNonNumerics)
return column()->labelsTempCount();

return nonEmptyNonNumerics;
return column()->labelsTempNumerics() > 1;
}

void ColumnModel::setCustomEmptyValues(const QStringList& customEmptyValues)
Expand Down Expand Up @@ -602,10 +600,9 @@ void ColumnModel::refresh()
emit nameEditableChanged();
emit columnDescriptionChanged();
emit computedTypeValuesChanged();
emit firstNonNumericRowChanged();
emit hasSeveralNumericValuesChanged();
emit computedTypeEditableChanged();
emit useCustomEmptyValuesChanged();
emit firstNonNumericRowChanged();
emit columnTypeValuesChanged();
emit computedTypeChanged();
emit emptyValuesChanged();
Expand Down
6 changes: 3 additions & 3 deletions Desktop/data/columnmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class ColumnModel : public DataSetTableProxy
Q_PROPERTY(bool isVirtual READ isVirtual NOTIFY isVirtualChanged )
Q_PROPERTY(bool compactMode READ compactMode WRITE setCompactMode NOTIFY compactModeChanged )
Q_PROPERTY(bool autoSort READ autoSort WRITE setAutoSort NOTIFY autoSortChanged )
Q_PROPERTY(int firstNonNumericRow READ firstNonNumericRow NOTIFY firstNonNumericRowChanged ) //Only works when autosort is on
Q_PROPERTY(bool hasSeveralNumericValues READ hasSeveralNumericValues NOTIFY hasSeveralNumericValuesChanged ) //Only works when autosort is on
Q_PROPERTY(int rowsTotal READ rowsTotal NOTIFY rowsTotalChanged )

public:
Expand All @@ -58,7 +58,7 @@ class ColumnModel : public DataSetTableProxy
QVariantList columnTypeValues() const;
bool useCustomEmptyValues() const;
QStringList emptyValues() const;
int firstNonNumericRow() const;
bool hasSeveralNumericValues() const;
int rowsTotal() const;


Expand Down Expand Up @@ -158,7 +158,7 @@ public slots:
void isVirtualChanged();
void compactModeChanged();
void autoSortChanged();
void firstNonNumericRowChanged();
void hasSeveralNumericValuesChanged();

private:
std::vector<qsizetype> getSortedSelection() const;
Expand Down
10 changes: 6 additions & 4 deletions Desktop/data/datasetpackage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -920,12 +920,14 @@ bool DataSetPackage::setLabelValue(const QModelIndex &index, const QString &newL

if(column->labelDoubleDummy() == label)
{
int replaceTill = -1;
int replaceTill = -1;
double oldDouble = column->labelsTempValueDouble(index.row());

if(aNumber)
{
int newHasRow = column->labelsDoubleValueIsTempLabelRow(aDouble);
int newHasRow = column->labelsDoubleValueIsTempLabelRow(aDouble);

if(!Utils::isEqual(aDouble, column->labelsTempValueDouble(index.row())))
if(!Utils::isEqual(aDouble, oldDouble))
{
assert(newHasRow != index.row()); //Because it shouldnt be the same after all
replaceTill = std::max(index.row(), newHasRow);
Expand All @@ -945,7 +947,7 @@ bool DataSetPackage::setLabelValue(const QModelIndex &index, const QString &newL
if(replaceTill == -1 && column->autoSortByValue())
replaceTill = column->labelsTempCount();

label = column->replaceDoublesTillLabelsRowWithLabels(replaceTill > -1 ? replaceTill : index.row());
label = column->replaceDoublesTillLabelsRowWithLabels(replaceTill > -1 ? replaceTill : index.row(), oldDouble);
aChange = true;
}

Expand Down
8 changes: 8 additions & 0 deletions Desktop/qquick/datasetview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ void DataSetView::setModel(QAbstractItemModel * model)
connect(model, &QAbstractItemModel::modelAboutToBeReset, this, &DataSetView::modelAboutToBeReset );

connect(_selectionModel, &QItemSelectionModel::selectionChanged, this, &DataSetView::selectionChanged);
connect(_selectionModel, &QItemSelectionModel::currentColumnChanged, this, &DataSetView::currentSelectedColumnHandler);

connect(model, &QAbstractItemModel::columnsAboutToBeInserted, this, &DataSetView::columnsAboutToBeInserted );
connect(model, &QAbstractItemModel::columnsAboutToBeRemoved, this, &DataSetView::columnsAboutToBeRemoved );
Expand Down Expand Up @@ -1550,6 +1551,13 @@ void DataSetView::resizeData(int rows, int columns)
_model->resize(rows - 1, columns - 1, false, tr("Resize data to %1 rows and %2 columns").arg(rows).arg(columns));
}

void DataSetView::currentSelectedColumnHandler(const QModelIndex &current, const QModelIndex &previous)
{
int selectedColumn = current.column();
if (selectedColumn >= 0)
emit DataSetPackage::pkg()->chooseColumn(selectedColumn);
}

void DataSetView::columnReverseValues(int columnIndex)
{
columnIndexSelectedApply(columnIndex, [&](intset col) { _model->columnReverseValues(col); });
Expand Down
1 change: 1 addition & 0 deletions Desktop/qquick/datasetview.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ public slots:

void setColumnType(int columnIndex, int newColumnType);
void resizeData(int rows, int columns);
void currentSelectedColumnHandler(const QModelIndex &current, const QModelIndex &previous);

protected:
void _copy(QPoint where, bool clear);
Expand Down
Loading