diff --git a/CHANGELOG.md b/CHANGELOG.md index 517dac372..dbc6170ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Added + +- Add 'isContiguous' property for dimension series + ## [0.16.0] - 2024-11-28 ### Fixed diff --git a/src/apps/weblib/cinterface.cpp b/src/apps/weblib/cinterface.cpp index 1c88e39e6..6b15ae9f5 100644 --- a/src/apps/weblib/cinterface.cpp +++ b/src/apps/weblib/cinterface.cpp @@ -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, diff --git a/src/apps/weblib/cinterface.h b/src/apps/weblib/cinterface.h index 7c78e8abd..1f0876d03 100644 --- a/src/apps/weblib/cinterface.h +++ b/src/apps/weblib/cinterface.h @@ -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, diff --git a/src/apps/weblib/interface.cpp b/src/apps/weblib/interface.cpp index 4b1261612..0eaef0b1b 100644 --- a/src/apps/weblib/interface.cpp +++ b/src/apps/weblib/interface.cpp @@ -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, @@ -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(); } diff --git a/src/apps/weblib/interface.h b/src/apps/weblib/interface.h index 7101ac75f..bda5f0760 100644 --- a/src/apps/weblib/interface.h +++ b/src/apps/weblib/interface.h @@ -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, diff --git a/src/apps/weblib/ts-api/cvizzu.types.d.ts b/src/apps/weblib/ts-api/cvizzu.types.d.ts index f66e4a130..a7d295b45 100644 --- a/src/apps/weblib/ts-api/cvizzu.types.d.ts +++ b/src/apps/weblib/ts-api/cvizzu.types.d.ts @@ -103,7 +103,8 @@ export interface CVizzu { categories: CArrayPtr, categoriesCount: number, categoryIndices: CArrayPtr, - categoryIndicesCount: number + categoryIndicesCount: number, + isContiguous: boolean ): void _data_addMeasure( chart: CChartPtr, diff --git a/src/apps/weblib/ts-api/data.ts b/src/apps/weblib/ts-api/data.ts index f3e3027ef..2da3963f8 100644 --- a/src/apps/weblib/ts-api/data.ts +++ b/src/apps/weblib/ts-api/data.ts @@ -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) } } } @@ -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 { @@ -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') } @@ -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') } @@ -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[] { diff --git a/src/apps/weblib/ts-api/module/cdata.ts b/src/apps/weblib/ts-api/module/cdata.ts index 4d865944c..c4876c293 100644 --- a/src/apps/weblib/ts-api/module/cdata.ts +++ b/src/apps/weblib/ts-api/module/cdata.ts @@ -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 @@ -66,7 +70,8 @@ export class CData extends CObject { categoriesPtrArr, categories.length, indexesArr, - indexes.length + indexes.length, + isContiguous ) } finally { this._wasm._free(cname) diff --git a/src/apps/weblib/typeschema-api/data.yaml b/src/apps/weblib/typeschema-api/data.yaml index 4ded1fe65..8035a008f 100644 --- a/src/apps/weblib/typeschema-api/data.yaml +++ b/src/apps/weblib/typeschema-api/data.yaml @@ -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 @@ -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: @@ -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 diff --git a/src/base/conv/auto_json.h b/src/base/conv/auto_json.h index 764c504bc..2ec693e7b 100644 --- a/src/base/conv/auto_json.h +++ b/src/base/conv/auto_json.h @@ -336,11 +336,15 @@ struct JSONObj : protected JSONRepeat<'{', '}'> return std::move(*this); } - template JSONObj &&mergeObj(const T &obj) && + template + JSONObj &mergeObj(const T &obj) { auto pre_size = json.size(); - staticObj(obj); + if constexpr (isStatic) + staticObj(obj); + else + dynamicObj(obj); json.pop_back(); @@ -351,7 +355,7 @@ struct JSONObj : protected JSONRepeat<'{', '}'> else was = true; - return std::move(*this); + return *this; } }; diff --git a/src/chart/generator/plotbuilder.cpp b/src/chart/generator/plotbuilder.cpp index 3b6fb2e34..cf4a90834 100644 --- a/src/chart/generator/plotbuilder.cpp +++ b/src/chart/generator/plotbuilder.cpp @@ -93,11 +93,26 @@ Buckets PlotBuilder::generateMarkers(std::size_t &mainBucketSize) plot->markers.reserve(dataCube.df->get_record_count()); } - std::multimap map; - for (auto &&[ix, mid] : plot->getOptions()->markersInfo) - map.emplace(mid, ix); + struct CmpBySec + { + [[nodiscard]] bool operator()( + const std::pair &lhs, + const std::pair &rhs) const + { + return lhs.second < rhs.second; + } + }; + + auto &&set = + std::multiset>, + 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, @@ -105,10 +120,12 @@ Buckets PlotBuilder::generateMarkers(std::size_t &mainBucketSize) 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)) @@ -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()}; } } @@ -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()}}; } @@ -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 { diff --git a/src/chart/main/events.h b/src/chart/main/events.h index 93db5de4d..db8a3ad72 100644 --- a/src/chart/main/events.h +++ b/src/chart/main/events.h @@ -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))); } }; diff --git a/src/dataframe/impl/dataframe.cpp b/src/dataframe/impl/dataframe.cpp index feece15d4..acdf385e3 100644 --- a/src/dataframe/impl/dataframe.cpp +++ b/src/dataframe/impl/dataframe.cpp @@ -204,8 +204,8 @@ void dataframe::add_dimension( std::span dimension_categories, std::span dimension_values, std::string_view name, - adding_type adding_strategy, - std::span> info) & + std::span> info, + adding_type adding_strategy) & { change_state_to(state_type::modifying, state_modification_reason::needs_series_type); @@ -276,8 +276,8 @@ void dataframe::add_dimension( void dataframe::add_measure(std::span measure_values, std::string_view name, - adding_type adding_strategy, - std::span> info) & + std::span> info, + adding_type adding_strategy) & { change_state_to(state_type::modifying, state_modification_reason::needs_series_type); @@ -656,17 +656,18 @@ std::string dataframe::as_string() const & default: error(error_type::series_not_found, name); case dimension: { const auto &[name, dim] = unsafe_get(ser); - obj("name", name)("type", "dimension")("unit", - "")("length", dim.values.size())("categories", - dim.categories); + obj("name", name)("type", "dimension")("length", + dim.values.size())("categories", dim.categories) + .mergeObj(dim.info); break; } case measure: { const auto &[name, mea] = unsafe_get(ser); auto &&[min, max] = mea.get_min_max(); - obj("name", name)("type", "measure")("unit", - mea.info.at("unit"))("length", mea.values.size()) - .nested("range")("min", min)("max", max); + obj("name", name)("type", "measure")("length", + mea.values.size()) + .nested("range")("min", min)("max", max) + .mergeObj(mea.info); break; } } diff --git a/src/dataframe/impl/dataframe.h b/src/dataframe/impl/dataframe.h index 73aba79a9..aa60cfdfe 100644 --- a/src/dataframe/impl/dataframe.h +++ b/src/dataframe/impl/dataframe.h @@ -69,15 +69,17 @@ class dataframe std::span dimension_categories, std::span dimension_values, std::string_view name, - adding_type adding_strategy, - std::span> info) - &; + std::span> info = + {}, + adding_type adding_strategy = + adding_type::create_or_override) &; void add_measure(std::span measure_values, std::string_view name, - adding_type adding_strategy, - std::span> info) - &; + std::span> info = + {}, + adding_type adding_strategy = + adding_type::create_or_override) &; void add_series_by_other(std::string_view curr_series, std::string_view name, diff --git a/src/dataframe/interface.cpp b/src/dataframe/interface.cpp index 90f1033e3..64823e549 100644 --- a/src/dataframe/interface.cpp +++ b/src/dataframe/interface.cpp @@ -66,26 +66,26 @@ void dataframe_interface::add_dimension( std::span dimension_categories, std::span dimension_values, std::string_view name, - adding_type adding_strategy, - std::span> info) & + std::span> info, + adding_type adding_strategy) & { as_impl(this).add_dimension(dimension_categories, dimension_values, name, - adding_strategy, - info); + info, + adding_strategy); } void dataframe_interface::add_measure( std::span measure_values, std::string_view name, - adding_type adding_strategy, - std::span> info) & + std::span> info, + adding_type adding_strategy) & { as_impl(this).add_measure(measure_values, name, - adding_strategy, - info); + info, + adding_strategy); } void dataframe_interface::add_series_by_other( diff --git a/src/dataframe/interface.h b/src/dataframe/interface.h index c2b868cc9..6c2233368 100644 --- a/src/dataframe/interface.h +++ b/src/dataframe/interface.h @@ -106,15 +106,13 @@ class alignas(align_impl) dataframe_interface std::span dimension_categories, std::span dimension_values, std::string_view name, - adding_type adding_strategy, - std::span> info) - &; + std::span> info, + adding_type adding_strategy) &; void add_measure(std::span measure_values, std::string_view name, - adding_type adding_strategy, - std::span> info) - &; + std::span> info, + adding_type adding_strategy) &; void add_series_by_other(std::string_view curr_series, std::string_view name, diff --git a/src/dataframe/old/datatable.cpp b/src/dataframe/old/datatable.cpp index d3baca7cf..cc2842cf8 100644 --- a/src/dataframe/old/datatable.cpp +++ b/src/dataframe/old/datatable.cpp @@ -27,35 +27,6 @@ namespace Vizzu::Data { - -void DataTable::addColumn(std::string_view name, - std::string_view unit, - const std::span &values) -{ - df.add_measure(values, - name.data(), - dataframe::adding_type::create_or_override, - {{std::pair{"unit", unit.data()}}}); -} - -void DataTable::addColumn(std::string_view name, - const std::span &categories, - const std::span &values) -{ - df.add_dimension(categories, - values, - name.data(), - dataframe::adding_type::create_or_override, - {}); -} - -void DataTable::pushRow(const std::span &cells) -{ - df.add_record(cells); -} - -std::string DataTable::getInfos() const { return df.as_string(); } - bool DataCube::iterator_t::operator!=(const iterator_t &other) const { return parent != other.parent; @@ -77,7 +48,7 @@ SeriesIndex::SeriesIndex(dataframe::series_meta_t const &meta) : SeriesIndex::SeriesIndex(std::string const &str, const DataTable &table) : - SeriesIndex(table.getDf().get_series_meta(str)) + SeriesIndex(table.get_series_meta(str)) {} void SeriesIndex::setAggr(const std::string &aggr) @@ -136,7 +107,7 @@ DataCube::DataCube(const DataTable &table, auto empty = dimensions.empty() && measures.empty(); df = {empty ? dataframe::dataframe::create_new() - : table.getDf().copy(false)}; + : table.copy(false)}; if (empty) { df->finalize(); @@ -241,12 +212,6 @@ const std::string &DataCube::getName( {seriesId.getColIndex(), seriesId.getAggr()}); } -std::string_view DataTable::getUnit( - std::string_view const &colIx) const -{ - return df.get_series_info(colIx, "unit"); -} - MarkerId DataCube::getId(const SeriesList &sl, const std::optional &ll, const MultiIndex &mi) const diff --git a/src/dataframe/old/datatable.h b/src/dataframe/old/datatable.h index 72aff2b0c..e9747f6ea 100644 --- a/src/dataframe/old/datatable.h +++ b/src/dataframe/old/datatable.h @@ -19,35 +19,6 @@ enum class ChannelId : std::uint8_t; namespace Vizzu::Data { -class DataTable -{ -public: - using Type = dataframe::series_type; - - void addColumn(std::string_view name, - std::string_view unit, - const std::span &values); - - void addColumn(std::string_view name, - const std::span &categories, - const std::span &values); - - void pushRow(const std::span &cells); - - [[nodiscard]] std::string_view getUnit( - std::string_view const &colIx) const; - - [[nodiscard]] std::string getInfos() const; - - [[nodiscard]] const dataframe::dataframe &getDf() const - { - return df; - } - -private: - dataframe::dataframe df; -}; - class DataCube { struct iterator_t; diff --git a/src/dataframe/old/types.h b/src/dataframe/old/types.h index 5684a7c2c..0613fe81a 100644 --- a/src/dataframe/old/types.h +++ b/src/dataframe/old/types.h @@ -10,12 +10,13 @@ namespace Vizzu::dataframe { struct series_meta_t; +class dataframe; } namespace Vizzu::Data { -class DataTable; +using DataTable = dataframe::dataframe; class DataCube; struct RowWrapper diff --git a/test/qtest/chart.cpp b/test/qtest/chart.cpp index 67079d446..151099f3f 100644 --- a/test/qtest/chart.cpp +++ b/test/qtest/chart.cpp @@ -26,13 +26,13 @@ void TestChart::prepareData() std::vector val{1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; auto &table = chart.getChart().getTable(); - table.addColumn("Cat1", - std::span(cat1), - std::array{0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u}); - table.addColumn("Cat2", - std::span(cat2), - std::array{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u}); - table.addColumn("Val", "", std::span(val)); + table.add_dimension(cat1, + std::array{0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u}, + "Cat1"); + table.add_dimension(cat2, + std::array{0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u}, + "Cat2"); + table.add_measure(val, "Val"); chart.getChart() .getEventDispatcher() diff --git a/test/unit/chart/events.cpp b/test/unit/chart/events.cpp index abb55ce36..b48f9cba8 100644 --- a/test/unit/chart/events.cpp +++ b/test/unit/chart/events.cpp @@ -58,41 +58,40 @@ struct MyCanvas final : Gfx::ICanvas, Vizzu::Draw::Painter auto testcase_0 = [](Vizzu::Data::DataTable &table) { - table.addColumn("Index", - std::initializer_list{}, - std::initializer_list{}); - table.addColumn("x", "", std::initializer_list{}); - table.addColumn("y", "", std::initializer_list{}); + table.add_dimension(std::initializer_list{}, + std::initializer_list{}, + "Index"); + table.add_measure(std::initializer_list{}, "x"); + table.add_measure(std::initializer_list{}, "y"); }; auto testcase_1 = [](Vizzu::Data::DataTable &table) { - table.addColumn("Dim5", - {{"A", "B", "C", "D", "E"}}, - {{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4}}); - table.addColumn("Dim2", - {{"a", "b"}}, - {{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}); - table.addColumn("Dim3", - {{"a", "b", "c"}}, - {{0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 0, 2, 2, 1, 0}}); - table.addColumn("Meas1", - "", - {{1, 2, 4, 3, 3, 4, 2, 1, 4, 3, 1, 2, 2, 1, 3, 4}}); - table.addColumn("Meas2", - "", - {{0, -1, 5, 6, 6, 5, -1, 0, 5, 6, 0, -1, -1, 0, 6, -5}}); + table.add_dimension({{"A", "B", "C", "D", "E"}}, + {{0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4}}, + "Dim5"); + table.add_dimension({{"a", "b"}}, + {{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}, + "Dim2"); + table.add_dimension({{"a", "b", "c"}}, + {{0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 0, 2, 2, 1, 0}}, + "Dim3"); + table.add_measure( + {{1, 2, 4, 3, 3, 4, 2, 1, 4, 3, 1, 2, 2, 1, 3, 4}}, + "Meas1"); + table.add_measure( + {{0, -1, 5, 6, 6, 5, -1, 0, 5, 6, 0, -1, -1, 0, 6, -5}}, + "Meas2"); }; auto testcase_2 = [](Vizzu::Data::DataTable &table) { - table.addColumn("Channel title for long names", - {{ - "Long name wich has no end", - R"(Raw + table.add_dimension({{ + "Long name wich has no end", + R"(Raw break)", - R"(キャラクターセット)", - }}, + R"(キャラクターセット)", + }}, {{0, 0, 0, @@ -140,20 +139,20 @@ break)", 2, 2, 2, - 2}}); - - table.addColumn("Childs of long names which have no end", - {{"Very long label of this element", - "", - "It is also long enough", - "Short one", - "Jap", - "キャラクターセット", - R"(Raw + 2}}, + "Channel title for long names"); + + table.add_dimension({{"Very long label of this element", + "", + "It is also long enough", + "Short one", + "Jap", + "キャラクターセット", + R"(Raw break)", - "h", - "i", - "j"}}, + "h", + "i", + "j"}}, {{ 0, 1, @@ -196,58 +195,58 @@ break)", 8, 9, - }}); - - table.addColumn("値3", - "", - {{639, - 354, - 278, - 312, - 1241, - 1512, - 863, - 789, - 765, - 653, - 542, - 497, - 673, - 412, - 308, - 345, - 1329, - 1671, - 962, - 821, - 798, - 681, - 584, - 518, - 706, - 432, - 326, - 358, - 1382, - 1715, - 1073, - 912, - 821, - 721, - 618, - 542, - 721, - 462, - 372, - 367, - 1404, - 1729, - 1142, - 941, - 834, - 778, - 651, - 598}}); + }}, + "Childs of long names which have no end"); + + table.add_measure({{639, + 354, + 278, + 312, + 1241, + 1512, + 863, + 789, + 765, + 653, + 542, + 497, + 673, + 412, + 308, + 345, + 1329, + 1671, + 962, + 821, + 798, + 681, + 584, + 518, + 706, + 432, + 326, + 358, + 1382, + 1715, + 1073, + 912, + 821, + 721, + 618, + 542, + 721, + 462, + 372, + 367, + 1404, + 1729, + 1142, + 941, + 834, + 778, + 651, + 598}}, + "値3"); }; struct chart_setup