diff --git a/public/main.js b/public/main.js index e86b10fed054712542a3404f8bdbc58792a007a2..ba2eabf117a49415d06054c920f571a800745183 100644 --- a/public/main.js +++ b/public/main.js @@ -6319,7 +6319,7 @@ var $author$project$Main$init = function (_v0) { $gampleman$elm_visualization$Zoom$init( {height: $author$project$TreeView$h, width: $author$project$TreeView$w}))) }, - {modelID: '0'}, + {input: '', modelID: '0'}, {parallelCoordinatesPlot: false, scatterPlot: true, starPlot: false, treeView: false}), $author$project$Main$fetchData); }; @@ -9172,34 +9172,45 @@ var $author$project$Main$update = F2( $elm$core$Platform$Cmd$none); } case 'ScatterplotMsg': - 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); + switch (msg.a.$) { + case '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); + case 'ChangeAttribute2': + 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); + default: + var id = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + plotVisible: {parallelCoordinatesPlot: false, scatterPlot: false, starPlot: true, treeView: false}, + starplotOption: {input: model.starplotOption.input, modelID: id} + }), + $elm$core$Platform$Cmd$none); } case 'ParallelCoordinatesMsg': var _v2 = msg.a; @@ -9216,28 +9227,39 @@ var $author$project$Main$update = F2( }), $elm$core$Platform$Cmd$none); case 'TreeViewMsg': - if (msg.a.$ === 'ZoomMsg') { - var m = msg.a.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - treeOption: { - zoomOption: A2($gampleman$elm_visualization$Zoom$update, m, model.treeOption.zoomOption) - } - }), - $elm$core$Platform$Cmd$none); - } else { - var t = msg.a.a; - return _Utils_Tuple2( - _Utils_update( - model, - { - treeOption: { - zoomOption: A2($author$project$TreeView$performZoom, t, model.treeOption.zoomOption) - } - }), - $elm$core$Platform$Cmd$none); + switch (msg.a.$) { + case 'ZoomMsg': + var m = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + treeOption: { + zoomOption: A2($gampleman$elm_visualization$Zoom$update, m, model.treeOption.zoomOption) + } + }), + $elm$core$Platform$Cmd$none); + case 'Click': + var t = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + treeOption: { + zoomOption: A2($author$project$TreeView$performZoom, t, model.treeOption.zoomOption) + } + }), + $elm$core$Platform$Cmd$none); + default: + var id = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + plotVisible: {parallelCoordinatesPlot: false, scatterPlot: false, starPlot: true, treeView: false}, + starplotOption: {input: model.starplotOption.input, modelID: id} + }), + $elm$core$Platform$Cmd$none); } case 'ZooomMsg': var m = msg.a; @@ -9251,8 +9273,29 @@ var $author$project$Main$update = F2( }), $elm$core$Platform$Cmd$none); case 'StarplotMsg': - var _v3 = msg.a; - return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); + switch (msg.a.$) { + case 'Nothing1': + var _v3 = msg.a; + return _Utils_Tuple2(model, $elm$core$Platform$Cmd$none); + case 'InputChange': + var id = msg.a.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + starplotOption: {input: id, modelID: model.starplotOption.modelID} + }), + $elm$core$Platform$Cmd$none); + default: + var _v4 = msg.a; + return _Utils_Tuple2( + _Utils_update( + model, + { + starplotOption: {input: model.starplotOption.input, modelID: model.starplotOption.input} + }), + $elm$core$Platform$Cmd$none); + } case 'SetViewScatterplot': return _Utils_Tuple2( _Utils_update( @@ -9480,7 +9523,7 @@ var $avh4$elm_color$Color$RgbaSpace = F4( function (a, b, c, d) { return {$: 'RgbaSpace', a: a, b: b, c: c, d: d}; }); -var $avh4$elm_color$Color$black = A4($avh4$elm_color$Color$RgbaSpace, 0 / 255, 0 / 255, 0 / 255, 1.0); +var $avh4$elm_color$Color$darkBlue = A4($avh4$elm_color$Color$RgbaSpace, 32 / 255, 74 / 255, 135 / 255, 1.0); var $elm$svg$Svg$Attributes$d = _VirtualDom_attribute('d'); var $elm$svg$Svg$trustedNode = _VirtualDom_nodeNS('http://www.w3.org/2000/svg'); var $elm$svg$Svg$path = $elm$svg$Svg$trustedNode('path'); @@ -10241,7 +10284,7 @@ var $author$project$ParallelCoordinates$createLine = function (path) { _List_fromArray( [ $elm_community$typed_svg$TypedSvg$Attributes$stroke( - $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$black)), + $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$darkBlue)), $elm_community$typed_svg$TypedSvg$Attributes$strokeWidth( $elm_community$typed_svg$TypedSvg$Types$Px(0.5)), $elm_community$typed_svg$TypedSvg$Attributes$fill($elm_community$typed_svg$TypedSvg$Types$PaintNone) @@ -11259,7 +11302,7 @@ var $gampleman$elm_visualization$Scale$linear = F2( return $gampleman$elm_visualization$Scale$Scale( A2($gampleman$elm_visualization$Scale$Continuous$linear, range_, domain_)); }); -var $author$project$ParallelCoordinates$padding = 50; +var $author$project$ParallelCoordinates$padding = 60; var $author$project$ParallelCoordinates$defaultExtent = _Utils_Tuple2(0, 200000); var $gampleman$elm_visualization$Statistics$extentBy = F2( function (fn, list) { @@ -11463,7 +11506,7 @@ var $author$project$ParallelCoordinates$parallelCoordinatesPlot = F2( $elm_community$typed_svg$TypedSvg$svg, _List_fromArray( [ - A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$ParallelCoordinates$w + 45, $author$project$ParallelCoordinates$h + 45), + A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$ParallelCoordinates$w + 60, $author$project$ParallelCoordinates$h + 40), $elm_community$typed_svg$TypedSvg$Attributes$width( $elm_community$typed_svg$TypedSvg$Types$Percent(100)), $elm_community$typed_svg$TypedSvg$Attributes$height( @@ -11477,11 +11520,11 @@ var $author$project$ParallelCoordinates$parallelCoordinatesPlot = F2( _List_Nil, _List_fromArray( [ - $elm_community$typed_svg$TypedSvg$Core$text('\r\n .axis .tick text { display: none; }\r\n .axis:hover .tick text { display: inline; }\r\n ') + $elm_community$typed_svg$TypedSvg$Core$text('\r\n .axis .tick text { display: none; font-size:13px }\r\n .axis:hover .tick text { display: inline; }\r\n ') ])), A2($elm_community$typed_svg$TypedSvg$g, _List_Nil, _List_Nil) ]), - _Utils_ap(yaxis, lines))); + _Utils_ap(lines, yaxis))); }); var $author$project$ParallelCoordinates$viewParallelCoordinates = function (model) { var filteredSmartphoneData = $author$project$ParallelCoordinates$filterSPData(model.data); @@ -11757,6 +11800,9 @@ var $author$project$Scatterplot$filterSmartphonesXY = F3( }); var $author$project$Scatterplot$h = 450; var $author$project$Scatterplot$padding = 50; +var $author$project$Scatterplot$SetStarPlot = function (a) { + return {$: 'SetStarPlot', a: a}; +}; var $elm_community$typed_svg$TypedSvg$circle = $elm_community$typed_svg$TypedSvg$Core$node('circle'); var $elm_community$typed_svg$TypedSvg$Attributes$cx = function (length) { return A2( @@ -11812,7 +11858,9 @@ var $author$project$Scatterplot$point = F3( $elm_community$typed_svg$TypedSvg$Types$Px(10.0)), $elm_community$typed_svg$TypedSvg$Attributes$fontFamily( _List_fromArray( - ['sans-serif'])) + ['sans-serif'])), + $elm$html$Html$Events$onClick( + $author$project$Scatterplot$SetStarPlot(xyPoint.id)) ]), _List_fromArray( [ @@ -11839,7 +11887,7 @@ var $author$project$Scatterplot$point = F3( ]), _List_fromArray( [ - $elm$html$Html$text(xyPoint.pointName) + $elm$html$Html$text('ID:' + (xyPoint.id + (' | ' + xyPoint.pointName))) ])) ])); }); @@ -12052,6 +12100,46 @@ var $author$project$Scatterplot$viewScatterplot = function (model) { $author$project$Scatterplot$scatterplot(filteredSmartphoneData) ])); }; +var $author$project$Starplot$InputChange = function (a) { + return {$: 'InputChange', a: a}; +}; +var $author$project$Starplot$SubmitNumber = {$: 'SubmitNumber'}; +var $author$project$Starplot$starlength = 180; +var $author$project$Starplot$calculateStarValue = F3( + function (smartphone, max, func) { + if (smartphone.$ === 'Just') { + var sp = smartphone.a; + var _v1 = func(sp); + if (_v1.$ === 'Just') { + var sV = _v1.a; + if (max.$ === 'Just') { + var m = max.a; + return (sV / m) * $author$project$Starplot$starlength; + } else { + return -1; + } + } else { + return -1; + } + } else { + return -1; + } + }); +var $elm$core$List$maximum = function (list) { + if (list.b) { + var x = list.a; + var xs = list.b; + return $elm$core$Maybe$Just( + A3($elm$core$List$foldl, $elm$core$Basics$max, x, xs)); + } else { + return $elm$core$Maybe$Nothing; + } +}; +var $author$project$Starplot$findMaxValue = F2( + function (model, func) { + return $elm$core$List$maximum( + A2($elm$core$List$filterMap, func, model.data)); + }); var $author$project$Starplot$checkID = F2( function (modelID, smartphone) { return _Utils_eq( @@ -12065,77 +12153,413 @@ var $author$project$Starplot$findSmartphoneById = function (model) { $author$project$Starplot$checkID(model.starplotOption.modelID), model.data)); }; -var $author$project$Starplot$h = 450; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$height = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$height( - $elm_community$typed_svg$TypedSvg$Types$px(value)); -}; +var $elm$html$Html$h3 = _VirtualDom_node('h3'); +var $elm$html$Html$input = _VirtualDom_node('input'); +var $elm$html$Html$Attributes$placeholder = $elm$html$Html$Attributes$stringProperty('placeholder'); +var $avh4$elm_color$Color$black = A4($avh4$elm_color$Color$RgbaSpace, 0 / 255, 0 / 255, 0 / 255, 1.0); var $author$project$Starplot$midX = 450; var $author$project$Starplot$midY = 225; -var $elm_community$typed_svg$TypedSvg$rect = $elm_community$typed_svg$TypedSvg$Core$node('rect'); -var $avh4$elm_color$Color$rgba = F4( - function (r, g, b, a) { - return A4($avh4$elm_color$Color$RgbaSpace, r, g, b, a); +var $author$project$Starplot$createAxis = function (axisPoint) { + return A2( + $gampleman$elm_visualization$Shape$line, + $gampleman$elm_visualization$Shape$linearCurve, + _List_fromArray( + [ + $elm$core$Maybe$Just( + _Utils_Tuple2($author$project$Starplot$midX, $author$project$Starplot$midY)), + $elm$core$Maybe$Just( + _Utils_Tuple2($author$project$Starplot$midX + (axisPoint.a * $author$project$Starplot$starlength), $author$project$Starplot$midY + (axisPoint.b * $author$project$Starplot$starlength))) + ])); +}; +var $elm$core$Debug$toString = _Debug_toString; +var $author$project$Starplot$createLabels = F3( + function (label, vlabel, labelPoint) { + return A2( + $elm_community$typed_svg$TypedSvg$g, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$class( + _List_fromArray( + ['label'])) + ]), + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$g, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$class( + _List_fromArray( + ['starLabel'])) + ]), + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$text_, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$InPx$x(($author$project$Starplot$midX + (labelPoint.a * $author$project$Starplot$starlength)) - 20), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$y($author$project$Starplot$midY + (labelPoint.b * $author$project$Starplot$starlength)) + ]), + _List_fromArray( + [ + $elm$html$Html$text(label) + ])) + ])), + A2( + $elm_community$typed_svg$TypedSvg$g, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$class( + _List_fromArray( + ['valueLabel'])) + ]), + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$text_, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$InPx$x(($author$project$Starplot$midX + (labelPoint.a * $author$project$Starplot$starlength)) - 20), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$y($author$project$Starplot$midY + (labelPoint.b * $author$project$Starplot$starlength)) + ]), + _List_fromArray( + [ + $elm$html$Html$text( + (vlabel < 0) ? 'NaN' : $elm$core$Debug$toString(vlabel)) + ])) + ])) + ])); }); +var $avh4$elm_color$Color$darkGray = A4($avh4$elm_color$Color$RgbaSpace, 186 / 255, 189 / 255, 182 / 255, 1.0); +var $author$project$Starplot$h = 450; +var $avh4$elm_color$Color$red = A4($avh4$elm_color$Color$RgbaSpace, 204 / 255, 0 / 255, 0 / 255, 1.0); var $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth = function (value) { return $elm_community$typed_svg$TypedSvg$Attributes$strokeWidth( $elm_community$typed_svg$TypedSvg$Types$px(value)); }; var $author$project$Starplot$w = 990; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$width = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$width( - $elm_community$typed_svg$TypedSvg$Types$px(value)); -}; -var $author$project$Starplot$starplot = function (smartphone) { - var a = 1; - return A2( - $elm_community$typed_svg$TypedSvg$svg, - _List_fromArray( - [ - A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$Starplot$w, $author$project$Starplot$h), - $elm_community$typed_svg$TypedSvg$Attributes$width( - $elm_community$typed_svg$TypedSvg$Types$Percent(100)), - $elm_community$typed_svg$TypedSvg$Attributes$height( - $elm_community$typed_svg$TypedSvg$Types$Percent(100)) - ]), - _List_fromArray( +var $author$project$Starplot$starplot = F4( + function (smartphone, starValues, labels, func) { + var valueLabel = A2( + $elm$core$List$map, + function (f) { + var _v3 = f(smartphone); + if (_v3.$ === 'Just') { + var value = _v3.a; + return value; + } else { + return -1; + } + }, + func); + var starLabel = A4( + $elm$core$List$map3, + $author$project$Starplot$createLabels, + labels, + valueLabel, + _List_fromArray( + [ + _Utils_Tuple2(0, -1.1), + _Utils_Tuple2(0.7, -0.95), + _Utils_Tuple2(0.95, -0.45), + _Utils_Tuple2(0.95, 0.45), + _Utils_Tuple2(0.7, 0.95), + _Utils_Tuple2(0, 1.1), + _Utils_Tuple2(-0.7, 0.95), + _Utils_Tuple2(-0.95, 0.45), + _Utils_Tuple2(-1.1, -0.45), + _Utils_Tuple2(-0.7, -0.95) + ])); + var axisMultiplikator = _List_fromArray( [ + _Utils_Tuple2(0, -0.9), + _Utils_Tuple2(0.5, -0.75), + _Utils_Tuple2(0.75, -0.25), + _Utils_Tuple2(0.75, 0.25), + _Utils_Tuple2(0.5, 0.75), + _Utils_Tuple2(0, 0.9), + _Utils_Tuple2(-0.5, 0.75), + _Utils_Tuple2(-0.75, 0.25), + _Utils_Tuple2(-0.75, -0.25), + _Utils_Tuple2(-0.5, -0.75) + ]); + var axisMultiplikatorHalf = A2( + $elm$core$List$map, + function (_v2) { + var x = _v2.a; + var y = _v2.b; + return _Utils_Tuple2(x / 2, y / 2); + }, + axisMultiplikator); + var pathCircleHalf = A2( + $gampleman$elm_visualization$Shape$line, + $gampleman$elm_visualization$Shape$linearCurve, + _Utils_ap( A2( - $elm_community$typed_svg$TypedSvg$rect, + $elm$core$List$map, + function (_v1) { + var x = _v1.a; + var y = _v1.b; + return $elm$core$Maybe$Just( + _Utils_Tuple2($author$project$Starplot$midX + (x * $author$project$Starplot$starlength), $author$project$Starplot$midY + (y * $author$project$Starplot$starlength))); + }, + axisMultiplikatorHalf), _List_fromArray( [ - $elm_community$typed_svg$TypedSvg$Attributes$InPx$width($author$project$Starplot$midX), - $elm_community$typed_svg$TypedSvg$Attributes$InPx$height($author$project$Starplot$midY), - $elm_community$typed_svg$TypedSvg$Attributes$fill( - $elm_community$typed_svg$TypedSvg$Types$Paint( - A4($avh4$elm_color$Color$rgba, 0, 0, 0, 0))), - $elm_community$typed_svg$TypedSvg$Attributes$stroke( - $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$black)), - $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth(2) - ]), - _List_Nil), + $elm$core$Maybe$Just( + _Utils_Tuple2( + $author$project$Starplot$midX + (A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(0, 0.9), + $elm$core$List$head(axisMultiplikatorHalf)).a * $author$project$Starplot$starlength), + $author$project$Starplot$midY + (A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(0, 0.9), + $elm$core$List$head(axisMultiplikatorHalf)).b * $author$project$Starplot$starlength))) + ]))); + var pathCircleMax = A2( + $gampleman$elm_visualization$Shape$line, + $gampleman$elm_visualization$Shape$linearCurve, + _Utils_ap( A2( - $elm_community$typed_svg$TypedSvg$text_, + $elm$core$List$map, + function (_v0) { + var x = _v0.a; + var y = _v0.b; + return $elm$core$Maybe$Just( + _Utils_Tuple2($author$project$Starplot$midX + (x * $author$project$Starplot$starlength), $author$project$Starplot$midY + (y * $author$project$Starplot$starlength))); + }, + axisMultiplikator), _List_fromArray( [ - $elm_community$typed_svg$TypedSvg$Attributes$InPx$x(100), - $elm_community$typed_svg$TypedSvg$Attributes$InPx$y(100) - ]), + $elm$core$Maybe$Just( + _Utils_Tuple2( + $author$project$Starplot$midX + (A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(0, 0.9), + $elm$core$List$head(axisMultiplikator)).a * $author$project$Starplot$starlength), + $author$project$Starplot$midY + (A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(0, 0.9), + $elm$core$List$head(axisMultiplikator)).b * $author$project$Starplot$starlength))) + ]))); + var pathCircleSmartphone = A2( + $gampleman$elm_visualization$Shape$line, + $gampleman$elm_visualization$Shape$linearCurve, + _Utils_ap( + A3( + $elm$core$List$map2, + F2( + function (axisM, starV) { + return $elm$core$Maybe$Just( + _Utils_Tuple2($author$project$Starplot$midX + (axisM.a * starV), $author$project$Starplot$midY + (axisM.b * starV))); + }), + axisMultiplikator, + starValues), _List_fromArray( [ - $elm$html$Html$text('Test, hier entsteht bald ein StarPlot.') - ])) - ])); -}; + $elm$core$Maybe$Just( + _Utils_Tuple2( + $author$project$Starplot$midX + (A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(0, 0.9), + $elm$core$List$head(axisMultiplikator)).a * A2( + $elm$core$Maybe$withDefault, + 0, + $elm$core$List$head(starValues))), + $author$project$Starplot$midY + (A2( + $elm$core$Maybe$withDefault, + _Utils_Tuple2(0, 0.9), + $elm$core$List$head(axisMultiplikator)).b * A2( + $elm$core$Maybe$withDefault, + 0, + $elm$core$List$head(starValues))))) + ]))); + var starAxisMax = A2($elm$core$List$map, $author$project$Starplot$createAxis, axisMultiplikator); + return A2( + $elm_community$typed_svg$TypedSvg$svg, + _List_fromArray( + [ + A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$Starplot$w, $author$project$Starplot$h), + $elm_community$typed_svg$TypedSvg$Attributes$width( + $elm_community$typed_svg$TypedSvg$Types$Percent(100)), + $elm_community$typed_svg$TypedSvg$Attributes$height( + $elm_community$typed_svg$TypedSvg$Types$Percent(100)) + ]), + _Utils_ap( + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$style, + _List_Nil, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Core$text('\r\n .valueLabel { display: none }\r\n .label:hover .valueLabel { display: inline; }\r\n .label:hover .starLabel { display: none; }\r\n ') + ])), + A2( + $elm_community$typed_svg$TypedSvg$circle, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$InPx$cx($author$project$Starplot$midX), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$cy($author$project$Starplot$midY), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$r(1), + $elm_community$typed_svg$TypedSvg$Attributes$stroke( + $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$black)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth(1) + ]), + _List_Nil), + A2( + $folkertdev$one_true_path_experiment$Path$element, + pathCircleMax, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$stroke( + $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$darkGray)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth(0.8), + $elm_community$typed_svg$TypedSvg$Attributes$fill($elm_community$typed_svg$TypedSvg$Types$PaintNone) + ])), + A2( + $folkertdev$one_true_path_experiment$Path$element, + pathCircleHalf, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$stroke( + $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$darkGray)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth(0.5), + $elm_community$typed_svg$TypedSvg$Attributes$fill($elm_community$typed_svg$TypedSvg$Types$PaintNone) + ])), + A2( + $folkertdev$one_true_path_experiment$Path$element, + pathCircleSmartphone, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$stroke( + $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$red)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth(2), + $elm_community$typed_svg$TypedSvg$Attributes$fill($elm_community$typed_svg$TypedSvg$Types$PaintNone) + ])) + ]), + _Utils_ap( + starLabel, + A2( + $elm$core$List$map, + function (p) { + return A2( + $folkertdev$one_true_path_experiment$Path$element, + p, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$stroke( + $elm_community$typed_svg$TypedSvg$Types$Paint($avh4$elm_color$Color$black)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$strokeWidth(0.5), + $elm_community$typed_svg$TypedSvg$Attributes$fill($elm_community$typed_svg$TypedSvg$Types$PaintNone) + ])); + }, + starAxisMax)))); + }); var $author$project$Starplot$viewStarplot = function (model) { + var starplotViewHead = function (spd) { + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$h3, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text( + ('ID:' + A2($elm$core$Maybe$withDefault, 'NaN', spd.id)) + (' | ' + A2($elm$core$Maybe$withDefault, 'NaN', spd.model))) + ])), + $elm$html$Html$text('ID auswaehlen: '), + A2( + $elm$html$Html$input, + _List_fromArray( + [ + $elm$html$Html$Attributes$placeholder('Enter a number'), + $elm$html$Html$Events$onInput($author$project$Starplot$InputChange) + ]), + _List_Nil), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick($author$project$Starplot$SubmitNumber) + ]), + _List_fromArray( + [ + $elm$html$Html$text('Submit') + ])) + ])); + }; var starplotData = $author$project$Starplot$findSmartphoneById(model); - return _Utils_eq(starplotData, $elm$core$Maybe$Nothing) ? A2( - $elm$html$Html$div, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('Error: Starplot kann nicht dargestellt werden, da zu dieser Id keine Data vorliegen.') - ])) : $author$project$Starplot$starplot(starplotData); + var smartphoneFunctions = _List_fromArray( + [ + function ($) { + return $.price; + }, + function ($) { + return $.rating; + }, + function ($) { + return $.num_cores; + }, + function ($) { + return $.processor_speed; + }, + function ($) { + return $.battery; + }, + function ($) { + return $.fast_charging; + }, + function ($) { + return $.memory; + }, + function ($) { + return $.ram; + }, + function ($) { + return $.screen_size; + }, + function ($) { + return $.refresh_rate; + } + ]); + var maxValues = A2( + $elm$core$List$map, + $author$project$Starplot$findMaxValue(model), + smartphoneFunctions); + var starValues = A3( + $elm$core$List$map2, + $author$project$Starplot$calculateStarValue(starplotData), + maxValues, + smartphoneFunctions); + var labels = _List_fromArray( + ['Price', 'Rating', 'NumCores', 'Processor Speed', 'Battery', 'Fast Charging', 'Memory', 'RAM', 'Screen Size', 'Refresh Rate']); + if (starplotData.$ === 'Just') { + var spd = starplotData.a; + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + starplotViewHead(spd), + A4($author$project$Starplot$starplot, spd, starValues, labels, smartphoneFunctions) + ])); + } else { + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + starplotViewHead( + {id: $elm$core$Maybe$Nothing, model: $elm$core$Maybe$Nothing}), + $elm$html$Html$text('Error: Starplot kann nicht dargestellt werden, da zu dieser ID (' + (model.starplotOption.modelID + ') keine Data vorliegen Probiere Sie eine andere ID aus. Die ID muss eine Nummer sein.')) + ])); + } }; var $author$project$TreeView$ZoomMsg = function (a) { return {$: 'ZoomMsg', a: a}; @@ -12530,12 +12954,19 @@ var $gampleman$elm_visualization$Zoom$events = F2( A2($gampleman$elm_visualization$Zoom$onGesture, zoom, tagger), A2($gampleman$elm_visualization$Zoom$onTouch, zoom, tagger))))); }); +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$height = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$height( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; var $author$project$TreeView$Click = function (a) { return {$: 'Click', a: a}; }; var $elm_community$typed_svg$TypedSvg$Types$ClipPathFunc = function (a) { return {$: 'ClipPathFunc', a: a}; }; +var $author$project$TreeView$SetStarPlotFromTree = function (a) { + return {$: 'SetStarPlotFromTree', a: a}; +}; var $elm_community$typed_svg$TypedSvg$clipPath = $elm_community$typed_svg$TypedSvg$Core$node('clipPath'); var $elm_community$typed_svg$TypedSvg$TypesToStrings$clipPathToString = function (clipPath) { switch (clipPath.$) { @@ -12640,7 +13071,9 @@ var $author$project$TreeView$label = function (item) { _List_fromArray( [ A2($elm_community$typed_svg$TypedSvg$Types$Translate, item.x, item.y) - ])) + ])), + $elm$html$Html$Events$onClick( + $author$project$TreeView$SetStarPlotFromTree(item.node.id)) ]), _List_fromArray( [ @@ -14416,6 +14849,7 @@ var $author$project$TreeView$filterSPData = function (smartphone) { }; 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 }; @@ -14787,11 +15221,12 @@ var $author$project$TreeView$tree = function (model) { A3( $gampleman$elm_rosetree$Tree$sumUp, function (n) { - return {kind: $author$project$TreeView$Leaf, name: n.name, size: n.size}; + return {id: n.id, kind: $author$project$TreeView$Leaf, name: n.name, size: n.size}; }, F2( function (node, children) { return { + id: node.id, kind: $author$project$TreeView$Node, name: node.name, size: $elm$core$List$sum( @@ -14806,12 +15241,13 @@ var $author$project$TreeView$tree = function (model) { A2( $elm$core$Result$withDefault, $gampleman$elm_rosetree$Tree$singleton( - {name: 'Smartphone', size: 0}), + {id: '-1', name: 'Smartphone', size: 0}), A2( $gampleman$elm_rosetree$Tree$stratifyWithPath, { createMissingNode: function (path) { return { + id: '-1', name: A2($elm$core$String$join, '.', path), size: 0 }; @@ -14978,6 +15414,11 @@ var $gampleman$elm_rosetree$Tree$links = function (t) { _List_Nil, t)); }; +var $elm_community$typed_svg$TypedSvg$rect = $elm_community$typed_svg$TypedSvg$Core$node('rect'); +var $avh4$elm_color$Color$rgba = F4( + function (r, g, b, a) { + return A4($avh4$elm_color$Color$RgbaSpace, r, g, b, a); + }); var $gampleman$elm_rosetree$Tree$foldr = F3( function (f, acc, t) { return A3( @@ -15000,12 +15441,20 @@ var $gampleman$elm_visualization$Zoom$transform = function (_v0) { return $elm$svg$Svg$Attributes$transform( $gampleman$elm_visualization$Zoom$Transform$toString(zoom.transform)); }; +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$width = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$width( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; var $author$project$TreeView$viewTree = function (model) { return A2( $elm_community$typed_svg$TypedSvg$svg, _List_fromArray( [ - A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$TreeView$w, $author$project$TreeView$h) + A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$TreeView$w, $author$project$TreeView$h), + $elm_community$typed_svg$TypedSvg$Attributes$width( + $elm_community$typed_svg$TypedSvg$Types$Percent(100)), + $elm_community$typed_svg$TypedSvg$Attributes$height( + $elm_community$typed_svg$TypedSvg$Types$Percent(100)) ]), _List_fromArray( [ diff --git a/src/Main.elm b/src/Main.elm index 4ad2ea43a7a0bef8d9532d31429d9dc169377464..cf17dbafa7b87647df44d3b5d06bf2263e5d65d7 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -61,6 +61,7 @@ init _ = |> Zoom.translateExtent ( ( 0, 0 ), ( TreeView.w, TreeView.h ) ) } { modelID = "0" + , input = "" } { scatterPlot = True , parallelCoordinatesPlot = False @@ -134,6 +135,17 @@ update msg model = , Cmd.none ) + ScatterplotMsg (SetStarPlot id) -> + ( { model + | starplotOption = + { modelID = id + , input = model.starplotOption.input + } + , plotVisible = { scatterPlot = False, parallelCoordinatesPlot = False, treeView = False, starPlot = True } + } + , Cmd.none + ) + ParallelCoordinatesMsg (ChangeOrder pos1 pos2) -> ( { model | parallelPlotOption = @@ -150,6 +162,17 @@ update msg model = TreeViewMsg (Click t) -> ( { model | treeOption = { zoomOption = TreeView.performZoom t model.treeOption.zoomOption } }, Cmd.none ) + TreeViewMsg (SetStarPlotFromTree id) -> + ( { model + | starplotOption = + { modelID = id + , input = model.starplotOption.input + } + , plotVisible = { scatterPlot = False, parallelCoordinatesPlot = False, treeView = False, starPlot = True } + } + , Cmd.none + ) + ZooomMsg m -> ( { model | treeOption = { zoomOption = Zoom.update m model.treeOption.zoomOption } }, Cmd.none ) @@ -158,6 +181,26 @@ update msg model = , Cmd.none ) + StarplotMsg (InputChange id) -> + ( { model + | starplotOption = + { modelID = model.starplotOption.modelID + , input = id + } + } + , Cmd.none + ) + + StarplotMsg SubmitNumber -> + ( { model + | starplotOption = + { modelID = model.starplotOption.input + , input = model.starplotOption.input + } + } + , Cmd.none + ) + SetViewScatterplot -> ( { model | plotVisible = { scatterPlot = True, parallelCoordinatesPlot = False, treeView = False, starPlot = False } }, Cmd.none ) diff --git a/src/Model.elm b/src/Model.elm index 02e8b1cd17e301fe5f35c1e738a443da1cf637fb..eba3607eed019b7b58688eab6e133fe776f4700a 100644 --- a/src/Model.elm +++ b/src/Model.elm @@ -42,4 +42,5 @@ type alias TreeOption = type alias StarPlotOption = { modelID : String + , input : String } diff --git a/src/ParallelCoordinates.elm b/src/ParallelCoordinates.elm index f5933ba2fdd275e3f6deeda97265c293541420b6..ba0ea7cd1f4d8ca3241392f83eec3d1448a2ba32 100644 --- a/src/ParallelCoordinates.elm +++ b/src/ParallelCoordinates.elm @@ -1,7 +1,5 @@ module ParallelCoordinates exposing (..) ---import Scatterplot exposing (ScatterPlotOption) - import Axis exposing (..) import Color import ExtendedFunctions exposing (listmap10, map10) @@ -34,7 +32,7 @@ h = padding : Float padding = - 50 + 60 axisPaddig : Float @@ -142,18 +140,18 @@ parallelCoordinatesPlot model smartphonesList = List.map createLine paths in svg - [ viewBox 0 0 (w + 45) (h + 45) + [ viewBox 0 0 (w + 60) (h + 40) , TypedSvg.Attributes.width <| TypedSvg.Types.Percent 100 , TypedSvg.Attributes.height <| TypedSvg.Types.Percent 100 ] ([ style [] [ TypedSvg.Core.text """ - .axis .tick text { display: none; } + .axis .tick text { display: none; font-size:13px } .axis:hover .tick text { display: inline; } """ ] , g [] [] ] - ++ yaxis ++ lines + ++ yaxis ) @@ -161,7 +159,7 @@ createLine : Path.Path -> Svg msg createLine path = g [] [ Path.element path - [ stroke <| Paint <| Color.black + [ stroke <| Paint <| Color.darkBlue , strokeWidth <| Px 0.5 , fill PaintNone ] diff --git a/src/Scatterplot.elm b/src/Scatterplot.elm index b86821e8f27d26150d31bde7de8ab424116544ee..86198301859e5da14ae26d32ddfc14ba20656ff8 100644 --- a/src/Scatterplot.elm +++ b/src/Scatterplot.elm @@ -3,7 +3,7 @@ module Scatterplot exposing (..) import Axis exposing (..) import Html exposing (Html, option) import Html.Attributes exposing (value) -import Html.Events exposing (onInput) +import Html.Events exposing (onClick, onInput) import Model exposing (Model) import Scale exposing (ContinuousScale) import Statistics @@ -62,7 +62,7 @@ defaultExtent = ( 0, 200000 ) -scatterplot : XyData -> Svg msg +scatterplot : XyData -> Svg Msg scatterplot model = let xValues : List Float @@ -115,9 +115,9 @@ scatterplot model = ] -point : ContinuousScale Float -> ContinuousScale Float -> Point -> Svg msg +point : ContinuousScale Float -> ContinuousScale Float -> Point -> Svg Msg point scaleX scaleY xyPoint = - g [ class [ "point" ], fontSize <| Px 10.0, fontFamily [ "sans-serif" ] ] + g [ class [ "point" ], fontSize <| Px 10.0, fontFamily [ "sans-serif" ], onClick (SetStarPlot xyPoint.id) ] [ circle [ cx (Scale.convert scaleX xyPoint.x) , cy (Scale.convert scaleY xyPoint.y) @@ -129,7 +129,7 @@ point scaleX scaleY xyPoint = , y (Scale.convert scaleY xyPoint.y) , textAnchor AnchorMiddle ] - [ Html.text xyPoint.pointName ] + [ Html.text ("ID:" ++ xyPoint.id ++ " | " ++ xyPoint.pointName) ] ] @@ -282,3 +282,4 @@ attributeSelector attNr = type Msg = ChangeAttribute1 String | ChangeAttribute2 String + | SetStarPlot String diff --git a/src/Starplot.elm b/src/Starplot.elm index 1a4ac539b5a4d9d76df2e8143f686bd8314e8f46..5d4a51613738f998064d87e5fd34a768ba3f2400 100644 --- a/src/Starplot.elm +++ b/src/Starplot.elm @@ -1,13 +1,18 @@ module Starplot exposing (..) import Color -import Html exposing (Html, div, text) +import Debug exposing (toString) +import Html exposing (Html, button, div, h3, input, text) +import Html.Attributes exposing (placeholder, value) +import Html.Events exposing (onClick, onInput) import List import Model exposing (Model) +import Path +import Shape import SmartPhoneType exposing (Smartphone) -import TypedSvg exposing (rect, svg, text_) -import TypedSvg.Attributes exposing (fill, stroke, viewBox) -import TypedSvg.Attributes.InPx exposing (height, strokeWidth, width, x, y) +import TypedSvg exposing (circle, g, svg, text_) +import TypedSvg.Attributes exposing (class, fill, stroke, viewBox) +import TypedSvg.Attributes.InPx exposing (cx, cy, r, strokeWidth, x, y) import TypedSvg.Core exposing (Svg) import TypedSvg.Types exposing (AnchorAlignment(..), Length(..), Paint(..), Transform(..)) @@ -39,55 +44,309 @@ padding = starlength : Float starlength = - 100 + 180 type Msg = Nothing1 + | InputChange String + | SubmitNumber -starplot : Maybe Smartphone -> Svg msg -starplot smartphone = +starplot : Smartphone -> List Float -> List String -> List (Smartphone -> Maybe Float) -> Svg msg +starplot smartphone starValues labels func = let - a = - 1 + axisMultiplikator = + [ ( 0, -0.9 ) + , ( 0.5, -0.75 ) + , ( 0.75, -0.25 ) + , ( 0.75, 0.25 ) + , ( 0.5, 0.75 ) + , ( 0, 0.9 ) + , ( -0.5, 0.75 ) + , ( -0.75, 0.25 ) + , ( -0.75, -0.25 ) + , ( -0.5, -0.75 ) + ] + + axisMultiplikatorHalf = + List.map (\( x, y ) -> ( x / 2, y / 2 )) axisMultiplikator + + starAxisMax = + List.map createAxis + axisMultiplikator + + valueLabel = + List.map + (\f -> + case f smartphone of + Just value -> + value + + Nothing -> + -1 + ) + func + + starLabel = + List.map3 createLabels + labels + valueLabel + [ ( 0, -1.1 ) + , ( 0.7, -0.95 ) + , ( 0.95, -0.45 ) + , ( 0.95, 0.45 ) + , ( 0.7, 0.95 ) + , ( 0, 1.1 ) + , ( -0.7, 0.95 ) + , ( -0.95, 0.45 ) + , ( -1.1, -0.45 ) -- individuel + , ( -0.7, -0.95 ) + ] + + pathCircleMax = + Shape.line Shape.linearCurve <| + List.map (\( x, y ) -> Just ( midX + x * starlength, midY + y * starlength )) axisMultiplikator + ++ [ Just + ( midX + (Tuple.first <| Maybe.withDefault ( 0, 0.9 ) <| List.head axisMultiplikator) * starlength + , midY + (Tuple.second <| Maybe.withDefault ( 0, 0.9 ) <| List.head axisMultiplikator) * starlength + ) + ] + + pathCircleHalf = + Shape.line Shape.linearCurve <| + List.map (\( x, y ) -> Just ( midX + x * starlength, midY + y * starlength )) axisMultiplikatorHalf + ++ [ Just + ( midX + (Tuple.first <| Maybe.withDefault ( 0, 0.9 ) <| List.head axisMultiplikatorHalf) * starlength + , midY + (Tuple.second <| Maybe.withDefault ( 0, 0.9 ) <| List.head axisMultiplikatorHalf) * starlength + ) + ] + + pathCircleSmartphone = + Shape.line Shape.linearCurve <| + List.map2 + (\axisM starV -> + Just + ( midX + Tuple.first axisM * starV + , midY + Tuple.second axisM * starV + ) + ) + axisMultiplikator + starValues + ++ [ Just + ( midX + + (Tuple.first <| + Maybe.withDefault ( 0, 0.9 ) <| + List.head axisMultiplikator + ) + * Maybe.withDefault 0 (List.head starValues) + , midY + + (Tuple.second <| + Maybe.withDefault ( 0, 0.9 ) <| + List.head axisMultiplikator + ) + * Maybe.withDefault 0 (List.head starValues) + ) + ] + + {- valueLabel = + List.map2 createValueLabels + (List.map + (\f -> + case f smartphone of + Just value -> + value + + Nothing -> + -1 + ) + func + ) + [ ( 0, -1.1 ) + , ( 0.7, -0.95 ) + , ( 0.95, -0.45 ) + , ( 0.95, 0.45 ) + , ( 0.7, 0.95 ) + , ( 0, 1.1 ) + , ( -0.7, 0.95 ) + , ( -0.95, 0.45 ) + , ( -1.1, -0.45 ) -- individuel + , ( -0.7, -0.95 ) + ] + -} in svg [ viewBox 0 0 w h , TypedSvg.Attributes.width <| TypedSvg.Types.Percent 100 , TypedSvg.Attributes.height <| TypedSvg.Types.Percent 100 ] - [ rect - [ width midX - , height midY - , fill (Paint (Color.rgba 0 0 0 0)) + ([ TypedSvg.style [] [ TypedSvg.Core.text """ + .valueLabel { display: none } + .label:hover .valueLabel { display: inline; } + .label:hover .starLabel { display: none; } + """ ] + , circle + [ cx midX + , cy midY + , r 1 , stroke (Paint Color.black) - , strokeWidth 2 + , strokeWidth 1 ] [] - , text_ [ x 100, y 100 ] [ text "Test, hier entsteht bald ein StarPlot." ] + , Path.element pathCircleMax + [ stroke <| Paint <| Color.darkGray + , strokeWidth 0.8 + , fill PaintNone + ] + , Path.element pathCircleHalf + [ stroke <| Paint <| Color.darkGray + , strokeWidth 0.5 + , fill PaintNone + ] + , Path.element pathCircleSmartphone + [ stroke <| Paint <| Color.red + , strokeWidth 2 + , fill PaintNone + ] + ] + ++ starLabel + ++ List.map + (\p -> + Path.element p + [ stroke <| Paint <| Color.black + , strokeWidth 0.5 + , fill PaintNone + ] + ) + starAxisMax + ) + + +createAxis : ( Float, Float ) -> Path.Path +createAxis axisPoint = + [ Just ( midX, midY ), Just ( midX + Tuple.first axisPoint * starlength, midY + Tuple.second axisPoint * starlength ) ] |> Shape.line Shape.linearCurve + + +createLabels : String -> Float -> ( Float, Float ) -> Svg msg +createLabels label vlabel labelPoint = + g [ class [ "label" ] ] + [ g [ class [ "starLabel" ] ] + [ text_ [ x (midX + Tuple.first labelPoint * starlength - 20), y (midY + Tuple.second labelPoint * starlength) ] [ Html.text label ] + ] + , g [ class [ "valueLabel" ] ] + [ text_ [ x (midX + Tuple.first labelPoint * starlength - 20), y (midY + Tuple.second labelPoint * starlength) ] + [ Html.text <| + if vlabel < 0 then + "NaN" + + else + toString vlabel + ] + ] ] + +{- createValueLabels : Float -> ( Float, Float ) -> Svg msg + createValueLabels label labelPoint = + text_ [ class [ "valueLabel" ], x (midX + Tuple.first labelPoint * starlength - 20), y (midY + Tuple.second labelPoint * starlength) ] [ Html.text <| toString label ] +-} + + findSmartphoneById : Model -> Maybe Smartphone findSmartphoneById model = List.head <| List.filter (checkID model.starplotOption.modelID) model.data +findMaxValue : Model -> (Smartphone -> Maybe Float) -> Maybe Float +findMaxValue model func = + List.maximum <| List.filterMap func model.data + + checkID : String -> Smartphone -> Bool checkID modelID smartphone = Maybe.withDefault "NaN" smartphone.id == modelID +calculateStarValue : Maybe Smartphone -> Maybe Float -> (Smartphone -> Maybe Float) -> Float +calculateStarValue smartphone max func = + case smartphone of + Just sp -> + case func sp of + Just sV -> + case max of + Just m -> + sV / m * starlength + + Nothing -> + -1 + + Nothing -> + -1 + + Nothing -> + -1 + + viewStarplot : Model -> Html Msg viewStarplot model = let + smartphoneFunctions = + [ .price + , .rating + , .num_cores + , .processor_speed + , .battery + , .fast_charging + , .memory + , .ram + , .screen_size + , .refresh_rate + ] + + labels = + [ "Price" + , "Rating" + , "NumCores" + , "Processor Speed" + , "Battery" + , "Fast Charging" + , "Memory" + , "RAM" + , "Screen Size" + , "Refresh Rate" + ] + starplotData = findSmartphoneById model + + maxValues = + List.map (findMaxValue model) + smartphoneFunctions + + starValues = + List.map2 (calculateStarValue starplotData) + maxValues + smartphoneFunctions + + starplotViewHead spd = + div [] + [ h3 [] [ text <| ("ID:" ++ Maybe.withDefault "NaN" spd.id) ++ (" | " ++ Maybe.withDefault "NaN" spd.model) ] + , text "ID auswaehlen: " + , input [ placeholder "Enter a number", onInput InputChange ] [] + , button [ onClick SubmitNumber ] [ text "Submit" ] + ] in - if starplotData == Maybe.Nothing then - div [] [ text "Error: Starplot kann nicht dargestellt werden, da zu dieser Id keine Data vorliegen." ] + case starplotData of + Just spd -> + div [] + [ starplotViewHead spd + , starplot spd starValues labels smartphoneFunctions + ] - else - starplot starplotData + Nothing -> + div [] + [ starplotViewHead { id = Nothing, model = Nothing } + , text <| "Error: Starplot kann nicht dargestellt werden, da zu dieser ID (" ++ model.starplotOption.modelID ++ ") keine Data vorliegen Probiere Sie eine andere ID aus. Die ID muss eine Nummer sein." + ] diff --git a/src/TreeView.elm b/src/TreeView.elm index 7e3e1c7ff2ca52e9638c5db325fb0f12d08e1a57..8d1f4a376d836c15f43f8df898317e1363350966 100644 --- a/src/TreeView.elm +++ b/src/TreeView.elm @@ -4,6 +4,7 @@ import Color import Curve import ExtendedFunctions exposing (map10) import Hierarchy +import Html.Events exposing (onClick) import List.Extra import Model exposing (Model) import Path @@ -96,7 +97,7 @@ type alias Datum = , y : Float , width : Float , height : Float - , node : { size : Float, name : String, kind : Kind } + , node : { size : Float, id : String, name : String, kind : Kind } , bbox : { x : Float, y : Float, width : Float, height : Float } } @@ -104,6 +105,7 @@ type alias Datum = type Msg = ZoomMsg Zoom.OnZoom | Click Datum + | SetStarPlotFromTree String performZoom : Datum -> Zoom -> Zoom @@ -139,7 +141,11 @@ performZoom t = viewTree : Model -> Svg Msg viewTree model = - svg [ viewBox 0 0 w h ] + svg + [ viewBox 0 0 w h + , TypedSvg.Attributes.width <| TypedSvg.Types.Percent 100 + , TypedSvg.Attributes.height <| TypedSvg.Types.Percent 100 + ] [ rect (width w :: height h @@ -185,7 +191,7 @@ label item = -- corner = -- min item.width item.height * 0.2 -- in - g [ transform [ Translate item.x item.y ] ] + g [ transform [ Translate item.x item.y ], onClick (SetStarPlotFromTree item.node.id) ] [ Path.element [ Curve.linearClosed [ ( 0, item.height ) @@ -287,7 +293,7 @@ type Kind | Node -tree : Model -> Tree { name : String, kind : Kind, size : Float } +tree : Model -> Tree { name : String, id : String, kind : Kind, size : Float } tree model = let filteredSmartphoneData = @@ -302,25 +308,26 @@ tree model = in Tree.stratifyWithPath { path = \item -> String.split "." item.name - , createMissingNode = \path -> { name = String.join "." path, size = 0 } + , createMissingNode = \path -> { name = String.join "." path, id = "-1", size = 0 } } (getTreeData limitedfilteredSmartphones) - |> Result.withDefault (Tree.singleton { name = "Smartphone", size = 0 }) - |> Tree.sumUp (\n -> { name = n.name, size = n.size, kind = Leaf }) + |> Result.withDefault (Tree.singleton { name = "Smartphone", id = "-1", size = 0 }) + |> Tree.sumUp (\n -> { name = n.name, id = n.id, size = n.size, kind = Leaf }) (\node children -> - { name = node.name, size = List.sum (List.map .size children), kind = Node } + { name = node.name, id = node.id, size = List.sum (List.map .size children), kind = Node } ) |> Tree.sortBy (Tree.label >> .name) -getTreeData : List Smartphone -> List { name : String, size : Float } +getTreeData : List Smartphone -> List { name : String, id : String, size : Float } getTreeData smartphones = List.map getTreeString smartphones -getTreeString : Smartphone -> { name : String, size : Float } +getTreeString : Smartphone -> { name : String, id : String, size : Float } getTreeString smartphone = { name = "Smartphone." ++ Maybe.withDefault "" smartphone.brand ++ "." ++ Maybe.withDefault "" smartphone.model + , id = Maybe.withDefault "-1" smartphone.id , size = 1000 }