diff --git a/public/main.js b/public/main.js index c4597f8e91d417c4fd582856c54342b19c1fda93..338b4abfd2d90f20eef0c11b9d31a0f88508ee97 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 = F4( - function (data, error, csvdata, scatterplotOptions) { - return {csvdata: csvdata, data: data, error: error, scatterplotOptions: scatterplotOptions}; +var $author$project$Model$Model = F5( + function (data, error, csvdata, scatterplotOptions, parallelPlotOption) { + return {csvdata: csvdata, data: data, error: error, parallelPlotOption: parallelPlotOption, scatterplotOptions: scatterplotOptions}; }); var $author$project$Main$DataReceived = function (a) { return {$: 'DataReceived', a: a}; @@ -6164,12 +6164,49 @@ var $author$project$Main$fetchData = $elm$http$Http$get( }); var $author$project$Main$init = function (_v0) { return _Utils_Tuple2( - A4( - $author$project$Main$Model, + A5( + $author$project$Model$Model, _List_Nil, $elm$core$Maybe$Nothing, '', - {att1List: _List_Nil, att2List: _List_Nil, attribute1: 'Price', attribute2: 'Rating'}), + {att1List: _List_Nil, att2List: _List_Nil, attribute1: 'Price', attribute2: 'Rating'}, + { + orderedLabels: _List_fromArray( + ['Price', 'Rating', 'NumCores', 'Processor Speed', 'Battery', 'Fast Charging', 'Memory', 'RAM', 'Screen Size', 'Refresh Rate']), + orderedList: _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; + } + ]) + }), $author$project$Main$fetchData); }; var $elm$core$Platform$Sub$batch = _Platform_batch; @@ -7496,6 +7533,194 @@ var $author$project$Main$decoder = A2( var $author$project$Main$parseCSV = function (csv) { return A3($BrianHicks$elm_csv$Csv$Decode$decodeCsv, $BrianHicks$elm_csv$Csv$Decode$FieldNamesFromFirstRow, $author$project$Main$decoder, csv); }; +var $elm$core$List$takeReverse = F3( + function (n, list, kept) { + takeReverse: + while (true) { + if (n <= 0) { + return kept; + } else { + if (!list.b) { + return kept; + } else { + var x = list.a; + var xs = list.b; + var $temp$n = n - 1, + $temp$list = xs, + $temp$kept = A2($elm$core$List$cons, x, kept); + n = $temp$n; + list = $temp$list; + kept = $temp$kept; + continue takeReverse; + } + } + } + }); +var $elm$core$List$takeTailRec = F2( + function (n, list) { + return $elm$core$List$reverse( + A3($elm$core$List$takeReverse, n, list, _List_Nil)); + }); +var $elm$core$List$takeFast = F3( + function (ctr, n, list) { + if (n <= 0) { + return _List_Nil; + } else { + var _v0 = _Utils_Tuple2(n, list); + _v0$1: + while (true) { + _v0$5: + while (true) { + if (!_v0.b.b) { + return list; + } else { + if (_v0.b.b.b) { + switch (_v0.a) { + case 1: + break _v0$1; + case 2: + var _v2 = _v0.b; + var x = _v2.a; + var _v3 = _v2.b; + var y = _v3.a; + return _List_fromArray( + [x, y]); + case 3: + if (_v0.b.b.b.b) { + var _v4 = _v0.b; + var x = _v4.a; + var _v5 = _v4.b; + var y = _v5.a; + var _v6 = _v5.b; + var z = _v6.a; + return _List_fromArray( + [x, y, z]); + } else { + break _v0$5; + } + default: + if (_v0.b.b.b.b && _v0.b.b.b.b.b) { + var _v7 = _v0.b; + var x = _v7.a; + var _v8 = _v7.b; + var y = _v8.a; + var _v9 = _v8.b; + var z = _v9.a; + var _v10 = _v9.b; + var w = _v10.a; + var tl = _v10.b; + return (ctr > 1000) ? A2( + $elm$core$List$cons, + x, + A2( + $elm$core$List$cons, + y, + A2( + $elm$core$List$cons, + z, + A2( + $elm$core$List$cons, + w, + A2($elm$core$List$takeTailRec, n - 4, tl))))) : A2( + $elm$core$List$cons, + x, + A2( + $elm$core$List$cons, + y, + A2( + $elm$core$List$cons, + z, + A2( + $elm$core$List$cons, + w, + A3($elm$core$List$takeFast, ctr + 1, n - 4, tl))))); + } else { + break _v0$5; + } + } + } else { + if (_v0.a === 1) { + break _v0$1; + } else { + break _v0$5; + } + } + } + } + return list; + } + var _v1 = _v0.b; + var x = _v1.a; + return _List_fromArray( + [x]); + } + }); +var $elm$core$List$take = F2( + function (n, list) { + return A3($elm$core$List$takeFast, 0, n, list); + }); +var $elm_community$list_extra$List$Extra$splitAt = F2( + function (n, xs) { + return _Utils_Tuple2( + A2($elm$core$List$take, n, xs), + A2($elm$core$List$drop, n, xs)); + }); +var $elm_community$list_extra$List$Extra$uncons = function (list) { + if (!list.b) { + return $elm$core$Maybe$Nothing; + } else { + var first = list.a; + var rest = list.b; + return $elm$core$Maybe$Just( + _Utils_Tuple2(first, rest)); + } +}; +var $elm_community$list_extra$List$Extra$swapAt = F3( + function (index1, index2, l) { + swapAt: + while (true) { + if (_Utils_eq(index1, index2) || (index1 < 0)) { + return l; + } else { + if (_Utils_cmp(index1, index2) > 0) { + var $temp$index1 = index2, + $temp$index2 = index1, + $temp$l = l; + index1 = $temp$index1; + index2 = $temp$index2; + l = $temp$l; + continue swapAt; + } else { + var _v0 = A2($elm_community$list_extra$List$Extra$splitAt, index1, l); + var part1 = _v0.a; + var tail1 = _v0.b; + var _v1 = A2($elm_community$list_extra$List$Extra$splitAt, index2 - index1, tail1); + var head2 = _v1.a; + var tail2 = _v1.b; + var _v2 = _Utils_Tuple2( + $elm_community$list_extra$List$Extra$uncons(head2), + $elm_community$list_extra$List$Extra$uncons(tail2)); + if ((_v2.a.$ === 'Just') && (_v2.b.$ === 'Just')) { + var _v3 = _v2.a.a; + var value1 = _v3.a; + var part2 = _v3.b; + var _v4 = _v2.b.a; + var value2 = _v4.a; + var part3 = _v4.b; + return $elm$core$List$concat( + _List_fromArray( + [ + part1, + A2($elm$core$List$cons, value2, part2), + A2($elm$core$List$cons, value1, part3) + ])); + } else { + return l; + } + } + } + } + }); var $author$project$Main$update = F2( function (msg, model) { switch (msg.$) { @@ -7530,7 +7755,7 @@ var $author$project$Main$update = F2( }), $elm$core$Platform$Cmd$none); } - default: + case 'ScatterplotMsg': if (msg.a.$ === 'ChangeAttribute1') { var value = msg.a.a; return _Utils_Tuple2( @@ -7560,400 +7785,1006 @@ var $author$project$Main$update = F2( }), $elm$core$Platform$Cmd$none); } + default: + 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); } }); +var $author$project$Main$ParallelCoordinatesMsg = function (a) { + return {$: 'ParallelCoordinatesMsg', a: a}; +}; var $author$project$Main$ScatterplotMsg = function (a) { return {$: 'ScatterplotMsg', a: 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$ChangeAttribute1 = function (a) { - return {$: 'ChangeAttribute1', a: a}; +var $author$project$ParallelCoordinates$ChangeOrder = F2( + function (a, b) { + return {$: 'ChangeOrder', a: a, b: b}; + }); +var $elm$html$Html$br = _VirtualDom_node('br'); +var $elm$html$Html$button = _VirtualDom_node('button'); +var $author$project$ParallelCoordinates$map10 = function (func) { + return function (maybe1) { + return function (maybe2) { + return function (maybe3) { + return function (maybe4) { + return function (maybe5) { + return function (maybe6) { + return function (maybe7) { + return function (maybe8) { + return function (maybe9) { + return function (maybe10) { + if (maybe1.$ === 'Just') { + var value1 = maybe1.a; + if (maybe2.$ === 'Just') { + var value2 = maybe2.a; + if (maybe3.$ === 'Just') { + var value3 = maybe3.a; + if (maybe4.$ === 'Just') { + var value4 = maybe4.a; + if (maybe5.$ === 'Just') { + var value5 = maybe5.a; + if (maybe6.$ === 'Just') { + var value6 = maybe6.a; + if (maybe7.$ === 'Just') { + var value7 = maybe7.a; + if (maybe8.$ === 'Just') { + var value8 = maybe8.a; + if (maybe9.$ === 'Just') { + var value9 = maybe9.a; + if (maybe10.$ === 'Just') { + var value10 = maybe10.a; + return $elm$core$Maybe$Just( + func(value1)(value2)(value3)(value4)(value5)(value6)(value7)(value8)(value9)(value10)); + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + } else { + return $elm$core$Maybe$Nothing; + } + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; }; -var $author$project$Scatterplot$ChangeAttribute2 = function (a) { - return {$: 'ChangeAttribute2', a: a}; +var $author$project$ParallelCoordinates$mapToSPData = function (smartphone) { + return $author$project$ParallelCoordinates$map10( + function (price) { + return function (rating) { + return function (num_cores) { + return function (processor_speed) { + return function (battery) { + return function (fast_charging) { + return function (memory) { + return function (ram) { + return function (screen_size) { + return function (refresh_rate) { + return { + battery: $elm$core$Maybe$Just(battery), + brand: smartphone.brand, + camera: smartphone.camera, + card: smartphone.card, + fast_charging: $elm$core$Maybe$Just(fast_charging), + g5: smartphone.g5, + id: smartphone.id, + ir_blaster: smartphone.ir_blaster, + memory: $elm$core$Maybe$Just(memory), + model: smartphone.model, + nfc: smartphone.nfc, + num_cores: $elm$core$Maybe$Just(num_cores), + os: smartphone.os, + price: $elm$core$Maybe$Just(price), + processor_brand: smartphone.processor_brand, + processor_name: smartphone.processor_name, + processor_speed: $elm$core$Maybe$Just(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.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 $elm$html$Html$Events$alwaysStop = function (x) { - return _Utils_Tuple2(x, true); +var $author$project$ParallelCoordinates$filterSPData = function (smartphone) { + var smartphoneList = A2($elm$core$List$filterMap, $author$project$ParallelCoordinates$mapToSPData, smartphone); + return smartphoneList; }; -var $elm$virtual_dom$VirtualDom$MayStopPropagation = function (a) { - return {$: 'MayStopPropagation', 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$stopPropagationOn = F2( +var $elm$html$Html$Events$on = F2( function (event, decoder) { return A2( $elm$virtual_dom$VirtualDom$on, event, - $elm$virtual_dom$VirtualDom$MayStopPropagation(decoder)); + $elm$virtual_dom$VirtualDom$Normal(decoder)); }); -var $elm$json$Json$Decode$field = _Json_decodeField; -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) { +var $elm$html$Html$Events$onClick = function (msg) { 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))); + $elm$html$Html$Events$on, + 'click', + $elm$json$Json$Decode$succeed(msg)); }; -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_community$typed_svg$TypedSvg$Types$Percent = function (a) { + return {$: 'Percent', a: a}; +}; +var $gampleman$elm_visualization$Scale$convert = F2( + function (_v0, value) { + var scale = _v0.a; + return A3(scale.convert, scale.domain, scale.range, value); }); -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_community$typed_svg$TypedSvg$Types$Paint = function (a) { + return {$: 'Paint', a: a}; }; -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_community$typed_svg$TypedSvg$Types$PaintNone = {$: 'PaintNone'}; +var $elm_community$typed_svg$TypedSvg$Types$Px = function (a) { + return {$: 'Px', a: a}; +}; +var $avh4$elm_color$Color$RgbaSpace = F4( + function (a, b, c, d) { + return {$: 'RgbaSpace', a: a, b: b, c: c, d: d}; }); -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; +var $avh4$elm_color$Color$black = A4($avh4$elm_color$Color$RgbaSpace, 0 / 255, 0 / 255, 0 / 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'); +var $folkertdev$one_true_path_experiment$SubPath$Empty = {$: 'Empty'}; +var $folkertdev$one_true_path_experiment$SubPath$SubPath = function (a) { + return {$: 'SubPath', a: a}; +}; +var $folkertdev$elm_deque$Deque$Deque = function (a) { + return {$: 'Deque', a: a}; +}; +var $folkertdev$elm_deque$Internal$empty = {front: _List_Nil, rear: _List_Nil, sizeF: 0, sizeR: 0}; +var $folkertdev$elm_deque$Deque$empty = $folkertdev$elm_deque$Deque$Deque($folkertdev$elm_deque$Internal$empty); +var $folkertdev$elm_deque$Internal$rebalance = function (deque) { + var sizeF = deque.sizeF; + var sizeR = deque.sizeR; + var front = deque.front; + var rear = deque.rear; + var size1 = ((sizeF + sizeR) / 2) | 0; + var size2 = (sizeF + sizeR) - size1; + var balanceConstant = 4; + if ((sizeF + sizeR) < 2) { + return deque; + } else { + if (_Utils_cmp(sizeF, (balanceConstant * sizeR) + 1) > 0) { + var newRear = _Utils_ap( + rear, + $elm$core$List$reverse( + A2($elm$core$List$drop, size1, front))); + var newFront = A2($elm$core$List$take, size1, front); + return {front: newFront, rear: newRear, sizeF: size1, sizeR: size2}; } else { - var a = ma.a; - if (mb.$ === 'Nothing') { - return $elm$core$Maybe$Nothing; + if (_Utils_cmp(sizeR, (balanceConstant * sizeF) + 1) > 0) { + var newRear = A2($elm$core$List$take, size1, rear); + var newFront = _Utils_ap( + front, + $elm$core$List$reverse( + A2($elm$core$List$drop, size1, rear))); + return {front: newFront, rear: newRear, sizeF: size1, sizeR: size2}; } 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)); - } + return deque; } } - }); -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 $folkertdev$elm_deque$Internal$fromList = function (list) { + return $folkertdev$elm_deque$Internal$rebalance( + { + front: list, + rear: _List_Nil, + sizeF: $elm$core$List$length(list), + sizeR: 0 + }); +}; +var $folkertdev$elm_deque$Deque$fromList = A2($elm$core$Basics$composeL, $folkertdev$elm_deque$Deque$Deque, $folkertdev$elm_deque$Internal$fromList); +var $folkertdev$one_true_path_experiment$LowLevel$Command$ClosePath = {$: 'ClosePath'}; +var $folkertdev$one_true_path_experiment$LowLevel$Command$CurveTo = function (a) { + return {$: 'CurveTo', a: a}; +}; +var $folkertdev$one_true_path_experiment$LowLevel$Command$EllipticalArc = function (a) { + return {$: 'EllipticalArc', a: a}; +}; +var $folkertdev$one_true_path_experiment$LowLevel$Command$LineTo = function (a) { + return {$: 'LineTo', a: a}; +}; +var $folkertdev$one_true_path_experiment$LowLevel$Command$QuadraticBezierCurveTo = function (a) { + return {$: 'QuadraticBezierCurveTo', a: a}; +}; +var $folkertdev$one_true_path_experiment$LowLevel$Command$merge = F2( + function (instruction1, instruction2) { + var _v0 = _Utils_Tuple2(instruction1, instruction2); + _v0$5: + while (true) { + switch (_v0.a.$) { + case 'LineTo': + if (_v0.b.$ === 'LineTo') { + var p1 = _v0.a.a; + var p2 = _v0.b.a; + return $elm$core$Result$Ok( + $folkertdev$one_true_path_experiment$LowLevel$Command$LineTo( + _Utils_ap(p1, p2))); + } else { + break _v0$5; + } + case 'CurveTo': + if (_v0.b.$ === 'CurveTo') { + var p1 = _v0.a.a; + var p2 = _v0.b.a; + return $elm$core$Result$Ok( + $folkertdev$one_true_path_experiment$LowLevel$Command$CurveTo( + _Utils_ap(p1, p2))); + } else { + break _v0$5; + } + case 'QuadraticBezierCurveTo': + if (_v0.b.$ === 'QuadraticBezierCurveTo') { + var p1 = _v0.a.a; + var p2 = _v0.b.a; + return $elm$core$Result$Ok( + $folkertdev$one_true_path_experiment$LowLevel$Command$QuadraticBezierCurveTo( + _Utils_ap(p1, p2))); + } else { + break _v0$5; + } + case 'EllipticalArc': + if (_v0.b.$ === 'EllipticalArc') { + var p1 = _v0.a.a; + var p2 = _v0.b.a; + return $elm$core$Result$Ok( + $folkertdev$one_true_path_experiment$LowLevel$Command$EllipticalArc( + _Utils_ap(p1, p2))); + } else { + break _v0$5; + } + default: + if (_v0.b.$ === 'ClosePath') { + var _v1 = _v0.a; + var _v2 = _v0.b; + return $elm$core$Result$Ok($folkertdev$one_true_path_experiment$LowLevel$Command$ClosePath); + } else { + break _v0$5; + } + } + } + return $elm$core$Result$Err( + _Utils_Tuple2(instruction1, instruction2)); }); -var $elm_community$typed_svg$TypedSvg$Types$AnchorMiddle = {$: 'AnchorMiddle'}; -var $elm_community$typed_svg$TypedSvg$Types$Percent = function (a) { - return {$: 'Percent', a: a}; +var $folkertdev$elm_deque$Internal$toList = function (deque) { + return _Utils_ap( + deque.front, + $elm$core$List$reverse(deque.rear)); }; -var $elm_community$typed_svg$TypedSvg$Types$Px = function (a) { - return {$: 'Px', a: a}; +var $folkertdev$elm_deque$Deque$unwrap = function (_v0) { + var boundedDeque = _v0.a; + return boundedDeque; }; -var $elm_community$typed_svg$TypedSvg$Types$Translate = F2( +var $folkertdev$elm_deque$Deque$toList = A2($elm$core$Basics$composeL, $folkertdev$elm_deque$Internal$toList, $folkertdev$elm_deque$Deque$unwrap); +var $folkertdev$one_true_path_experiment$SubPath$compressHelper = function (drawtos) { + var folder = F2( + function (instruction, _v3) { + var previous = _v3.a; + var accum = _v3.b; + var _v2 = A2($folkertdev$one_true_path_experiment$LowLevel$Command$merge, previous, instruction); + if (_v2.$ === 'Ok') { + var merged = _v2.a; + return _Utils_Tuple2(merged, accum); + } else { + return _Utils_Tuple2( + instruction, + A2($elm$core$List$cons, previous, accum)); + } + }); + var _v0 = $folkertdev$elm_deque$Deque$toList(drawtos); + if (!_v0.b) { + return $folkertdev$elm_deque$Deque$empty; + } else { + var first = _v0.a; + var rest = _v0.b; + return $folkertdev$elm_deque$Deque$fromList( + $elm$core$List$reverse( + function (_v1) { + var a = _v1.a; + var b = _v1.b; + return A2($elm$core$List$cons, a, b); + }( + A3( + $elm$core$List$foldl, + folder, + _Utils_Tuple2(first, _List_Nil), + rest)))); + } +}; +var $folkertdev$one_true_path_experiment$SubPath$compress = function (subpath) { + if (subpath.$ === 'Empty') { + return $folkertdev$one_true_path_experiment$SubPath$Empty; + } else { + var data = subpath.a; + return $folkertdev$one_true_path_experiment$SubPath$SubPath( + _Utils_update( + data, + { + drawtos: $folkertdev$one_true_path_experiment$SubPath$compressHelper(data.drawtos) + })); + } +}; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$DecimalPlaces = function (a) { + return {$: 'DecimalPlaces', a: a}; +}; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$decimalPlaces = $folkertdev$svg_path_lowlevel$Path$LowLevel$DecimalPlaces; +var $folkertdev$one_true_path_experiment$SubPath$defaultConfig = {decimalPlaces: $elm$core$Maybe$Nothing, mergeAdjacent: false}; +var $elm$core$Maybe$map = F2( + function (f, maybe) { + if (maybe.$ === 'Just') { + var value = maybe.a; + return $elm$core$Maybe$Just( + f(value)); + } else { + return $elm$core$Maybe$Nothing; + } + }); +var $folkertdev$one_true_path_experiment$SubPath$optionFolder = F2( + function (option, config) { + if (option.$ === 'DecimalPlaces') { + var n = option.a; + return _Utils_update( + config, + { + decimalPlaces: $elm$core$Maybe$Just(n) + }); + } else { + return _Utils_update( + config, + {mergeAdjacent: true}); + } + }); +var $elm$core$List$singleton = function (value) { + return _List_fromArray( + [value]); +}; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$Absolute = {$: 'Absolute'}; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$ClosePath = {$: 'ClosePath'}; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$CurveTo = F2( function (a, b) { - return {$: 'Translate', a: a, b: b}; + return {$: 'CurveTo', a: a, b: b}; }); -var $gampleman$elm_visualization$Scale$convert = F2( - function (_v0, value) { - var scale = _v0.a; - return A3(scale.convert, scale.domain, scale.range, value); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$EllipticalArc = F2( + function (a, b) { + return {$: 'EllipticalArc', a: a, b: b}; }); -var $elm$virtual_dom$VirtualDom$attribute = F2( - function (key, value) { - return A2( - _VirtualDom_attribute, - _VirtualDom_noOnOrFormAction(key), - _VirtualDom_noJavaScriptOrHtmlUri(value)); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$LineTo = F2( + function (a, b) { + return {$: 'LineTo', a: a, b: b}; }); -var $elm_community$typed_svg$TypedSvg$Core$attribute = $elm$virtual_dom$VirtualDom$attribute; -var $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString = function (length) { - switch (length.$) { - case 'Cm': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'cm'; - case 'Em': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'em'; - case 'Ex': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'ex'; - case 'In': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'in'; - case 'Mm': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'mm'; - case 'Num': - var x = length.a; - return $elm$core$String$fromFloat(x); - case 'Pc': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'pc'; - case 'Percent': - var x = length.a; - return $elm$core$String$fromFloat(x) + '%'; - case 'Pt': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'pt'; - case 'Px': - var x = length.a; - return $elm$core$String$fromFloat(x) + 'px'; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$QuadraticBezierCurveTo = F2( + function (a, b) { + return {$: 'QuadraticBezierCurveTo', a: a, b: b}; + }); +var $folkertdev$one_true_path_experiment$LowLevel$Command$toLowLevelDrawTo = function (drawto) { + switch (drawto.$) { + case 'LineTo': + var coordinates = drawto.a; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$LineTo, $folkertdev$svg_path_lowlevel$Path$LowLevel$Absolute, coordinates); + case 'CurveTo': + var coordinates = drawto.a; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$CurveTo, $folkertdev$svg_path_lowlevel$Path$LowLevel$Absolute, coordinates); + case 'QuadraticBezierCurveTo': + var coordinates = drawto.a; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$QuadraticBezierCurveTo, $folkertdev$svg_path_lowlevel$Path$LowLevel$Absolute, coordinates); + case 'EllipticalArc': + var _arguments = drawto.a; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$EllipticalArc, $folkertdev$svg_path_lowlevel$Path$LowLevel$Absolute, _arguments); default: - var x = length.a; - return $elm$core$String$fromFloat(x) + 'rem'; + return $folkertdev$svg_path_lowlevel$Path$LowLevel$ClosePath; } }; -var $elm_community$typed_svg$TypedSvg$Attributes$fontSize = function (length) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'font-size', - $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); -}; -var $elm$virtual_dom$VirtualDom$nodeNS = F2( - function (namespace, tag) { - return A2( - _VirtualDom_nodeNS, - namespace, - _VirtualDom_noScript(tag)); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$MoveTo = F2( + function (a, b) { + return {$: 'MoveTo', a: a, b: b}; }); -var $elm_community$typed_svg$TypedSvg$Core$node = $elm$virtual_dom$VirtualDom$nodeNS('http://www.w3.org/2000/svg'); -var $elm_community$typed_svg$TypedSvg$g = $elm_community$typed_svg$TypedSvg$Core$node('g'); -var $author$project$Scatterplot$h = 450; -var $elm_community$typed_svg$TypedSvg$Attributes$height = function (length) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'height', - $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +var $folkertdev$one_true_path_experiment$LowLevel$Command$toLowLevelMoveTo = function (_v0) { + var target = _v0.a; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$MoveTo, $folkertdev$svg_path_lowlevel$Path$LowLevel$Absolute, target); }; -var $author$project$Scatterplot$padding = 50; -var $elm_community$typed_svg$TypedSvg$circle = $elm_community$typed_svg$TypedSvg$Core$node('circle'); -var $elm_community$typed_svg$TypedSvg$Attributes$class = function (names) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'class', - A2($elm$core$String$join, ' ', names)); +var $folkertdev$one_true_path_experiment$SubPath$toLowLevel = function (subpath) { + if (subpath.$ === 'Empty') { + return $elm$core$Maybe$Nothing; + } else { + var moveto = subpath.a.moveto; + var drawtos = subpath.a.drawtos; + return $elm$core$Maybe$Just( + { + drawtos: A2( + $elm$core$List$map, + $folkertdev$one_true_path_experiment$LowLevel$Command$toLowLevelDrawTo, + $folkertdev$elm_deque$Deque$toList(drawtos)), + moveto: $folkertdev$one_true_path_experiment$LowLevel$Command$toLowLevelMoveTo(moveto) + }); + } }; -var $elm_community$typed_svg$TypedSvg$Attributes$cx = function (length) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'cx', - $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +var $elm$core$String$fromFloat = _String_fromNumber; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$defaultConfig = {floatFormatter: $elm$core$String$fromFloat}; +var $elm$core$Basics$negate = function (n) { + return -n; }; -var $elm_community$typed_svg$TypedSvg$Types$px = $elm_community$typed_svg$TypedSvg$Types$Px; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$cx = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$cx( - $elm_community$typed_svg$TypedSvg$Types$px(value)); +var $elm$core$Basics$abs = function (n) { + return (n < 0) ? (-n) : n; }; -var $elm_community$typed_svg$TypedSvg$Attributes$cy = function (length) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'cy', - $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +var $elm$core$Basics$pow = _Basics_pow; +var $elm$core$Basics$round = _Basics_round; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$roundTo = F2( + function (n, value) { + if (!n) { + return $elm$core$String$fromInt( + $elm$core$Basics$round(value)); + } else { + var sign = (value < 0.0) ? '-' : ''; + var exp = A2($elm$core$Basics$pow, 10, n); + var raised = $elm$core$Basics$abs( + $elm$core$Basics$round(value * exp)); + var decimals = raised % exp; + return (!decimals) ? _Utils_ap( + sign, + $elm$core$String$fromInt((raised / exp) | 0)) : (sign + ($elm$core$String$fromInt((raised / exp) | 0) + ('.' + $elm$core$String$fromInt(decimals)))); + } + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$optionFolder = F2( + function (option, config) { + var n = option.a; + return _Utils_update( + config, + { + floatFormatter: $folkertdev$svg_path_lowlevel$Path$LowLevel$roundTo(n) + }); + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$accumulateOptions = A2($elm$core$List$foldl, $folkertdev$svg_path_lowlevel$Path$LowLevel$optionFolder, $folkertdev$svg_path_lowlevel$Path$LowLevel$defaultConfig); +var $elm$core$List$isEmpty = function (xs) { + if (!xs.b) { + return true; + } else { + return false; + } }; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$cy = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$cy( - $elm_community$typed_svg$TypedSvg$Types$px(value)); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$isEmpty = function (command) { + switch (command.$) { + case 'LineTo': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'Horizontal': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'Vertical': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'CurveTo': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'SmoothCurveTo': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'QuadraticBezierCurveTo': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'SmoothQuadraticBezierCurveTo': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates); + case 'EllipticalArc': + var mode = command.a; + var _arguments = command.b; + return $elm$core$List$isEmpty(_arguments); + default: + return false; + } }; -var $elm_community$typed_svg$TypedSvg$Attributes$fontFamily = function (families) { - if (!families.b) { - return A2($elm_community$typed_svg$TypedSvg$Core$attribute, 'font-family', 'inherit'); +var $elm$core$Char$toLower = _Char_toLower; +var $elm$core$Char$toUpper = _Char_toUpper; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter = F2( + function (mode, character) { + if (mode.$ === 'Absolute') { + return $elm$core$String$fromChar( + $elm$core$Char$toUpper(character)); + } else { + return $elm$core$String$fromChar( + $elm$core$Char$toLower(character)); + } + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate = F2( + function (config, _v0) { + var x = _v0.a; + var y = _v0.b; + return config.floatFormatter(x) + (',' + config.floatFormatter(y)); + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate2 = F2( + function (config, _v0) { + var c1 = _v0.a; + var c2 = _v0.b; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, c1) + (' ' + A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, c2)); + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate3 = F2( + function (config, _v0) { + var c1 = _v0.a; + var c2 = _v0.b; + var c3 = _v0.c; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, c1) + (' ' + (A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, c2) + (' ' + A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, c3)))); + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$encodeFlags = function (_v0) { + var arcFlag = _v0.a; + var direction = _v0.b; + var _v1 = _Utils_Tuple2(arcFlag, direction); + if (_v1.a.$ === 'LargestArc') { + if (_v1.b.$ === 'Clockwise') { + var _v2 = _v1.a; + var _v3 = _v1.b; + return _Utils_Tuple2(1, 0); + } else { + var _v6 = _v1.a; + var _v7 = _v1.b; + return _Utils_Tuple2(1, 1); + } } else { + if (_v1.b.$ === 'Clockwise') { + var _v4 = _v1.a; + var _v5 = _v1.b; + return _Utils_Tuple2(0, 0); + } else { + var _v8 = _v1.a; + var _v9 = _v1.b; + return _Utils_Tuple2(0, 1); + } + } +}; +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyEllipticalArcArgument = F2( + function (config, _v0) { + var radii = _v0.radii; + var xAxisRotate = _v0.xAxisRotate; + var arcFlag = _v0.arcFlag; + var direction = _v0.direction; + var target = _v0.target; + var _v1 = $folkertdev$svg_path_lowlevel$Path$LowLevel$encodeFlags( + _Utils_Tuple2(arcFlag, direction)); + var arc = _v1.a; + var sweep = _v1.b; return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'font-family', - A2($elm$core$String$join, ', ', families)); + $elm$core$String$join, + ' ', + _List_fromArray( + [ + A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, radii), + $elm$core$String$fromFloat(xAxisRotate), + $elm$core$String$fromInt(arc), + $elm$core$String$fromInt(sweep), + A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, target) + ])); + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyDrawTo = F2( + function (config, command) { + if ($folkertdev$svg_path_lowlevel$Path$LowLevel$isEmpty(command)) { + return ''; + } else { + switch (command.$) { + case 'LineTo': + var mode = command.a; + var coordinates = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('L')), + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate(config), + coordinates))); + case 'Horizontal': + var mode = command.a; + var coordinates = command.b; + return $elm$core$List$isEmpty(coordinates) ? '' : _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('H')), + A2( + $elm$core$String$join, + ' ', + A2($elm$core$List$map, $elm$core$String$fromFloat, coordinates))); + case 'Vertical': + var mode = command.a; + var coordinates = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('V')), + A2( + $elm$core$String$join, + ' ', + A2($elm$core$List$map, $elm$core$String$fromFloat, coordinates))); + case 'CurveTo': + var mode = command.a; + var coordinates = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('C')), + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate3(config), + coordinates))); + case 'SmoothCurveTo': + var mode = command.a; + var coordinates = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('S')), + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate2(config), + coordinates))); + case 'QuadraticBezierCurveTo': + var mode = command.a; + var coordinates = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('Q')), + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate2(config), + coordinates))); + case 'SmoothQuadraticBezierCurveTo': + var mode = command.a; + var coordinates = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('T')), + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate(config), + coordinates))); + case 'EllipticalArc': + var mode = command.a; + var _arguments = command.b; + return _Utils_ap( + A2( + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCharacter, + mode, + _Utils_chr('A')), + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyEllipticalArcArgument(config), + _arguments))); + default: + return 'Z'; + } + } + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyMoveTo = F2( + function (config, _v0) { + var mode = _v0.a; + var coordinate = _v0.b; + if (mode.$ === 'Absolute') { + return 'M' + A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, coordinate); + } else { + return 'm' + A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyCoordinate, config, coordinate); + } + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$toStringSubPath = F2( + function (config, _v0) { + var moveto = _v0.moveto; + var drawtos = _v0.drawtos; + return A2($folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyMoveTo, config, moveto) + (' ' + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$stringifyDrawTo(config), + drawtos))); + }); +var $folkertdev$svg_path_lowlevel$Path$LowLevel$toStringWith = F2( + function (options, subpaths) { + var config = $folkertdev$svg_path_lowlevel$Path$LowLevel$accumulateOptions(options); + return A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $folkertdev$svg_path_lowlevel$Path$LowLevel$toStringSubPath(config), + subpaths)); + }); +var $folkertdev$one_true_path_experiment$SubPath$toStringWith = F2( + function (options, subpath) { + var config = A3($elm$core$List$foldl, $folkertdev$one_true_path_experiment$SubPath$optionFolder, $folkertdev$one_true_path_experiment$SubPath$defaultConfig, options); + var lowLevelOptions = function () { + var _v0 = config.decimalPlaces; + if (_v0.$ === 'Nothing') { + return _List_Nil; + } else { + var n = _v0.a; + return _List_fromArray( + [ + $folkertdev$svg_path_lowlevel$Path$LowLevel$decimalPlaces(n) + ]); + } + }(); + return A2( + $elm$core$Maybe$withDefault, + '', + A2( + $elm$core$Maybe$map, + A2( + $elm$core$Basics$composeL, + $folkertdev$svg_path_lowlevel$Path$LowLevel$toStringWith(lowLevelOptions), + $elm$core$List$singleton), + $folkertdev$one_true_path_experiment$SubPath$toLowLevel( + (config.mergeAdjacent ? $folkertdev$one_true_path_experiment$SubPath$compress : $elm$core$Basics$identity)(subpath)))); + }); +var $folkertdev$one_true_path_experiment$SubPath$toString = function (subpath) { + return A2($folkertdev$one_true_path_experiment$SubPath$toStringWith, _List_Nil, subpath); +}; +var $folkertdev$one_true_path_experiment$Path$toString = A2( + $elm$core$Basics$composeL, + $elm$core$String$join(' '), + $elm$core$List$map($folkertdev$one_true_path_experiment$SubPath$toString)); +var $folkertdev$one_true_path_experiment$Path$element = F2( + function (path, attributes) { + return A2( + $elm$svg$Svg$path, + A2( + $elm$core$List$cons, + $elm$svg$Svg$Attributes$d( + $folkertdev$one_true_path_experiment$Path$toString(path)), + attributes), + _List_Nil); + }); +var $elm$virtual_dom$VirtualDom$attribute = F2( + function (key, value) { + return A2( + _VirtualDom_attribute, + _VirtualDom_noOnOrFormAction(key), + _VirtualDom_noJavaScriptOrHtmlUri(value)); + }); +var $elm_community$typed_svg$TypedSvg$Core$attribute = $elm$virtual_dom$VirtualDom$attribute; +var $elm$core$String$concat = function (strings) { + return A2($elm$core$String$join, '', strings); +}; +var $avh4$elm_color$Color$toCssString = function (_v0) { + var r = _v0.a; + var g = _v0.b; + var b = _v0.c; + var a = _v0.d; + var roundTo = function (x) { + return $elm$core$Basics$round(x * 1000) / 1000; + }; + var pct = function (x) { + return $elm$core$Basics$round(x * 10000) / 100; + }; + return $elm$core$String$concat( + _List_fromArray( + [ + 'rgba(', + $elm$core$String$fromFloat( + pct(r)), + '%,', + $elm$core$String$fromFloat( + pct(g)), + '%,', + $elm$core$String$fromFloat( + pct(b)), + '%,', + $elm$core$String$fromFloat( + roundTo(a)), + ')' + ])); +}; +var $elm_community$typed_svg$TypedSvg$TypesToStrings$paintToString = function (paint) { + switch (paint.$) { + case 'Paint': + var color = paint.a; + return $avh4$elm_color$Color$toCssString(color); + case 'CSSVariable': + var string = paint.a; + return $elm$core$String$concat( + _List_fromArray( + ['var(' + (string + ')')])); + case 'Reference': + var string = paint.a; + return $elm$core$String$concat( + _List_fromArray( + ['url(#', string, ')'])); + case 'ContextFill': + return 'context-fill'; + case 'ContextStroke': + return 'context-stroke'; + default: + return 'none'; } }; -var $elm_community$typed_svg$TypedSvg$Attributes$r = function (length) { +var $elm_community$typed_svg$TypedSvg$Attributes$fill = A2( + $elm$core$Basics$composeL, + $elm_community$typed_svg$TypedSvg$Core$attribute('fill'), + $elm_community$typed_svg$TypedSvg$TypesToStrings$paintToString); +var $elm$virtual_dom$VirtualDom$nodeNS = F2( + function (namespace, tag) { + return A2( + _VirtualDom_nodeNS, + namespace, + _VirtualDom_noScript(tag)); + }); +var $elm_community$typed_svg$TypedSvg$Core$node = $elm$virtual_dom$VirtualDom$nodeNS('http://www.w3.org/2000/svg'); +var $elm_community$typed_svg$TypedSvg$g = $elm_community$typed_svg$TypedSvg$Core$node('g'); +var $elm_community$typed_svg$TypedSvg$Attributes$stroke = A2( + $elm$core$Basics$composeL, + $elm_community$typed_svg$TypedSvg$Core$attribute('stroke'), + $elm_community$typed_svg$TypedSvg$TypesToStrings$paintToString); +var $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString = function (length) { + switch (length.$) { + case 'Cm': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'cm'; + case 'Em': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'em'; + case 'Ex': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'ex'; + case 'In': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'in'; + case 'Mm': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'mm'; + case 'Num': + var x = length.a; + return $elm$core$String$fromFloat(x); + case 'Pc': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'pc'; + case 'Percent': + var x = length.a; + return $elm$core$String$fromFloat(x) + '%'; + case 'Pt': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'pt'; + case 'Px': + var x = length.a; + return $elm$core$String$fromFloat(x) + 'px'; + default: + var x = length.a; + return $elm$core$String$fromFloat(x) + 'rem'; + } +}; +var $elm_community$typed_svg$TypedSvg$Attributes$strokeWidth = function (length) { return A2( $elm_community$typed_svg$TypedSvg$Core$attribute, - 'r', + 'stroke-width', $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); }; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$r = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$r( - $elm_community$typed_svg$TypedSvg$Types$px(value)); +var $author$project$ParallelCoordinates$createLine = function (path) { + return A2( + $elm_community$typed_svg$TypedSvg$g, + _List_Nil, + _List_fromArray( + [ + A2( + $folkertdev$one_true_path_experiment$Path$element, + 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$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) + ])) + ])); }; -var $author$project$Scatterplot$radius = 2.0; +var $elm_community$typed_svg$TypedSvg$Types$AnchorMiddle = {$: 'AnchorMiddle'}; +var $elm_community$typed_svg$TypedSvg$Types$Translate = F2( + function (a, b) { + return {$: 'Translate', a: a, b: b}; + }); +var $elm_community$typed_svg$TypedSvg$Attributes$class = function (names) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'class', + A2($elm$core$String$join, ' ', names)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$fontSize = function (length) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'font-size', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +}; +var $elm$core$Tuple$second = function (_v0) { + var y = _v0.b; + return y; +}; +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': @@ -7973,80 +8804,6 @@ var $elm_community$typed_svg$TypedSvg$Attributes$textAnchor = function (anchorAl $elm_community$typed_svg$TypedSvg$TypesToStrings$anchorAlignmentToString(anchorAlignment)); }; var $elm_community$typed_svg$TypedSvg$text_ = $elm_community$typed_svg$TypedSvg$Core$node('text'); -var $elm_community$typed_svg$TypedSvg$Attributes$x = function (length) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'x', - $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); -}; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$x = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$x( - $elm_community$typed_svg$TypedSvg$Types$px(value)); -}; -var $elm_community$typed_svg$TypedSvg$Attributes$y = function (length) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'y', - $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); -}; -var $elm_community$typed_svg$TypedSvg$Attributes$InPx$y = function (value) { - return $elm_community$typed_svg$TypedSvg$Attributes$y( - $elm_community$typed_svg$TypedSvg$Types$px(value)); -}; -var $author$project$Scatterplot$point = F3( - function (scaleX, scaleY, xyPoint) { - return A2( - $elm_community$typed_svg$TypedSvg$g, - _List_fromArray( - [ - $elm_community$typed_svg$TypedSvg$Attributes$class( - _List_fromArray( - ['point'])), - $elm_community$typed_svg$TypedSvg$Attributes$fontSize( - $elm_community$typed_svg$TypedSvg$Types$Px(10.0)), - $elm_community$typed_svg$TypedSvg$Attributes$fontFamily( - _List_fromArray( - ['sans-serif'])) - ]), - _List_fromArray( - [ - A2( - $elm_community$typed_svg$TypedSvg$circle, - _List_fromArray( - [ - $elm_community$typed_svg$TypedSvg$Attributes$InPx$cx( - A2($gampleman$elm_visualization$Scale$convert, scaleX, xyPoint.x)), - $elm_community$typed_svg$TypedSvg$Attributes$InPx$cy( - A2($gampleman$elm_visualization$Scale$convert, scaleY, xyPoint.y)), - $elm_community$typed_svg$TypedSvg$Attributes$InPx$r($author$project$Scatterplot$radius) - ]), - _List_Nil), - A2( - $elm_community$typed_svg$TypedSvg$text_, - _List_fromArray( - [ - $elm_community$typed_svg$TypedSvg$Attributes$InPx$x( - A2($gampleman$elm_visualization$Scale$convert, scaleX, xyPoint.x)), - $elm_community$typed_svg$TypedSvg$Attributes$InPx$y( - A2($gampleman$elm_visualization$Scale$convert, scaleY, xyPoint.y)), - $elm_community$typed_svg$TypedSvg$Attributes$textAnchor($elm_community$typed_svg$TypedSvg$Types$AnchorMiddle) - ]), - _List_fromArray( - [ - $elm$html$Html$text(xyPoint.pointName) - ])) - ])); - }); -var $elm$core$Tuple$second = function (_v0) { - var y = _v0.b; - return y; -}; -var $elm_community$typed_svg$TypedSvg$style = $elm_community$typed_svg$TypedSvg$Core$node('style'); -var $elm_community$typed_svg$TypedSvg$svg = $elm_community$typed_svg$TypedSvg$Core$node('svg'); -var $elm_community$typed_svg$TypedSvg$Core$text = $elm$virtual_dom$VirtualDom$text; -var $elm$core$String$concat = function (strings) { - return A2($elm$core$String$join, '', strings); -}; var $elm_community$typed_svg$TypedSvg$TypesToStrings$transformToString = function (xform) { var tr = F2( function (name, args) { @@ -8125,86 +8882,17 @@ var $elm_community$typed_svg$TypedSvg$Attributes$transform = function (transform ' ', A2($elm$core$List$map, $elm_community$typed_svg$TypedSvg$TypesToStrings$transformToString, transforms))); }; -var $elm_community$typed_svg$TypedSvg$Attributes$viewBox = F4( - function (minX, minY, vWidth, vHeight) { - return A2( - $elm_community$typed_svg$TypedSvg$Core$attribute, - 'viewBox', - A2( - $elm$core$String$join, - ' ', - A2( - $elm$core$List$map, - $elm$core$String$fromFloat, - _List_fromArray( - [minX, minY, vWidth, vHeight])))); - }); -var $author$project$Scatterplot$w = 900; -var $author$project$Scatterplot$defaultExtent = _Utils_Tuple2(0, 200000); -var $gampleman$elm_visualization$Statistics$extentBy = F2( - function (fn, list) { - var min = F2( - function (a, b) { - return (_Utils_cmp( - fn(a), - fn(b)) < 0) ? a : b; - }); - var max = F2( - function (a, b) { - return (_Utils_cmp( - fn(a), - fn(b)) > 0) ? a : b; - }); - var helper = F2( - function (l, _v0) { - helper: - while (true) { - var mini = _v0.a; - var maxi = _v0.b; - if (!l.b) { - return _Utils_Tuple2(mini, maxi); - } else { - var x = l.a; - var xs = l.b; - var $temp$l = xs, - $temp$_v0 = _Utils_Tuple2( - A2(min, mini, x), - A2(max, maxi, x)); - l = $temp$l; - _v0 = $temp$_v0; - continue helper; - } - } - }); - if (!list.b) { - return $elm$core$Maybe$Nothing; - } else { - var x = list.a; - var xs = list.b; - return $elm$core$Maybe$Just( - A2( - helper, - xs, - _Utils_Tuple2(x, x))); - } - }); -var $gampleman$elm_visualization$Statistics$extent = $gampleman$elm_visualization$Statistics$extentBy($elm$core$Basics$identity); -var $author$project$Scatterplot$tickCount = 5; -var $author$project$Scatterplot$wideExtent = function (values) { - var tup = A2( - $elm$core$Maybe$withDefault, - $author$project$Scatterplot$defaultExtent, - $gampleman$elm_visualization$Statistics$extent(values)); - var minValue = ((tup.a - (tup.b / ($author$project$Scatterplot$tickCount * 2))) <= 0) ? 0 : (tup.a - (tup.b / ($author$project$Scatterplot$tickCount * 2))); - var maxValue = tup.b + (tup.b / ($author$project$Scatterplot$tickCount * 2)); - return _Utils_Tuple2(minValue, maxValue); -}; -var $elm_community$typed_svg$TypedSvg$Attributes$width = function (length) { +var $elm_community$typed_svg$TypedSvg$Types$px = $elm_community$typed_svg$TypedSvg$Types$Px; +var $elm_community$typed_svg$TypedSvg$Attributes$y = function (length) { return A2( $elm_community$typed_svg$TypedSvg$Core$attribute, - 'width', + 'y', $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); }; +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$y = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$y( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; var $elm$svg$Svg$Attributes$class = _VirtualDom_attribute('class'); var $gampleman$elm_visualization$Scale$tickFormat = function (_v0) { var opts = _v0.a; @@ -8293,15 +8981,12 @@ var $gampleman$elm_visualization$Axis$computeOptions = F2( }, postList); }); -var $elm$svg$Svg$Attributes$d = _VirtualDom_attribute('d'); var $elm$svg$Svg$Attributes$dy = _VirtualDom_attribute('dy'); var $elm$svg$Svg$Attributes$fill = _VirtualDom_attribute('fill'); var $elm$svg$Svg$Attributes$fontFamily = _VirtualDom_attribute('font-family'); var $elm$svg$Svg$Attributes$fontSize = _VirtualDom_attribute('font-size'); -var $elm$svg$Svg$trustedNode = _VirtualDom_nodeNS('http://www.w3.org/2000/svg'); var $elm$svg$Svg$g = $elm$svg$Svg$trustedNode('g'); var $elm$svg$Svg$line = $elm$svg$Svg$trustedNode('line'); -var $elm$svg$Svg$path = $elm$svg$Svg$trustedNode('path'); var $gampleman$elm_visualization$Scale$rangeExtent = function (_v0) { var options = _v0.a; return A2(options.rangeExtent, options.domain, options.range); @@ -8396,23 +9081,313 @@ var $elm$svg$Svg$Attributes$x2 = _VirtualDom_attribute('x2'); var $elm$svg$Svg$Attributes$y = _VirtualDom_attribute('y'); var $elm$svg$Svg$Attributes$y1 = _VirtualDom_attribute('y1'); var $elm$svg$Svg$Attributes$y2 = _VirtualDom_attribute('y2'); -var $gampleman$elm_visualization$Axis$verticalAttrs = { - horizontal: false, - translate: function (x) { - return 'translate(' + ($elm$core$String$fromFloat(x) + ', 0)'); +var $gampleman$elm_visualization$Axis$horizontalAttrs = { + horizontal: true, + translate: function (y) { + return 'translate(0, ' + ($elm$core$String$fromFloat(y) + ')'); }, - x: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y, $elm$core$String$fromFloat), - x1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y1, $elm$core$String$fromFloat), - x2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y2, $elm$core$String$fromFloat), - y: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x, $elm$core$String$fromFloat), - y1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x1, $elm$core$String$fromFloat), - y2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x2, $elm$core$String$fromFloat) + x: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x, $elm$core$String$fromFloat), + x1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x1, $elm$core$String$fromFloat), + x2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x2, $elm$core$String$fromFloat), + y: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y, $elm$core$String$fromFloat), + y1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y1, $elm$core$String$fromFloat), + y2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y2, $elm$core$String$fromFloat) }; -var $gampleman$elm_visualization$Axis$bottom = A4($gampleman$elm_visualization$Axis$element, $gampleman$elm_visualization$Axis$verticalAttrs, 1, '0.71em', 'middle'); -var $gampleman$elm_visualization$Axis$TickCount = function (a) { - return {$: 'TickCount', a: a}; +var $gampleman$elm_visualization$Axis$left = A4($gampleman$elm_visualization$Axis$element, $gampleman$elm_visualization$Axis$horizontalAttrs, -1, '0.32em', 'end'); +var $author$project$ParallelCoordinates$yAxis = function (scale) { + return A2($gampleman$elm_visualization$Axis$left, _List_Nil, scale); +}; +var $author$project$ParallelCoordinates$createYAxis = F3( + function (scaleX, scaleY, text) { + var index = scaleY.a; + return A2( + $elm_community$typed_svg$TypedSvg$g, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$transform( + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$Types$Translate, + A2($gampleman$elm_visualization$Scale$convert, scaleX, index), + 20) + ])) + ]), + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$g, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$class( + _List_fromArray( + ['axis'])) + ]), + _List_fromArray( + [ + $author$project$ParallelCoordinates$yAxis(scaleY.b) + ])), + A2( + $elm_community$typed_svg$TypedSvg$text_, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$InPx$y(-10), + $elm_community$typed_svg$TypedSvg$Attributes$textAnchor($elm_community$typed_svg$TypedSvg$Types$AnchorMiddle), + $elm_community$typed_svg$TypedSvg$Attributes$fontSize( + $elm_community$typed_svg$TypedSvg$Types$Px(14)) + ]), + _List_fromArray( + [ + $elm$html$Html$text(text) + ])) + ])); + }); +var $author$project$ParallelCoordinates$h = 450; +var $elm_community$typed_svg$TypedSvg$Attributes$height = function (length) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'height', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +}; +var $gampleman$elm_visualization$Shape$Generators$line = F2( + function (curve, data) { + var makeCurves = F2( + function (datum, _v3) { + var prev = _v3.a; + var list = _v3.b; + var _v0 = _Utils_Tuple3(prev, datum, list); + if (_v0.b.$ === 'Nothing') { + var _v1 = _v0.b; + var l = _v0.c; + return _Utils_Tuple2(false, l); + } else { + if (!_v0.a) { + var point = _v0.b.a; + var l = _v0.c; + return _Utils_Tuple2( + true, + A2( + $elm$core$List$cons, + _List_fromArray( + [point]), + l)); + } else { + if (_v0.c.b) { + var p1 = _v0.b.a; + var _v2 = _v0.c; + var ps = _v2.a; + var l = _v2.b; + return _Utils_Tuple2( + true, + A2( + $elm$core$List$cons, + A2($elm$core$List$cons, p1, ps), + l)); + } else { + var p1 = _v0.b.a; + var l = _v0.c; + return _Utils_Tuple2( + true, + A2( + $elm$core$List$cons, + _List_fromArray( + [p1]), + l)); + } + } + } + }); + return A2( + $elm$core$List$map, + curve, + A3( + $elm$core$List$foldr, + makeCurves, + _Utils_Tuple2(false, _List_Nil), + data).b); + }); +var $gampleman$elm_visualization$Shape$line = $gampleman$elm_visualization$Shape$Generators$line; +var $folkertdev$one_true_path_experiment$SubPath$empty = $folkertdev$one_true_path_experiment$SubPath$Empty; +var $folkertdev$one_true_path_experiment$LowLevel$Command$lineTo = $folkertdev$one_true_path_experiment$LowLevel$Command$LineTo; +var $folkertdev$one_true_path_experiment$LowLevel$Command$MoveTo = function (a) { + return {$: 'MoveTo', a: a}; +}; +var $folkertdev$one_true_path_experiment$LowLevel$Command$moveTo = $folkertdev$one_true_path_experiment$LowLevel$Command$MoveTo; +var $folkertdev$one_true_path_experiment$SubPath$with = F2( + function (moveto, drawtos) { + return $folkertdev$one_true_path_experiment$SubPath$SubPath( + { + drawtos: $folkertdev$elm_deque$Deque$fromList(drawtos), + moveto: moveto + }); + }); +var $folkertdev$one_true_path_experiment$Curve$linear = function (points) { + if (!points.b) { + return $folkertdev$one_true_path_experiment$SubPath$empty; + } else { + var x = points.a; + var xs = points.b; + return A2( + $folkertdev$one_true_path_experiment$SubPath$with, + $folkertdev$one_true_path_experiment$LowLevel$Command$moveTo(x), + _List_fromArray( + [ + $folkertdev$one_true_path_experiment$LowLevel$Command$lineTo(xs) + ])); + } +}; +var $gampleman$elm_visualization$Shape$linearCurve = $folkertdev$one_true_path_experiment$Curve$linear; +var $author$project$ParallelCoordinates$listmap10 = function (f) { + return function (la) { + return function (lb) { + return function (lc) { + return function (ld) { + return function (le) { + return function (lf) { + return function (lg) { + return function (lh) { + return function (li) { + return function (lj) { + var go = function (xs) { + return function (ys) { + return function (zs) { + return function (ws) { + return function (vs) { + return function (as1) { + return function (bs) { + return function (cs) { + return function (ds) { + return function (es) { + return function (acc) { + go: + while (true) { + var _v0 = _Utils_Tuple3(xs, ys, zs); + if ((_v0.a.b && _v0.b.b) && _v0.c.b) { + var _v1 = _v0.a; + var x = _v1.a; + var xr = _v1.b; + var _v2 = _v0.b; + var y = _v2.a; + var yr = _v2.b; + var _v3 = _v0.c; + var z = _v3.a; + var zr = _v3.b; + var _v4 = _Utils_Tuple3(ws, vs, as1); + if ((_v4.a.b && _v4.b.b) && _v4.c.b) { + var _v5 = _v4.a; + var w1 = _v5.a; + var wr = _v5.b; + var _v6 = _v4.b; + var v = _v6.a; + var vr = _v6.b; + var _v7 = _v4.c; + var a = _v7.a; + var ar = _v7.b; + var _v8 = _Utils_Tuple3(bs, cs, ds); + if ((_v8.a.b && _v8.b.b) && _v8.c.b) { + var _v9 = _v8.a; + var b = _v9.a; + var br = _v9.b; + var _v10 = _v8.b; + var c = _v10.a; + var cr = _v10.b; + var _v11 = _v8.c; + var d = _v11.a; + var dr = _v11.b; + if (es.b) { + var e = es.a; + var er = es.b; + var $temp$xs = xr, + $temp$ys = yr, + $temp$zs = zr, + $temp$ws = wr, + $temp$vs = vr, + $temp$as1 = ar, + $temp$bs = br, + $temp$cs = cr, + $temp$ds = dr, + $temp$es = er, + $temp$acc = A2( + $elm$core$List$cons, + f(x)(y)(z)(w1)(v)(a)(b)(c)(d)(e), + acc); + xs = $temp$xs; + ys = $temp$ys; + zs = $temp$zs; + ws = $temp$ws; + vs = $temp$vs; + as1 = $temp$as1; + bs = $temp$bs; + cs = $temp$cs; + ds = $temp$ds; + es = $temp$es; + acc = $temp$acc; + continue go; + } else { + return $elm$core$List$reverse(acc); + } + } else { + return $elm$core$List$reverse(acc); + } + } else { + return $elm$core$List$reverse(acc); + } + } else { + return $elm$core$List$reverse(acc); + } + } + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + return go(la)(lb)(lc)(ld)(le)(lf)(lg)(lh)(li)(lj)(_List_Nil); + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +}; +var $elm$core$List$map3 = _List_map3; +var $elm$core$Tuple$pair = F2( + function (a, b) { + return _Utils_Tuple2(a, b); + }); +var $elm_community$typed_svg$TypedSvg$style = $elm_community$typed_svg$TypedSvg$Core$node('style'); +var $elm_community$typed_svg$TypedSvg$svg = $elm_community$typed_svg$TypedSvg$Core$node('svg'); +var $elm_community$typed_svg$TypedSvg$Core$text = $elm$virtual_dom$VirtualDom$text; +var $elm_community$typed_svg$TypedSvg$Attributes$viewBox = F4( + function (minX, minY, vWidth, vHeight) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'viewBox', + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $elm$core$String$fromFloat, + _List_fromArray( + [minX, minY, vWidth, vHeight])))); + }); +var $author$project$ParallelCoordinates$w = 900; +var $elm_community$typed_svg$TypedSvg$Attributes$width = function (length) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'width', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); }; -var $gampleman$elm_visualization$Axis$tickCount = $gampleman$elm_visualization$Axis$TickCount; var $gampleman$elm_visualization$Scale$Scale = function (a) { return {$: 'Scale', a: a}; }; @@ -8521,10 +9496,6 @@ var $gampleman$elm_visualization$Scale$Continuous$e10 = $elm$core$Basics$sqrt(50 var $gampleman$elm_visualization$Scale$Continuous$e2 = $elm$core$Basics$sqrt(2); var $gampleman$elm_visualization$Scale$Continuous$e5 = $elm$core$Basics$sqrt(10); var $gampleman$elm_visualization$Scale$Continuous$ln10 = A2($elm$core$Basics$logBase, $elm$core$Basics$e, 10); -var $elm$core$Basics$negate = function (n) { - return -n; -}; -var $elm$core$Basics$pow = _Basics_pow; var $gampleman$elm_visualization$Scale$Continuous$tickIncrement = F3( function (start, stop, count) { var step = (stop - start) / A2($elm$core$Basics$max, 0, count); @@ -8570,9 +9541,6 @@ var $gampleman$elm_visualization$Scale$Continuous$nice = F2( }, domain); }); -var $elm$core$Basics$abs = function (n) { - return (n < 0) ? (-n) : n; -}; var $gampleman$elm_visualization$Scale$Continuous$exponent = function (num) { var helper = F2( function (soFar, x) { @@ -8643,7 +9611,6 @@ var $elm$core$String$padRight = F3( n - $elm$core$String$length(string), $elm$core$String$fromChar(_char))); }); -var $elm$core$Basics$round = _Basics_round; var $gampleman$elm_visualization$Scale$Continuous$toFixed = F2( function (precision, value) { var power_ = A2($elm$core$Basics$pow, 10, precision); @@ -8706,69 +9673,779 @@ var $gampleman$elm_visualization$Scale$Continuous$tickFormat = F2( $gampleman$elm_visualization$Scale$Continuous$precisionFixed( A3($gampleman$elm_visualization$Statistics$tickStep, start, stop, count))); }); -var $elmcraft$core_extra$Float$Extra$range = F3( - function (start, stop, step) { - if (!step) { - return _List_Nil; +var $elmcraft$core_extra$Float$Extra$range = F3( + function (start, stop, step) { + if (!step) { + return _List_Nil; + } else { + var n = A2( + $elm$core$Basics$max, + 0, + $elm$core$Basics$ceiling((stop - start) / step)); + var helper = F2( + function (i, list) { + helper: + while (true) { + if (i >= 0) { + var $temp$i = i - 1, + $temp$list = A2($elm$core$List$cons, start + (step * i), list); + i = $temp$i; + list = $temp$list; + continue helper; + } else { + return list; + } + } + }); + return A2(helper, n - 1, _List_Nil); + } + }); +var $gampleman$elm_visualization$Statistics$range = $elmcraft$core_extra$Float$Extra$range; +var $gampleman$elm_visualization$Statistics$ticks = F3( + function (start, stop, count) { + var step = A3($gampleman$elm_visualization$Statistics$tickStep, start, stop, count); + var end = ($elm$core$Basics$floor(stop / step) * step) + (step / 2); + var beg = $elm$core$Basics$ceiling(start / step) * step; + return A3($gampleman$elm_visualization$Statistics$range, beg, end, step); + }); +var $gampleman$elm_visualization$Scale$Continuous$ticks = F2( + function (_v0, count) { + var start = _v0.a; + var end = _v0.b; + return A3($gampleman$elm_visualization$Statistics$ticks, start, end, count); + }); +var $gampleman$elm_visualization$Scale$Continuous$scaleWithTransform = F4( + function (transform, untransform, range_, domain_) { + return { + convert: A2($gampleman$elm_visualization$Scale$Continuous$convertTransform, transform, $gampleman$elm_visualization$Interpolation$float), + domain: domain_, + invert: A2($gampleman$elm_visualization$Scale$Continuous$invertTransform, transform, untransform), + nice: $gampleman$elm_visualization$Scale$Continuous$nice, + range: range_, + rangeExtent: F2( + function (_v0, r) { + return r; + }), + tickFormat: $gampleman$elm_visualization$Scale$Continuous$tickFormat, + ticks: $gampleman$elm_visualization$Scale$Continuous$ticks + }; + }); +var $gampleman$elm_visualization$Scale$Continuous$linear = A2($gampleman$elm_visualization$Scale$Continuous$scaleWithTransform, $elm$core$Basics$identity, $elm$core$Basics$identity); +var $gampleman$elm_visualization$Scale$linear = F2( + function (range_, domain_) { + 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$defaultExtent = _Utils_Tuple2(0, 200000); +var $gampleman$elm_visualization$Statistics$extentBy = F2( + function (fn, list) { + var min = F2( + function (a, b) { + return (_Utils_cmp( + fn(a), + fn(b)) < 0) ? a : b; + }); + var max = F2( + function (a, b) { + return (_Utils_cmp( + fn(a), + fn(b)) > 0) ? a : b; + }); + var helper = F2( + function (l, _v0) { + helper: + while (true) { + var mini = _v0.a; + var maxi = _v0.b; + if (!l.b) { + return _Utils_Tuple2(mini, maxi); + } else { + var x = l.a; + var xs = l.b; + var $temp$l = xs, + $temp$_v0 = _Utils_Tuple2( + A2(min, mini, x), + A2(max, maxi, x)); + l = $temp$l; + _v0 = $temp$_v0; + continue helper; + } + } + }); + if (!list.b) { + return $elm$core$Maybe$Nothing; + } else { + var x = list.a; + var xs = list.b; + return $elm$core$Maybe$Just( + A2( + helper, + xs, + _Utils_Tuple2(x, x))); + } + }); +var $gampleman$elm_visualization$Statistics$extent = $gampleman$elm_visualization$Statistics$extentBy($elm$core$Basics$identity); +var $author$project$ParallelCoordinates$wideExtent = function (values) { + return A2( + $elm$core$Maybe$withDefault, + $author$project$ParallelCoordinates$defaultExtent, + $gampleman$elm_visualization$Statistics$extent(values)); +}; +var $author$project$ParallelCoordinates$xScale = function (values) { + return A2( + $gampleman$elm_visualization$Scale$linear, + _Utils_Tuple2($author$project$ParallelCoordinates$padding, $author$project$ParallelCoordinates$w - $author$project$ParallelCoordinates$padding), + $author$project$ParallelCoordinates$wideExtent(values)); +}; +var $author$project$ParallelCoordinates$yScale = function (values) { + return A2( + $gampleman$elm_visualization$Scale$linear, + _Utils_Tuple2($author$project$ParallelCoordinates$h, 0), + $author$project$ParallelCoordinates$wideExtent(values)); +}; +var $author$project$ParallelCoordinates$parallelCoordinatesPlot = F2( + function (model, smartphonesList) { + var multidimStrings = model.parallelPlotOption.orderedLabels; + var getAttributeList = F2( + function (attribute, smartphones) { + return A2($elm$core$List$map, attribute, smartphones); + }); + var convertMaybeList = F2( + function (maybeList, defaultValue) { + return A2( + $elm$core$List$map, + $elm$core$Maybe$withDefault(defaultValue), + maybeList); + }); + var getAllAttributeLists = F2( + function (attributes, smartphones) { + return A2( + $elm$core$List$map, + function (attribute) { + return A2( + convertMaybeList, + A2(getAttributeList, attribute, smartphones), + 0.0); + }, + attributes); + }); + var multiDimValues = A2(getAllAttributeLists, model.parallelPlotOption.orderedList, smartphonesList); + var dimLen = $elm$core$List$length(multiDimValues) - 1; + var xScaleLocal = $author$project$ParallelCoordinates$xScale( + A2( + $elm$core$List$map, + $elm$core$Basics$toFloat, + A2($elm$core$List$range, 0, dimLen))); + var yValues = multiDimValues; + var yScaleLocals = A2($elm$core$List$map, $author$project$ParallelCoordinates$yScale, yValues); + var pathGenerator = function (y1) { + return function (y2) { + return function (y3) { + return function (y4) { + return function (y5) { + return function (y6) { + return function (y7) { + return function (y8) { + return function (y9) { + return function (y10) { + var yPoints = _List_fromArray( + [y1, y2, y3, y4, y5, y6, y7, y8, y9, y10]); + var xPoints = _List_fromArray( + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + var yPointsScaled = A4( + $elm$core$List$map3, + F3( + function (yS, y, x) { + return $elm$core$Maybe$Just( + _Utils_Tuple2( + A2($gampleman$elm_visualization$Scale$convert, xScaleLocal, x), + A2($gampleman$elm_visualization$Scale$convert, yS, y) + 20)); + }), + yScaleLocals, + yPoints, + xPoints); + return A2($gampleman$elm_visualization$Shape$line, $gampleman$elm_visualization$Shape$linearCurve, yPointsScaled); + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + var yScaleLocalsWithIndex = A2( + $elm$core$List$indexedMap, + $elm$core$Tuple$pair, + A2($elm$core$List$map, $author$project$ParallelCoordinates$yScale, yValues)); + var yaxis = A3( + $elm$core$List$map2, + $author$project$ParallelCoordinates$createYAxis(xScaleLocal), + yScaleLocalsWithIndex, + multidimStrings); + var yValue1 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head(yValues)); + var yValue10 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 9, yValues))); + var yValue2 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 1, yValues))); + var yValue3 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 2, yValues))); + var yValue4 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 3, yValues))); + var yValue5 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 4, yValues))); + var yValue6 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 5, yValues))); + var yValue7 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 6, yValues))); + var yValue8 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 7, yValues))); + var yValue9 = A2( + $elm$core$Maybe$withDefault, + _List_Nil, + $elm$core$List$head( + A2($elm$core$List$drop, 8, yValues))); + var paths = $author$project$ParallelCoordinates$listmap10(pathGenerator)(yValue1)(yValue2)(yValue3)(yValue4)(yValue5)(yValue6)(yValue7)(yValue8)(yValue9)(yValue10); + var lines = A2($elm$core$List$map, $author$project$ParallelCoordinates$createLine, paths); + return A2( + $elm_community$typed_svg$TypedSvg$svg, + _List_fromArray( + [ + A4($elm_community$typed_svg$TypedSvg$Attributes$viewBox, 0, 0, $author$project$ParallelCoordinates$w + 30, $author$project$ParallelCoordinates$h + 30), + $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('\n .axis text { display: none; }\n .axis:hover text { display: inline; }\n .axis1:hover text {display: inline; }\n ') + ])), + A2($elm_community$typed_svg$TypedSvg$g, _List_Nil, _List_Nil) + ]), + _Utils_ap(yaxis, lines))); + }); +var $author$project$ParallelCoordinates$viewParallelCoordinates = function (model) { + var filteredSmartphoneData = $author$project$ParallelCoordinates$filterSPData(model.data); + return A2( + $elm$html$Html$div, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 0, 1)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('1<->2') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 1, 2)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('2<->3') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 2, 3)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('3<->4') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 3, 4)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('4<->5') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 4, 5)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('5<->6') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 5, 6)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('6<->7') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 6, 7)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('7<->8') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 7, 8)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('8<->9') + ])), + A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Events$onClick( + A2($author$project$ParallelCoordinates$ChangeOrder, 8, 9)) + ]), + _List_fromArray( + [ + $elm$html$Html$text('9<->10') + ])), + 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) + ])); +}; +var $author$project$Scatterplot$ChangeAttribute1 = function (a) { + return {$: 'ChangeAttribute1', a: a}; +}; +var $author$project$Scatterplot$ChangeAttribute2 = function (a) { + return {$: 'ChangeAttribute2', a: a}; +}; +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$field = _Json_decodeField; +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$option = _VirtualDom_node('option'); +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$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$Maybe$map3 = F4( + function (func, ma, mb, mc) { + if (ma.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; } else { - var n = A2( - $elm$core$Basics$max, - 0, - $elm$core$Basics$ceiling((stop - start) / step)); - var helper = F2( - function (i, list) { - helper: - while (true) { - if (i >= 0) { - var $temp$i = i - 1, - $temp$list = A2($elm$core$List$cons, start + (step * i), list); - i = $temp$i; - list = $temp$list; - continue helper; - } else { - return list; - } - } - }); - return A2(helper, n - 1, _List_Nil); + 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 $gampleman$elm_visualization$Statistics$range = $elmcraft$core_extra$Float$Extra$range; -var $gampleman$elm_visualization$Statistics$ticks = F3( - function (start, stop, count) { - var step = A3($gampleman$elm_visualization$Statistics$tickStep, start, stop, count); - var end = ($elm$core$Basics$floor(stop / step) * step) + (step / 2); - var beg = $elm$core$Basics$ceiling(start / step) * step; - return A3($gampleman$elm_visualization$Statistics$range, beg, end, step); - }); -var $gampleman$elm_visualization$Scale$Continuous$ticks = F2( - function (_v0, count) { - var start = _v0.a; - var end = _v0.b; - return A3($gampleman$elm_visualization$Statistics$ticks, start, end, count); - }); -var $gampleman$elm_visualization$Scale$Continuous$scaleWithTransform = F4( - function (transform, untransform, range_, domain_) { - return { - convert: A2($gampleman$elm_visualization$Scale$Continuous$convertTransform, transform, $gampleman$elm_visualization$Interpolation$float), - domain: domain_, - invert: A2($gampleman$elm_visualization$Scale$Continuous$invertTransform, transform, untransform), - nice: $gampleman$elm_visualization$Scale$Continuous$nice, - range: range_, - rangeExtent: F2( - function (_v0, r) { - return r; +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}; }), - tickFormat: $gampleman$elm_visualization$Scale$Continuous$tickFormat, - ticks: $gampleman$elm_visualization$Scale$Continuous$ticks - }; + 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 $gampleman$elm_visualization$Scale$Continuous$linear = A2($gampleman$elm_visualization$Scale$Continuous$scaleWithTransform, $elm$core$Basics$identity, $elm$core$Basics$identity); -var $gampleman$elm_visualization$Scale$linear = F2( - function (range_, domain_) { - return $gampleman$elm_visualization$Scale$Scale( - A2($gampleman$elm_visualization$Scale$Continuous$linear, range_, domain_)); +var $author$project$Scatterplot$h = 450; +var $author$project$Scatterplot$padding = 50; +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( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'cx', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$cx = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$cx( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$cy = function (length) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'cy', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$cy = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$cy( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$fontFamily = function (families) { + if (!families.b) { + return A2($elm_community$typed_svg$TypedSvg$Core$attribute, 'font-family', 'inherit'); + } else { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'font-family', + A2($elm$core$String$join, ', ', families)); + } +}; +var $elm_community$typed_svg$TypedSvg$Attributes$r = function (length) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'r', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$r = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$r( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; +var $author$project$Scatterplot$radius = 2.0; +var $elm_community$typed_svg$TypedSvg$Attributes$x = function (length) { + return A2( + $elm_community$typed_svg$TypedSvg$Core$attribute, + 'x', + $elm_community$typed_svg$TypedSvg$TypesToStrings$lengthToString(length)); +}; +var $elm_community$typed_svg$TypedSvg$Attributes$InPx$x = function (value) { + return $elm_community$typed_svg$TypedSvg$Attributes$x( + $elm_community$typed_svg$TypedSvg$Types$px(value)); +}; +var $author$project$Scatterplot$point = F3( + function (scaleX, scaleY, xyPoint) { + return A2( + $elm_community$typed_svg$TypedSvg$g, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$class( + _List_fromArray( + ['point'])), + $elm_community$typed_svg$TypedSvg$Attributes$fontSize( + $elm_community$typed_svg$TypedSvg$Types$Px(10.0)), + $elm_community$typed_svg$TypedSvg$Attributes$fontFamily( + _List_fromArray( + ['sans-serif'])) + ]), + _List_fromArray( + [ + A2( + $elm_community$typed_svg$TypedSvg$circle, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$InPx$cx( + A2($gampleman$elm_visualization$Scale$convert, scaleX, xyPoint.x)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$cy( + A2($gampleman$elm_visualization$Scale$convert, scaleY, xyPoint.y)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$r($author$project$Scatterplot$radius) + ]), + _List_Nil), + A2( + $elm_community$typed_svg$TypedSvg$text_, + _List_fromArray( + [ + $elm_community$typed_svg$TypedSvg$Attributes$InPx$x( + A2($gampleman$elm_visualization$Scale$convert, scaleX, xyPoint.x)), + $elm_community$typed_svg$TypedSvg$Attributes$InPx$y( + A2($gampleman$elm_visualization$Scale$convert, scaleY, xyPoint.y)), + $elm_community$typed_svg$TypedSvg$Attributes$textAnchor($elm_community$typed_svg$TypedSvg$Types$AnchorMiddle) + ]), + _List_fromArray( + [ + $elm$html$Html$text(xyPoint.pointName) + ])) + ])); }); +var $author$project$Scatterplot$w = 900; +var $author$project$Scatterplot$defaultExtent = _Utils_Tuple2(0, 200000); +var $author$project$Scatterplot$tickCount = 5; +var $author$project$Scatterplot$wideExtent = function (values) { + var tup = A2( + $elm$core$Maybe$withDefault, + $author$project$Scatterplot$defaultExtent, + $gampleman$elm_visualization$Statistics$extent(values)); + var minValue = ((tup.a - (tup.b / ($author$project$Scatterplot$tickCount * 2))) <= 0) ? 0 : (tup.a - (tup.b / ($author$project$Scatterplot$tickCount * 2))); + var maxValue = tup.b + (tup.b / ($author$project$Scatterplot$tickCount * 2)); + return _Utils_Tuple2(minValue, maxValue); +}; +var $gampleman$elm_visualization$Axis$verticalAttrs = { + horizontal: false, + translate: function (x) { + return 'translate(' + ($elm$core$String$fromFloat(x) + ', 0)'); + }, + x: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y, $elm$core$String$fromFloat), + x1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y1, $elm$core$String$fromFloat), + x2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y2, $elm$core$String$fromFloat), + y: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x, $elm$core$String$fromFloat), + y1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x1, $elm$core$String$fromFloat), + y2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x2, $elm$core$String$fromFloat) +}; +var $gampleman$elm_visualization$Axis$bottom = A4($gampleman$elm_visualization$Axis$element, $gampleman$elm_visualization$Axis$verticalAttrs, 1, '0.71em', 'middle'); +var $gampleman$elm_visualization$Axis$TickCount = function (a) { + return {$: 'TickCount', a: a}; +}; +var $gampleman$elm_visualization$Axis$tickCount = $gampleman$elm_visualization$Axis$TickCount; var $author$project$Scatterplot$xScale = function (values) { return A2( $gampleman$elm_visualization$Scale$linear, @@ -8784,19 +10461,6 @@ var $author$project$Scatterplot$xAxis = function (values) { ]), $author$project$Scatterplot$xScale(values)); }; -var $gampleman$elm_visualization$Axis$horizontalAttrs = { - horizontal: true, - translate: function (y) { - return 'translate(0, ' + ($elm$core$String$fromFloat(y) + ')'); - }, - x: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x, $elm$core$String$fromFloat), - x1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x1, $elm$core$String$fromFloat), - x2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$x2, $elm$core$String$fromFloat), - y: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y, $elm$core$String$fromFloat), - y1: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y1, $elm$core$String$fromFloat), - y2: A2($elm$core$Basics$composeL, $elm$svg$Svg$Attributes$y2, $elm$core$String$fromFloat) -}; -var $gampleman$elm_visualization$Axis$left = A4($gampleman$elm_visualization$Axis$element, $gampleman$elm_visualization$Axis$horizontalAttrs, -1, '0.32em', 'end'); var $author$project$Scatterplot$yScale = function (values) { return A2( $gampleman$elm_visualization$Scale$linear, @@ -8848,7 +10512,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, @@ -8971,7 +10635,11 @@ var $author$project$Main$view = function (model) { A2( $elm$html$Html$map, $author$project$Main$ScatterplotMsg, - $author$project$Scatterplot$viewScatterplot(model)) + $author$project$Scatterplot$viewScatterplot(model)), + A2( + $elm$html$Html$map, + $author$project$Main$ParallelCoordinatesMsg, + $author$project$ParallelCoordinates$viewParallelCoordinates(model)) ])); }; var $author$project$Main$main = $elm$browser$Browser$element( diff --git a/src/Main.elm b/src/Main.elm index 1fdf5938107b4e51886132527489e66c773d5bc1..f4e581e0bb58cfe5bdf60ff2fb2b24325e6db690 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -1,13 +1,14 @@ module Main exposing (..) ---import ParallelCoordinates exposing (ParallelPlotOption) - import Browser import Csv.Decode as Decode exposing (Decoder) import Html exposing (Html, div) import Http +import List.Extra +import Model exposing (Model) +import ParallelCoordinates exposing (Msg(..)) import Result exposing (Result(..)) -import Scatterplot exposing (Msg(..), ScatterPlotOption) +import Scatterplot exposing (Msg(..)) import SmartPhoneType exposing (Smartphone) @@ -21,19 +22,49 @@ main = -- MODEL - - -type alias Model = - { data : List Smartphone - , error : Maybe String - , csvdata : String - , scatterplotOptions : ScatterPlotOption - } +{- type alias Model = + { data : List Smartphone + , error : Maybe String + , csvdata : String + , scatterplotOptions : ScatterPlotOption + , parallelPlotOption : ParallelPlotOption + } +-} init : () -> ( Model, Cmd Msg ) init _ = - ( Model [] Nothing "" { attribute1 = "Price", attribute2 = "Rating", att1List = [], att2List = [] }, fetchData ) + ( Model [] + Nothing + "" + { attribute1 = "Price", attribute2 = "Rating", att1List = [], att2List = [] } + { orderedList = + [ .price + , .rating + , .num_cores + , .processor_speed + , .battery + , .fast_charging + , .memory + , .ram + , .screen_size + , .refresh_rate + ] + , orderedLabels = + [ "Price" + , "Rating" + , "NumCores" + , "Processor Speed" + , "Battery" + , "Fast Charging" + , "Memory" + , "RAM" + , "Screen Size" + , "Refresh Rate" + ] + } + , fetchData + ) @@ -44,6 +75,7 @@ type Msg = FetchData | DataReceived (Result Http.Error String) | ScatterplotMsg Scatterplot.Msg + | ParallelCoordinatesMsg ParallelCoordinates.Msg update : Msg -> Model -> ( Model, Cmd Msg ) @@ -91,6 +123,16 @@ update msg model = , Cmd.none ) + ParallelCoordinatesMsg (ChangeOrder pos1 pos2) -> + ( { model + | parallelPlotOption = + { orderedList = List.Extra.swapAt pos1 pos2 model.parallelPlotOption.orderedList + , orderedLabels = List.Extra.swapAt pos1 pos2 model.parallelPlotOption.orderedLabels + } + } + , Cmd.none + ) + createAttList : Model -> String -> List (Maybe Float) createAttList model att = @@ -136,6 +178,7 @@ view : Model -> Html Msg view model = div [] [ Scatterplot.viewScatterplot model |> Html.map ScatterplotMsg + , ParallelCoordinates.viewParallelCoordinates model |> Html.map ParallelCoordinatesMsg ] diff --git a/src/Model.elm b/src/Model.elm new file mode 100644 index 0000000000000000000000000000000000000000..9e994a1808c12d4692e3424bef2a16b65a0bb290 --- /dev/null +++ b/src/Model.elm @@ -0,0 +1,26 @@ +module Model exposing (..) + +import SmartPhoneType exposing (Smartphone) + + +type alias Model = + { data : List Smartphone + , error : Maybe String + , csvdata : String + , scatterplotOptions : ScatterPlotOption + , parallelPlotOption : ParallelPlotOption + } + + +type alias ScatterPlotOption = + { attribute1 : String + , attribute2 : String + , att1List : List (Maybe Float) + , att2List : List (Maybe Float) + } + + +type alias ParallelPlotOption = + { orderedList : List (Smartphone -> Maybe Float) + , orderedLabels : List String + } diff --git a/src/ParallelCoordinates.elm b/src/ParallelCoordinates.elm index deb57eb14b8fec1905586daa56aaddec3ca75b21..5b971ec99aa4ff81e7874031ca115b43181282b0 100644 --- a/src/ParallelCoordinates.elm +++ b/src/ParallelCoordinates.elm @@ -1,5 +1,7 @@ module ParallelCoordinates exposing (..) +--import Scatterplot exposing (ScatterPlotOption) + import Axis exposing (..) import Browser import Color @@ -10,6 +12,7 @@ import Html.Events exposing (on, onClick) import List exposing (concatMap) import List.Extra import Maybe exposing (map) +import Model exposing (Model) import Path import Scale exposing (ContinuousScale) import Shape @@ -19,431 +22,404 @@ import TypedSvg exposing (circle, g, line, polygon, rect, style, svg, text_) import TypedSvg.Attributes exposing (class, fill, fontSize, stroke, strokeWidth, textAnchor, transform, viewBox, width, x1, x2, y1, y2) import TypedSvg.Attributes.InPx exposing (cx, cy, r, x, y) import TypedSvg.Core exposing (Svg) -import TypedSvg.Types exposing (AnchorAlignment(..), Length(..), Paint(..), Transform(..), px) +import TypedSvg.Types exposing (AnchorAlignment(..), Length(..), Paint(..), Transform(..)) + + +w : Float +w = + 900 + +h : Float +h = + 450 -{- - type alias ParallelPlotOption = - { attribute1 : String - , attribute2 : String - , att1List : List (Maybe Float) - , att2List : List (Maybe Float) - } +padding : Float +padding = + 50 - w : Float - w = - 900 +tickCount : Int +tickCount = + 3 - h : Float - h = - 450 +defaultExtent : ( number, number1 ) +defaultExtent = + ( 0, 200000 ) - padding : Float - padding = - 50 +parallelCoordinatesPlot : Model -> List Smartphone -> Svg msg +parallelCoordinatesPlot model smartphonesList = + let + getAttributeList : (Smartphone -> Maybe Float) -> List Smartphone -> List (Maybe Float) + getAttributeList attribute smartphones = + List.map attribute smartphones + convertMaybeList : List (Maybe Float) -> Float -> List Float + convertMaybeList maybeList defaultValue = + List.map (Maybe.withDefault defaultValue) maybeList - tickCount : Int - tickCount = - 3 + getAllAttributeLists : List (Smartphone -> Maybe Float) -> List Smartphone -> List (List Float) + getAllAttributeLists attributes smartphones = + List.map (\attribute -> convertMaybeList (getAttributeList attribute smartphones) 0.0) attributes + multiDimValues = + getAllAttributeLists model.parallelPlotOption.orderedList smartphonesList - defaultExtent : ( number, number1 ) - defaultExtent = - ( 0, 200000 ) + multidimStrings = + model.parallelPlotOption.orderedLabels + dimLen = + List.length multiDimValues - 1 - parallelCoodinatesPlot : MultiDimData -> Svg msg - parallelCoodinatesPlot multidimData = - let - dimLen = - List.length multidimData.data - 1 + yValues = + multiDimValues - yValues = - multidimData.data - |> List.map - (\dimData -> - dimData |> List.map .value - ) + yScaleLocals = + List.map yScale yValues - dimStrings = - multidimData.dimDescription + yScaleLocalsWithIndex = + List.indexedMap Tuple.pair (List.map yScale yValues) - yScaleLocals = - List.indexedMap Tuple.pair (List.map yScale yValues) + xScaleLocal = + xScale (List.map toFloat (List.range 0 dimLen)) - xScaleLocal = - xScale (List.map toFloat (List.range 0 dimLen)) + yaxis = + List.map2 (createYAxis xScaleLocal) yScaleLocalsWithIndex multidimStrings - yaxis = - List.map2 (createYAxis xScaleLocal) yScaleLocals dimStrings + yValue1 = + Maybe.withDefault [] <| List.head yValues - yValue1 = - Maybe.withDefault [] <| List.head yValues + yValue2 = + Maybe.withDefault [] <| List.head <| List.drop 1 yValues - yValue2 = - Maybe.withDefault [] <| List.head <| List.drop 1 yValues + yValue3 = + Maybe.withDefault [] <| List.head <| List.drop 2 yValues - yValue3 = - Maybe.withDefault [] <| List.head <| List.drop 2 yValues + yValue4 = + Maybe.withDefault [] <| List.head <| List.drop 3 yValues - yValue4 = - Maybe.withDefault [] <| List.head <| List.drop 3 yValues + yValue5 = + Maybe.withDefault [] <| List.head <| List.drop 4 yValues - yScale1 = - Tuple.second <| Maybe.withDefault ( 0, Scale.linear ( padding, w - padding ) ( 0, 0 ) ) (List.head yScaleLocals) + yValue6 = + Maybe.withDefault [] <| List.head <| List.drop 5 yValues - yScale2 = - Tuple.second <| Maybe.withDefault ( 0, Scale.linear ( padding, w - padding ) ( 0, 0 ) ) (List.head <| List.drop 1 yScaleLocals) + yValue7 = + Maybe.withDefault [] <| List.head <| List.drop 6 yValues - yScale3 = - Tuple.second <| Maybe.withDefault ( 0, Scale.linear ( padding, w - padding ) ( 0, 0 ) ) (List.head <| List.drop 2 yScaleLocals) + yValue8 = + Maybe.withDefault [] <| List.head <| List.drop 7 yValues - yScale4 = - Tuple.second <| Maybe.withDefault ( 0, Scale.linear ( padding, w - padding ) ( 0, 0 ) ) (List.head <| List.drop 3 yScaleLocals) + yValue9 = + Maybe.withDefault [] <| List.head <| List.drop 8 yValues - paths = - List.map4 pathGenerator yValue1 yValue2 yValue3 yValue4 + yValue10 = + Maybe.withDefault [] <| List.head <| List.drop 9 yValues - pathGenerator : Float -> Float -> Float -> Float -> Path.Path - pathGenerator y1 y2 y3 y4 = - let - p1 = - ( Scale.convert xScaleLocal 0, Scale.convert yScale1 y1 + 20 ) + paths = + listmap10 pathGenerator yValue1 yValue2 yValue3 yValue4 yValue5 yValue6 yValue7 yValue8 yValue9 yValue10 - p2 = - ( Scale.convert xScaleLocal 1, Scale.convert yScale2 y2 + 20 ) + pathGenerator : Float -> Float -> Float -> Float -> Float -> Float -> Float -> Float -> Float -> Float -> Path.Path + pathGenerator y1 y2 y3 y4 y5 y6 y7 y8 y9 y10 = + let + yPoints = + [ y1, y2, y3, y4, y5, y6, y7, y8, y9, y10 ] - p3 = - ( Scale.convert xScaleLocal 2, Scale.convert yScale3 y3 + 20 ) + xPoints = + [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] - p4 = - ( Scale.convert xScaleLocal 3, Scale.convert yScale4 y4 + 20 ) - in - [ Just p1, Just p2, Just p3, Just p4 ] |> Shape.line Shape.linearCurve + yPointsScaled = + List.map3 (\yS y x -> Just ( Scale.convert xScaleLocal x, Scale.convert yS y + 20 )) yScaleLocals yPoints xPoints + in + yPointsScaled |> Shape.line Shape.linearCurve - lines = - List.map createLine paths - in - svg - [ viewBox 0 0 (w + 30) (h + 30) - , TypedSvg.Attributes.width <| TypedSvg.Types.Percent 100 - , TypedSvg.Attributes.height <| TypedSvg.Types.Percent 100 - ] - ([ style [] [ TypedSvg.Core.text """ - .axis text { display: none; } - .axis:hover text { display: inline; } - """ ] - , g [] [] + lines = + List.map createLine paths + in + svg + [ viewBox 0 0 (w + 30) (h + 30) + , TypedSvg.Attributes.width <| TypedSvg.Types.Percent 100 + , TypedSvg.Attributes.height <| TypedSvg.Types.Percent 100 + ] + ([ style [] [ TypedSvg.Core.text """ + .axis text { display: none; } + .axis:hover text { display: inline; } + .axis1:hover text {display: inline; } + """ ] + , g [] [] + ] + ++ yaxis + ++ lines + ) + + +createLine : Path.Path -> Svg msg +createLine path = + g [] + [ Path.element path + [ stroke <| Paint <| Color.black + , strokeWidth <| Px 0.5 + , fill PaintNone ] - ++ yaxis - ++ lines - ) - - - createLine : Path.Path -> Svg msg - createLine path = - g [] - [ Path.element path - [ stroke <| Paint <| Color.black - , strokeWidth <| Px 1 - , fill PaintNone - ] - ] - - - createYAxis : ContinuousScale Float -> ( Int, ContinuousScale Float ) -> String -> Svg msg - createYAxis scaleX scaleY text = - let - index = - Tuple.first scaleY |> toFloat - in - g [ transform [ Translate (Scale.convert scaleX index) 20 ] ] - [ g [ class [ "axis" ] ] [ yAxis (Tuple.second scaleY) ] - , text_ - [ y -10, textAnchor AnchorMiddle, fontSize <| Px 14 ] - [ Html.text text ] - ] - - - yAxis : ContinuousScale Float -> Svg msg - yAxis scale = - Axis.left [] scale - - - xScale : List Float -> ContinuousScale Float - xScale values = - Scale.linear ( padding, w - padding ) (wideExtent values) - - - yScale : List Float -> ContinuousScale Float - yScale values = - Scale.linear ( h, 0 ) (wideExtent values) - - - wideExtent : List Float -> ( Float, Float ) - wideExtent values = - Maybe.withDefault defaultExtent (Statistics.extent values) - - - filterCarData : - List Car - -> CarType - -> List CarData - filterCarData my_cars carType = - let - carDataList = - List.filterMap mapToCarData my_cars - - carsInType = - List.filter (carInCarType carType) carDataList - in - carsInType - - - mapToCarData : Car -> Maybe CarData - mapToCarData car = - map6 - (\cityMPG retailPrice name dealerCost carLen carType -> - { vehicle = name - , cityMPG = toFloat cityMPG - , retailPrice = toFloat retailPrice - , dealerCost = toFloat dealerCost - , carLen = toFloat carLen - , carType = carType - } - ) - car.cityMPG - car.retailPrice - (Just car.vehicleName) - car.dealerCost - car.carLen - (Just car.carType) - - - carInCarType : CarType -> CarData -> Bool + ] + + +createYAxis : ContinuousScale Float -> ( Int, ContinuousScale Float ) -> String -> Svg msg +createYAxis scaleX scaleY text = + let + index = + Tuple.first scaleY |> toFloat + in + g [ transform [ Translate (Scale.convert scaleX index) 20 ] ] + [ g [ class [ "axis" ] ] [ yAxis (Tuple.second scaleY) ] + , text_ + [ y -10, textAnchor AnchorMiddle, fontSize <| Px 14 ] + [ Html.text text ] + ] + + +yAxis : ContinuousScale Float -> Svg msg +yAxis scale = + Axis.left [] scale + + +xScale : List Float -> ContinuousScale Float +xScale values = + Scale.linear ( padding, w - padding ) (wideExtent values) + + +yScale : List Float -> ContinuousScale Float +yScale values = + Scale.linear ( h, 0 ) (wideExtent values) + + +wideExtent : List Float -> ( Float, Float ) +wideExtent values = + Maybe.withDefault defaultExtent (Statistics.extent values) + + +filterSPData : + List Smartphone + -> List Smartphone +filterSPData smartphone = + let + smartphoneList = + List.filterMap mapToSPData smartphone + + {- carsInType = + List.filter (carInCarType carType) carDataList + -} + in + smartphoneList + + +mapToSPData : Smartphone -> Maybe Smartphone +mapToSPData smartphone = + map10 + (\price rating num_cores processor_speed battery fast_charging memory ram screen_size refresh_rate -> + { id = smartphone.id + , brand = smartphone.brand + , model = smartphone.model + , price = Just price + , rating = Just rating + , g5 = smartphone.g5 + , nfc = smartphone.nfc + , ir_blaster = smartphone.ir_blaster + , processor_name = smartphone.processor_name + , processor_brand = smartphone.processor_brand + , num_cores = Just num_cores + , processor_speed = Just processor_speed + , battery = Just battery + , fast_charging = Just 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.price + smartphone.rating + smartphone.num_cores + smartphone.processor_speed + smartphone.battery + smartphone.fast_charging + smartphone.memory + smartphone.ram + smartphone.screen_size + 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 - transfromCarDataToMultiDimData : List ( String, List ( Float, String ) ) -> MultiDimData - transfromCarDataToMultiDimData dimList = - let - dimDescription = - List.map Tuple.first (List.map ffks dimList) - - data = - List.map Tuple.second (List.map ffks dimList) - in - MultiDimData dimDescription data - ffks : ( String, List ( Float, String ) ) -> ( String, List MultiDimPoint ) - ffks data = - let - multiDimPointList = - List.map transformToMultiDimPoint (Tuple.second data) - in - ( Tuple.first data, multiDimPointList ) + 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) +-} - cityMPGValue : CarData -> ( Float, String ) - cityMPGValue car = - ( car.cityMPG, car.vehicle ) - - - retailPriceValue : CarData -> ( Float, String ) - retailPriceValue car = - ( car.retailPrice, car.vehicle ) - - - dealerCostValue : CarData -> ( Float, String ) - dealerCostValue car = - ( car.dealerCost, car.vehicle ) - - - carLenValue : CarData -> ( Float, String ) - carLenValue car = - ( car.carLen, car.vehicle ) - - - pointNameValue : CarData -> String - pointNameValue = - .vehicle - - - getIndex : String -> Model -> Int - getIndex str model = - let - rangeList = - List.range 0 <| List.length model.reihenfolge - 1 - - findIndex : Int -> Maybe Int - findIndex index = - if List.Extra.getAt index model.reihenfolge == Just str then - Just index - - else - Nothing - - i = - List.filterMap findIndex rangeList - in - Maybe.withDefault 0 (List.head i) - - - view : Model -> Html Msg - view model = - let - carType = - model.carType - - filteredCarsData = - filterCarData cars carType - - numberCarsInType = - List.length filteredCarsData - - cityMPGValues = - List.map cityMPGValue filteredCarsData - - retailPriceValues = - List.map retailPriceValue filteredCarsData - - dealerCostValues = - List.map dealerCostValue filteredCarsData - - carLenValues = - List.map carLenValue filteredCarsData - - iCityMPG = - getIndex "cityMPG" - - dimList = - List.map Tuple.second - (List.sortBy Tuple.first - [ ( getIndex "cityMPG" model, ( "cityMPG", cityMPGValues ) ) - , ( getIndex "retailPrice" model, ( "retailPrice", retailPriceValues ) ) - , ( getIndex "dealerCost" model, ( "dealerCost", dealerCostValues ) ) - , ( getIndex "carLen" model, ( "carLen", carLenValues ) ) - ] - ) - - multiDimData = - transfromCarDataToMultiDimData dimList - in - Html.div [] - [ Html.p [ fontSize <| Px 5 ] - [ Html.text - ("CarType: " - ++ toString carType - ++ " | Cars in Typ: " - ++ String.fromInt numberCarsInType - ) - ] - , b [] [ text "Car Type: " ] - , button [ onClick SetSmall_Sporty_Compact_Large_Sedan ] [ text "SSCLS" ] - , button [ onClick SetSports_Car ] [ text "Sport Car" ] - , button [ onClick SetSUV ] [ text "SUV" ] - , button [ onClick SetWagon ] [ text "Wagon" ] - , button [ onClick SetMinivan ] [ text "Minivan" ] - , button [ onClick SetPickup ] [ text "Pickup" ] - , br [] [] - , button [ onClick (Down "cityMPG") ] [ text "Down cityMPG" ] - , button [ onClick (Up "cityMPG") ] [ text "Up cityMPG" ] - , br [] [] - , button [ onClick (Down "retailPrice") ] [ text "Down retailPrice" ] - , button [ onClick (Up "retailPrice") ] [ text "Up retailPrice" ] - , br [] [] - , button [ onClick (Down "dealerCost") ] [ text "Down dealerCost" ] - , button [ onClick (Up "dealerCost") ] [ text "Up dealerCost" ] - , br [] [] - , button [ onClick (Down "carLen") ] [ text "Down carLen" ] - , button [ onClick (Up "carLen") ] [ text "Up carLen" ] - , br [] [] - , br [] [] - , parallelCoodinatesPlot multiDimData - ] - - - type alias MultiDimPoint = - { pointName : String, value : Float } - - - type alias MultiDimData = - { dimDescription : List String - , data : List (List MultiDimPoint) - } - - - type Msg - = SetSmall_Sporty_Compact_Large_Sedan - | SetSports_Car - | SetSUV - | SetWagon - | SetMinivan - | SetPickup - | Up String - | Down String - - - type alias Model = - { carType : CarType - , reihenfolge : List String - } - - - update : Msg -> Model -> Model - update msg model = - case msg of - SetSmall_Sporty_Compact_Large_Sedan -> - { model | carType = Small_Sporty_Compact_Large_Sedan } - - SetSports_Car -> - { model | carType = Sports_Car } - - SetSUV -> - { model | carType = SUV } - - SetWagon -> - { model | carType = Wagon } - - SetMinivan -> - { model | carType = Minivan } - - SetPickup -> - { model | carType = Pickup } - - Up str -> - { model - | reihenfolge = - if getIndex str model < (List.length model.reihenfolge - 1) then - List.Extra.swapAt (getIndex str model) (getIndex str model + 1) model.reihenfolge - - else - model.reihenfolge - } - - Down str -> - { model - | reihenfolge = - if getIndex str model > 0 then - List.Extra.swapAt (getIndex str model) (getIndex str model - 1) model.reihenfolge - - else - model.reihenfolge - } --} +viewParallelCoordinates : Model -> Html Msg +viewParallelCoordinates model = + let + filteredSmartphoneData = + filterSPData model.data + 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 + ] + + +type alias MultiDimPoint = + { pointName : String, value : Float } + + +type alias MultiDimData = + { dimDescription : List String + , data : List (List MultiDimPoint) + } + + +type Msg + = ChangeOrder Int Int + + +map10 : (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> result) -> Maybe a -> Maybe b -> Maybe c -> Maybe d -> Maybe e -> Maybe f -> Maybe g -> Maybe h -> Maybe i -> Maybe j -> Maybe result +map10 func maybe1 maybe2 maybe3 maybe4 maybe5 maybe6 maybe7 maybe8 maybe9 maybe10 = + case maybe1 of + Just value1 -> + case maybe2 of + Just value2 -> + case maybe3 of + Just value3 -> + case maybe4 of + Just value4 -> + case maybe5 of + Just value5 -> + case maybe6 of + Just value6 -> + case maybe7 of + Just value7 -> + case maybe8 of + Just value8 -> + case maybe9 of + Just value9 -> + case maybe10 of + Just value10 -> + Just (func value1 value2 value3 value4 value5 value6 value7 value8 value9 value10) + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + Nothing -> + Nothing + + +listmap10 : + (a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k) + -> List a + -> List b + -> List c + -> List d + -> List e + -> List f + -> List g + -> List h + -> List i + -> List j + -> List k +listmap10 f la lb lc ld le lf lg lh li lj = + let + go xs ys zs ws vs as1 bs cs ds es acc = + case ( xs, ys, zs ) of + ( x :: xr, y :: yr, z :: zr ) -> + case ( ws, vs, as1 ) of + ( w1 :: wr, v :: vr, a :: ar ) -> + case ( bs, cs, ds ) of + ( b :: br, c :: cr, d :: dr ) -> + case es of + e :: er -> + go xr yr zr wr vr ar br cr dr er (f x y z w1 v a b c d e :: acc) + + [] -> + List.reverse acc + + _ -> + List.reverse acc + + _ -> + List.reverse acc + + _ -> + List.reverse acc + in + go la lb lc ld le lf lg lh li lj [] diff --git a/src/Scatterplot.elm b/src/Scatterplot.elm index 26e017e5960ccbb0e1a9a108d17456db3ffafaf0..760b4aa9b823b3e539a4678ff3a9799c6960fe61 100644 --- a/src/Scatterplot.elm +++ b/src/Scatterplot.elm @@ -4,8 +4,8 @@ import Axis exposing (..) import Html exposing (Html, option) import Html.Attributes exposing (value) import Html.Events exposing (onInput) +import Model exposing (Model) import Scale exposing (ContinuousScale) -import SmartPhoneType exposing (Smartphone) import Statistics import TypedSvg exposing (circle, g, style, svg, text_) import TypedSvg.Attributes exposing (class, fontFamily, fontSize, textAnchor, transform, viewBox) @@ -14,20 +14,22 @@ import TypedSvg.Core exposing (Svg) import TypedSvg.Types exposing (AnchorAlignment(..), Length(..), Transform(..)) -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) - } +{- type alias Model = + { data : List Smartphone + , error : Maybe String + , csvdata : String + , scatterplotOptions : ScatterPlotOption + , parallelPlotOption : ParallelPlotOption + } +-} +{- type alias ScatterPlotOption = + { attribute1 : String + , attribute2 : String + , att1List : List (Maybe Float) + , att2List : List (Maybe Float) + } +-} w : Float