diff --git a/public/main.js b/public/main.js index 111df25af1f507a8a3955f41171592061beee7f7..3445abbdb1de99771ee0c488494b190a5b077663 100644 --- a/public/main.js +++ b/public/main.js @@ -6304,12 +6304,13 @@ var $author$project$Main$init = function (_v0) { function ($) { return $.refresh_rate; } - ]) + ]), + selectedFilter: {brand: 'all', g5: 'all', ir_blaster: 'all', nfc: 'all'} }, { dropCount: 0, inputDropCount: '', - selectedFilter: {brand: 'all', g5: 'false', ir_blaster: 'false', nfc: 'false'}, + selectedFilter: {brand: 'all', g5: 'true', ir_blaster: 'false', nfc: 'false'}, zoomOption: A2( $gampleman$elm_visualization$Zoom$translateExtent, _Utils_Tuple2( @@ -9222,37 +9223,91 @@ var $author$project$Main$update = F2( $elm$core$Platform$Cmd$none); } case 'ParallelCoordinatesMsg': - if (msg.a.$ === 'ChangeOrder') { - var _v2 = msg.a; - var pos1 = _v2.a; - var pos2 = _v2.b; - return _Utils_Tuple2( - _Utils_update( - model, - { - parallelPlotOption: { - orderedLabels: A3($elm_community$list_extra$List$Extra$swapAt, pos1, pos2, model.parallelPlotOption.orderedLabels), - orderedList: A3($elm_community$list_extra$List$Extra$swapAt, pos1, pos2, model.parallelPlotOption.orderedList) - } - }), - $elm$core$Platform$Cmd$none); - } else { - var _v3 = msg.a; - var att1 = _v3.a; - var att2 = _v3.b; - return _Utils_Tuple2( - _Utils_update( - model, - { - plotVisible: {parallelCoordinatesPlot: false, scatterPlot: true, starPlot: false, treeView: false}, - scatterplotOptions: { - att1List: A2($author$project$Main$createAttList, model, att1), - att2List: A2($author$project$Main$createAttList, model, att2), - attribute1: att1, - attribute2: att2 - } - }), - $elm$core$Platform$Cmd$none); + switch (msg.a.$) { + case 'ChangeOrder': + var _v2 = msg.a; + var pos1 = _v2.a; + var pos2 = _v2.b; + return _Utils_Tuple2( + _Utils_update( + model, + { + parallelPlotOption: { + orderedLabels: A3($elm_community$list_extra$List$Extra$swapAt, pos1, pos2, model.parallelPlotOption.orderedLabels), + orderedList: A3($elm_community$list_extra$List$Extra$swapAt, pos1, pos2, model.parallelPlotOption.orderedList), + selectedFilter: model.parallelPlotOption.selectedFilter + } + }), + $elm$core$Platform$Cmd$none); + case 'SetScatterPlotFromParallelPlot': + var _v3 = msg.a; + var att1 = _v3.a; + var att2 = _v3.b; + return _Utils_Tuple2( + _Utils_update( + model, + { + plotVisible: {parallelCoordinatesPlot: false, scatterPlot: true, starPlot: false, treeView: false}, + scatterplotOptions: { + att1List: A2($author$project$Main$createAttList, model, att1), + att2List: A2($author$project$Main$createAttList, model, att2), + attribute1: att1, + attribute2: att2 + } + }), + $elm$core$Platform$Cmd$none); + case 'SetBrandParallel': + var value = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + parallelPlotOption: { + orderedLabels: model.parallelPlotOption.orderedLabels, + orderedList: model.parallelPlotOption.orderedList, + selectedFilter: {brand: value, g5: model.parallelPlotOption.selectedFilter.g5, ir_blaster: model.parallelPlotOption.selectedFilter.ir_blaster, nfc: model.parallelPlotOption.selectedFilter.nfc} + } + }), + $elm$core$Platform$Cmd$none); + case 'Set5GParallel': + var value = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + parallelPlotOption: { + orderedLabels: model.parallelPlotOption.orderedLabels, + orderedList: model.parallelPlotOption.orderedList, + selectedFilter: {brand: model.parallelPlotOption.selectedFilter.brand, g5: value, ir_blaster: model.parallelPlotOption.selectedFilter.ir_blaster, nfc: model.parallelPlotOption.selectedFilter.nfc} + } + }), + $elm$core$Platform$Cmd$none); + case 'SetNFCParallel': + var value = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + parallelPlotOption: { + orderedLabels: model.parallelPlotOption.orderedLabels, + orderedList: model.parallelPlotOption.orderedList, + selectedFilter: {brand: model.parallelPlotOption.selectedFilter.brand, g5: model.parallelPlotOption.selectedFilter.g5, ir_blaster: model.parallelPlotOption.selectedFilter.ir_blaster, nfc: value} + } + }), + $elm$core$Platform$Cmd$none); + default: + var value = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + parallelPlotOption: { + orderedLabels: model.parallelPlotOption.orderedLabels, + orderedList: model.parallelPlotOption.orderedList, + selectedFilter: {brand: model.parallelPlotOption.selectedFilter.brand, g5: model.parallelPlotOption.selectedFilter.g5, ir_blaster: value, nfc: model.parallelPlotOption.selectedFilter.nfc} + } + }), + $elm$core$Platform$Cmd$none); } case 'TreeViewMsg': switch (msg.a.$) { @@ -9525,6 +9580,79 @@ var $elm$html$Html$Events$onClick = function (msg) { }; var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; +var $author$project$ParallelCoordinates$Set5GParallel = function (a) { + return {$: 'Set5GParallel', a: a}; +}; +var $author$project$ParallelCoordinates$SetBrandParallel = function (a) { + return {$: 'SetBrandParallel', a: a}; +}; +var $author$project$ParallelCoordinates$SetIRBlasterParallel = function (a) { + return {$: 'SetIRBlasterParallel', a: a}; +}; +var $author$project$ParallelCoordinates$SetNFCParallel = function (a) { + return {$: 'SetNFCParallel', a: a}; +}; +var $elm$html$Html$option = _VirtualDom_node('option'); +var $elm$json$Json$Encode$bool = _Json_wrap; +var $elm$html$Html$Attributes$boolProperty = F2( + function (key, bool) { + return A2( + _VirtualDom_property, + key, + $elm$json$Json$Encode$bool(bool)); + }); +var $elm$html$Html$Attributes$selected = $elm$html$Html$Attributes$boolProperty('selected'); +var $elm$json$Json$Encode$string = _Json_wrap; +var $elm$html$Html$Attributes$stringProperty = F2( + function (key, string) { + return A2( + _VirtualDom_property, + key, + $elm$json$Json$Encode$string(string)); + }); +var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); +var $author$project$ParallelCoordinates$createSelectorOptions = F2( + function (select, valueOption) { + return _Utils_eq(select, valueOption) ? A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value(valueOption), + $elm$html$Html$Attributes$selected(true) + ]), + _List_fromArray( + [ + $elm$html$Html$text(valueOption) + ])) : A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value(valueOption) + ]), + _List_fromArray( + [ + $elm$html$Html$text(valueOption) + ])); + }); +var $author$project$ParallelCoordinates$fromBrand = F2( + function (model, smartphone) { + return (_Utils_eq( + model.parallelPlotOption.selectedFilter.brand, + A2($elm$core$Maybe$withDefault, '', smartphone.brand)) || (model.parallelPlotOption.selectedFilter.brand === 'all')) ? true : false; + }); +var $elm$core$Basics$not = _Basics_not; +var $author$project$ParallelCoordinates$has5G = F2( + function (model, smartphone) { + return (((model.parallelPlotOption.selectedFilter.g5 === 'true') && A2($elm$core$Maybe$withDefault, false, smartphone.g5)) || (model.parallelPlotOption.selectedFilter.g5 === 'all')) ? true : (((model.parallelPlotOption.selectedFilter.g5 === 'false') && (!A2($elm$core$Maybe$withDefault, true, smartphone.g5))) ? true : false); + }); +var $author$project$ParallelCoordinates$hasIRBlaster = F2( + function (model, smartphone) { + return (((model.parallelPlotOption.selectedFilter.ir_blaster === 'true') && A2($elm$core$Maybe$withDefault, false, smartphone.ir_blaster)) || (model.parallelPlotOption.selectedFilter.ir_blaster === 'all')) ? true : (((model.parallelPlotOption.selectedFilter.ir_blaster === 'false') && (!A2($elm$core$Maybe$withDefault, true, smartphone.ir_blaster))) ? true : false); + }); +var $author$project$ParallelCoordinates$hasNFC = F2( + function (model, smartphone) { + return (((model.parallelPlotOption.selectedFilter.nfc === 'true') && A2($elm$core$Maybe$withDefault, false, smartphone.nfc)) || (model.parallelPlotOption.selectedFilter.nfc === 'all')) ? true : (((model.parallelPlotOption.selectedFilter.nfc === 'false') && (!A2($elm$core$Maybe$withDefault, true, smartphone.nfc))) ? true : false); + }); var $elm$core$Maybe$andThen = F2( function (callback, maybeValue) { if (maybeValue.$ === 'Just') { @@ -9654,9 +9782,67 @@ var $author$project$ParallelCoordinates$mapToSPData = function (smartphone) { }; })(smartphone.price)(smartphone.rating)(smartphone.num_cores)(smartphone.processor_speed)(smartphone.battery)(smartphone.fast_charging)(smartphone.memory)(smartphone.ram)(smartphone.screen_size)(smartphone.refresh_rate); }; -var $author$project$ParallelCoordinates$filterSPData = function (smartphone) { - var smartphoneList = A2($elm$core$List$filterMap, $author$project$ParallelCoordinates$mapToSPData, smartphone); - return smartphoneList; +var $author$project$ParallelCoordinates$filterSPData = F2( + function (smartphone, model) { + var smartphoneList = A2( + $elm$core$List$filter, + $author$project$ParallelCoordinates$hasIRBlaster(model), + A2( + $elm$core$List$filter, + $author$project$ParallelCoordinates$hasNFC(model), + A2( + $elm$core$List$filter, + $author$project$ParallelCoordinates$has5G(model), + A2( + $elm$core$List$filter, + $author$project$ParallelCoordinates$fromBrand(model), + A2($elm$core$List$filterMap, $author$project$ParallelCoordinates$mapToSPData, smartphone))))); + return smartphoneList; + }); +var $elm$core$Set$Set_elm_builtin = function (a) { + return {$: 'Set_elm_builtin', a: a}; +}; +var $elm$core$Set$empty = $elm$core$Set$Set_elm_builtin($elm$core$Dict$empty); +var $elm$core$Set$insert = F2( + function (key, _v0) { + var dict = _v0.a; + return $elm$core$Set$Set_elm_builtin( + A3($elm$core$Dict$insert, key, _Utils_Tuple0, dict)); + }); +var $elm$core$Set$fromList = function (list) { + return A3($elm$core$List$foldl, $elm$core$Set$insert, $elm$core$Set$empty, list); +}; +var $elm$html$Html$Events$alwaysStop = function (x) { + return _Utils_Tuple2(x, true); +}; +var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { + return {$: 'MayStopPropagation', a: a}; +}; +var $elm$html$Html$Events$stopPropagationOn = F2( + function (event, decoder) { + return A2( + $elm$virtual_dom$VirtualDom$on, + event, + $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); + }); +var $elm$json$Json$Decode$at = F2( + function (fields, decoder) { + return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); + }); +var $elm$json$Json$Decode$string = _Json_decodeString; +var $elm$html$Html$Events$targetValue = A2( + $elm$json$Json$Decode$at, + _List_fromArray( + ['target', 'value']), + $elm$json$Json$Decode$string); +var $elm$html$Html$Events$onInput = function (tagger) { + return A2( + $elm$html$Html$Events$stopPropagationOn, + 'input', + A2( + $elm$json$Json$Decode$map, + $elm$html$Html$Events$alwaysStop, + A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); }; var $elm_community$typed_svg$TypedSvg$Types$Percent = function (a) { return {$: 'Percent', a: a}; @@ -11697,13 +11883,71 @@ var $author$project$ParallelCoordinates$parallelCoordinatesPlot = F2( ]), _Utils_ap(lines, yaxis))); }); +var $elm$html$Html$select = _VirtualDom_node('select'); var $author$project$ParallelCoordinates$viewParallelCoordinates = function (model) { - var filteredSmartphoneData = $author$project$ParallelCoordinates$filterSPData(model.data); + var otherFilterValues = _List_fromArray( + ['all', 'true', 'false']); + var filteredSmartphoneData = A2($author$project$ParallelCoordinates$filterSPData, model.data, model); + var brandList = $elm$core$Set$toList( + $elm$core$Set$fromList( + A2( + $elm$core$List$filterMap, + function ($) { + return $.brand; + }, + model.data))); + var brandFilterValues = A2($elm$core$List$cons, 'all', brandList); return A2( $elm$html$Html$div, _List_Nil, _List_fromArray( [ + $elm$html$Html$text(' Brand: '), + A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput($author$project$ParallelCoordinates$SetBrandParallel) + ]), + A2( + $elm$core$List$map, + $author$project$ParallelCoordinates$createSelectorOptions(model.parallelPlotOption.selectedFilter.brand), + brandFilterValues)), + $elm$html$Html$text(' 5G: '), + A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput($author$project$ParallelCoordinates$Set5GParallel) + ]), + A2( + $elm$core$List$map, + $author$project$ParallelCoordinates$createSelectorOptions(model.parallelPlotOption.selectedFilter.g5), + otherFilterValues)), + $elm$html$Html$text(' NFC: '), + A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput($author$project$ParallelCoordinates$SetNFCParallel) + ]), + A2( + $elm$core$List$map, + $author$project$ParallelCoordinates$createSelectorOptions(model.parallelPlotOption.selectedFilter.nfc), + otherFilterValues)), + $elm$html$Html$text(' IR-Blaster: '), + A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput($author$project$ParallelCoordinates$SetIRBlasterParallel) + ]), + A2( + $elm$core$List$map, + $author$project$ParallelCoordinates$createSelectorOptions(model.parallelPlotOption.selectedFilter.ir_blaster), + otherFilterValues)), + A2($elm$html$Html$br, _List_Nil, _List_Nil), + A2($elm$html$Html$br, _List_Nil, _List_Nil), A2($author$project$ParallelCoordinates$parallelCoordinatesPlot, model, filteredSmartphoneData) ])); }; @@ -11713,25 +11957,6 @@ var $author$project$Scatterplot$ChangeAttribute1 = function (a) { var $author$project$Scatterplot$ChangeAttribute2 = function (a) { return {$: 'ChangeAttribute2', a: a}; }; -var $elm$html$Html$option = _VirtualDom_node('option'); -var $elm$json$Json$Encode$bool = _Json_wrap; -var $elm$html$Html$Attributes$boolProperty = F2( - function (key, bool) { - return A2( - _VirtualDom_property, - key, - $elm$json$Json$Encode$bool(bool)); - }); -var $elm$html$Html$Attributes$selected = $elm$html$Html$Attributes$boolProperty('selected'); -var $elm$json$Json$Encode$string = _Json_wrap; -var $elm$html$Html$Attributes$stringProperty = F2( - function (key, string) { - return A2( - _VirtualDom_property, - key, - $elm$json$Json$Encode$string(string)); - }); -var $elm$html$Html$Attributes$value = $elm$html$Html$Attributes$stringProperty('value'); var $author$project$Scatterplot$createSelectorOptions = F2( function (select, att) { return _Utils_eq(select, att) ? A2( @@ -11755,39 +11980,6 @@ var $author$project$Scatterplot$createSelectorOptions = F2( $elm$html$Html$text(att) ])); }); -var $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); -}; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 'MayStopPropagation', a: a}; -}; -var $elm$html$Html$Events$stopPropagationOn = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); - }); -var $elm$json$Json$Decode$at = F2( - function (fields, decoder) { - return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); - }); -var $elm$json$Json$Decode$string = _Json_decodeString; -var $elm$html$Html$Events$targetValue = A2( - $elm$json$Json$Decode$at, - _List_fromArray( - ['target', 'value']), - $elm$json$Json$Decode$string); -var $elm$html$Html$Events$onInput = function (tagger) { - return A2( - $elm$html$Html$Events$stopPropagationOn, - 'input', - A2( - $elm$json$Json$Decode$map, - $elm$html$Html$Events$alwaysStop, - A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); -}; -var $elm$html$Html$select = _VirtualDom_node('select'); var $author$project$Scatterplot$attributeSelector = F2( function (attNr, model) { var attributes = _List_fromArray( @@ -13371,7 +13563,7 @@ var $author$project$TreeView$label = function (item) { function (c, _v1) { var word = _v1.a; var soFar = _v1.b; - return $elm$core$Char$isUpper(c) ? _Utils_Tuple2( + return ($elm$core$Char$toCode(c) === 32) ? _Utils_Tuple2( _List_fromArray( [c]), function () { @@ -15006,7 +15198,6 @@ var $author$project$TreeView$fromBrand = F2( model.treeOption.selectedFilter.brand, A2($elm$core$Maybe$withDefault, '', smartphone.brand)) || (model.treeOption.selectedFilter.brand === 'all')) ? true : false; }); -var $elm$core$Basics$not = _Basics_not; var $author$project$TreeView$has5G = F2( function (model, smartphone) { return (((model.treeOption.selectedFilter.g5 === 'true') && A2($elm$core$Maybe$withDefault, false, smartphone.g5)) || (model.treeOption.selectedFilter.g5 === 'all')) ? true : (((model.treeOption.selectedFilter.g5 === 'false') && (!A2($elm$core$Maybe$withDefault, true, smartphone.g5))) ? true : false); @@ -15019,55 +15210,8 @@ var $author$project$TreeView$hasNFC = F2( function (model, smartphone) { return (((model.treeOption.selectedFilter.nfc === 'true') && A2($elm$core$Maybe$withDefault, false, smartphone.nfc)) || (model.treeOption.selectedFilter.nfc === 'all')) ? true : (((model.treeOption.selectedFilter.nfc === 'false') && (!A2($elm$core$Maybe$withDefault, true, smartphone.nfc))) ? true : false); }); -var $author$project$TreeView$mapToSPData = function (smartphone) { - return $author$project$ExtendedFunctions$map10( - function (brand) { - return function (model) { - return function (price) { - return function (rating) { - return function (battery) { - return function (processor_name) { - return function (memory) { - return function (ram) { - return function (screen_size) { - return function (refresh_rate) { - return { - battery: $elm$core$Maybe$Just(battery), - brand: $elm$core$Maybe$Just(brand), - camera: smartphone.camera, - card: smartphone.card, - fast_charging: smartphone.fast_charging, - g5: smartphone.g5, - id: smartphone.id, - ir_blaster: smartphone.ir_blaster, - memory: $elm$core$Maybe$Just(memory), - model: $elm$core$Maybe$Just(model), - nfc: smartphone.nfc, - num_cores: smartphone.num_cores, - os: smartphone.os, - price: $elm$core$Maybe$Just(price), - processor_brand: smartphone.processor_brand, - processor_name: $elm$core$Maybe$Just(processor_name), - processor_speed: smartphone.processor_speed, - ram: $elm$core$Maybe$Just(ram), - rating: $elm$core$Maybe$Just(rating), - refresh_rate: $elm$core$Maybe$Just(refresh_rate), - resolution: smartphone.resolution, - screen_size: $elm$core$Maybe$Just(screen_size) - }; - }; - }; - }; - }; - }; - }; - }; - }; - }; - })(smartphone.brand)(smartphone.model)(smartphone.price)(smartphone.rating)(smartphone.battery)(smartphone.processor_name)(smartphone.memory)(smartphone.ram)(smartphone.screen_size)(smartphone.refresh_rate); -}; var $author$project$TreeView$filterSPData = F2( - function (model, smartphone) { + function (model, smartphones) { var smartphoneList = A2( $elm$core$List$filter, $author$project$TreeView$hasIRBlaster(model), @@ -15080,18 +15224,23 @@ var $author$project$TreeView$filterSPData = F2( A2( $elm$core$List$filter, $author$project$TreeView$fromBrand(model), - A2($elm$core$List$filterMap, $author$project$TreeView$mapToSPData, smartphone))))); + smartphones)))); return smartphoneList; }); -var $author$project$TreeView$getTreeString = function (smartphone) { - return { - id: A2($elm$core$Maybe$withDefault, '-1', smartphone.id), - name: 'Smartphone.' + (A2($elm$core$Maybe$withDefault, '', smartphone.brand) + ('.' + A2($elm$core$Maybe$withDefault, '', smartphone.model))), - size: 1000 - }; -}; +var $author$project$TreeView$getTreeString = F2( + function (nodeCount, smartphone) { + return { + id: A2($elm$core$Maybe$withDefault, '-1', smartphone.id), + name: 'Smartphone.' + (A2($elm$core$Maybe$withDefault, '', smartphone.brand) + ('.' + A2($elm$core$Maybe$withDefault, '', smartphone.model))), + size: (nodeCount < 20) ? 1000000 : (((nodeCount >= 20) && (nodeCount < 40)) ? 500000 : (((nodeCount >= 40) && (nodeCount < 70)) ? 200000 : (((nodeCount >= 70) && (nodeCount < 100)) ? 50000 : (((nodeCount >= 100) && (nodeCount < 200)) ? 20000 : (((nodeCount >= 200) && (nodeCount < 300)) ? 5000 : (((nodeCount >= 300) && (nodeCount < 500)) ? 1000 : 500)))))) + }; + }); var $author$project$TreeView$getTreeData = function (smartphones) { - return A2($elm$core$List$map, $author$project$TreeView$getTreeString, smartphones); + var listlength = $elm$core$List$length(smartphones); + return A2( + $elm$core$List$map, + $author$project$TreeView$getTreeString(listlength), + smartphones); }; var $elm$core$List$sortWith = _List_sortWith; var $gampleman$elm_rosetree$Tree$sortWith = F2( @@ -15131,16 +15280,6 @@ var $gampleman$elm_rosetree$Tree$children = function (_v0) { var c = _v0.b; return c; }; -var $elm$core$Set$Set_elm_builtin = function (a) { - return {$: 'Set_elm_builtin', a: a}; -}; -var $elm$core$Set$empty = $elm$core$Set$Set_elm_builtin($elm$core$Dict$empty); -var $elm$core$Set$insert = F2( - function (key, _v0) { - var dict = _v0.a; - return $elm$core$Set$Set_elm_builtin( - A3($elm$core$Dict$insert, key, _Utils_Tuple0, dict)); - }); var $elm$core$Dict$member = F2( function (key, dict) { var _v0 = A2($elm$core$Dict$get, key, dict); @@ -15544,11 +15683,11 @@ var $author$project$TreeView$layedOut = function (model) { if (kind.$ === 'Leaf') { return _Utils_Tuple2( $elm$core$Basics$sqrt(size) / 1.1, - $elm$core$Basics$sqrt(size) * 1.1); + $elm$core$Basics$sqrt(size) * 2.5); } else { return _Utils_Tuple2( - $elm$core$Basics$sqrt(size) * 1.05, - $elm$core$Basics$sqrt(size) / 1.05); + $elm$core$Basics$sqrt(size) * 1.7, + $elm$core$Basics$sqrt(size) / 1.1); } }), $gampleman$elm_visualization$Hierarchy$parentChildMargin(900), @@ -15788,9 +15927,6 @@ var $author$project$TreeView$createViewTree = function (model) { ])), nodeCounts); }; -var $elm$core$Set$fromList = function (list) { - return A3($elm$core$List$foldl, $elm$core$Set$insert, $elm$core$Set$empty, list); -}; var $author$project$TreeView$viewTree = function (model) { var treeViewInfo = $author$project$TreeView$createViewTree(model); var treeView = treeViewInfo.a; diff --git a/src/Main.elm b/src/Main.elm index 38995cd3fcbdd7938eaec0a723889a203ae040a6..8802cc26074cdc93018dd97c4ac131bd97c6bfcc 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -54,6 +54,12 @@ init _ = , "Screen Size" , "Refresh Rate" ] + , selectedFilter = + { brand = "all" + , g5 = "all" + , nfc = "all" + , ir_blaster = "all" + } } { zoomOption = Zoom.init { width = TreeView.w, height = TreeView.h } @@ -63,7 +69,7 @@ init _ = , inputDropCount = "" , selectedFilter = { brand = "all" - , g5 = "false" + , g5 = "true" , nfc = "false" , ir_blaster = "false" } @@ -180,6 +186,7 @@ update msg model = | parallelPlotOption = { orderedList = List.Extra.swapAt pos1 pos2 model.parallelPlotOption.orderedList , orderedLabels = List.Extra.swapAt pos1 pos2 model.parallelPlotOption.orderedLabels + , selectedFilter = model.parallelPlotOption.selectedFilter } } , Cmd.none @@ -198,6 +205,70 @@ update msg model = , Cmd.none ) + ParallelCoordinatesMsg (SetBrandParallel value) -> + ( { model + | parallelPlotOption = + { orderedList = model.parallelPlotOption.orderedList + , orderedLabels = model.parallelPlotOption.orderedLabels + , selectedFilter = + { brand = value + , g5 = model.parallelPlotOption.selectedFilter.g5 + , nfc = model.parallelPlotOption.selectedFilter.nfc + , ir_blaster = model.parallelPlotOption.selectedFilter.ir_blaster + } + } + } + , Cmd.none + ) + + ParallelCoordinatesMsg (Set5GParallel value) -> + ( { model + | parallelPlotOption = + { orderedList = model.parallelPlotOption.orderedList + , orderedLabels = model.parallelPlotOption.orderedLabels + , selectedFilter = + { brand = model.parallelPlotOption.selectedFilter.brand + , g5 = value + , nfc = model.parallelPlotOption.selectedFilter.nfc + , ir_blaster = model.parallelPlotOption.selectedFilter.ir_blaster + } + } + } + , Cmd.none + ) + + ParallelCoordinatesMsg (SetNFCParallel value) -> + ( { model + | parallelPlotOption = + { orderedList = model.parallelPlotOption.orderedList + , orderedLabels = model.parallelPlotOption.orderedLabels + , selectedFilter = + { brand = model.parallelPlotOption.selectedFilter.brand + , g5 = model.parallelPlotOption.selectedFilter.g5 + , nfc = value + , ir_blaster = model.parallelPlotOption.selectedFilter.ir_blaster + } + } + } + , Cmd.none + ) + + ParallelCoordinatesMsg (SetIRBlasterParallel value) -> + ( { model + | parallelPlotOption = + { orderedList = model.parallelPlotOption.orderedList + , orderedLabels = model.parallelPlotOption.orderedLabels + , selectedFilter = + { brand = model.parallelPlotOption.selectedFilter.brand + , g5 = model.parallelPlotOption.selectedFilter.g5 + , nfc = model.parallelPlotOption.selectedFilter.nfc + , ir_blaster = value + } + } + } + , Cmd.none + ) + TreeViewMsg (ZoomMsg m) -> ( { model | treeOption = diff --git a/src/Model.elm b/src/Model.elm index 548dac27bca356b196ce57710c5a7ccbe5488dae..a0764f60dc84cc0f35ca19cd104fbdabe2a3799c 100644 --- a/src/Model.elm +++ b/src/Model.elm @@ -32,6 +32,7 @@ type alias ScatterPlotOption = type alias ParallelPlotOption = { orderedList : List (Smartphone -> Maybe Float) , orderedLabels : List String + , selectedFilter : FilterOptions } diff --git a/src/ParallelCoordinates.elm b/src/ParallelCoordinates.elm index 2bd2c2d2922ba6e1c8468275a8edbd3b75834fd0..55387c2ed64f290eaa84841a7d14b9d696848b7e 100644 --- a/src/ParallelCoordinates.elm +++ b/src/ParallelCoordinates.elm @@ -3,13 +3,15 @@ module ParallelCoordinates exposing (..) import Axis exposing (..) import Color import ExtendedFunctions exposing (listmap10, map10) -import Html exposing (Html, text) -import Html.Events exposing (onClick) +import Html exposing (Html, br, option, select, text) +import Html.Attributes exposing (selected, value) +import Html.Events exposing (onClick, onInput) import List import Maybe import Model exposing (Model) import Path import Scale exposing (ContinuousScale) +import Set import Shape import SmartPhoneType exposing (Smartphone) import Statistics @@ -231,18 +233,77 @@ wideExtent values = filterSPData : List Smartphone + -> Model -> List Smartphone -filterSPData smartphone = +filterSPData smartphone model = let smartphoneList = - List.filterMap mapToSPData smartphone - - -- smartphoneFromBrand = - -- List.filter (isSmartphoneFromBrand brand) smartphoneList + List.filter (hasIRBlaster model) <| + List.filter (hasNFC model) <| + List.filter (has5G model) <| + List.filter (fromBrand model) <| + List.filterMap mapToSPData smartphone in smartphoneList +fromBrand : Model -> Smartphone -> Bool +fromBrand model smartphone = + if model.parallelPlotOption.selectedFilter.brand == Maybe.withDefault "" smartphone.brand || model.parallelPlotOption.selectedFilter.brand == "all" then + True + + else + False + + +has5G : Model -> Smartphone -> Bool +has5G model smartphone = + if + (model.parallelPlotOption.selectedFilter.g5 == "true" && Maybe.withDefault False smartphone.g5) + || model.parallelPlotOption.selectedFilter.g5 + == "all" + then + True + + else if model.parallelPlotOption.selectedFilter.g5 == "false" && not (Maybe.withDefault True smartphone.g5) then + True + + else + False + + +hasNFC : Model -> Smartphone -> Bool +hasNFC model smartphone = + if + (model.parallelPlotOption.selectedFilter.nfc == "true" && Maybe.withDefault False smartphone.nfc) + || model.parallelPlotOption.selectedFilter.nfc + == "all" + then + True + + else if model.parallelPlotOption.selectedFilter.nfc == "false" && not (Maybe.withDefault True smartphone.nfc) then + True + + else + False + + +hasIRBlaster : Model -> Smartphone -> Bool +hasIRBlaster model smartphone = + if + (model.parallelPlotOption.selectedFilter.ir_blaster == "true" && Maybe.withDefault False smartphone.ir_blaster) + || model.parallelPlotOption.selectedFilter.ir_blaster + == "all" + then + True + + else if model.parallelPlotOption.selectedFilter.ir_blaster == "false" && not (Maybe.withDefault True smartphone.ir_blaster) then + True + + else + False + + mapToSPData : Smartphone -> Maybe Smartphone mapToSPData smartphone = map10 @@ -283,66 +344,48 @@ mapToSPData smartphone = smartphone.refresh_rate - -{- carInCarType : CarType -> CarData -> Bool - carInCarType carType carData = - if carData.carType == carType then - True - - else - False --} -{- transfromCarDataToMultiDimData : List ( String, List ( Float, String ) ) -> MultiDimData - transfromCarDataToMultiDimData dimList = - let - dimDescription = - List.map Tuple.first (List.map transformToMultiDimTupel dimList) - - data = - List.map Tuple.second (List.map transformToMultiDimTupel dimList) - in - MultiDimData dimDescription data - - - - transformToMultiDimTupel : ( String, List ( Float, String ) ) -> ( String, List MultiDimPoint ) - transformToMultiDimTupel data = - let - multiDimPointList = - List.map transformToMultiDimPoint (Tuple.second data) - in - ( Tuple.first data, multiDimPointList ) - - - transformToMultiDimPoint : ( Float, String ) -> MultiDimPoint - transformToMultiDimPoint data = - MultiDimPoint (Tuple.second data) (Tuple.first data) --} - - viewParallelCoordinates : Model -> Html Msg viewParallelCoordinates model = let filteredSmartphoneData = - filterSPData model.data + filterSPData model.data model + + brandList = + Set.toList <| Set.fromList <| List.filterMap .brand model.data + + brandFilterValues = + "all" :: brandList + + otherFilterValues = + [ "all", "true", "false" ] in Html.div [] - [ {- button [ onClick (ChangeOrder 0 1) ] [ text "1<->2" ] - , button [ onClick (ChangeOrder 1 2) ] [ text "2<->3" ] - , button [ onClick (ChangeOrder 2 3) ] [ text "3<->4" ] - , button [ onClick (ChangeOrder 3 4) ] [ text "4<->5" ] - , button [ onClick (ChangeOrder 4 5) ] [ text "5<->6" ] - , button [ onClick (ChangeOrder 5 6) ] [ text "6<->7" ] - , button [ onClick (ChangeOrder 6 7) ] [ text "7<->8" ] - , button [ onClick (ChangeOrder 7 8) ] [ text "8<->9" ] - , button [ onClick (ChangeOrder 8 9) ] [ text "9<->10" ] - , br [] [] - , br [] [] - -} - parallelCoordinatesPlot model filteredSmartphoneData + [ text " Brand: " + , select [ onInput SetBrandParallel ] (List.map (createSelectorOptions model.parallelPlotOption.selectedFilter.brand) brandFilterValues) + , text " 5G: " + , select [ onInput Set5GParallel ] + (List.map (createSelectorOptions model.parallelPlotOption.selectedFilter.g5) otherFilterValues) + , text " NFC: " + , select [ onInput SetNFCParallel ] + (List.map (createSelectorOptions model.parallelPlotOption.selectedFilter.nfc) otherFilterValues) + , text " IR-Blaster: " + , select [ onInput SetIRBlasterParallel ] + (List.map (createSelectorOptions model.parallelPlotOption.selectedFilter.ir_blaster) otherFilterValues) + , br [] [] + , br [] [] + , parallelCoordinatesPlot model filteredSmartphoneData ] +createSelectorOptions : String -> String -> Html Msg +createSelectorOptions select valueOption = + if select == valueOption then + option [ value valueOption, selected True ] [ Html.text valueOption ] + + else + option [ value valueOption ] [ Html.text valueOption ] + + type alias MultiDimPoint = { pointName : String, value : Float } @@ -356,3 +399,7 @@ type alias MultiDimData = type Msg = ChangeOrder Int Int | SetScatterPlotFromParallelPlot String String + | SetBrandParallel String + | Set5GParallel String + | SetNFCParallel String + | SetIRBlasterParallel String diff --git a/src/TreeView.elm b/src/TreeView.elm index b9f8eb8b260c7c1b6fdfc924817f1947c6c40ba9..80f8d704e88cc34eb8a40f779e19cef9a0fb9c06 100644 --- a/src/TreeView.elm +++ b/src/TreeView.elm @@ -3,7 +3,6 @@ module TreeView exposing (..) import Color import Curve import Debug exposing (toString) -import ExtendedFunctions exposing (map10) import Hierarchy import Html exposing (Html, br, button, div, input, option, select, text) import Html.Attributes exposing (selected, value) @@ -56,10 +55,10 @@ layedOut model = (\{ kind, size } -> case kind of Leaf -> - ( sqrt size / 1.1, sqrt size * 1.1 ) + ( sqrt size / 1.1, sqrt size * 2.5 ) Node -> - ( sqrt size * 1.05, sqrt size / 1.05 ) + ( sqrt size * 1.7, sqrt size / 1.1 ) ) , Hierarchy.parentChildMargin 900 , Hierarchy.peerMargin 60 @@ -296,7 +295,7 @@ label item = -- , ( item.width, corner ) -- ] ] - [ fill (Paint (Color.rgb 1 1 0.8)) -- yellow + [ fill (Paint (Color.rgb 1 1 0.8)) , stroke (Paint Color.black) , style "vector-effect: non-scaling-stroke" , id ("path-" ++ item.node.name) @@ -312,7 +311,7 @@ label item = |> Maybe.withDefault item.node.name |> String.foldl (\c ( word, soFar ) -> - if Char.isUpper c then + if Char.toCode c == 32 then ( [ c ] , case word of [] -> @@ -412,26 +411,53 @@ tree model = getTreeData : List Smartphone -> List { name : String, id : String, size : Float } getTreeData smartphones = - List.map getTreeString smartphones + let + listlength = + List.length smartphones + in + List.map (getTreeString listlength) smartphones -getTreeString : Smartphone -> { name : String, id : String, size : Float } -getTreeString smartphone = +getTreeString : Int -> Smartphone -> { name : String, id : String, size : Float } +getTreeString nodeCount smartphone = { name = "Smartphone." ++ Maybe.withDefault "" smartphone.brand ++ "." ++ Maybe.withDefault "" smartphone.model , id = Maybe.withDefault "-1" smartphone.id - , size = 1000 + , size = + if nodeCount < 20 then + 1000000 + + else if nodeCount >= 20 && nodeCount < 40 then + 500000 + + else if nodeCount >= 40 && nodeCount < 70 then + 200000 + + else if nodeCount >= 70 && nodeCount < 100 then + 50000 + + else if nodeCount >= 100 && nodeCount < 200 then + 20000 + + else if nodeCount >= 200 && nodeCount < 300 then + 5000 + + else if nodeCount >= 300 && nodeCount < 500 then + 1000 + + else + 500 } filterSPData : Model -> List Smartphone -> List Smartphone -filterSPData model smartphone = +filterSPData model smartphones = let smartphoneList = List.filter (hasIRBlaster model) <| List.filter (hasNFC model) <| List.filter (has5G model) <| List.filter (fromBrand model) <| - List.filterMap mapToSPData smartphone + smartphones in smartphoneList @@ -493,47 +519,46 @@ hasIRBlaster model smartphone = False -mapToSPData : Smartphone -> Maybe Smartphone -mapToSPData smartphone = - map10 - (\brand model price rating battery processor_name memory ram screen_size refresh_rate -> - { id = smartphone.id - , brand = Just brand - , model = Just model - , price = Just price - , rating = Just rating - , g5 = smartphone.g5 - , nfc = smartphone.nfc - , ir_blaster = smartphone.ir_blaster - , processor_name = Just processor_name - , processor_brand = smartphone.processor_brand - , num_cores = smartphone.num_cores - , processor_speed = smartphone.processor_speed - , battery = Just battery - , fast_charging = smartphone.fast_charging - , memory = Just memory - , ram = Just ram - , screen_size = Just screen_size - , resolution = smartphone.resolution - , refresh_rate = Just refresh_rate - , camera = smartphone.camera - , card = smartphone.card - , os = smartphone.os - } - ) - smartphone.brand - smartphone.model - smartphone.price - smartphone.rating - smartphone.battery - smartphone.processor_name - smartphone.memory - smartphone.ram - smartphone.screen_size - smartphone.refresh_rate - - +{- mapToSPData : Smartphone -> Maybe Smartphone + mapToSPData smartphone = + map10 + (\brand model price rating battery processor_name memory ram screen_size refresh_rate -> + { id = smartphone.id + , brand = Just brand + , model = Just model + , price = Just price + , rating = Just rating + , g5 = smartphone.g5 + , nfc = smartphone.nfc + , ir_blaster = smartphone.ir_blaster + , processor_name = Just processor_name + , processor_brand = smartphone.processor_brand + , num_cores = smartphone.num_cores + , processor_speed = smartphone.processor_speed + , battery = Just battery + , fast_charging = smartphone.fast_charging + , memory = Just memory + , ram = Just ram + , screen_size = Just screen_size + , resolution = smartphone.resolution + , refresh_rate = Just refresh_rate + , camera = smartphone.camera + , card = smartphone.card + , os = smartphone.os + } + ) + smartphone.brand + smartphone.model + smartphone.price + smartphone.rating + smartphone.battery + smartphone.processor_name + smartphone.memory + smartphone.ram + smartphone.screen_size + smartphone.refresh_rate +-} {- mapToSPData : Smartphone -> Maybe Smartphone mapToSPData smartphone = map21