diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..91e5c898
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..79ee123c
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 00000000..c6cc8c81
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/changelog.md b/changelog.md
index 6af61b5d..842ff533 100644
--- a/changelog.md
+++ b/changelog.md
@@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
+## [v3.2.0] - 2018-02-27
+
+### Added
+- Added tree view to calculator selection overlay with calculators sorted by category, closes #162.
+
+### Fixed
+- Fixed TravisCI build error, where error was 'npm ERR! enoent ENOENT: no such file or directory, chmod '/home/travis/build/mbedded-ninja/NinjaCalc/node_modules/topojson/node_modules/topojson-server/bin/geo2topo''. This was fixed by removing topojson as a dependency and just using topojson-client, topojson-server and topojson-simplify individually (they are still dependencies).
+
## [v3.1.0] - 2018-02-18
### Added
diff --git a/package-lock.json b/package-lock.json
index 83cef770..e6133394 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6943,6 +6943,9 @@
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
+ "phantomjs-polyfill-find": {
+ "version": "github:ptim/phantomjs-polyfill-find#026b69dcabe743265f5214775e42f8d1e8aabedc"
+ },
"phantomjs-prebuilt": {
"version": "2.1.16",
"resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
@@ -8860,43 +8863,6 @@
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
},
- "topojson": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/topojson/-/topojson-3.0.2.tgz",
- "integrity": "sha512-u3zeuL6WEVL0dmsRn7uHZKc4Ao4gpW3sORUv+N3ezLTvY3JdCuyg0hvpWiIfFw8p/JwVN++SvAsFgcFEeR15rQ==",
- "requires": {
- "topojson-client": "3.0.0",
- "topojson-server": "3.0.0",
- "topojson-simplify": "3.0.2"
- },
- "dependencies": {
- "topojson-client": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.0.0.tgz",
- "integrity": "sha1-H5kpOnfvQqRI0DKoGqmCtz82DS8=",
- "requires": {
- "commander": "2.14.1"
- }
- },
- "topojson-server": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/topojson-server/-/topojson-server-3.0.0.tgz",
- "integrity": "sha1-N4546Hw5cqe1vixdYENptrrmnF4=",
- "requires": {
- "commander": "2.14.1"
- }
- },
- "topojson-simplify": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/topojson-simplify/-/topojson-simplify-3.0.2.tgz",
- "integrity": "sha512-gyYSVRt4jO/0RJXKZQPzTDQRWV+D/nOfiljNUv0HBXslFLtq3yxRHrl7jbrjdbda5Ytdr7M8BZUI4OxU7tnbRQ==",
- "requires": {
- "commander": "2.14.1",
- "topojson-client": "3.0.0"
- }
- }
- }
- },
"topojson-client": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.0.0.tgz",
diff --git a/package.json b/package.json
index af230816..419f7ba5 100644
--- a/package.json
+++ b/package.json
@@ -77,7 +77,6 @@
"semver": "^5.3.0",
"sinon": "^1.17.7",
"sinon-chai": "^2.8.0",
- "topojson": "^3.0.2",
"topojson-client": "^3.0.0",
"topojson-server": "^3.0.0",
"topojson-simplify": "^3.0.2",
diff --git a/src/components/CalculatorSelectionOverlay/CalculatorSelectionOverlay.vue b/src/components/CalculatorSelectionOverlay/CalculatorSelectionOverlay.vue
index ed020bd9..5df390ed 100644
--- a/src/components/CalculatorSelectionOverlay/CalculatorSelectionOverlay.vue
+++ b/src/components/CalculatorSelectionOverlay/CalculatorSelectionOverlay.vue
@@ -5,15 +5,28 @@
-
@@ -39,19 +53,73 @@
CalcPreview
},
data: function () {
- return {}
+ return {
+ }
},
computed: {
searchText: {
get () {
- return this.$store.state.searchText
+ return this.$store.state.core.searchText
},
set (value) {
this.$store.dispatch('setSearchText', value)
}
+ },
+ treeData () {
+ var output = {
+ 'name': 'root',
+ 'selected': false,
+ 'children': []
+ }
+
+ console.log(this.$store)
+ var self = this
+ this.$store.state.core.availableCalcs.map(function (calc) {
+ // console.log('calc =')
+ // console.log(calc)
+ self.addCategoriesToTree(calc.category, output)
+ // console.log('After adding category elements for 1 calculator, output =')
+ // console.log(output)
+ })
+ return output
}
},
methods: {
+ addCategoriesToTree (categories, treeNode) {
+ // console.log('addCategoriesToTree() called with categories =')
+ console.log(categories)
+
+ // Copy array, we are going to modify it, and we don't want to touch
+ // the original!
+ categories = categories.slice()
+ // console.log(', treeNode =')
+ // console.log(treeNode)
+
+ var inTree = false
+ treeNode.children.map(function (childNode) {
+ if (childNode.name === categories[0]) {
+ inTree = true
+ }
+ })
+
+ // Add first category element if it doesn't already exist
+ if (!inTree) {
+ console.log('Category ' + categories[0] + ' not found in tree.')
+ var newTreeNode = {
+ 'name': categories[0],
+ 'selected': false,
+ 'children': []
+ }
+ treeNode.children.push(newTreeNode)
+ }
+
+ // Remove first category element
+ categories.splice(0, 1)
+
+ if (categories.length > 0) {
+ this.addCategoriesToTree(categories, treeNode.children[treeNode.children.length - 1])
+ }
+ },
borderClicked (event) {
this.$store.commit('showCalculatorSelectionOverlay', {
trueFalse: false
@@ -60,10 +128,21 @@
overlayClicked (event) {
// Do nothing, this handler exists purely to swallow event
// (event does not bubble because of .stop modifier in HTML)
+ },
+ itemClick (node) {
+ console.log(node.model.text + ' clicked !')
+ },
+ categoryClicked (category) {
+ console.log('categoryClicked() called. category =')
+ console.log(category)
+ this.$store.dispatch('setSelCategory', category)
}
},
watch: {},
mounted () {
+ if (!this.$store.state.core.calcsFilteredByCategoryAndSearch) {
+ throw Error('this.$store.state.core.calcsFilteredByCategoryAndSearch was null.')
+ }
}
}
diff --git a/src/components/Calculators/Geospatial/TwoCoordinateGeodesics/MainView.vue b/src/components/Calculators/Geospatial/TwoCoordinateGeodesics/MainView.vue
index a9321bc4..34a93668 100644
--- a/src/components/Calculators/Geospatial/TwoCoordinateGeodesics/MainView.vue
+++ b/src/components/Calculators/Geospatial/TwoCoordinateGeodesics/MainView.vue
@@ -81,7 +81,7 @@
/* eslint-disable */
import * as d3 from 'd3'
- import * as topojson from 'topojson'
+ import feature from 'topojson-client/src/feature'
import versor from 'versor';
import { Coordinate, CoordinateUnits, Geospatial } from 'src/misc/Geospatial/Geospatial'
@@ -374,8 +374,9 @@
this.graticule = d3.geoGraticule10()
this.path = d3.geoPath(this.projection).context(this.context)
- this.land = topojson.feature(world110m, world110m.objects.land)
- this.countries = topojson.feature(world110m, world110m.objects.countries)
+ // feature() is from the topojson-client library (DO NOT ADD topojson AS A DEPENDENCY)
+ this.land = feature(world110m, world110m.objects.land)
+ this.countries = feature(world110m, world110m.objects.countries)
// this.countryList = cList
this.scale()
diff --git a/src/main.js b/src/main.js
index 2fd025a7..24538f7d 100644
--- a/src/main.js
+++ b/src/main.js
@@ -30,6 +30,9 @@ import ElementUI from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
Vue.use(ElementUI)
+// import VJstree from 'vue-jstree'
+// Vue.component('v-jstree', VJstree)
+
import './style/style.css'
// =========================================== //
@@ -48,6 +51,15 @@ Vue.component('calc-var-checkbox', CalcVarCheckbox)
import VariableRowVerbose from 'src/misc/CalculatorEngineV2/view/VariableRowVerbose.vue'
Vue.component('variable-row-verbose', VariableRowVerbose)
+// =========================================== //
+// ===== TREE VIEW COMPONENT REGISTRATION ==== //
+// =========================================== //
+import TreeView from 'misc/TreeView/TreeView'
+Vue.component('tree-view', TreeView)
+
+import TreeItem from 'misc/TreeView/TreeItem'
+Vue.component('tree-item', TreeItem)
+
// =========================================== //
// ============= IMPORT VUEX STORE =========== //
// =========================================== //
diff --git a/src/misc/TreeView/TreeItem.vue b/src/misc/TreeView/TreeItem.vue
new file mode 100644
index 00000000..b3e65702
--- /dev/null
+++ b/src/misc/TreeView/TreeItem.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+ {{ data.name }}
+
+
+
+
+
+
+
+
+
diff --git a/src/misc/TreeView/TreeView.vue b/src/misc/TreeView/TreeView.vue
new file mode 100644
index 00000000..e7273984
--- /dev/null
+++ b/src/misc/TreeView/TreeView.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/store/index.js b/src/store/index.js
index 1332d14a..cd64c1bb 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -9,8 +9,7 @@ export default new Vuex.Store({
count: 0,
showLeftSideBar: false,
showCalculatorSelectionOverlay: false,
- activeTabId: '',
- searchText: ''
+ activeTabId: ''
},
mutations: {
showLeftSideBar (state, payload) {
@@ -57,18 +56,7 @@ export default new Vuex.Store({
state.activeTabId = state.core.openCalcs[state.core.openCalcs.length - 1].uniqueId
}
},
- actions: {
- /**
- * This will set the search text, and also update the filteredAvailableCalcs variable,
- * depending on the search text.
- * @param context
- * @param value
- */
- setSearchText (context, value) {
- context.commit('setSearchText', value)
- context.commit('updateFilteredAvailableCalcs', context.state.searchText)
- }
- },
+ actions: {},
modules: {
core
}
diff --git a/src/store/modules/core.js b/src/store/modules/core.js
index b9a6ee19..3cf45b17 100644
--- a/src/store/modules/core.js
+++ b/src/store/modules/core.js
@@ -5,8 +5,15 @@ const state = {
// These are presented to the user, but filtered first.
availableCalcs: [],
- // This is updated whenever the search text is changed.
- filteredAvailableCalcs: [],
+ selCategory: [],
+
+ // This is updated whenever the selected category is changed.
+ calcsFilteredByCategory: [],
+
+ searchText: '',
+
+ // This is updated whenever the category or search text is changed.
+ calcsFilteredByCategoryAndSearch: [],
openCalcs: []
}
@@ -16,16 +23,22 @@ const mutations = {
registerCalc (state, payload) {
state.availableCalcs.push(payload)
},
- updateFilteredAvailableCalcs (state, searchText) {
+ setSearchText (state, searchText) {
+ state.searchText = searchText
+ },
+ updateFilteredCalcsOnSearchText (state) {
+ // console.log('updateFilteredAvailableCalcs() called.')
// Update the filtered available calculators. If the search text is '' (i.e.
// empty), return all the calculators.
- if (searchText === '') {
- state.filteredAvailableCalcs = state.availableCalcs
+ if (state.searchText === '') {
+ state.calcsFilteredByCategoryAndSearch = state.calcsFilteredByCategory
+ // console.log('state.calcsFilteredByCategoryAndSearch = ')
+ // console.log(state.calcsFilteredByCategoryAndSearch)
return
}
- state.filteredAvailableCalcs = state.availableCalcs.filter(calc => {
+ state.calcsFilteredByCategoryAndSearch = state.calcsFilteredByCategory.filter(calc => {
// Create regex pattern from search text
- var regex = new RegExp(searchText, 'gi')
+ var regex = new RegExp(state.searchText, 'gi')
// Search in calculator title (display name)
if (calc.displayName.match(regex)) return true
// Search through the tags
@@ -34,6 +47,9 @@ const mutations = {
}
})
},
+ setSelCategory (state, category) {
+ state.selCategory = category
+ },
openCalc (state, payload) {
// Find a unique ID to use
var maxId = 0
@@ -58,6 +74,30 @@ const mutations = {
// Unique ID is used as a unique tab ID
uniqueId: newUniqueId
})
+ },
+ updateFilteredCalcsOnCategory (state) {
+ // console.log('$state.core.mutations.updateFilteredCalcsOnCategory() called.')
+
+ state.calcsFilteredByCategory = state.availableCalcs.filter(calc => {
+ // console.log('calc =')
+ // console.log(calc)
+ if (state.selCategory.length > calc.category.length) {
+ // console.log('Selected category more specific than calc category, excluding...')
+ return false
+ }
+ for (var i = 0; i < state.selCategory.length; i++) {
+ if (state.selCategory[i] !== calc.category[i]) {
+ // console.log('Selected category does not mactch calc category, excluding...')
+ return false
+ }
+ }
+
+ // console.log('Selected category matches calculator category.')
+ return true
+ })
+
+ // console.log('calcsFilteredByCategory =')
+ // console.log(state.calcsFilteredByCategory)
}
}
@@ -71,12 +111,23 @@ const actions = {
registerCalc ({state, commit, rootState}, value) {
Vue.component(value.mainView.name, value.mainView)
commit('registerCalc', value)
- commit('updateFilteredAvailableCalcs', rootState.searchText)
+ commit('updateFilteredCalcsOnCategory')
+ commit('updateFilteredCalcsOnSearchText')
},
openCalc ({state, commit, rootState}, value) {
console.log('core.actions.openCalc() called.')
commit('openCalc', value)
commit('setLastCalcAsActive')
+ },
+ setSearchText ({state, commit, rootState}, value) {
+ commit('setSearchText', value)
+ commit('updateFilteredCalcsOnSearchText')
+ },
+ setSelCategory ({state, commit, rootState}, value) {
+ console.log('core.actions.setCategory() called.')
+ commit('setSelCategory', value)
+ commit('updateFilteredCalcsOnCategory')
+ commit('updateFilteredCalcsOnSearchText')
}
}