Skip to content
Draft
Show file tree
Hide file tree
Changes from 6 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
2 changes: 2 additions & 0 deletions project/cmake/weblib/emcc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} \
-s EXPORTED_FUNCTIONS=[\
'_malloc',\
'_free',\
'_vizzu_createData',\
'_vizzu_createExternalData',\
'_vizzu_createChart',\
'_vizzu_createCanvas',\
'_vizzu_pointerDown',\
Expand Down
32 changes: 29 additions & 3 deletions src/apps/weblib/cinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ static_assert(offsetof(Point, y) == 8);
static_assert(offsetof(Value, dimension) == 0);
static_assert(offsetof(Value, measureValue) == 8);
static_assert(offsetof(Value, dimensionValue) == 8);
static_assert(sizeof(const char *) == 4);

constexpr std::uint_fast32_t hash(std::string_view s) noexcept
{
Expand Down Expand Up @@ -123,9 +124,34 @@ const char *vizzu_version() { return Interface::version(); }

void vizzu_setLogging(bool enable) { Interface::setLogging(enable); }

APIHandles::Chart vizzu_createChart()
APIHandles::DataTable vizzu_createData()
{
return Interface::getInstance().createChart();
return Interface::getInstance().createData();
}

APIHandles::DataTable vizzu_createExternalData(
void (*stringDeleter)(const char *),
bool (*seriesMeta)(const char *),
const char *(*seriesInfo)(const char *, const char *),
void (*aggregator)(APIHandles::DataTable,
bool (*)(const Vizzu::Data::RowWrapper *),
bool (*)(const Vizzu::Data::RowWrapper *),
std::uint32_t,
const char *const *,
std::uint32_t,
const char *const *,
const char *const *,
const char **),
void (*deleter)())
{
return Interface::getInstance().createExternalData(
{{stringDeleter, seriesMeta, seriesInfo, aggregator},
deleter});
}

APIHandles::Chart vizzu_createChart(APIHandles::DataTable data)
{
return Interface::getInstance().createChart(data);
}

APIHandles::Canvas vizzu_createCanvas()
Expand Down Expand Up @@ -295,7 +321,7 @@ const Value *record_getValue(const Vizzu::Data::RowWrapper *record,

void data_addDimension(APIHandles::Chart chart,
const char *name,
const char **categories,
const char *const *categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount,
Expand Down
20 changes: 18 additions & 2 deletions src/apps/weblib/cinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace APIHandles
{
using Any = const void *;
using Chart = const void *;
using DataTable = const void *;
using Snapshot = const void *;
using Event = Util::EventDispatcher::Params *;
using Animation = const void *;
Expand All @@ -39,7 +40,22 @@ struct alignas(double) Value
};
};

extern APIHandles::Chart vizzu_createChart();
extern APIHandles::DataTable vizzu_createData();
extern APIHandles::DataTable vizzu_createExternalData(
void (*stringDeleter)(const char *),
bool (*seriesMeta)(const char *),
const char *(*seriesInfo)(const char *, const char *),
void (*aggregator)(APIHandles::DataTable,
bool (*)(const Vizzu::Data::RowWrapper *),
bool (*)(const Vizzu::Data::RowWrapper *),
std::uint32_t,
const char *const *,
std::uint32_t,
const char *const *,
const char *const *,
const char **),
void (*deleter)());
extern APIHandles::Chart vizzu_createChart(APIHandles::DataTable);
extern APIHandles::Canvas vizzu_createCanvas();
extern void vizzu_pointerDown(APIHandles::Chart chart,
APIHandles::Canvas canvas,
Expand Down Expand Up @@ -79,7 +95,7 @@ extern const char *vizzu_version();

extern void data_addDimension(APIHandles::Chart chart,
const char *name,
const char **categories,
const char *const *categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount,
Expand Down
200 changes: 185 additions & 15 deletions src/apps/weblib/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include "cinterface.h"
#include "interfacejs.h"
#include "jscriptcanvas.h"
#include "jsfunctionwrapper.h"
#include "jswrappers.h"
#include "objectregistry.h"

namespace Vizzu
Expand Down Expand Up @@ -216,6 +216,12 @@ std::variant<double, const std::string *> Interface::getRecordValue(
return record.get_value(column);
}

std::shared_ptr<Data::DataTable> Interface::getTable(
ObjectRegistryHandle data)
{
return objects.get<Data::DataTable>(data);
}

void Interface::addEventListener(ObjectRegistryHandle chart,
const char *event,
void (*callback)(APIHandles::Event, const char *))
Expand Down Expand Up @@ -314,49 +320,214 @@ void Interface::setAnimValue(ObjectRegistryHandle chart,
getChart(chart)->getAnimOptions().set(path, value);
}

void Interface::addDimension(ObjectRegistryHandle chart,
void Interface::addDimension(ObjectRegistryHandle table,
const char *name,
const char **categories,
const char *const *categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount,
bool isContiguous)
{
getChart(chart)->getTable().add_dimension(
{categories, categoriesCount},
getTable(table)->add_dimension({categories, categoriesCount},
{categoryIndices, categoryIndicesCount},
name,
{{{"isContiguous", isContiguous ? "true" : "false"}}});
}

void Interface::addMeasure(ObjectRegistryHandle chart,
void Interface::addMeasure(ObjectRegistryHandle table,
const char *name,
const char *unit,
const double *values,
std::uint32_t count)
{
getChart(chart)->getTable().add_measure({values, count},
getTable(table)->add_measure({values, count},
name,
{{std::pair{"unit", unit}}});
}

void Interface::addRecord(ObjectRegistryHandle chart,
void Interface::addRecord(ObjectRegistryHandle table,
const char *const *cells,
std::uint32_t count)
{
getChart(chart)->getTable().add_record({cells, count});
getTable(table)->add_record({cells, count});
}

const char *Interface::dataMetaInfo(ObjectRegistryHandle chart)
const char *Interface::dataMetaInfo(ObjectRegistryHandle table)
{
thread_local std::string res;
res = getChart(chart)->getTable().as_string();
res = getTable(table)->as_string();
return res.c_str();
}

ObjectRegistryHandle Interface::createChart()
struct IntFDataTable final : Data::DataTable
{
JsCompositionWrapper<Interface::ExternalData> externalData;

[[nodiscard]] explicit IntFDataTable(
JsCompositionWrapper<Interface::ExternalData>
&&external_data) :
externalData(std::move(external_data))
{}

[[nodiscard]] dataframe::series_meta_t get_series_meta(
const std::string &id) const & override
{
return {id,
externalData.values.seriesMeta(id.c_str())
? dataframe::series_type::dimension
: dataframe::series_type::measure};
}

[[nodiscard]] std::string_view get_series_info(
const std::string &id,
const char *key) const & override
{
thread_local std::string res;
res = create_unique_ptr(
externalData.values.seriesInfo(id.c_str(), key),
externalData.values.stringDeleter)
.get();
return res;
}

[[noreturn]] static void unsupported()
{
throw std::logic_error("unsupported");
}

[[noreturn]] void add_dimension(std::span<const char *const>,
std::span<const std::uint32_t>,
std::string_view,
std::span<const std::pair<const char *, const char *>>,
dataframe::adding_type)
& override
{
unsupported();
}

[[noreturn]] void add_measure(std::span<const double>,
std::string_view,
std::span<const std::pair<const char *, const char *>>,
dataframe::adding_type)
& override
{
unsupported();
}

[[noreturn]] void add_record(std::span<const char *const>)
& override
{
unsupported();
}

[[nodiscard]] std::string as_string() const & override
{
unsupported();
}

[[nodiscard]] std::pair<
std::shared_ptr<dataframe::dataframe_interface>,
std::map<Data::SeriesIndex, std::string>>
aggregate(const Data::Filter &filter,
const std::set<Data::SeriesIndex> &aggregate_by,
const std::set<Data::SeriesIndex> &aggregating)
const & override
{
auto &intf = Interface::getInstance();
auto &&res = dataframe::dataframe::create_new();

std::vector<const char *> aggregateBy(aggregate_by.size());
std::ranges::transform(aggregate_by,
aggregateBy.begin(),
[](const Data::SeriesIndex &index)
{
return index.getColIndex().c_str();
});

std::vector<const char *> aggregatingCols(aggregating.size());
std::ranges::transform(aggregating,
aggregatingCols.begin(),
[](const Data::SeriesIndex &index)
{
return index.getColIndex().c_str();
});

using ArrType =
Refl::EnumArray<dataframe::aggregator_type, std::string>;
static ArrType arr = std::apply(
[](auto &&...names)
{
return ArrType{{std::string{names}...}};
},
Refl::enum_names<dataframe::aggregator_type>);

std::vector<const char *> aggregatingFun(aggregating.size());
std::ranges::transform(aggregating,
aggregatingFun.begin(),
[](const Data::SeriesIndex &index) -> const char *
{
return arr[index.getAggr()].c_str();
});

std::vector<
std::unique_ptr<const char, void (*)(const char *)>>
aggregatingNames;
aggregatingNames.reserve(aggregating.size());

{
std::vector<const char *> aggregatingRawNames(
aggregating.size());

externalData.values.aggregator(
create_unique_ptr(intf.createData(&res), &object_free)
.get(),
filter.getFun1(),
filter.getFun2(),
aggregateBy.size(),
aggregateBy.data(),
aggregating.size(),
aggregatingCols.data(),
aggregatingFun.data(),
aggregatingRawNames.data());

for (auto &&ptr : std::move(aggregatingRawNames))
aggregatingNames.emplace_back(ptr,
externalData.values.stringDeleter);
}

std::map<Data::SeriesIndex, std::string> resMap;
for (auto it = aggregatingNames.data();
auto &&agg : aggregating)
resMap[agg] = it++->get();

for (const auto &dim : aggregate_by)
res->set_sort(dim.getColIndex(),
dataframe::sort_type::less,
dataframe::na_position::first);

res->finalize();
return {res, resMap};
}
};

ObjectRegistryHandle Interface::createData(
std::shared_ptr<dataframe::dataframe_interface> *df)
{
return objects.reg(std::make_shared<Data::DataTableImpl>(
df ? *df : dataframe::dataframe::create_new()));
}

ObjectRegistryHandle Interface::createExternalData(
JsCompositionWrapper<ExternalData> &&externalData)
{
auto &&widget = std::make_shared<UI::ChartWidget>();
return objects.reg(
std::make_shared<IntFDataTable>(std::move(externalData)));
}

ObjectRegistryHandle Interface::createChart(ObjectRegistryHandle data)
{
auto &&widget = std::make_shared<UI::ChartWidget>(
objects.get<Data::DataTable>(data));

auto &openUrl = widget->openUrl;
auto &doChange = widget->getChart().onChanged;
Expand All @@ -380,8 +551,7 @@ ObjectRegistryHandle Interface::createChart()

ObjectRegistryHandle Interface::createCanvas()
{
return objects.reg(
std::make_shared<Vizzu::Main::JScriptCanvas>());
return objects.reg(std::make_shared<Main::JScriptCanvas>());
}

void Interface::setLogging(bool enable)
Expand Down
Loading