| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- const {
- formatMagnitudeNumber,
- formatScaledValue,
- getOption,
- normalizeIndex,
- parsePositiveNumber,
- selectBestUnit
- } = require('./calculator-helpers')
- const TWO_PI = 2 * Math.PI
- const MODE_OPTIONS = [
- { key: 'capacitive', label: '容抗' },
- { key: 'inductive', label: '感抗' }
- ]
- const REACTANCE_UNIT_OPTIONS = [
- { label: 'mΩ', factor: 1e-3 },
- { label: 'Ω', factor: 1 },
- { label: 'kΩ', factor: 1e3 },
- { label: 'MΩ', factor: 1e6 },
- { label: 'GΩ', factor: 1e9 }
- ]
- const ADMITTANCE_UNIT_OPTIONS = [
- { label: 'pS', factor: 1e-12 },
- { label: 'nS', factor: 1e-9 },
- { label: 'μS', factor: 1e-6 },
- { label: 'mS', factor: 1e-3 },
- { label: 'S', factor: 1 },
- { label: 'kS', factor: 1e3 },
- { label: 'MS', factor: 1e6 }
- ]
- const CAPACITANCE_UNIT_OPTIONS = [
- { label: 'pF', factor: 1e-12 },
- { label: 'nF', factor: 1e-9 },
- { label: 'μF', factor: 1e-6 },
- { label: 'mF', factor: 1e-3 },
- { label: 'F', factor: 1 }
- ]
- const INDUCTANCE_UNIT_OPTIONS = [
- { label: 'pH', factor: 1e-12 },
- { label: 'nH', factor: 1e-9 },
- { label: 'μH', factor: 1e-6 },
- { label: 'mH', factor: 1e-3 },
- { label: 'H', factor: 1 },
- { label: 'kH', factor: 1e3 }
- ]
- const FREQUENCY_UNIT_OPTIONS = [
- { label: 'Hz', factor: 1 },
- { label: 'kHz', factor: 1e3 },
- { label: 'MHz', factor: 1e6 },
- { label: 'GHz', factor: 1e9 },
- { label: 'THz', factor: 1e12 }
- ]
- function getReactiveUnitOptions(modeKey) {
- return modeKey === 'inductive' ? INDUCTANCE_UNIT_OPTIONS : CAPACITANCE_UNIT_OPTIONS
- }
- function formatUnitValue(baseValue, options, fallbackIndex = 0) {
- if (!Number.isFinite(baseValue)) return '--'
- const selected = selectBestUnit(options, baseValue, fallbackIndex)
- return formatScaledValue(baseValue, selected.unit, {
- fallbackText: '',
- includeUnit: true
- })
- }
- function createEmptyResultRows(modeKey) {
- const isInductive = modeKey === 'inductive'
- return [
- {
- label: isInductive ? '感抗 XL' : '容抗 XC',
- meta: isInductive ? 'XL = 2πfL' : 'XC = 1 / (2πfC)',
- value: '--'
- },
- {
- label: isInductive ? '感抗导纳 YL' : '容抗导纳 YC',
- meta: 'Y = 1 / X',
- value: '--'
- }
- ]
- }
- function calculateResultRows(modeKey, frequency, reactive) {
- const rows = createEmptyResultRows(modeKey)
- if (!Number.isFinite(frequency) || !Number.isFinite(reactive)) return rows
- const reactance = modeKey === 'inductive'
- ? TWO_PI * frequency * reactive
- : 1 / (TWO_PI * frequency * reactive)
- const admittance = 1 / reactance
- return [
- {
- ...rows[0],
- value: formatUnitValue(reactance, REACTANCE_UNIT_OPTIONS, 1)
- },
- {
- ...rows[1],
- value: formatUnitValue(admittance, ADMITTANCE_UNIT_OPTIONS, 4)
- }
- ]
- }
- function buildState(source = {}) {
- const modeIndex = normalizeIndex(source.reactanceModeIndex, MODE_OPTIONS, 0)
- const mode = getOption(MODE_OPTIONS, modeIndex)
- const reactiveUnitOptions = getReactiveUnitOptions(mode.key)
- const capacitanceUnitIndex = normalizeIndex(source.reactanceCapacitanceUnitIndex, CAPACITANCE_UNIT_OPTIONS, 1)
- const frequencyUnitIndex = normalizeIndex(source.reactanceFrequencyUnitIndex, FREQUENCY_UNIT_OPTIONS, 0)
- const inductanceUnitIndex = normalizeIndex(source.reactanceInductanceUnitIndex, INDUCTANCE_UNIT_OPTIONS, 3)
- const reactiveUnitIndex = mode.key === 'inductive' ? inductanceUnitIndex : capacitanceUnitIndex
- const frequencyUnit = getOption(FREQUENCY_UNIT_OPTIONS, frequencyUnitIndex)
- const reactiveUnit = getOption(reactiveUnitOptions, reactiveUnitIndex)
- const frequencyText = String(source.reactanceFrequencyValue || '')
- const reactiveText = String(source.reactanceReactiveValue || '')
- const frequencyNumber = parsePositiveNumber(frequencyText)
- const reactiveNumber = parsePositiveNumber(reactiveText)
- const invalidInput = [frequencyNumber, reactiveNumber].some((value) => Number.isNaN(value))
- const values = {
- frequency: Number.isFinite(frequencyNumber) ? frequencyNumber * frequencyUnit.factor : null,
- reactive: Number.isFinite(reactiveNumber) ? reactiveNumber * reactiveUnit.factor : null
- }
- let frequencyDisplayUnit = frequencyUnit
- let frequencyDisplayUnitIndex = frequencyUnitIndex
- let reactiveDisplayUnit = reactiveUnit
- let reactiveDisplayUnitIndex = reactiveUnitIndex
- let frequencyDisplayValue = Number.isFinite(frequencyNumber)
- ? formatMagnitudeNumber(frequencyNumber, { fallbackText: '' })
- : frequencyText
- let reactiveDisplayValue = Number.isFinite(reactiveNumber)
- ? formatMagnitudeNumber(reactiveNumber, { fallbackText: '' })
- : reactiveText
- const resultRows = invalidInput
- ? createEmptyResultRows(mode.key)
- : calculateResultRows(mode.key, values.frequency, values.reactive)
- return {
- reactanceCapacitanceUnitIndex: mode.key === 'capacitive' ? reactiveDisplayUnitIndex : capacitanceUnitIndex,
- reactanceErrorText: invalidInput ? '输入值需大于 0' : '',
- reactanceFrequencyDisplayValue: frequencyDisplayValue,
- reactanceFrequencyUnitIndex: frequencyDisplayUnitIndex,
- reactanceFrequencyUnitOptions: FREQUENCY_UNIT_OPTIONS,
- reactanceFrequencyUnitText: frequencyDisplayUnit.label,
- reactanceFrequencyValue: frequencyText,
- reactanceInductanceUnitIndex: mode.key === 'inductive' ? reactiveDisplayUnitIndex : inductanceUnitIndex,
- reactanceModeIndex: modeIndex,
- reactanceModeKey: mode.key,
- reactanceModeOptions: MODE_OPTIONS,
- reactanceModeText: mode.label,
- reactanceReactiveDisplayValue: reactiveDisplayValue,
- reactanceReactiveName: mode.key === 'inductive' ? '电感' : '电容',
- reactanceReactiveSymbol: mode.key === 'inductive' ? 'L' : 'C',
- reactanceReactiveUnitIndex: reactiveDisplayUnitIndex,
- reactanceReactiveUnitOptions: reactiveUnitOptions,
- reactanceReactiveUnitText: reactiveDisplayUnit.label,
- reactanceReactiveValue: reactiveText,
- reactanceResultRows: resultRows
- }
- }
- function createInitialState() {
- return buildState({
- reactanceCapacitanceUnitIndex: 1,
- reactanceFrequencyUnitIndex: 0,
- reactanceInductanceUnitIndex: 3,
- reactanceModeIndex: 0,
- reactanceReactiveValue: ''
- })
- }
- function updateState(state, changedData = {}) {
- return buildState({
- ...state,
- ...changedData
- })
- }
- function clearInputs(state = {}) {
- return updateState(state, {
- reactanceFrequencyValue: '',
- reactanceReactiveValue: ''
- })
- }
- function normalizeValue(state, fieldKey, fieldValue) {
- const source = buildState(state)
- const config = {
- frequency: {
- options: FREQUENCY_UNIT_OPTIONS,
- unitIndex: source.reactanceFrequencyUnitIndex,
- unitIndexKey: 'reactanceFrequencyUnitIndex',
- valueKey: 'reactanceFrequencyValue'
- },
- reactive: {
- options: source.reactanceReactiveUnitOptions,
- unitIndex: source.reactanceReactiveUnitIndex,
- unitIndexKey: source.reactanceModeKey === 'inductive'
- ? 'reactanceInductanceUnitIndex'
- : 'reactanceCapacitanceUnitIndex',
- valueKey: 'reactanceReactiveValue'
- }
- }[fieldKey]
- if (!config) return source
- const text = fieldValue === undefined ? source[config.valueKey] : fieldValue
- const numberValue = parsePositiveNumber(text)
- if (!Number.isFinite(numberValue)) {
- return updateState(source, {
- [config.valueKey]: text
- })
- }
- const currentUnit = getOption(config.options, config.unitIndex)
- const baseValue = numberValue * currentUnit.factor
- const selected = selectBestUnit(config.options, baseValue, config.unitIndex)
- return updateState(source, {
- [config.unitIndexKey]: selected.index,
- [config.valueKey]: formatScaledValue(baseValue, selected.unit, { fallbackText: '' })
- })
- }
- module.exports = {
- ADMITTANCE_UNIT_OPTIONS,
- CAPACITANCE_UNIT_OPTIONS,
- FREQUENCY_UNIT_OPTIONS,
- INDUCTANCE_UNIT_OPTIONS,
- MODE_OPTIONS,
- REACTANCE_UNIT_OPTIONS,
- clearInputs,
- createInitialState,
- normalizeValue,
- updateState
- }
|