From 6c68a93f328088ab6190feef8288f57813ec96f2 Mon Sep 17 00:00:00 2001 From: tomschindler <tom.schindler@student.uni-halle.de> Date: Wed, 26 Jun 2024 13:25:10 +0200 Subject: [PATCH] Scatterplot Attribute wechselbar --- public/index.html | 2 +- public/main.js | 518 ++++++++++++++++++++++++++++---------------- public/style.css | 4 +- src/Main.elm | 85 ++++++-- src/Scatterplot.elm | 126 ++++++++--- 5 files changed, 495 insertions(+), 240 deletions(-) diff --git a/public/index.html b/public/index.html index 8dc6556..57ee4ac 100644 --- a/public/index.html +++ b/public/index.html @@ -2,7 +2,7 @@ <html> <head> - <link rel="stylesheet" href="style.css"> + <!--<link rel="stylesheet" href="style.css">--> <script src="main.js"></script> </head> diff --git a/public/main.js b/public/main.js index 7eb45c1..5559943 100644 --- a/public/main.js +++ b/public/main.js @@ -5371,9 +5371,9 @@ var $elm$core$Task$perform = F2( A2($elm$core$Task$map, toMessage, task))); }); var $elm$browser$Browser$element = _Browser_element; -var $author$project$Main$Model = F3( - function (data, error, csvdata) { - return {csvdata: csvdata, data: data, error: error}; +var $author$project$Main$Model = F4( + function (data, error, csvdata, scatterplotOptions) { + return {csvdata: csvdata, data: data, error: error, scatterplotOptions: scatterplotOptions}; }); var $author$project$Main$DataReceived = function (a) { return {$: 'DataReceived', a: a}; @@ -6164,7 +6164,12 @@ var $author$project$Main$fetchData = $elm$http$Http$get( }); var $author$project$Main$init = function (_v0) { return _Utils_Tuple2( - A3($author$project$Main$Model, _List_Nil, $elm$core$Maybe$Nothing, ''), + A4( + $author$project$Main$Model, + _List_Nil, + $elm$core$Maybe$Nothing, + '', + {att1List: _List_Nil, att2List: _List_Nil, attribute1: 'Price', attribute2: 'Rating'}), $author$project$Main$fetchData); }; var $elm$core$Platform$Sub$batch = _Platform_batch; @@ -6172,6 +6177,60 @@ var $elm$core$Platform$Sub$none = $elm$core$Platform$Sub$batch(_List_Nil); var $author$project$Main$subscriptions = function (_v0) { return $elm$core$Platform$Sub$none; }; +var $author$project$Main$createAttList = F2( + function (model, att) { + return (att === 'Price') ? A2( + $elm$core$List$map, + function ($) { + return $.price; + }, + model.data) : ((att === 'Rating') ? A2( + $elm$core$List$map, + function ($) { + return $.rating; + }, + model.data) : ((att === 'NumCores') ? A2( + $elm$core$List$map, + function ($) { + return $.num_cores; + }, + model.data) : ((att === 'ProcessorSpeed') ? A2( + $elm$core$List$map, + function ($) { + return $.processor_speed; + }, + model.data) : ((att === 'Battery') ? A2( + $elm$core$List$map, + function ($) { + return $.battery; + }, + model.data) : ((att === 'FastCharging') ? A2( + $elm$core$List$map, + function ($) { + return $.fast_charging; + }, + model.data) : ((att === 'Memory') ? A2( + $elm$core$List$map, + function ($) { + return $.memory; + }, + model.data) : ((att === 'Ram') ? A2( + $elm$core$List$map, + function ($) { + return $.ram; + }, + model.data) : ((att === 'ScreenSize') ? A2( + $elm$core$List$map, + function ($) { + return $.screen_size; + }, + model.data) : ((att === 'RefreshRate') ? A2( + $elm$core$List$map, + function ($) { + return $.refresh_rate; + }, + model.data) : _List_Nil))))))))); + }); var $elm$core$Platform$Cmd$batch = _Platform_batch; var $elm$core$Platform$Cmd$none = $elm$core$Platform$Cmd$batch(_List_Nil); var $BrianHicks$elm_csv$Csv$Decode$FieldNamesFromFirstRow = {$: 'FieldNamesFromFirstRow'}; @@ -7158,21 +7217,6 @@ var $BrianHicks$elm_csv$Csv$Decode$float = $BrianHicks$elm_csv$Csv$Decode$fromSt $BrianHicks$elm_csv$Csv$Decode$ExpectedFloat(value)); } }); -var $BrianHicks$elm_csv$Csv$Decode$ExpectedInt = function (a) { - return {$: 'ExpectedInt', a: a}; -}; -var $BrianHicks$elm_csv$Csv$Decode$int = $BrianHicks$elm_csv$Csv$Decode$fromString( - function (value) { - var _v0 = $elm$core$String$toInt( - $elm$core$String$trim(value)); - if (_v0.$ === 'Just') { - var parsed = _v0.a; - return $elm$core$Result$Ok(parsed); - } else { - return $elm$core$Result$Err( - $BrianHicks$elm_csv$Csv$Decode$ExpectedInt(value)); - } - }); var $BrianHicks$elm_csv$Csv$Decode$into = $BrianHicks$elm_csv$Csv$Decode$succeed; var $BrianHicks$elm_csv$Csv$Decode$map2 = F3( function (transform, _v0, _v1) { @@ -7318,7 +7362,7 @@ var $author$project$Main$decoder = A2( A2( $BrianHicks$elm_csv$Csv$Decode$field, 'refresh_rate', - $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$int)), + $BrianHicks$elm_csv$Csv$Decode$blank($BrianHicks$elm_csv$Csv$Decode$float)), A2( $BrianHicks$elm_csv$Csv$Decode$pipeline, A2( @@ -7487,30 +7531,34 @@ var $author$project$Main$update = F2( $elm$core$Platform$Cmd$none); } default: - switch (msg.a.$) { - case 'ChangeText1': - var _v2 = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - {csvdata: 'Text1'}), - $elm$core$Platform$Cmd$none); - case 'ChangeText2': - var _v3 = msg.a; - return _Utils_Tuple2( - _Utils_update( - model, - {csvdata: 'Text2'}), - $elm$core$Platform$Cmd$none); - default: - var value = msg.a.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - csvdata: (value === 'Text1') ? 'Text1' : ((value === 'Text2') ? 'Text2' : '') - }), - $elm$core$Platform$Cmd$none); + if (msg.a.$ === 'ChangeAttribute1') { + var value = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + scatterplotOptions: { + att1List: A2($author$project$Main$createAttList, model, value), + att2List: model.scatterplotOptions.att2List, + attribute1: value, + attribute2: model.scatterplotOptions.attribute2 + } + }), + $elm$core$Platform$Cmd$none); + } else { + var value = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + scatterplotOptions: { + att1List: _List_Nil, + att2List: A2($author$project$Main$createAttList, model, value), + attribute1: model.scatterplotOptions.attribute1, + attribute2: value + } + }), + $elm$core$Platform$Cmd$none); } } }); @@ -7520,72 +7568,11 @@ var $author$project$Main$ScatterplotMsg = function (a) { var $elm$html$Html$div = _VirtualDom_node('div'); var $elm$virtual_dom$VirtualDom$map = _VirtualDom_map; var $elm$html$Html$map = $elm$virtual_dom$VirtualDom$map; -var $author$project$Scatterplot$ChangeText = function (a) { - return {$: 'ChangeText', a: a}; -}; -var $author$project$Scatterplot$ChangeText1 = {$: 'ChangeText1'}; -var $author$project$Scatterplot$ChangeText2 = {$: 'ChangeText2'}; -var $elm$html$Html$button = _VirtualDom_node('button'); -var $author$project$Scatterplot$XyData = F3( - function (xDescription, yDescription, data) { - return {data: data, xDescription: xDescription, yDescription: yDescription}; - }); -var $elm$core$String$fromFloat = _String_fromNumber; -var $elm$core$Maybe$map3 = F4( - function (func, ma, mb, mc) { - if (ma.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; - } else { - var a = ma.a; - if (mb.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; - } else { - var b = mb.a; - if (mc.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; - } else { - var c = mc.a; - return $elm$core$Maybe$Just( - A3(func, a, b, c)); - } - } - } - }); -var $author$project$Scatterplot$mapToPoint = function (smartphone) { - return A4( - $elm$core$Maybe$map3, - F3( - function (price, rating, id) { - return { - pointName: id + (' (' + ($elm$core$String$fromFloat(price) + (',' + ($elm$core$String$fromFloat(rating) + ')')))), - x: price, - y: rating - }; - }), - smartphone.price, - smartphone.memory, - smartphone.id); -}; -var $author$project$Scatterplot$filterSmartphones = function (smartphoneList) { - var filteredSmartphones = A2($elm$core$List$filterMap, $author$project$Scatterplot$mapToPoint, smartphoneList); - return A3($author$project$Scatterplot$XyData, 'price', 'memory', filteredSmartphones); +var $author$project$Scatterplot$ChangeAttribute1 = function (a) { + return {$: 'ChangeAttribute1', a: a}; }; -var $elm$virtual_dom$VirtualDom$Normal = function (a) { - return {$: 'Normal', a: a}; -}; -var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; -var $elm$html$Html$Events$on = F2( - function (event, decoder) { - return A2( - $elm$virtual_dom$VirtualDom$on, - event, - $elm$virtual_dom$VirtualDom$Normal(decoder)); - }); -var $elm$html$Html$Events$onClick = function (msg) { - return A2( - $elm$html$Html$Events$on, - 'click', - $elm$json$Json$Decode$succeed(msg)); +var $author$project$Scatterplot$ChangeAttribute2 = function (a) { + return {$: 'ChangeAttribute2', a: a}; }; var $elm$html$Html$Events$alwaysStop = function (x) { return _Utils_Tuple2(x, true); @@ -7593,6 +7580,7 @@ var $elm$html$Html$Events$alwaysStop = function (x) { var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { return {$: 'MayStopPropagation', a: a}; }; +var $elm$virtual_dom$VirtualDom$on = _VirtualDom_on; var $elm$html$Html$Events$stopPropagationOn = F2( function (event, decoder) { return A2( @@ -7621,6 +7609,218 @@ var $elm$html$Html$Events$onInput = function (tagger) { A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetValue))); }; var $elm$html$Html$option = _VirtualDom_node('option'); +var $elm$html$Html$select = _VirtualDom_node('select'); +var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; +var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; +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$attributeSelector = function (attNr) { + return A2( + $elm$html$Html$select, + _List_fromArray( + [ + $elm$html$Html$Events$onInput( + (attNr === 1) ? $author$project$Scatterplot$ChangeAttribute1 : $author$project$Scatterplot$ChangeAttribute2) + ]), + _Utils_ap( + (attNr === 1) ? _List_fromArray( + [ + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Price') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Price') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Rating') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Rating') + ])) + ]) : _List_fromArray( + [ + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Rating') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Rating') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Price') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Price') + ])) + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('NumCores') + ]), + _List_fromArray( + [ + $elm$html$Html$text('NumCores') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('ProcessorSpeed') + ]), + _List_fromArray( + [ + $elm$html$Html$text('ProcessorSpeed') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Battery') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Battery') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('FastCharging') + ]), + _List_fromArray( + [ + $elm$html$Html$text('FastCharging') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Memory') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Memory') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('Ram') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Ram') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('ScreenSize') + ]), + _List_fromArray( + [ + $elm$html$Html$text('ScreenSize') + ])), + A2( + $elm$html$Html$option, + _List_fromArray( + [ + $elm$html$Html$Attributes$value('RefreshRate') + ]), + _List_fromArray( + [ + $elm$html$Html$text('RefreshRate') + ])) + ]))); +}; +var $elm$html$Html$b = _VirtualDom_node('b'); +var $author$project$Scatterplot$XyData = F3( + function (xDescription, yDescription, data) { + return {data: data, xDescription: xDescription, yDescription: yDescription}; + }); +var $elm$core$List$map3 = _List_map3; +var $elm$core$String$fromFloat = _String_fromNumber; +var $elm$core$Maybe$map3 = F4( + function (func, ma, mb, mc) { + if (ma.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + var a = ma.a; + if (mb.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + var b = mb.a; + if (mc.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + var c = mc.a; + return $elm$core$Maybe$Just( + A3(func, a, b, c)); + } + } + } + }); +var $author$project$Scatterplot$mapToPoint = function (smartphoneData) { + return A4( + $elm$core$Maybe$map3, + F3( + function (att1, att2, name) { + return { + pointName: name + (' (' + ($elm$core$String$fromFloat(att1) + (',' + ($elm$core$String$fromFloat(att2) + ')')))), + x: att1, + y: att2 + }; + }), + smartphoneData.att1, + smartphoneData.att2, + smartphoneData.name); +}; +var $author$project$Scatterplot$filterSmartphonesXY = F3( + function (model, att1List, att2List) { + var modelList = A2( + $elm$core$List$map, + function ($) { + return $.model; + }, + model.data); + var smartphoneDataList = A4( + $elm$core$List$map3, + F3( + function (a1, a2, mn) { + return {att1: a1, att2: a2, name: mn}; + }), + att1List, + att2List, + modelList); + var filteredSmartphones = A2($elm$core$List$filterMap, $author$project$Scatterplot$mapToPoint, smartphoneDataList); + return A3($author$project$Scatterplot$XyData, model.scatterplotOptions.attribute1, model.scatterplotOptions.attribute2, filteredSmartphones); + }); var $elm_community$typed_svg$TypedSvg$Types$AnchorMiddle = {$: 'AnchorMiddle'}; var $elm_community$typed_svg$TypedSvg$Types$Percent = function (a) { return {$: 'Percent', a: a}; @@ -7754,8 +7954,6 @@ var $elm_community$typed_svg$TypedSvg$Attributes$InPx$r = function (value) { $elm_community$typed_svg$TypedSvg$Types$px(value)); }; var $author$project$Scatterplot$radius = 2.0; -var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; -var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; var $elm_community$typed_svg$TypedSvg$TypesToStrings$anchorAlignmentToString = function (anchorAlignment) { switch (anchorAlignment.$) { case 'AnchorInherit': @@ -8629,12 +8827,8 @@ var $author$project$Scatterplot$scatterplot = function (model) { }, model.data); var xScaleLocal = $author$project$Scatterplot$xScale(xValues); - var half = function (t) { - return (t.b - t.a) / 2; - }; var labelPositions = { - x: half( - $author$project$Scatterplot$wideExtent(xValues)), + x: $author$project$Scatterplot$wideExtent(xValues).b, y: $author$project$Scatterplot$wideExtent(yValues).b }; return A2( @@ -8654,7 +8848,7 @@ var $author$project$Scatterplot$scatterplot = function (model) { _List_Nil, _List_fromArray( [ - $elm_community$typed_svg$TypedSvg$Core$text('\r\n .point circle { stroke: rgba(0, 0, 0,0.4); fill: rgba(255, 255, 255,0.3); }\r\n .point text { display: none; }\r\n .point:hover circle { stroke: rgba(0, 0, 0,1.0); fill: rgb(118, 214, 78); }\r\n .point:hover text { display: inline; }\r\n ') + $elm_community$typed_svg$TypedSvg$Core$text('\n .point circle { stroke: rgba(0, 0, 0,0.4); fill: rgba(255, 255, 255,0.3); }\n .point text { display: none; }\n .point:hover circle { stroke: rgba(0, 0, 0,1.0); fill: rgb(118, 214, 78); }\n .point:hover text { display: inline; }\n ') ])), A2( $elm_community$typed_svg$TypedSvg$g, @@ -8682,7 +8876,7 @@ var $author$project$Scatterplot$scatterplot = function (model) { ]), _List_fromArray( [ - $elm$html$Html$text('Price') + $elm$html$Html$text(model.xDescription) ])) ])), A2( @@ -8711,7 +8905,7 @@ var $author$project$Scatterplot$scatterplot = function (model) { ]), _List_fromArray( [ - $elm$html$Html$text('Memory') + $elm$html$Html$text(model.yDescription) ])) ])), A2( @@ -8730,84 +8924,42 @@ var $author$project$Scatterplot$scatterplot = function (model) { model.data)) ])); }; -var $elm$html$Html$select = _VirtualDom_node('select'); -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$viewScatterplot = function (model) { - var filteredSmartphoneData = $author$project$Scatterplot$filterSmartphones(model.data); + var att2List = _Utils_eq(model.scatterplotOptions.att2List, _List_Nil) ? A2( + $elm$core$List$map, + function ($) { + return $.rating; + }, + model.data) : model.scatterplotOptions.att2List; + var att1List = _Utils_eq(model.scatterplotOptions.att1List, _List_Nil) ? A2( + $elm$core$List$map, + function ($) { + return $.price; + }, + model.data) : model.scatterplotOptions.att1List; + var filteredSmartphoneData = A3($author$project$Scatterplot$filterSmartphonesXY, model, att1List, att2List); return A2( $elm$html$Html$div, _List_Nil, _List_fromArray( [ A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Scatterplot$ChangeText1) - ]), - _List_fromArray( - [ - $elm$html$Html$text('Text1') - ])), - A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Events$onClick($author$project$Scatterplot$ChangeText2) - ]), + $elm$html$Html$b, + _List_Nil, _List_fromArray( [ - $elm$html$Html$text('Text2') + $elm$html$Html$text('Attribut 1: ') ])), + $author$project$Scatterplot$attributeSelector(1), A2( - $elm$html$Html$select, - _List_fromArray( - [ - $elm$html$Html$Events$onInput($author$project$Scatterplot$ChangeText) - ]), + $elm$html$Html$b, + _List_Nil, _List_fromArray( [ - A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value('') - ]), - _List_fromArray( - [ - $elm$html$Html$text('') - ])), - A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value('Text1') - ]), - _List_fromArray( - [ - $elm$html$Html$text('Text1') - ])), - A2( - $elm$html$Html$option, - _List_fromArray( - [ - $elm$html$Html$Attributes$value('Text2') - ]), - _List_fromArray( - [ - $elm$html$Html$text('Text2') - ])) + $elm$html$Html$text(' Attribut 2: ') ])), - $author$project$Scatterplot$scatterplot(filteredSmartphoneData), - $elm$html$Html$text(model.csvdata) + $author$project$Scatterplot$attributeSelector(2), + $author$project$Scatterplot$scatterplot(filteredSmartphoneData) ])); }; var $author$project$Main$view = function (model) { diff --git a/public/style.css b/public/style.css index 2129f86..ae1f65d 100644 --- a/public/style.css +++ b/public/style.css @@ -1,4 +1,4 @@ -body { +/* body { font-family: sans-serif; margin: auto; max-width: 1280px; @@ -20,7 +20,7 @@ body { .navbar a:hover { color: #ffffff; -} +} */ #test1 { background-color: blue; diff --git a/src/Main.elm b/src/Main.elm index cef1010..0d9364a 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -3,7 +3,6 @@ module Main exposing (..) import Browser import Csv.Decode as Decode exposing (Decoder) import Html exposing (Html, div) -import Html.Attributes exposing (id) import Http import Result exposing (Result(..)) import Scatterplot exposing (Msg(..)) @@ -41,7 +40,7 @@ type alias Smartphone = , ram : Maybe Float , screen_size : Maybe Float , resolution : Maybe String - , refresh_rate : Maybe Int + , refresh_rate : Maybe Float , camera : Maybe String , card : Maybe String , os : Maybe String @@ -52,12 +51,21 @@ type alias Model = { data : List Smartphone , error : Maybe String , csvdata : String + , scatterplotOptions : ScatterPlotOption + } + + +type alias ScatterPlotOption = + { attribute1 : String + , attribute2 : String + , att1List : List (Maybe Float) + , att2List : List (Maybe Float) } init : () -> ( Model, Cmd Msg ) init _ = - ( Model [] Nothing "", fetchData ) + ( Model [] Nothing "" { attribute1 = "Price", attribute2 = "Rating", att1List = [], att2List = [] }, fetchData ) @@ -91,28 +99,67 @@ update msg model = DataReceived (Err _) -> ( { model | error = Just "Failed to load data" }, Cmd.none ) - ScatterplotMsg Scatterplot.ChangeText1 -> - ( { model | csvdata = "Text1" }, Cmd.none ) - - ScatterplotMsg Scatterplot.ChangeText2 -> - ( { model | csvdata = "Text2" }, Cmd.none ) - - ScatterplotMsg (Scatterplot.ChangeText value) -> + ScatterplotMsg (ChangeAttribute1 value) -> ( { model - | csvdata = - if value == "Text1" then - "Text1" - - else if value == "Text2" then - "Text2" + | scatterplotOptions = + { attribute1 = value + , attribute2 = model.scatterplotOptions.attribute2 + , att1List = createAttList model value + , att2List = model.scatterplotOptions.att2List + } + } + , Cmd.none + ) - else - "" + ScatterplotMsg (ChangeAttribute2 value) -> + ( { model + | scatterplotOptions = + { attribute1 = model.scatterplotOptions.attribute1 + , attribute2 = value + , att1List = [] + , att2List = createAttList model value + } } , Cmd.none ) +createAttList : Model -> String -> List (Maybe Float) +createAttList model att = + if att == "Price" then + List.map .price model.data + + else if att == "Rating" then + List.map .rating model.data + + else if att == "NumCores" then + List.map .num_cores model.data + + else if att == "ProcessorSpeed" then + List.map .processor_speed model.data + + else if att == "Battery" then + List.map .battery model.data + + else if att == "FastCharging" then + List.map .fast_charging model.data + + else if att == "Memory" then + List.map .memory model.data + + else if att == "Ram" then + List.map .ram model.data + + else if att == "ScreenSize" then + List.map .screen_size model.data + + else if att == "RefreshRate" then + List.map .refresh_rate model.data + + else + [] + + -- VIEW @@ -166,7 +213,7 @@ decoder = |> Decode.pipeline (Decode.field "RAM" (Decode.blank Decode.float)) |> Decode.pipeline (Decode.field "screen_size" (Decode.blank Decode.string |> Decode.map toInche)) |> Decode.pipeline (Decode.field "resolution" (Decode.blank Decode.string)) - |> Decode.pipeline (Decode.field "refresh_rate" (Decode.blank Decode.int)) + |> Decode.pipeline (Decode.field "refresh_rate" (Decode.blank Decode.float)) |> Decode.pipeline (Decode.field "camera" (Decode.blank Decode.string)) |> Decode.pipeline (Decode.field "card" (Decode.blank Decode.string)) |> Decode.pipeline (Decode.field "os" (Decode.blank Decode.string)) diff --git a/src/Scatterplot.elm b/src/Scatterplot.elm index 0332953..f614d62 100644 --- a/src/Scatterplot.elm +++ b/src/Scatterplot.elm @@ -2,8 +2,8 @@ module Scatterplot exposing (..) import Axis exposing (..) import Html exposing (Html, option) -import Html.Attributes exposing (disabled, value) -import Html.Events exposing (onClick, onInput) +import Html.Attributes exposing (value) +import Html.Events exposing (onInput) import Scale exposing (ContinuousScale) import Statistics import TypedSvg exposing (circle, g, style, svg, text_) @@ -17,6 +17,15 @@ type alias Model = { data : List Smartphone , error : Maybe String , csvdata : String + , scatterplotOptions : ScatterPlotOption + } + + +type alias ScatterPlotOption = + { attribute1 : String + , attribute2 : String + , att1List : List (Maybe Float) + , att2List : List (Maybe Float) } @@ -43,7 +52,7 @@ type alias Smartphone = , ram : Maybe Float , screen_size : Maybe Float , resolution : Maybe String - , refresh_rate : Maybe Int + , refresh_rate : Maybe Float , camera : Maybe String , card : Maybe String , os : Maybe String @@ -102,13 +111,12 @@ scatterplot model = yScaleLocal = yScale yValues - half : ( Float, Float ) -> Float - half t = - (Tuple.second t - Tuple.first t) / 2 - + -- half : ( Float, Float ) -> Float + -- half t = + -- (Tuple.second t - Tuple.first t) / 2 labelPositions : { x : Float, y : Float } labelPositions = - { x = wideExtent xValues |> half + { x = wideExtent xValues |> Tuple.second , y = wideExtent yValues |> Tuple.second } in @@ -125,13 +133,13 @@ scatterplot model = [ xAxis xValues , text_ [ x (Scale.convert xScaleLocal labelPositions.x), y 30, textAnchor AnchorMiddle, fontSize <| Px 14 ] - [ Html.text "Price" ] + [ Html.text model.xDescription ] ] , g [ transform [ Translate (padding - 1) (padding - 1) ] ] [ yAxis yValues , text_ [ x 0, y (Scale.convert yScaleLocal labelPositions.y - 10), textAnchor AnchorMiddle, fontSize <| Px 14 ] - [ Html.text "Memory" ] + [ Html.text model.yDescription ] ] -- datenpunkte zeichnen @@ -208,49 +216,97 @@ type alias XyData = } -filterSmartphones : List Smartphone -> XyData -filterSmartphones smartphoneList = +filterSmartphonesXY : Model -> List (Maybe Float) -> List (Maybe Float) -> XyData +filterSmartphonesXY model att1List att2List = let + modelList = + List.map .model model.data + + smartphoneDataList = + List.map3 (\a1 a2 mn -> { att1 = a1, att2 = a2, name = mn }) att1List att2List modelList + filteredSmartphones = - List.filterMap mapToPoint smartphoneList + List.filterMap mapToPoint smartphoneDataList in - XyData "price" "memory" filteredSmartphones + XyData model.scatterplotOptions.attribute1 model.scatterplotOptions.attribute2 filteredSmartphones -mapToPoint : Smartphone -> Maybe Point -mapToPoint smartphone = +mapToPoint : { att1 : Maybe Float, att2 : Maybe Float, name : Maybe String } -> Maybe Point +mapToPoint smartphoneData = Maybe.map3 - (\price rating id -> - { pointName = id ++ " (" ++ String.fromFloat price ++ "," ++ String.fromFloat rating ++ ")" - , x = price - , y = rating + (\att1 att2 name -> + { pointName = name ++ " (" ++ String.fromFloat att1 ++ "," ++ String.fromFloat att2 ++ ")" + , x = att1 + , y = att2 } ) - smartphone.price - smartphone.memory - smartphone.id + smartphoneData.att1 + smartphoneData.att2 + smartphoneData.name viewScatterplot : Model -> Html Msg viewScatterplot model = let + att1List = + if model.scatterplotOptions.att1List == [] then + List.map .price model.data + + else + model.scatterplotOptions.att1List + + att2List = + if model.scatterplotOptions.att2List == [] then + List.map .rating model.data + + else + model.scatterplotOptions.att2List + filteredSmartphoneData = - filterSmartphones model.data + filterSmartphonesXY model att1List att2List in Html.div [] - [ Html.button [ onClick ChangeText1 ] [ Html.text "Text1" ] - , Html.button [ onClick ChangeText2 ] [ Html.text "Text2" ] - , Html.select [ onInput ChangeText ] - [ option [ value "" ] [ Html.text "" ] - , option [ value "Text1" ] [ Html.text "Text1" ] - , option [ value "Text2" ] [ Html.text "Text2" ] - ] + [ Html.b [] [ Html.text "Attribut 1: " ] + , attributeSelector 1 + , Html.b [] [ Html.text " Attribut 2: " ] + , attributeSelector 2 , scatterplot filteredSmartphoneData - , Html.text model.csvdata ] +attributeSelector : Int -> Html Msg +attributeSelector attNr = + Html.select + [ onInput + (if attNr == 1 then + ChangeAttribute1 + + else + ChangeAttribute2 + ) + ] + ((if attNr == 1 then + [ option [ value "Price" ] [ Html.text "Price" ] + , option [ value "Rating" ] [ Html.text "Rating" ] + ] + + else + [ option [ value "Rating" ] [ Html.text "Rating" ] + , option [ value "Price" ] [ Html.text "Price" ] + ] + ) + ++ [ option [ value "NumCores" ] [ Html.text "NumCores" ] + , option [ value "ProcessorSpeed" ] [ Html.text "ProcessorSpeed" ] + , option [ value "Battery" ] [ Html.text "Battery" ] + , option [ value "FastCharging" ] [ Html.text "FastCharging" ] + , option [ value "Memory" ] [ Html.text "Memory" ] + , option [ value "Ram" ] [ Html.text "Ram" ] + , option [ value "ScreenSize" ] [ Html.text "ScreenSize" ] + , option [ value "RefreshRate" ] [ Html.text "RefreshRate" ] + ] + ) + + type Msg - = ChangeText1 - | ChangeText2 - | ChangeText String + = ChangeAttribute1 String + | ChangeAttribute2 String -- GitLab