UI: Refactoring units models; Add new units acceleration, angle, area, angular-acceleration
This commit is contained in:
parent
6d2d07da24
commit
cfcb16a61b
@ -21,12 +21,11 @@ import { isDefinedAndNotNull, isUndefinedOrNull } from '@core/utils';
|
||||
|
||||
export interface Conversion<
|
||||
TMeasures extends string,
|
||||
TSystems extends string,
|
||||
TUnits extends string,
|
||||
> {
|
||||
abbr: TUnits;
|
||||
measure: TMeasures;
|
||||
system: TSystems;
|
||||
system: UnitSystem;
|
||||
unit: Unit;
|
||||
}
|
||||
|
||||
@ -39,10 +38,10 @@ export interface Conversion<
|
||||
|
||||
type Entries<T, S extends keyof T> = [S, T[keyof T]];
|
||||
|
||||
export type UnitCache<TMeasures, TSystems, TUnits> = Map<
|
||||
export type UnitCache<TMeasures, TUnits> = Map<
|
||||
string,
|
||||
{
|
||||
system: TSystems;
|
||||
system: UnitSystem;
|
||||
measure: TMeasures;
|
||||
unit: Unit;
|
||||
abbr: TUnits;
|
||||
@ -51,14 +50,13 @@ export type UnitCache<TMeasures, TSystems, TUnits> = Map<
|
||||
|
||||
export class Converter<
|
||||
TMeasures extends AllMeasures,
|
||||
TSystems extends UnitSystem,
|
||||
TUnits extends string,
|
||||
> {
|
||||
private measureData: Record<TMeasures, TbMeasure<TSystems, TUnits>>;
|
||||
private readonly measureData: Record<TMeasures, TbMeasure<TUnits>>;
|
||||
private unitCache: Map<
|
||||
string,
|
||||
{
|
||||
system: TSystems;
|
||||
system: UnitSystem;
|
||||
measure: TMeasures;
|
||||
unit: Unit;
|
||||
abbr: TUnits;
|
||||
@ -66,8 +64,8 @@ export class Converter<
|
||||
>;
|
||||
|
||||
constructor(
|
||||
measures: Record<TMeasures, TbMeasure<TSystems, TUnits>>,
|
||||
unitCache: UnitCache<TMeasures, TSystems, TUnits>
|
||||
measures: Record<TMeasures, TbMeasure<TUnits>>,
|
||||
unitCache: UnitCache<TMeasures, TUnits>
|
||||
) {
|
||||
this.measureData = measures;
|
||||
this.unitCache = unitCache;
|
||||
@ -96,18 +94,8 @@ export class Converter<
|
||||
|
||||
if (origin.system !== destination.system) {
|
||||
const measure = this.measureData[origin.measure];
|
||||
const anchors = measure.anchors;
|
||||
if (!anchors) {
|
||||
throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`);
|
||||
}
|
||||
|
||||
const anchor = anchors[origin.system];
|
||||
if (!anchor) {
|
||||
throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`);
|
||||
}
|
||||
|
||||
const transform = anchor[destination.system]?.transform;
|
||||
const ratio = anchor[destination.system]?.ratio;
|
||||
const transform = measure[origin.system]?.transform;
|
||||
const ratio = measure[origin.system]?.ratio;
|
||||
|
||||
if (typeof transform === 'function') {
|
||||
result = transform(result);
|
||||
@ -146,16 +134,8 @@ export class Converter<
|
||||
}
|
||||
if (origin.system !== destination.system) {
|
||||
const measure = this.measureData[origin.measure];
|
||||
const anchors = measure.anchors;
|
||||
if (!anchors) {
|
||||
throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`);
|
||||
}
|
||||
const anchor = anchors[origin.system];
|
||||
if (!anchor) {
|
||||
throw Error(`Unable to convert units. Anchors are missing for "${origin.measure}" and "${destination.measure}" measures.`);
|
||||
}
|
||||
const transform = anchor[destination.system]?.transform;
|
||||
const ratio = anchor[destination.system]?.ratio;
|
||||
const transform = measure[origin.system]?.transform;
|
||||
const ratio = measure[origin.system]?.ratio;
|
||||
if (typeof transform === 'function') {
|
||||
result = transform(result);
|
||||
} else if (typeof ratio === 'number') {
|
||||
@ -234,7 +214,7 @@ export class Converter<
|
||||
// return best;
|
||||
// }
|
||||
|
||||
getUnit(abbr: TUnits | (string & {})): Conversion<TMeasures, TSystems, TUnits> | null {
|
||||
getUnit(abbr: TUnits | (string & {})): Conversion<TMeasures, TUnits> | null {
|
||||
return this.unitCache.get(abbr) ?? null;
|
||||
}
|
||||
|
||||
@ -247,7 +227,7 @@ export class Converter<
|
||||
return null;
|
||||
}
|
||||
|
||||
private describeUnit(unit: Conversion<TMeasures, TSystems, TUnits>): UnitDescription {
|
||||
private describeUnit(unit: Conversion<TMeasures, TUnits>): UnitDescription {
|
||||
return {
|
||||
abbr: unit.abbr,
|
||||
measure: unit.measure,
|
||||
@ -268,11 +248,11 @@ export class Converter<
|
||||
const measure = this.measureData[measureName];
|
||||
if (isDefinedAndNotNull(unitSystem)) {
|
||||
let currentUnitSystem = unitSystem;
|
||||
let units = measure.systems[currentUnitSystem];
|
||||
let units = measure[currentUnitSystem];
|
||||
if (isUndefinedOrNull(units)) {
|
||||
if (currentUnitSystem === UnitSystem.IMPERIAL) {
|
||||
currentUnitSystem = UnitSystem.METRIC;
|
||||
units = measure.systems[currentUnitSystem];
|
||||
units = measure[currentUnitSystem];
|
||||
}
|
||||
if (!units) {
|
||||
console.log(`Measure "${measureName}" in ${currentUnitSystem} system is not found.`);
|
||||
@ -280,29 +260,29 @@ export class Converter<
|
||||
}
|
||||
}
|
||||
for (const [abbr, unit] of Object.entries(
|
||||
units
|
||||
units.units
|
||||
)) {
|
||||
list.push(
|
||||
this.describeUnit({
|
||||
abbr: abbr as TUnits,
|
||||
measure: measureName as TMeasures,
|
||||
system: currentUnitSystem as TSystems,
|
||||
system: currentUnitSystem,
|
||||
unit: unit as Unit,
|
||||
})
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (const [systemName, units] of Object.entries(
|
||||
(measure as TbMeasure<TSystems, TUnits>).systems
|
||||
)) {
|
||||
measure
|
||||
) as Entries<TbMeasure<TUnits>, UnitSystem>[]) {
|
||||
for (const [abbr, unit] of Object.entries(
|
||||
units as Partial<Record<TUnits, Unit>>
|
||||
units.units as Partial<Record<TUnits, Unit>>
|
||||
)) {
|
||||
list.push(
|
||||
this.describeUnit({
|
||||
abbr: abbr as TUnits,
|
||||
measure: measureName as TMeasures,
|
||||
system: systemName as TSystems,
|
||||
system: systemName,
|
||||
unit: unit as Unit,
|
||||
})
|
||||
);
|
||||
@ -313,11 +293,11 @@ export class Converter<
|
||||
for (const [name, measure] of Object.entries(this.measureData)) {
|
||||
if (isDefinedAndNotNull(unitSystem)) {
|
||||
let currentUnitSystem = unitSystem;
|
||||
let units = (measure as TbMeasure<TSystems, TUnits>).systems[currentUnitSystem];
|
||||
let units = (measure as TbMeasure<TUnits>)[currentUnitSystem]?.units;
|
||||
if (isUndefinedOrNull(units)) {
|
||||
if (currentUnitSystem === UnitSystem.IMPERIAL) {
|
||||
currentUnitSystem = UnitSystem.METRIC;
|
||||
units = (measure as TbMeasure<TSystems, TUnits>).systems[currentUnitSystem];
|
||||
units = (measure as TbMeasure<TUnits>)[currentUnitSystem]?.units;
|
||||
}
|
||||
if (!units) {
|
||||
console.log(`Measure "${measureName}" in ${currentUnitSystem} system is not found.`);
|
||||
@ -331,23 +311,23 @@ export class Converter<
|
||||
this.describeUnit({
|
||||
abbr: abbr as TUnits,
|
||||
measure: name as TMeasures,
|
||||
system: currentUnitSystem as TSystems,
|
||||
system: currentUnitSystem,
|
||||
unit: unit as Unit,
|
||||
})
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (const [systemName, units] of Object.entries(
|
||||
(measure as TbMeasure<TSystems, TUnits>).systems
|
||||
)) {
|
||||
measure
|
||||
) as Entries<TbMeasure<TUnits>, UnitSystem>[]) {
|
||||
for (const [abbr, unit] of Object.entries(
|
||||
units as Partial<Record<TUnits, Unit>>
|
||||
units.units as Partial<Record<TUnits, Unit>>
|
||||
)) {
|
||||
list.push(
|
||||
this.describeUnit({
|
||||
abbr: abbr as TUnits,
|
||||
measure: name as TMeasures,
|
||||
system: systemName as TSystems,
|
||||
system: systemName,
|
||||
unit: unit as Unit,
|
||||
})
|
||||
);
|
||||
@ -397,21 +377,20 @@ export class Converter<
|
||||
|
||||
export function buildUnitCache<
|
||||
TMeasures extends string,
|
||||
TSystems extends UnitSystem,
|
||||
TUnits extends string,
|
||||
>(measures: Record<TMeasures, TbMeasure<TSystems, TUnits>>,
|
||||
>(measures: Record<TMeasures, TbMeasure<TUnits>>,
|
||||
translate: TranslateService
|
||||
) {
|
||||
const unitCache: UnitCache<TMeasures, TSystems, TUnits> = new Map();
|
||||
const unitCache: UnitCache<TMeasures, TUnits> = new Map();
|
||||
for (const [measureName, measure] of Object.entries(measures) as Entries<
|
||||
typeof measures,
|
||||
TMeasures
|
||||
>[]) {
|
||||
for (const [systemName, system] of Object.entries(
|
||||
measure.systems
|
||||
) as Entries<Record<TSystems, Record<TUnits, Unit>>, TSystems>[]) {
|
||||
for (const [testAbbr, unit] of Object.entries(system) as Entries<
|
||||
typeof system,
|
||||
measure
|
||||
) as Entries<TbMeasure<TUnits>, UnitSystem>[]) {
|
||||
for (const [testAbbr, unit] of Object.entries(system.units) as Entries<
|
||||
Record<TUnits, Unit>,
|
||||
TUnits
|
||||
>[]) {
|
||||
unit.name = translate.instant(unit.name);
|
||||
@ -429,16 +408,15 @@ export function buildUnitCache<
|
||||
|
||||
export function configureMeasurements<
|
||||
TMeasures extends AllMeasures,
|
||||
TSystems extends UnitSystem,
|
||||
TUnits extends string,
|
||||
>(
|
||||
measures: Record<TMeasures, TbMeasure<TSystems, TUnits>>,
|
||||
measures: Record<TMeasures, TbMeasure<TUnits>>,
|
||||
translate: TranslateService
|
||||
): Converter<TMeasures, TSystems, TUnits> {
|
||||
): Converter<TMeasures, TUnits> {
|
||||
if (typeof measures !== 'object') {
|
||||
throw new TypeError('The measures argument needs to be an object');
|
||||
}
|
||||
|
||||
const unitCache = buildUnitCache(measures, translate);
|
||||
return new Converter<TMeasures, TSystems, TUnits>(measures, unitCache);
|
||||
return new Converter<TMeasures, TUnits>(measures, unitCache);
|
||||
}
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
///
|
||||
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models';
|
||||
|
||||
export type AccelerationMetricUnits = 'G' | 'm/s²' | 'km/h²' | 'Gal';
|
||||
export type AccelerationImperialUnits = 'ft/s²';
|
||||
|
||||
export type AccelerationUnits = AccelerationMetricUnits | AccelerationImperialUnits;
|
||||
|
||||
const METRIC: TbMeasureUnits<AccelerationMetricUnits> = {
|
||||
ratio: 3.28084,
|
||||
units: {
|
||||
'G': {
|
||||
name: 'unit.g-force',
|
||||
tags: ['acceleration', 'gravity', 'g-force', 'load', 'G'],
|
||||
to_anchor: 9.80665,
|
||||
},
|
||||
'm/s²': {
|
||||
name: 'unit.meters-per-second-squared',
|
||||
tags: ['peak', 'peak to peak', 'root mean square (RMS)', 'vibration', 'meters per second squared', 'm/s²'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
'Gal': {
|
||||
name: 'unit.gal',
|
||||
tags: ['acceleration', 'gravity', 'g-force', 'Gal'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
'km/h²': {
|
||||
name: 'unit.kilometer-per-hour-squared',
|
||||
tags: ['acceleration', 'rate of change of velocity', 'kilometer per hour squared', 'km/h²'],
|
||||
to_anchor: 1 / 12960,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const IMPERIAL: TbMeasureUnits<AccelerationImperialUnits> = {
|
||||
ratio: 1 / 3.28084,
|
||||
units: {
|
||||
'ft/s²': {
|
||||
name: 'unit.foot-per-second-squared',
|
||||
tags: ['acceleration', 'rate of change of velocity', 'foot per second squared', 'ft/s²'],
|
||||
to_anchor: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const measure: TbMeasure<AccelerationUnits> = {
|
||||
METRIC,
|
||||
IMPERIAL
|
||||
};
|
||||
|
||||
export default measure;
|
||||
@ -14,24 +14,38 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import temperature, {
|
||||
TemperatureUnits,
|
||||
} from './temperature';
|
||||
import { TbMeasure } from '@shared/models/unit.models';
|
||||
import acceleration, { AccelerationUnits } from '@core/services/unit/definitions/acceleration';
|
||||
import angle, { AngleUnits } from '@core/services/unit/definitions/angle';
|
||||
import angularAcceleration, { AngularAccelerationUnits } from '@core/services/unit/definitions/angular-acceleration';
|
||||
import area, { AreaUnits } from '@core/services/unit/definitions/area';
|
||||
import temperature, { TemperatureUnits } from './temperature';
|
||||
import time, { TimeUnits } from './time';
|
||||
import { TbMeasure, UnitSystem } from '@shared/models/unit.models';
|
||||
|
||||
export type AllMeasuresUnits =
|
||||
| AccelerationUnits
|
||||
| AngleUnits
|
||||
| AngularAccelerationUnits
|
||||
| AreaUnits
|
||||
| TemperatureUnits
|
||||
| TimeUnits;
|
||||
|
||||
export type AllMeasures =
|
||||
| 'acceleration'
|
||||
| 'angle'
|
||||
| 'angularAcceleration'
|
||||
| 'area'
|
||||
| 'temperature'
|
||||
| 'time';
|
||||
|
||||
const allMeasures: Record<
|
||||
AllMeasures,
|
||||
TbMeasure<UnitSystem, AllMeasuresUnits>
|
||||
TbMeasure<AllMeasuresUnits>
|
||||
> = {
|
||||
acceleration,
|
||||
angle,
|
||||
angularAcceleration,
|
||||
area,
|
||||
temperature,
|
||||
time,
|
||||
};
|
||||
|
||||
67
ui-ngx/src/app/core/services/unit/definitions/angle.ts
Normal file
67
ui-ngx/src/app/core/services/unit/definitions/angle.ts
Normal file
@ -0,0 +1,67 @@
|
||||
///
|
||||
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models';
|
||||
|
||||
export type AngleUnits = AngleSIUnits;
|
||||
|
||||
export type AngleSIUnits = 'rad' | 'deg' | 'grad' | 'arcmin' | 'arcsec' | 'mil' | 'rev';
|
||||
|
||||
const METRIC: TbMeasureUnits<AngleSIUnits> = {
|
||||
units: {
|
||||
rad: {
|
||||
name: 'unit.rad',
|
||||
tags: ['angle', 'radian', 'radians', 'rad'],
|
||||
to_anchor: 180 / Math.PI,
|
||||
},
|
||||
deg: {
|
||||
name: 'unit.degree',
|
||||
tags: ['angle', 'degree', 'degrees', 'deg'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
grad: {
|
||||
name: 'unit.gradian',
|
||||
tags: ['angle', 'gradian', 'grades', 'grad'],
|
||||
to_anchor: 9 / 10,
|
||||
},
|
||||
arcmin: {
|
||||
name: 'unit.arcminute',
|
||||
tags: ['angle', 'arcminute', 'arcminutes', 'arcmin'],
|
||||
to_anchor: 1 / 60
|
||||
},
|
||||
arcsec: {
|
||||
name: 'unit.arcsecond',
|
||||
tags: ['angle', 'arcsecond', 'arcseconds', 'arcsec'],
|
||||
to_anchor: 1 / 3600
|
||||
},
|
||||
mil: {
|
||||
name: 'unit.mil',
|
||||
tags: ['angle', 'military angle', 'angular mil', 'mil'],
|
||||
to_anchor: 9 / (50 * Math.PI),
|
||||
},
|
||||
rev: {
|
||||
name: 'revolution',
|
||||
tags: ['angle', 'revolution', 'full circle', 'complete turn', 'rev'],
|
||||
to_anchor: 360,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const measure: TbMeasure<AngleUnits> = {
|
||||
METRIC,
|
||||
};
|
||||
|
||||
export default measure;
|
||||
@ -0,0 +1,51 @@
|
||||
///
|
||||
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models';
|
||||
|
||||
export type AngularAccelerationMetricUnits = 'rad/s²';
|
||||
export type AngularAccelerationImperialUnits = 'rpm/s';
|
||||
|
||||
export type AngularAccelerationUnits = AngularAccelerationMetricUnits | AngularAccelerationImperialUnits;
|
||||
|
||||
const METRIC: TbMeasureUnits<AngularAccelerationMetricUnits> = {
|
||||
ratio: 30 / Math.PI,
|
||||
units: {
|
||||
'rad/s²': {
|
||||
name: 'unit.radian-per-second-squared',
|
||||
tags: ['angular acceleration', 'rotation rate of change', 'rad/s²'],
|
||||
to_anchor: 1,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const IMPERIAL: TbMeasureUnits<AngularAccelerationImperialUnits> = {
|
||||
ratio: Math.PI / 30,
|
||||
units: {
|
||||
'rpm/s': {
|
||||
name: 'unit.revolutions-per-minute-per-second',
|
||||
tags: ['angular acceleration', 'rotation rate of change', 'rpm/s'],
|
||||
to_anchor: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const measure: TbMeasure<AngularAccelerationUnits> = {
|
||||
METRIC,
|
||||
IMPERIAL
|
||||
};
|
||||
|
||||
export default measure;
|
||||
101
ui-ngx/src/app/core/services/unit/definitions/area.ts
Normal file
101
ui-ngx/src/app/core/services/unit/definitions/area.ts
Normal file
@ -0,0 +1,101 @@
|
||||
///
|
||||
/// Copyright © 2016-2025 The Thingsboard Authors
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models';
|
||||
|
||||
export type AreaMetricUnits = 'mm²' | 'cm²' | 'm²' | 'a' | 'ha' | 'km²';
|
||||
export type AreaImperialUnits = 'in²' | 'yd²' | 'ft²' | 'ac' | 'ml²' | 'cin';
|
||||
|
||||
export type AreaUnits = AreaMetricUnits | AreaImperialUnits;
|
||||
|
||||
const METRIC: TbMeasureUnits<AreaMetricUnits> = {
|
||||
ratio: 10.7639,
|
||||
units: {
|
||||
'mm²': {
|
||||
name: 'unit.square-millimeter',
|
||||
tags: ['area','lot','zone','space','region','square millimeter','square millimeters','mm²','sq-mm'],
|
||||
to_anchor: 1 / 1000000,
|
||||
},
|
||||
'cm²': {
|
||||
name: 'unit.square-centimeter',
|
||||
tags: ['area','lot','zone','space','region','square centimeter','square centimeters','cm²','sq-cm'],
|
||||
to_anchor: 1 / 10000,
|
||||
},
|
||||
'm²': {
|
||||
name: 'unit.square-meter',
|
||||
tags: ['area','lot','zone','space','region','square meter','square meters','m²','sq-m'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
a: {
|
||||
name: 'unit.are',
|
||||
tags: ['area','land measurement','are'],
|
||||
to_anchor: 100,
|
||||
},
|
||||
ha: {
|
||||
name: 'unit.hectare',
|
||||
tags: ['area','lot','zone','space','region','hectare','hectares','ha'],
|
||||
to_anchor: 10000,
|
||||
},
|
||||
'km²': {
|
||||
name: 'unit.square-kilometer',
|
||||
tags: ['area','lot','zone','space','region','square kilometer','square kilometers','km²','sq-km'],
|
||||
to_anchor: 1000000,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const IMPERIAL: TbMeasureUnits<AreaImperialUnits> = {
|
||||
ratio: 1 / 10.7639,
|
||||
units: {
|
||||
'in²': {
|
||||
name: 'unit.square-inch',
|
||||
tags: ['area','lot','zone','space','region','square inch','square inches','in²','sq-in'],
|
||||
to_anchor: 1 / 144,
|
||||
},
|
||||
'yd²': {
|
||||
name: 'unit.square-yard',
|
||||
tags: ['area','lot','zone','space','region','square yard','square yards','yd²','sq-yd'],
|
||||
to_anchor: 9,
|
||||
},
|
||||
'ft²': {
|
||||
name: 'unit.square-foot',
|
||||
tags: ['area','lot','zone','space','region','square foot','square feet','ft²','sq-ft'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
ac: {
|
||||
name: 'unit.acre',
|
||||
tags: ['area','lot','zone','space','region','acre','acres','a'],
|
||||
to_anchor: 43560,
|
||||
},
|
||||
'ml²': {
|
||||
name: 'unit.square-mile',
|
||||
tags: ['area','lot','zone','space','region','square mile','square miles','ml²','sq-mi'],
|
||||
to_anchor: 27878400,
|
||||
},
|
||||
cin: {
|
||||
name: 'unit.circular-inch',
|
||||
tags: ['area','circular measurement','circular inch','circin'],
|
||||
to_anchor: Math.PI / 576
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const measure: TbMeasure<AreaUnits> = {
|
||||
METRIC,
|
||||
IMPERIAL
|
||||
};
|
||||
|
||||
export default measure;
|
||||
@ -14,7 +14,7 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { TbMeasure, Unit, UnitSystem } from '@shared/models/unit.models';
|
||||
import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models';
|
||||
|
||||
export type TemperatureMetricUnits = '°C' | 'K';
|
||||
export type TemperatureImperialUnits = '°F' | '°R';
|
||||
@ -23,55 +23,43 @@ export type TemperatureUnits =
|
||||
| TemperatureMetricUnits
|
||||
| TemperatureImperialUnits;
|
||||
|
||||
const METRIC: Record<TemperatureMetricUnits, Unit> = {
|
||||
'°C': {
|
||||
name: 'unit.celsius',
|
||||
tags: ['temperature','heat','cold','warmth','degrees','celsius','shipment condition','°C'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
K: {
|
||||
name: 'unit.kelvin',
|
||||
tags: ['temperature','heat','cold','warmth','degrees','kelvin','K','color quality','white balance','color temperature'],
|
||||
to_anchor: 1,
|
||||
anchor_shift: 273.15,
|
||||
},
|
||||
const METRIC: TbMeasureUnits<TemperatureMetricUnits> = {
|
||||
transform: (C) => C / (5 / 9) + 32,
|
||||
units: {
|
||||
'°C': {
|
||||
name: 'unit.celsius',
|
||||
tags: ['temperature', 'heat', 'cold', 'warmth', 'degrees', 'celsius', 'shipment condition', '°C'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
K: {
|
||||
name: 'unit.kelvin',
|
||||
tags: ['temperature', 'heat', 'cold', 'warmth', 'degrees', 'kelvin', 'K', 'color quality', 'white balance', 'color temperature'],
|
||||
to_anchor: 1,
|
||||
anchor_shift: 273.15,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const IMPERIAL: Record<TemperatureImperialUnits, Unit> = {
|
||||
'°F': {
|
||||
name: 'unit.fahrenheit',
|
||||
tags: ['temperature','heat','cold','warmth','degrees','fahrenheit','°F'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
'°R': {
|
||||
name: 'unit.rankine',
|
||||
tags: ['temperature','heat','cold','warmth','Rankine','°R'],
|
||||
to_anchor: 1,
|
||||
anchor_shift: 459.67,
|
||||
},
|
||||
const IMPERIAL: TbMeasureUnits<TemperatureImperialUnits> = {
|
||||
transform: (F) => (F - 32) * (5 / 9),
|
||||
units: {
|
||||
'°F': {
|
||||
name: 'unit.fahrenheit',
|
||||
tags: ['temperature', 'heat', 'cold', 'warmth', 'degrees', 'fahrenheit', '°F'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
'°R': {
|
||||
name: 'unit.rankine',
|
||||
tags: ['temperature', 'heat', 'cold', 'warmth', 'Rankine', '°R'],
|
||||
to_anchor: 1,
|
||||
anchor_shift: 459.67,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const measure: TbMeasure<UnitSystem, TemperatureUnits> = {
|
||||
systems: {
|
||||
METRIC,
|
||||
IMPERIAL,
|
||||
},
|
||||
anchors: {
|
||||
METRIC: {
|
||||
IMPERIAL: {
|
||||
transform: function (C: number): number {
|
||||
return C / (5 / 9) + 32;
|
||||
},
|
||||
},
|
||||
},
|
||||
IMPERIAL: {
|
||||
METRIC: {
|
||||
transform: function (F: number): number {
|
||||
return (F - 32) * (5 / 9);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
const measure: TbMeasure<TemperatureUnits> = {
|
||||
METRIC,
|
||||
IMPERIAL
|
||||
};
|
||||
|
||||
export default measure;
|
||||
|
||||
@ -14,11 +14,14 @@
|
||||
/// limitations under the License.
|
||||
///
|
||||
|
||||
import { TbMeasure, Unit, UnitSystem } from '@shared/models/unit.models';
|
||||
import { TbMeasure, TbMeasureUnits } from '@shared/models/unit.models';
|
||||
|
||||
export type TimeUnits = TimeSIUnits;
|
||||
|
||||
export type TimeSIUnits =
|
||||
| 'ns'
|
||||
| 'μs'
|
||||
| 'ms'
|
||||
| 's'
|
||||
| 'min'
|
||||
| 'h'
|
||||
@ -29,48 +32,63 @@ export type TimeSIUnits =
|
||||
|
||||
const daysInYear = 365.25;
|
||||
|
||||
const METRIC: Record<TimeSIUnits, Unit> = {
|
||||
s: {
|
||||
name: 'unit.second',
|
||||
tags: ["time","duration","interval","angle","second","arcsecond","sec"],
|
||||
to_anchor: 1,
|
||||
},
|
||||
min: {
|
||||
name: 'unit.minute',
|
||||
tags: ["time","duration","interval","angle","minute","arcminute","min"],
|
||||
to_anchor: 60,
|
||||
},
|
||||
h: {
|
||||
name: 'unit.hour',
|
||||
tags: ["time","duration","interval","h"],
|
||||
to_anchor: 60 * 60,
|
||||
},
|
||||
d: {
|
||||
name: 'unit.day',
|
||||
tags: ["time","duration","interval","d"],
|
||||
to_anchor: 60 * 60 * 24,
|
||||
},
|
||||
wk: {
|
||||
name: 'unit.week',
|
||||
tags: ["time","duration","interval","wk"],
|
||||
to_anchor: 60 * 60 * 24 * 7,
|
||||
},
|
||||
mo: {
|
||||
name: 'unit.month',
|
||||
tags: ["time","duration","interval","mo"],
|
||||
to_anchor: (60 * 60 * 24 * daysInYear) / 12,
|
||||
},
|
||||
yr: {
|
||||
name: 'unit.year',
|
||||
tags: ["time","duration","interval","yr"],
|
||||
to_anchor: 60 * 60 * 24 * daysInYear,
|
||||
},
|
||||
const METRIC: TbMeasureUnits<TimeSIUnits> = {
|
||||
units: {
|
||||
ns: {
|
||||
name: 'unit.nanosecond',
|
||||
tags: ['time', 'duration', 'interval', 'ns'],
|
||||
to_anchor: 1 / 1000000000
|
||||
},
|
||||
'μs': {
|
||||
name: 'unit.microsecond',
|
||||
tags: ['time', 'duration', 'interval', 'h'],
|
||||
to_anchor: 1 / 1000000
|
||||
},
|
||||
ms: {
|
||||
name: 'unit.millisecond',
|
||||
tags: ['time', 'duration', 'interval', 'ms'],
|
||||
to_anchor: 1 / 1000
|
||||
},
|
||||
s: {
|
||||
name: 'unit.second',
|
||||
tags: ['time', 'duration', 'interval', 'second', 'sec'],
|
||||
to_anchor: 1,
|
||||
},
|
||||
min: {
|
||||
name: 'unit.minute',
|
||||
tags: ['time', 'duration', 'interval', 'minute', 'min'],
|
||||
to_anchor: 60,
|
||||
},
|
||||
h: {
|
||||
name: 'unit.hour',
|
||||
tags: ['time', 'duration', 'interval', 'h'],
|
||||
to_anchor: 60 * 60,
|
||||
},
|
||||
d: {
|
||||
name: 'unit.day',
|
||||
tags: ['time', 'duration', 'interval', 'd'],
|
||||
to_anchor: 60 * 60 * 24,
|
||||
},
|
||||
wk: {
|
||||
name: 'unit.week',
|
||||
tags: ['time', 'duration', 'interval', 'wk'],
|
||||
to_anchor: 60 * 60 * 24 * 7,
|
||||
},
|
||||
mo: {
|
||||
name: 'unit.month',
|
||||
tags: ['time', 'duration', 'interval', 'mo'],
|
||||
to_anchor: (60 * 60 * 24 * daysInYear) / 12,
|
||||
},
|
||||
yr: {
|
||||
name: 'unit.year',
|
||||
tags: ['time', 'duration', 'interval', 'yr'],
|
||||
to_anchor: 60 * 60 * 24 * daysInYear,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const measure: TbMeasure<UnitSystem, TimeUnits> = {
|
||||
systems: {
|
||||
METRIC,
|
||||
},
|
||||
const measure: TbMeasure<TimeUnits> = {
|
||||
METRIC,
|
||||
};
|
||||
|
||||
export default measure;
|
||||
|
||||
@ -31,14 +31,14 @@ import { AppState } from '@core/core.state';
|
||||
export class UnitService {
|
||||
|
||||
private currentUnitSystem: UnitSystem = UnitSystem.METRIC;
|
||||
private converter: Converter<AllMeasures, UnitSystem, AllMeasuresUnits>;
|
||||
private converter: Converter<AllMeasures, AllMeasuresUnits>;
|
||||
|
||||
constructor(private store: Store<AppState>,
|
||||
private translate: TranslateService) {
|
||||
this.translate.onLangChange.pipe(
|
||||
takeUntilDestroyed()
|
||||
).subscribe(() => {
|
||||
this.converter = configureMeasurements<AllMeasures, UnitSystem, AllMeasuresUnits>(allMeasures, this.translate);
|
||||
this.converter = configureMeasurements<AllMeasures, AllMeasuresUnits>(allMeasures, this.translate);
|
||||
console.warn(this.converter?.list());
|
||||
console.warn(this.converter?.list('temperature'));
|
||||
console.warn(this.converter?.list('temperature', UnitSystem.METRIC));
|
||||
|
||||
@ -57,14 +57,12 @@ export interface TbUnitMapping {
|
||||
HYBRID: string;
|
||||
}
|
||||
|
||||
export interface TbAnchor {
|
||||
export type TbMeasure<TUnits extends string> = Partial<Record<UnitSystem, TbMeasureUnits<TUnits>>>;
|
||||
|
||||
export interface TbMeasureUnits<TUnits extends string> {
|
||||
ratio?: number;
|
||||
transform?: (value: number) => number;
|
||||
}
|
||||
|
||||
export interface TbMeasure<TSystems extends UnitSystem, TUnits extends string> {
|
||||
systems: Partial<Record<TSystems, Partial<Record<TUnits, Unit>>>>;
|
||||
anchors?: Partial<Record<TSystems, Partial<Record<TSystems, TbAnchor>>>>;
|
||||
units?: Partial<Record<TUnits, Unit>>;
|
||||
}
|
||||
|
||||
const searchUnitTags = (unit: UnitDescription, searchText: string): boolean =>
|
||||
|
||||
@ -6160,6 +6160,9 @@
|
||||
"millibars": "Millibars",
|
||||
"inch-of-mercury": "One inch of mercury",
|
||||
"richter-scale": "Richter Scale",
|
||||
"nanosecond": "Nanosecond",
|
||||
"microsecond": "Microsecond",
|
||||
"millisecond": "Millisecond",
|
||||
"second": "Second",
|
||||
"minute": "Minute",
|
||||
"hour": "Hour",
|
||||
@ -6197,6 +6200,8 @@
|
||||
"degree": "Degree",
|
||||
"radian": "Radian",
|
||||
"gradian": "Gradian",
|
||||
"arcminute": "Arcminute",
|
||||
"arcsecond": "Arcsecond",
|
||||
"mil": "Mil",
|
||||
"revolution": "Revolution",
|
||||
"siemens": "Siemens",
|
||||
@ -6267,7 +6272,6 @@
|
||||
"radian-per-second": "Radian per second",
|
||||
"radian-per-second-squared": "Radian per second squared",
|
||||
"revolutions-per-minute-per-second": "Angular acceleration",
|
||||
"revolutions-per-minute-per-second-squared": "Angular Acceleration",
|
||||
"deg-per-second": "deg/s",
|
||||
"degrees-brix": "Degrees Brix",
|
||||
"katal": "Katal",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user