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

Add isContiguous to dimension #627

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Added

- Add 'isContiguous' property for dimension series

## [0.16.0] - 2024-11-28

### Fixed
Expand Down
6 changes: 4 additions & 2 deletions src/apps/weblib/cinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,16 @@ void data_addDimension(APIHandles::Chart chart,
const char **categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount)
std::uint32_t categoryIndicesCount,
bool isContiguous)
{
Interface::getInstance().addDimension(chart,
name,
categories,
categoriesCount,
categoryIndices,
categoryIndicesCount);
categoryIndicesCount,
isContiguous);
}

void data_addMeasure(APIHandles::Chart chart,
Expand Down
3 changes: 2 additions & 1 deletion src/apps/weblib/cinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ extern void data_addDimension(APIHandles::Chart chart,
const char **categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount);
std::uint32_t categoryIndicesCount,
bool isContiguous);
extern void data_addMeasure(APIHandles::Chart chart,
const char *name,
const char *unit,
Expand Down
23 changes: 12 additions & 11 deletions src/apps/weblib/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,13 +319,14 @@ void Interface::addDimension(ObjectRegistryHandle chart,
const char **categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount)
std::uint32_t categoryIndicesCount,
bool isContiguous)
{
if (categories) {
getChart(chart)->getTable().addColumn(name,
{categories, categoriesCount},
{categoryIndices, categoryIndicesCount});
}
getChart(chart)->getTable().add_dimension(
{categories, categoriesCount},
{categoryIndices, categoryIndicesCount},
name,
{{{"isContiguous", isContiguous ? "true" : "false"}}});
}

void Interface::addMeasure(ObjectRegistryHandle chart,
Expand All @@ -334,22 +335,22 @@ void Interface::addMeasure(ObjectRegistryHandle chart,
const double *values,
std::uint32_t count)
{
getChart(chart)->getTable().addColumn(name,
unit,
{values, count});
getChart(chart)->getTable().add_measure({values, count},
name,
{{std::pair{"unit", unit}}});
}

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

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

Expand Down
3 changes: 2 additions & 1 deletion src/apps/weblib/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ class Interface
const char **categories,
std::uint32_t categoriesCount,
const std::uint32_t *categoryIndices,
std::uint32_t categoryIndicesCount);
std::uint32_t categoryIndicesCount,
bool isContiguous);
void addMeasure(ObjectRegistryHandle chart,
const char *name,
const char *unit,
Expand Down
3 changes: 2 additions & 1 deletion src/apps/weblib/ts-api/cvizzu.types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ export interface CVizzu {
categories: CArrayPtr,
categoriesCount: number,
categoryIndices: CArrayPtr,
categoryIndicesCount: number
categoryIndicesCount: number,
isContiguous: boolean
): void
_data_addMeasure(
chart: CChartPtr,
Expand Down
39 changes: 29 additions & 10 deletions src/apps/weblib/ts-api/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,19 +83,25 @@ export class Data {

if (this._isIndexedDimension(series)) {
this._validateIndexedDimension(series)
this._addDimension(series.name, series.values ?? [], series.categories)
this._addDimension(
series.name,
series.values ?? [],
series.categories,
series.isContiguous ?? false
)
} else {
const values = series?.values ?? ([] as DataTypes[])
const seriesType = series?.type ?? this._detectType(values)

if (seriesType === 'dimension') {
if (this._isDetectedDimension(series, seriesType)) {
const { indexes, categories } = this._convertDimension(values)
this._addDimension(series.name, indexes, categories)
this._addDimension(series.name, indexes, categories, series.isContiguous ?? false)
} else if (this._isMeasure(series, seriesType)) {
if (!series.unit) series.unit = ''
this._addMeasure(series.name, series.unit, values)
} else {
throw new Error('invalid series type: ' + series.type)
const seriesBase = series as D.SeriesBase
throw new Error('invalid series type: ' + seriesBase.type)
}
}
}
Expand All @@ -107,11 +113,15 @@ export class Data {
return true
}

private _isDetectedDimension(series: D.Series, type: string | null): series is D.Dimension {
return (
type === 'dimension' ||
('isContiguous' in series && typeof series.isContiguous === 'boolean')
)
}

private _isMeasure(series: D.Series, type: string | null): series is D.Measure {
if (type === 'measure' || ('unit' in series && typeof series.unit === 'string')) {
return true
}
return false
return type === 'measure' || ('unit' in series && typeof series.unit === 'string')
}

private _validateIndexedDimension(series: D.IndexDimension): void {
Expand Down Expand Up @@ -151,7 +161,12 @@ export class Data {
return null
}

private _addDimension(name: string, indexes: number[], categories: string[]): void {
private _addDimension(
name: string,
indexes: number[],
categories: string[],
isContiguous: boolean
): void {
if (typeof name !== 'string') {
throw new Error('first parameter should be string')
}
Expand All @@ -164,6 +179,10 @@ export class Data {
throw new Error('third parameter should be an array')
}

if (typeof isContiguous !== 'boolean') {
throw new Error('fourth parameter should be boolean')
}

if (!this._isStringArray(categories)) {
throw new Error('third parameter should be an array of strings')
}
Expand All @@ -172,7 +191,7 @@ export class Data {
throw new Error('the measure index array element should be number')
}

this._cData.addDimension(name, indexes, categories)
this._cData.addDimension(name, indexes, categories, isContiguous)
}

private _isStringArray(values: unknown[]): values is string[] {
Expand Down
13 changes: 9 additions & 4 deletions src/apps/weblib/ts-api/module/cdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ export class CData extends CObject {
return { series: JSON.parse(info) }
}

addDimension(name: string, indexes: number[], categories: string[]): void {
addDimension(
name: string,
indexes: number[],
categories: string[],
isContiguous: boolean
): void {
const categoriesPointer = new Uint32Array(categories.length)
for (let i = 0; i < categories.length; i++) {
const categoryPointer = this._toCString(categories[i]!)
categoriesPointer[i] = categoryPointer
categoriesPointer[i] = this._toCString(categories[i]!)
}

const categoriesPointerArrayLen = categories.length * 4
Expand All @@ -66,7 +70,8 @@ export class CData extends CObject {
categoriesPtrArr,
categories.length,
indexesArr,
indexes.length
indexes.length,
isContiguous
)
} finally {
this._wasm._free(cname)
Expand Down
16 changes: 15 additions & 1 deletion src/apps/weblib/typeschema-api/data.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ definitions:
type: array
items:
$ref: DimensionValue
isContiguous:
description: |
If set to true, the dimension handled as a contiguous dimension
like timestamps.
type: boolean

IndexDimension:
$extends: SeriesBase
Expand Down Expand Up @@ -97,6 +102,11 @@ definitions:
type: array
items:
type: number
isContiguous:
description: |
If set to true, the dimension handled as a contiguous dimension
like timestamps.
type: boolean
required: [categories]

ImplicitStringDimension:
Expand Down Expand Up @@ -238,7 +248,11 @@ definitions:
length:
description: Count of values in the series.
type: number
required: [type, categories, length]
isContiguous:
description: |
The dimension handled as a contiguous dimension like timestamps.
type: boolean
required: [type, categories, length, isContiguous]

MeasureInfo:
$extends: SeriesBase
Expand Down
10 changes: 7 additions & 3 deletions src/base/conv/auto_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,15 @@ struct JSONObj : protected JSONRepeat<'{', '}'>
return std::move(*this);
}

template <class T> JSONObj &&mergeObj(const T &obj) &&
template <bool isStatic = true, class T>
JSONObj &mergeObj(const T &obj)
{
auto pre_size = json.size();

staticObj(obj);
if constexpr (isStatic)
staticObj(obj);
else
dynamicObj(obj);

json.pop_back();

Expand All @@ -351,7 +355,7 @@ struct JSONObj : protected JSONRepeat<'{', '}'>
else
was = true;

return std::move(*this);
return *this;
}
};

Expand Down
41 changes: 30 additions & 11 deletions src/chart/generator/plotbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,22 +93,39 @@ Buckets PlotBuilder::generateMarkers(std::size_t &mainBucketSize)
plot->markers.reserve(dataCube.df->get_record_count());
}

std::multimap<Marker::MarkerIndex, Options::MarkerInfoId> map;
for (auto &&[ix, mid] : plot->getOptions()->markersInfo)
map.emplace(mid, ix);
struct CmpBySec
{
[[nodiscard]] bool operator()(
const std::pair<const Options::MarkerInfoId,
Marker::MarkerIndex> &lhs,
const std::pair<const Options::MarkerInfoId,
Marker::MarkerIndex> &rhs) const
{
return lhs.second < rhs.second;
}
};

auto &&set =
std::multiset<std::reference_wrapper<
const std::pair<const Options::MarkerInfoId,
Marker::MarkerIndex>>,
CmpBySec>{plot->getOptions()->markersInfo.begin(),
plot->getOptions()->markersInfo.end()};

for (auto first = map.begin(); auto &&index : dataCube)
for (auto first = set.begin(); auto &&index : dataCube)
for (auto &marker =
plot->markers.emplace_back(*plot->getOptions(),
dataCube,
stats,
mainIds,
subIds,
index,
map.contains(index.marker_id));
first != map.end() && first->first == marker.idx;
first != set.end()
&& first->get().second == index.marker_id);
first != set.end()
&& first->get().second == index.marker_id;
++first)
plot->markersInfo.insert({first->second,
plot->markersInfo.insert({first->get().first,
Plot::MarkerInfo{Plot::MarkerInfoContent{marker}}});

if (!std::ranges::is_sorted(plot->markers, {}, &Marker::idx))
Expand Down Expand Up @@ -357,7 +374,8 @@ void PlotBuilder::calcLegendAndLabel(const Data::DataTable &dataTable)
calcLegend.title = dataCube.getName(*meas);
calcLegend.measure = {std::get<0>(stats.at(type)),
meas->getColIndex(),
dataTable.getUnit(meas->getColIndex()),
dataTable.get_series_info(meas->getColIndex(),
"unit"),
scale.step.getValue()};
}
}
Expand Down Expand Up @@ -398,8 +416,9 @@ void PlotBuilder::calcLegendAndLabel(const Data::DataTable &dataTable)
.at(ChannelId::label)
.measure())
plot->axises.label = {
::Anim::String{
std::string{dataTable.getUnit(meas->getColIndex())}},
::Anim::String{std::string{
dataTable.get_series_info(meas->getColIndex(),
"unit")}},
::Anim::String{meas->getColIndex()}};
}

Expand Down Expand Up @@ -428,7 +447,7 @@ void PlotBuilder::calcAxis(const Data::DataTable &dataTable,
else
axis.measure = {std::get<0>(stats.at(type)),
meas.getColIndex(),
dataTable.getUnit(meas.getColIndex()),
dataTable.get_series_info(meas.getColIndex(), "unit"),
scale.step.getValue()};
}
else {
Expand Down
2 changes: 1 addition & 1 deletion src/chart/main/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class Events
void appendToJSON(Conv::JSONObj &&jsonObj) const override
{
Element::appendToJSON(
std::move(jsonObj).mergeObj(properties));
std::move(jsonObj.mergeObj(properties)));
}
};

Expand Down
Loading