Add support for non-numerical values to the DashboardItemTimevaryingText (closes #3653)

This commit is contained in:
Alexander Bock
2025-05-12 21:19:24 +02:00
parent fd0d52afa9
commit 22735c5aaf
5 changed files with 123 additions and 43 deletions

View File

@@ -0,0 +1,10 @@
{
"data": [
[ "2024-05-10T00:00:00Z", 2.33 ],
[ "2024-05-10T03:00:00Z", true ],
[ "2024-05-10T06:00:00Z", "Test string" ],
[ "2024-05-10T09:00:00Z", { "a": 1.0, "b": 2.0 } ],
[ "2024-05-10T12:00:00Z", [ 1.0, 2.0, 3.0 ] ],
[ "2024-05-10T15:00:00Z", 3 ]
]
}

View File

@@ -0,0 +1,17 @@
-- Mixed
-- This example shows how to create a time-varying text dashboard item that is using a
-- mixed type of data entries in the `DataFile`.
local Item = {
Type = "DashboardItemTimeVaryingText",
Identifier = "DashboardItemTimeVaryingText_Example_Mixed",
DataFile = asset.resource("data/dummydata_mixed.json"),
}
asset.onInitialize(function()
openspace.dashboard.addDashboardItem(Item)
end)
asset.onDeinitialize(function()
openspace.dashboard.removeDashboardItem(Item)
end)

View File

@@ -4,7 +4,7 @@
local Item = {
Type = "DashboardItemTimeVaryingText",
Identifier = "DashboardItemTimeVaryingText_Example-Styled",
Identifier = "DashboardItemTimeVaryingText_Example_Styled",
DataFile = asset.resource("data/dummydata.json"),
FormatString = "Observed KP index: {}",
FontSize = 40

View File

@@ -50,8 +50,9 @@ namespace {
openspace::properties::Property::Visibility::User
};
// This `DashboardItem` displays text based on the content of a provided data file. The
// value that is displayed depends on the current in-game simulation time.
// This `DashboardItem` displays text based on the content of a provided data file.
// The value that is displayed depends on the current in-game simulation time.
//
// The JSON must contain a 'data' array with timestamp-value pairs. Example format:
// {\"data\": [[\"2024-05-10T00:00:00Z\", 2.33], [\"2024-05-10T03:00:00Z\", 3.0]]}
struct [[codegen::Dictionary(DashboardItemTimeVaryingText)]] Parameters {
@@ -59,7 +60,7 @@ namespace {
std::optional<std::string> formatString;
// [[codegen::verbatim(DataFileInfo.description)]]
std::string dataFile;
std::filesystem::path dataFile;
};
#include "dashboarditemtimevaryingtext_codegen.cpp"
} // namespace
@@ -84,14 +85,9 @@ DashboardItemTimeVaryingText::DashboardItemTimeVaryingText(
_formatString = p.formatString.value_or(_formatString);
addProperty(_formatString);
_dataFile = absPath(p.dataFile).string();
_dataFile.onChange([this]() { loadDataFromJson(_dataFile); });
_dataFile = p.dataFile.string();
addProperty(_dataFile);
_dataFile.onChange([this]() {
loadDataFromJson(_dataFile);
});
loadDataFromJson(_dataFile);
}
void DashboardItemTimeVaryingText::update() {
@@ -109,14 +105,70 @@ void DashboardItemTimeVaryingText::update() {
if (newIdx != _activeTriggerTimeIndex) {
_activeTriggerTimeIndex = newIdx;
double timeKey = _startTimes[_activeTriggerTimeIndex];
double value = _data[timeKey];
std::ostringstream oss;
oss << value;
std::string valueString = oss.str();
const nlohmann::json value = _data[timeKey];
try {
_buffer = std::vformat(_formatString.value(),
std::make_format_args(valueString));
switch (value.type()) {
case nlohmann::json::value_t::null:
case nlohmann::json::value_t::discarded:
break;
case nlohmann::json::value_t::boolean: {
const bool v = value.get<bool>();
_buffer = std::vformat(
_formatString.value(),
std::make_format_args(v)
);
break;
}
case nlohmann::json::value_t::string: {
const std::string v = value.get<std::string>();
_buffer = std::vformat(
_formatString.value(),
std::make_format_args(v)
);
break;
}
case nlohmann::json::value_t::number_integer: {
const int v = value.get<int>();
_buffer = std::vformat(
_formatString.value(),
std::make_format_args(v)
);
break;
}
case nlohmann::json::value_t::number_unsigned: {
const unsigned v = value.get<unsigned>();
_buffer = std::vformat(
_formatString.value(),
std::make_format_args(v)
);
break;
}
case nlohmann::json::value_t::number_float: {
const double v = value.get<double>();
_buffer = std::vformat(
_formatString.value(),
std::make_format_args(v)
);
break;
}
case nlohmann::json::value_t::object:
case nlohmann::json::value_t::array: {
const std::string v = nlohmann::to_string(value);
_buffer = std::vformat(
_formatString.value(),
std::make_format_args(v)
);
break;
}
case nlohmann::json::value_t::binary: {
LWARNINGC(
"DashboardItemTimeVaryingText",
"Binary data is not supported"
);
break;
}
}
}
catch (const std::format_error&) {
LERRORC("DashboardItemTimeVaryingText", "Illegal format string");
@@ -154,8 +206,7 @@ void DashboardItemTimeVaryingText::loadDataFromJson(const std::string& filePath)
for (const nlohmann::json& item : jsonData["data"]) {
const std::string& timeString = item[0].get<std::string>();
double j2000Time = Time::convertTime(timeString);
double value = item[1].get<double>();
_data[j2000Time] = value;
_data[j2000Time] = item[1];
_startTimes.push_back(j2000Time);
}

View File

@@ -22,40 +22,42 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_BASE___DASHBOARDITEMTIMEVARYINGTEXT___H__
#define __OPENSPACE_MODULE_BASE___DASHBOARDITEMTIMEVARYINGTEXT___H__
#ifndef __OPENSPACE_MODULE_BASE___DASHBOARDITEMTIMEVARYINGTEXT___H__
#define __OPENSPACE_MODULE_BASE___DASHBOARDITEMTIMEVARYINGTEXT___H__
#include <openspace/rendering/dashboardtextitem.h>
#include <openspace/rendering/dashboardtextitem.h>
#include <openspace/properties/misc/stringproperty.h>
#include <openspace/properties/misc/stringproperty.h>
#include <openspace/json.h>
namespace openspace {
namespace openspace {
namespace documentation { struct Documentation; }
namespace documentation { struct Documentation; }
class DashboardItemTimeVaryingText : public DashboardTextItem {
public:
explicit DashboardItemTimeVaryingText(const ghoul::Dictionary& dictionary);
~DashboardItemTimeVaryingText() override = default;
class DashboardItemTimeVaryingText : public DashboardTextItem {
public:
explicit DashboardItemTimeVaryingText(const ghoul::Dictionary& dictionary);
~DashboardItemTimeVaryingText() override = default;
void update() override;
void update() override;
static documentation::Documentation Documentation();
static documentation::Documentation Documentation();
private:
void loadDataFromJson(const std::string& filePath);
void computeSequenceEndTime();
int updateActiveTriggerTimeIndex(double currentTime) const;
private:
void loadDataFromJson(const std::string& filePath);
void computeSequenceEndTime();
int updateActiveTriggerTimeIndex(double currentTime) const;
properties::StringProperty _formatString;
properties::StringProperty _dataFile;
properties::StringProperty _formatString;
properties::StringProperty _dataFile;
std::unordered_map<double, double> _data;
std::vector<double> _startTimes;
std::unordered_map<double, nlohmann::json> _data;
std::vector<double> _startTimes;
int _activeTriggerTimeIndex = -1;
double _sequenceEndTime = 0.0;
int _activeTriggerTimeIndex = -1;
double _sequenceEndTime = 0.0;
};
} // namespace openspace
} // namespace openspace
#endif // __OPENSPACE_MODULE_BASE___DASHBOARDITEMTIMEVARYINGTEXT___H__