diff --git a/src/components/pivottable-ui/VPivottableUi.vue b/src/components/pivottable-ui/VPivottableUi.vue index ac936e3..3632d48 100644 --- a/src/components/pivottable-ui/VPivottableUi.vue +++ b/src/components/pivottable-ui/VPivottableUi.vue @@ -32,7 +32,7 @@ :aggregatorName="state.aggregatorName" :rowOrder="state.rowOrder" :colOrder="state.colOrder" - :attributeNames="state.attributeNames" + :attributeNames="attributeNames" :hiddenFromAggregators="state.hiddenFromAggregators" :vals="state.vals" @update:aggregatorName="onUpdateAggregatorName" @@ -107,7 +107,7 @@ import VAggregatorCell from './VAggregatorCell.vue' import VDragAndDropCell from './VDragAndDropCell.vue' import { VPivottable } from '@/' import { computed, ref, toRefs, watch } from 'vue' -import { usePropsState } from '@/composables' +import { usePropsState, useMaterializeInput } from '@/composables' import TableRenderer from '../pivottable/renderer/index' const props = defineProps({ @@ -145,6 +145,7 @@ const props = defineProps({ default: false } }) +// TODO const pivotUiState = ref({ unusedOrder: props.unusedAttrs, zIndices: {}, @@ -156,7 +157,14 @@ const pivotUiState = ref({ }) const propsRefs = toRefs(props) -const { state, updateState, updateMultiple } = usePropsState(propsRefs) +const { state, updateState } = usePropsState(propsRefs) +const { allFilters } = useMaterializeInput( + computed(() => props.data), + { + derivedAttributes: computed(() => props.derivedAttributes) + } +) + const rendererItems = computed(() => Object.keys(state.value.renderers).length ? state.value.renderers : TableRenderer) const aggregatorItems = computed(() => state.value.aggregators) const rowAttrs = computed(() => { @@ -173,8 +181,14 @@ const colAttrs = computed(() => { !state.value.hiddenFromDragDrop.includes(e) ) }) +const attributeNames = computed(() => { + return Object.keys(allFilters.value).filter(e => + !state.value.hiddenAttributes.includes(e) && + !state.value.hiddenFromAggregators.includes(e) + ) +}) const unusedAttrs = computed(() => { - return state.value.attributes + return attributeNames.value .filter( e => !state.value.rows.includes(e) && @@ -185,48 +199,6 @@ const unusedAttrs = computed(() => { .sort(sortAs(state.value.unusedOrder)) }) -const materializeInput = nextData => { - if (props.data === nextData) { - return - } - const newState = { - data: nextData, - attrValues: {}, - materializedInput: [] - } - - let recordsProcessed = 0 - PivotData.forEachRecord( - newState.data, - props.derivedAttributes, - function (record) { - newState.materializedInput.push(record) - for (const attr of Object.keys(record)) { - if (!(attr in newState.attrValues)) { - newState.attrValues[attr] = {} - if (recordsProcessed > 0) { - newState.attrValues[attr].null = recordsProcessed - } - } - } - for (const attr in newState.attrValues) { - const value = attr in record ? record[attr] : 'null' - if (!(value in newState.attrValues[attr])) { - newState.attrValues[attr][value] = 0 - } - newState.attrValues[attr][value]++ - } - recordsProcessed++ - } - ) - - updateMultiple({ - ...state.value, - ...newState, - ...pivotUiState.value - }) -} - const onMoveFilterBoxToTop = ({ attribute }) => { updateState('maxZIndex', state.value.maxZIndex++) updateState('zIndices', { @@ -268,7 +240,6 @@ const pivotData = computed(() => new PivotData(state.value)) watch(() => props.data, value => { updateState('unusedOrder', props.unusedAttrs) - materializeInput(value) }) diff --git a/src/composables/index.js b/src/composables/index.js index 3c5f459..5f18d43 100644 --- a/src/composables/index.js +++ b/src/composables/index.js @@ -1,2 +1,3 @@ export { usePivotData, providePivotData } from './pivotData' export { usePropsState } from './usePropsState' +export { useMaterializeInput } from './useMaterializeInput' diff --git a/src/composables/useMaterializeInput.js b/src/composables/useMaterializeInput.js new file mode 100644 index 0000000..114bab9 --- /dev/null +++ b/src/composables/useMaterializeInput.js @@ -0,0 +1,66 @@ +import { ref, watch } from 'vue' +import { PivotData } from '@/helper/utilities.js' + +export function useMaterializeInput (dataSource, options) { + const rawData = ref(null) + const allFilters = ref({}) + const materializedInput = ref([]) + + function processData (data) { + if (!data || rawData.value === data) return + + rawData.value = data + const newAllFilters = {} + const newMaterializedInput = [] + + let recordsProcessed = 0 + + PivotData.forEachRecord( + data, + options.derivedAttributes.value, + function (record) { + newMaterializedInput.push(record) + + for (const attr of Object.keys(record)) { + if (!(attr in newAllFilters)) { + newAllFilters[attr] = {} + if (recordsProcessed > 0) { + newAllFilters[attr].null = recordsProcessed + } + } + } + + for (const attr in newAllFilters) { + const value = attr in record ? record[attr] : 'null' + if (!(value in newAllFilters[attr])) { + newAllFilters[attr][value] = 0 + } + newAllFilters[attr][value]++ + } + + recordsProcessed++ + } + ) + + allFilters.value = newAllFilters + materializedInput.value = newMaterializedInput + + return { + AllFilters: newAllFilters, + materializedInput: newMaterializedInput + } + } + + watch(() => dataSource.value, processData, { immediate: true }) + + watch(() => options.derivedAttributes.value, () => { + processData(dataSource.value) + }) + + return { + rawData, + allFilters, + materializedInput, + processData + } +}