Skip to content

Commit 289ab7f

Browse files
authored
Merge branch 'main' into clang-tidy-fixes
2 parents f859520 + ef7a0e4 commit 289ab7f

File tree

12 files changed

+100
-107
lines changed

12 files changed

+100
-107
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
## [Unreleased]
44

5-
### Fixed
5+
### Fixed
66

77
- Area charts with data series started with zero: tooltip fixed.
8+
- Series whose contained ',' and aggregated were not working properly.
89

910
## [0.12.0] - 2024-07-29
1011

src/apps/weblib/ts-api/module/cchart.ts

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@ import { CString, CFunction, CEventPtr } from '../cvizzu.types'
33
import * as Anim from '../types/anim.js'
44
import * as Config from '../types/config.js'
55
import * as Styles from '../types/styles.js'
6-
import * as Data from '../types/data.js'
76

87
import { CManagedObject, CObject, CEnv } from './cenv.js'
98
import { CPointerClosure } from './objregistry.js'
109
import { CProxy } from './cproxy.js'
1110
import { CCanvas } from './ccanvas.js'
1211
import { CAnimation } from './canimctrl.js'
1312

14-
import { isIterable } from '../utils.js'
15-
1613
/** Stored Chart object. */
1714
export class Snapshot extends CManagedObject {}
1815

@@ -136,42 +133,15 @@ export class CChart extends CManagedObject {
136133
this._wasm._chart_getList,
137134
this._wasm._chart_getValue,
138135
this._wasm._chart_setValue,
139-
(value: unknown): value is Record<string, unknown> =>
140-
isIterable(value) && !this._isSeriesDescriptor(value),
141-
(value: unknown): string => {
142-
// workaround: we should be able to pass series descriptor as two string
143-
if (this._isSeriesDescriptor(value)) {
144-
return value.aggregator ? `${value.aggregator}(${value.name})` : value.name
145-
} else {
146-
return String(value).toString()
147-
}
148-
},
149136
(path: string, value: string): unknown => {
150137
// workaround because channel.*.set returns already json instead of scalars
151138
if (path.startsWith('channels.') && path.endsWith('.set')) {
152-
return JSON.parse(value).map((v: string) => this._toSeriesDescriptor(v))
139+
return JSON.parse(value)
153140
} else return value
154141
}
155142
)
156143
}
157144

158-
private _toSeriesDescriptor(value: string): Data.SeriesDescriptor {
159-
const pattern = /^(\w+)\((.*?)\)$/
160-
const match = value.match(pattern)
161-
if (match) {
162-
return {
163-
name: match[2]!,
164-
aggregator: match[1]! as Data.AggregatorType
165-
}
166-
} else {
167-
return { name: value }
168-
}
169-
}
170-
171-
private _isSeriesDescriptor(value: unknown): value is Data.SeriesDescriptor {
172-
return typeof value === 'object' && value !== null && 'name' in value
173-
}
174-
175145
private _makeStyle(computed: boolean): CStyle {
176146
return new CStyle(
177147
this.getId,

src/apps/weblib/ts-api/module/cproxy.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { CPointer, CString } from '../cvizzu.types'
22

33
import { CObject } from './cenv.js'
4-
import { mirrorObject, iterateObject, isIterable, type ShouldIterate } from '../utils.js'
4+
import { mirrorObject, iterateObject } from '../utils.js'
55
import { Mirrored } from '../tsutils.js'
66
import { CPointerClosure } from './objregistry.js'
77

@@ -13,8 +13,6 @@ export class CProxy<T> extends CObject {
1313
private _lister: Lister
1414
private _getter: Getter
1515
private _setter: Setter
16-
private _shouldIterate: ShouldIterate
17-
private _toString: (value: unknown) => string
1816
private _fromString: (path: string, str: string) => unknown
1917

2018
constructor(
@@ -23,21 +21,17 @@ export class CProxy<T> extends CObject {
2321
lister: Lister,
2422
getter: Getter,
2523
setter: Setter,
26-
shouldIterate?: ShouldIterate,
27-
toString?: (value: unknown) => string,
2824
fromString?: (path: string, str: string) => unknown
2925
) {
3026
super(getId, cenv)
3127
this._lister = lister
3228
this._getter = getter
3329
this._setter = setter
34-
this._shouldIterate = shouldIterate || isIterable
35-
this._toString = toString || ((value: unknown): string => String(value).toString())
3630
this._fromString = fromString || ((_path: string, str: string): unknown => str)
3731
}
3832

3933
set(value: T): void {
40-
iterateObject(value, this.setParam.bind(this), this._shouldIterate)
34+
iterateObject(value, this.setParam.bind(this))
4135
}
4236

4337
get(): Mirrored<T> {
@@ -64,7 +58,7 @@ export class CProxy<T> extends CObject {
6458

6559
setParam(path: string, value: unknown): void {
6660
const cpath = this._toCString(path)
67-
const cvalue = this._toCString(this._toString(value))
61+
const cvalue = this._toCString(String(value).toString())
6862
try {
6963
this._call(this._setter)(cpath, cvalue)
7064
} finally {

src/apps/weblib/ts-api/utils.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,18 @@ export function recursiveCopy<T>(value: T, Ignore?: new (...args: never[]) => un
2727
}
2828

2929
type Visitor = (path: string, value: unknown) => void
30-
export type ShouldIterate = (value: unknown) => value is Record<string, unknown>
3130

3231
export function isIterable(value: unknown): value is Record<string, unknown> {
3332
return typeof value === 'object' && value !== null
3433
}
3534

36-
export function iterateObject<T>(
37-
obj: T,
38-
paramHandler: Visitor,
39-
shouldIterate: ShouldIterate = isIterable,
40-
path: string = ''
41-
): void {
35+
export function iterateObject<T>(obj: T, paramHandler: Visitor, path: string = ''): void {
4236
if (obj && obj !== null && typeof obj === 'object') {
4337
Object.keys(obj).forEach((key) => {
4438
const newPath = path + (path.length === 0 ? '' : '.') + key
4539
const value = obj[key as keyof T]
46-
if (shouldIterate(value)) {
47-
iterateObject(value, paramHandler, shouldIterate, newPath)
40+
if (isIterable(value)) {
41+
iterateObject(value, paramHandler, newPath)
4842
} else {
4943
paramHandler(newPath, value)
5044
}

src/base/type/uniquelist.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ template <class T> class UniqueList
141141
return true;
142142
}
143143

144+
[[nodiscard]] T pop_back()
145+
{
146+
return extract(items.find(last->first)).key();
147+
}
148+
144149
[[nodiscard]] iterator<> begin() const noexcept
145150
{
146151
return {first};

src/chart/options/config.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,29 @@ void Config::setChannelParam(const std::string &path,
222222
if (parts.size() == 3 && value == "null")
223223
channel.reset();
224224
else {
225-
if (std::stoi(parts.at(3)) == 0) channel.reset();
226-
channel.addSeries({value, table});
225+
if (const std::string_view command =
226+
parts.size() == 4 ? std::string_view{"name"}
227+
: parts.at(4);
228+
command == "name") {
229+
if (std::stoi(parts.at(3)) == 0) channel.reset();
230+
if (value.empty()) { channel.measureId.emplace(); }
231+
else
232+
channel.addSeries({value, table});
233+
}
234+
else if (command == "aggregator") {
235+
if (value != "null") {
236+
if (!channel.measureId.has_value())
237+
channel.measureId.emplace(
238+
channel.dimensionIds.pop_back());
239+
240+
channel.measureId->setAggr(value);
241+
}
242+
else if (channel.measureId)
243+
channel.measureId->setAggr(
244+
channel.measureId->getColIndex().empty()
245+
? "count"
246+
: "sum");
247+
}
227248
}
228249
return;
229250
}
@@ -250,10 +271,8 @@ std::string Config::getChannelParam(const std::string &path) const
250271
if (property == "set") {
251272
std::string res;
252273
Conv::JSONArr arr{res};
253-
if (auto &&measure = channel.measureId)
254-
arr << measure->toString();
255-
for (auto &&dim : channel.dimensions())
256-
arr << dim.getColIndex();
274+
if (auto &&measure = channel.measureId) arr << *measure;
275+
for (auto &&dim : channel.dimensions()) arr << dim;
257276
return res;
258277
}
259278

src/dataframe/impl/data_source.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ enum class error_type : std::uint8_t {
2929
internal_error
3030
};
3131

32+
struct series_meta_t
33+
{
34+
std::string_view name;
35+
series_type type;
36+
};
37+
3238
[[maybe_unused]] [[noreturn]] void error(error_type err,
3339
std::string_view arg = {});
3440

src/dataframe/impl/dataframe.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,7 @@ std::string dataframe::get_record_id_by_dims(std::size_t my_record,
737737
return get_data_source().get_id(my_record, dimensions);
738738
}
739739

740-
dataframe::series_meta_t dataframe::get_series_meta(
741-
const std::string &id) const
740+
series_meta_t dataframe::get_series_meta(const std::string &id) const
742741
{
743742
switch (auto &&ser = get_data_source().get_series(id)) {
744743
using enum series_type;

src/dataframe/impl/dataframe.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,6 @@ class dataframe
117117
[[nodiscard]] std::span<const std::string> get_categories(
118118
const std::string_view &dimension) const &;
119119

120-
struct series_meta_t
121-
{
122-
std::string_view name;
123-
series_type type;
124-
};
125-
126120
[[nodiscard]] series_meta_t get_series_meta(
127121
const std::string &id) const;
128122

src/dataframe/old/datatable.cpp

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "base/text/funcstring.h"
2020
#include "chart/options/options.h"
2121
#include "chart/options/shapetype.h"
22+
#include "dataframe/impl/aggregators.h"
23+
#include "dataframe/impl/data_source.h"
2224
#include "dataframe/interface.h"
2325

2426
#include "types.h"
@@ -66,29 +68,21 @@ const MultiIndex &DataCube::iterator_t::operator*() const
6668
return index;
6769
}
6870

71+
SeriesIndex::SeriesIndex(dataframe::series_meta_t const &meta) :
72+
name{meta.name}
73+
{
74+
if (meta.type == dataframe::series_type::measure)
75+
aggregator.emplace(dataframe::aggregator_type::sum);
76+
}
77+
6978
SeriesIndex::SeriesIndex(std::string const &str,
7079
const DataTable &table) :
71-
orig_name(str)
80+
SeriesIndex(table.getDf().get_series_meta(str))
81+
{}
82+
83+
void SeriesIndex::setAggr(const std::string &aggr)
7284
{
73-
constinit static auto names =
74-
Refl::get_names<dataframe::aggregator_type>();
75-
if (const Text::FuncString func(str, false);
76-
!func.isEmpty()
77-
&& std::find(names.begin(), names.end(), func.getName())
78-
!= names.end()) {
79-
aggr = Refl::get_enum<dataframe::aggregator_type>(
80-
func.getName());
81-
if (!func.getParams().empty())
82-
sid = table.getDf()
83-
.get_series_meta(func.getParams().at(0))
84-
.name;
85-
}
86-
else {
87-
auto &&[s, type] = table.getDf().get_series_meta(str);
88-
sid = s;
89-
if (type == DataTable::Type::measure)
90-
aggr = dataframe::aggregator_type::sum;
91-
}
85+
aggregator = Refl::get_enum<dataframe::aggregator_type>(aggr);
9286
}
9387

9488
DataCube::iterator_t DataCube::begin() const

0 commit comments

Comments
 (0)