You need to sign in before continuing.

Commit 24be6abbe533e5aa1870c9770f86cd4c39deb30e

Authored by Luigi Serra
1 parent 6f8e74f7

selection controllet with preset

controllets/data-sevc-controllet/data-sevc-controllet.html 100755 → 100644
@@ -255,14 +255,14 @@ Example: @@ -255,14 +255,14 @@ Example:
255 height: 50vh; 255 height: 50vh;
256 } 256 }
257 257
258 - #selected_fields_main_container{ 258 + #selectedFields_main_container{
259 position: relative; 259 position: relative;
260 height: 50vh; 260 height: 50vh;
261 } 261 }
262 262
263 #idm_layout_main_container{ 263 #idm_layout_main_container{
264 position: relative; 264 position: relative;
265 - height: 25vh; 265 + height: 65vh;
266 } 266 }
267 267
268 paper-menu{ 268 paper-menu{
@@ -299,7 +299,7 @@ Example: @@ -299,7 +299,7 @@ Example:
299 </iron-ajax> 299 </iron-ajax>
300 300
301 <iron-ajax 301 <iron-ajax
302 - id="selected_datalet_request" 302 + id="selectedDatalet_request"
303 url={{deepUrl}} 303 url={{deepUrl}}
304 verbose="true" 304 verbose="true"
305 on-response="handleSelectedDatalet" 305 on-response="handleSelectedDatalet"
@@ -400,7 +400,7 @@ Example: @@ -400,7 +400,7 @@ Example:
400 <div id="toolbar_title" class="big">Data mapping</div> 400 <div id="toolbar_title" class="big">Data mapping</div>
401 <div id="toolbar_description" class="small">Select the visualization from the slider, drag and drop the selected fields in visualization parameter area, customize the visualization if you need</div> 401 <div id="toolbar_description" class="small">Select the visualization from the slider, drag and drop the selected fields in visualization parameter area, customize the visualization if you need</div>
402 </div> 402 </div>
403 - <paper-icon-button id="finish_button" on-click="_onFinish" icon="add-circle" alt="Conforms the creation" title="finish"></paper-icon-button> 403 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
404 </div> 404 </div>
405 405
406 406
@@ -410,11 +410,11 @@ Example: @@ -410,11 +410,11 @@ Example:
410 <div id="visualization_slider_area" class="area_container"></div> 410 <div id="visualization_slider_area" class="area_container"></div>
411 <div id="fields_mapping_area" class="area_container"> 411 <div id="fields_mapping_area" class="area_container">
412 412
413 - <div id="selected_fields_main_container" class="field-mapping-card"> 413 + <div id="selectedFields_main_container" class="field-mapping-card">
414 <div class="title"> 414 <div class="title">
415 <div class="medium">Selected fields</div> 415 <div class="medium">Selected fields</div>
416 </div> 416 </div>
417 - <div id="selected_fields_container" class="area_container"></div> 417 + <div id="selectedFields_container" class="area_container"></div>
418 </div> 418 </div>
419 419
420 <div id="idm_fields_main_container" class="field-mapping-card"> 420 <div id="idm_fields_main_container" class="field-mapping-card">
@@ -423,21 +423,43 @@ Example: @@ -423,21 +423,43 @@ Example:
423 </div> 423 </div>
424 <div id="datalet_idm_fields_container" class="area_container"></div> 424 <div id="datalet_idm_fields_container" class="area_container"></div>
425 </div> 425 </div>
426 -  
427 - <div id="idm_layout_main_container" class="area_container">  
428 - <div class="title">  
429 - <div class="medium">Layout fields</div>  
430 - </div>  
431 - <div id="idm_layout_container" class="area_container"></div>  
432 - </div>  
433 </div> 426 </div>
434 </div> 427 </div>
435 428
436 - <div id="datalet_placeholder" style="min-width: 43%;"></div> 429 + <div id="datalet_placeholder" style="min-width: 43%;margin-top:10px;"></div>
437 430
  431 + </div>
438 432
  433 + </div>
  434 +
  435 + </neon-animatable>
  436 +
  437 + <neon-animatable>
  438 + <div class="vertical justified layout">
  439 +
  440 + <div class="horizontal layout">
  441 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  442 + <div class="avatar">4</div>
  443 + <div class="title flex">
  444 + <div id="toolbar_title" class="big">Finalize visualization</div>
  445 + <div id="toolbar_description" class="small">Assign the values for label parameters (e.g. title for you visualization).</div>
  446 + </div>
  447 + <paper-icon-button id="finish_button" on-click="_onFinish" icon="add-circle" alt="Conforms the creation" title="finish"></paper-icon-button>
439 </div> 448 </div>
440 449
  450 + <div class="horizontal layout">
  451 + <div style="margin-top: 10px;">
  452 + <div class="title">
  453 + <div class="medium">Layout fields</div>
  454 + </div>
  455 + <div id="idm_layout_main_container" class="area_container">
  456 + <div id="idm_layout_container" class="area_container"></div>
  457 + </div>
  458 + </div>
  459 +
  460 + <div id="datalet_placeholder_2" style="min-width: 43%;margin-top: 10px;"></div>
  461 +
  462 + </div>
441 </div> 463 </div>
442 464
443 </neon-animatable> 465 </neon-animatable>
@@ -533,7 +555,7 @@ Example: @@ -533,7 +555,7 @@ Example:
533 */ 555 */
534 dataUrl : { 556 dataUrl : {
535 type : String, 557 type : String,
536 - value : "", 558 + value : undefined,
537 observer : '_dataUrlChanged' 559 observer : '_dataUrlChanged'
538 }, 560 },
539 /** 561 /**
@@ -545,7 +567,7 @@ Example: @@ -545,7 +567,7 @@ Example:
545 */ 567 */
546 deepUrl : { 568 deepUrl : {
547 type : String, 569 type : String,
548 - value : "" 570 + value : undefined
549 }, 571 },
550 /** 572 /**
551 * It's used to store the list of datalets returned from DEEP 573 * It's used to store the list of datalets returned from DEEP
@@ -561,33 +583,40 @@ Example: @@ -561,33 +583,40 @@ Example:
561 /** 583 /**
562 * It's used to store the selected datalet. It will be set when the controllet get the event of selection by item slider (items-slider-controllet_item-selected) 584 * It's used to store the selected datalet. It will be set when the controllet get the event of selection by item slider (items-slider-controllet_item-selected)
563 * 585 *
564 - * @attribute selected_datalet 586 + * @attribute selectedDatalet
565 * @type String 587 * @type String
566 * @default '' 588 * @default ''
567 */ 589 */
568 - selected_datalet : { 590 + selectedDatalet : {
569 type : String, 591 type : String,
570 - value : "" 592 + value : undefined
571 }, 593 },
572 /** 594 /**
573 * It's used to store the list of selected fields by user 595 * It's used to store the list of selected fields by user
574 * 596 *
575 - * @attribute selected_fields 597 + * @attribute selectedFields
576 * @type Array 598 * @type Array
577 * @default empty 599 * @default empty
578 */ 600 */
579 - selected_fields : { 601 + selectedFields : {
580 type : Array, 602 type : Array,
581 - value : [] 603 + value : undefined
  604 + },
  605 + /**
  606 + * It contains all attributes for the datalet preset. It'll be used when the controllet is called to modify an exsting datalet.
  607 + */
  608 + dataletPreset:{
  609 + type: Object,
  610 + value: undefined
582 }, 611 },
583 /** 612 /**
584 * It's used to store the params to give to datalet. This kind of params will not processed by selection step 613 * It's used to store the params to give to datalet. This kind of params will not processed by selection step
585 * 614 *
586 - * @attribute params_fields 615 + * @attribute paramsFields
587 * @type Object 616 * @type Object
588 * @default empty 617 * @default empty
589 */ 618 */
590 - params_fields:{ 619 + paramsFields:{
591 type: Object, 620 type: Object,
592 value: {} 621 value: {}
593 }, 622 },
@@ -627,11 +656,15 @@ Example: @@ -627,11 +656,15 @@ Example:
627 ready : function(){ 656 ready : function(){
628 657
629 $(this.$.fields_placeholder).perfectScrollbar(); 658 $(this.$.fields_placeholder).perfectScrollbar();
630 - $(this.$.selected_fields_main_container).perfectScrollbar(); 659 + $(this.$.selectedFields_main_container).perfectScrollbar();
631 $(this.$.idm_fields_main_container).perfectScrollbar(); 660 $(this.$.idm_fields_main_container).perfectScrollbar();
632 $(this.$.idm_layout_main_container).perfectScrollbar(); 661 $(this.$.idm_layout_main_container).perfectScrollbar();
633 $(this.$.table_fields_container).perfectScrollbar(); 662 $(this.$.table_fields_container).perfectScrollbar();
634 663
  664 + if(this.dataletPreset != undefined) {
  665 + this.$.data_url.value = this.dataletPreset['data-url'];
  666 + this.selected = 3;
  667 + }
635 }, 668 },
636 669
637 /** 670 /**
@@ -643,7 +676,7 @@ Example: @@ -643,7 +676,7 @@ Example:
643 */ 676 */
644 handleResponseData : function(e){ 677 handleResponseData : function(e){
645 678
646 - this.$.fields_treeview.init(e.detail.response); 679 + this.$.fields_treeview.init(e.detail.response, this.selectedFields);
647 680
648 }, 681 },
649 682
@@ -664,8 +697,13 @@ Example: @@ -664,8 +697,13 @@ Example:
664 this.datalets_list.push(datalet_info); 697 this.datalets_list.push(datalet_info);
665 } 698 }
666 699
667 - this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +  
668 - '\'></items-slider-controllet>'; 700 + if(this.selectedDatalet == undefined)
  701 + this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +
  702 + '\'></items-slider-controllet>';
  703 + else
  704 + this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +
  705 + 'selected-card=\'' + this.selectedDatalet + '\'></items-slider-controllet>';
  706 +
669 }, 707 },
670 /** 708 /**
671 * Callback to dataset selection from list in the phase three. When a datalet is selected this function will build a bundle of box items, based on the datalet input data model, 709 * Callback to dataset selection from list in the phase three. When a datalet is selected this function will build a bundle of box items, based on the datalet input data model,
@@ -681,35 +719,69 @@ Example: @@ -681,35 +719,69 @@ Example:
681 this.$.datalet_idm_fields_container.innerHTML = ""; 719 this.$.datalet_idm_fields_container.innerHTML = "";
682 this.$.idm_layout_container.innerHTML = ""; 720 this.$.idm_layout_container.innerHTML = "";
683 721
  722 + var input;
  723 + var layouts = jQuery.extend(true, {}, response.idm.inputs.layouts);
  724 +
684 if(response.idm.inputs.input.constructor == Object) { 725 if(response.idm.inputs.input.constructor == Object) {
685 - var input = response.idm.inputs.input;  
686 - if(input.selection == "*") {  
687 - var input_selected_fields = Polymer.dom(this.$.selected_fields_container).querySelectorAll('draggable-element-controllet');  
688 - for (var j = 0; j < input_selected_fields.length; j++) {  
689 - this.$.datalet_idm_fields_container.innerHTML += '<draggable-element-controllet is-target="true" heading="Field ' + (j + 1) + '" description="' + input.description + '" number="' + (j + 1) + '"></draggable-element-controllet><br>'; 726 + if(response.idm.inputs.input.selection == "*")
  727 + {
  728 + input = response.idm.inputs.input;
  729 + response.idm.inputs.input = new Array();
  730 + for(var i=0;i<this.selectedFields.length;i++){
  731 + var newInput = jQuery.extend(true, {}, input);
  732 + newInput.name = input.name + ' ' + (i + 1);
  733 + response.idm.inputs.input.push(newInput);
690 } 734 }
691 } 735 }
692 - }else{  
693 - for(var i =0; i < response.idm.inputs.input.length; i++){  
694 - var input = response.idm.inputs.input[i];  
695 - this.$.datalet_idm_fields_container.innerHTML += '<draggable-element-controllet is-target="true" id="' + input.name + '" heading="' + input.name + '" description="' + input.description + '" number="' + (i + 1) + '"></draggable-element-controllet><br>'; 736 + }
  737 +
  738 + var heading;
  739 + var id;
  740 +
  741 + for(var i =0; i < response.idm.inputs.input.length; i++) {
  742 + var html = '<draggable-element-controllet is-target="true" ';
  743 + input = response.idm.inputs.input[i];
  744 +
  745 + heading = ' heading="' + input.name + '"';
  746 + id = ' id="' + (i + 1) + '"';
  747 +
  748 + html += heading + id;
  749 + html += ' description="' + input.description + '"' +
  750 + ' number="' + (i + 1) + '"';
  751 +
  752 + if(this.selectedFields != undefined) {
  753 + if(this.selectedFields[i] != undefined) {
  754 + html += ' value="' + this.selectedFields[i] + '"' +
  755 + ' label="' + this.selectedFields[i].split(",")[this.selectedFields[i].split(",").length - 1] + '"';
  756 + }
696 } 757 }
  758 +
  759 + html += '></draggable-element-controllet><br>';
  760 + this.$.datalet_idm_fields_container.innerHTML += html;
  761 +
697 } 762 }
698 763
699 - if(response.idm.inputs.layouts.input.constructor == Object) {  
700 - var input = response.idm.inputs.layouts.input;  
701 - this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + input.name + '" description="' + input.description + '" number="1"></text-element-controllet>';  
702 - }else{  
703 - for(var i =0; i < response.idm.inputs.layouts.input.length; i++){  
704 - var input = response.idm.inputs.layouts.input[i];  
705 - this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + input.name + '" ' +  
706 - 'description="' + input.description + '" ' +  
707 - 'number="' + (i+1) + '">' +  
708 - '</text-element-controllet>'; 764 + if(layouts.input != undefined) {
  765 + if(layouts.input.constructor == Object){
  766 + layouts.input = new Array(jQuery.extend(true, {}, layouts.input));
709 } 767 }
710 768
  769 + html = '<text-element-controllet ';
  770 + for (var i = 0; i < layouts.input.length; i++) {
  771 + html += '<text-element-controllet heading="' + layouts.input[i].name + '" ' +
  772 + 'description="' + layouts.input[i].description + '" ' +
  773 + 'number="' + (i + 1) + '" ';
  774 + if(this.dataletPreset != undefined){
  775 + html += 'value="' + this.dataletPreset[Object.keys(this.dataletPreset)[(i + 1)]] + '"';
  776 + }
  777 +
  778 + html += '></text-element-controllet>';
  779 + }
  780 + this.$.idm_layout_container.innerHTML = html;
711 } 781 }
712 782
  783 + if(this.selectedFields != undefined) this.generateDataletPreview();
  784 +
713 }, 785 },
714 /** 786 /**
715 * Generate the datalet preview when user mapped fields. it even retrieves the value of layout inputs values. 787 * Generate the datalet preview when user mapped fields. it even retrieves the value of layout inputs values.
@@ -719,34 +791,42 @@ Example: @@ -719,34 +791,42 @@ Example:
719 generateDataletPreview : function(){ 791 generateDataletPreview : function(){
720 792
721 var input_mapped_fields = Polymer.dom(this.$.datalet_idm_fields_container).querySelectorAll('draggable-element-controllet[is-target=true]'); 793 var input_mapped_fields = Polymer.dom(this.$.datalet_idm_fields_container).querySelectorAll('draggable-element-controllet[is-target=true]');
722 - this.selected_fields = Array(); 794 + this.selectedFields = Array();
723 795
724 for (var i = 0; i < input_mapped_fields.length; i++) { 796 for (var i = 0; i < input_mapped_fields.length; i++) {
725 if (input_mapped_fields[i].value != "") { 797 if (input_mapped_fields[i].value != "") {
726 - this.selected_fields.push(input_mapped_fields[i].value); 798 + this.selectedFields.push(input_mapped_fields[i].value);
727 } 799 }
728 } 800 }
729 801
730 var input_layouts_fields = Polymer.dom(this.$.idm_layout_container).querySelectorAll('text-element-controllet'); 802 var input_layouts_fields = Polymer.dom(this.$.idm_layout_container).querySelectorAll('text-element-controllet');
731 - this.params_fields = {'data-url' : this.dataUrl}; 803 + this.paramsFields = {'data-url' : this.dataUrl};
732 804
733 for (var i = 0; i < input_layouts_fields.length; i++) { 805 for (var i = 0; i < input_layouts_fields.length; i++) {
734 if (input_layouts_fields[i].value != "") { 806 if (input_layouts_fields[i].value != "") {
735 - this.params_fields[input_layouts_fields[i].heading] = input_layouts_fields[i].value; 807 + this.paramsFields[input_layouts_fields[i].heading] = input_layouts_fields[i].value;
736 } 808 }
737 } 809 }
738 810
739 811
740 var datalet_params ={ 812 var datalet_params ={
741 - component : this.selected_datalet,  
742 - params : this.params_fields,  
743 - fields : this.selected_fields, 813 + component : this.selectedDatalet,
  814 + params : this.paramsFields,
  815 + fields : this.selectedFields,
744 placeHolder : this.$.datalet_placeholder 816 placeHolder : this.$.datalet_placeholder
745 }; 817 };
746 818
  819 + var datalet_params_2 ={
  820 + component : this.selectedDatalet,
  821 + params : this.paramsFields,
  822 + fields : this.selectedFields,
  823 + placeHolder : this.$.datalet_placeholder_2
  824 + };
  825 +
747 826
748 ComponentService.deep_url = this.deepUrl; 827 ComponentService.deep_url = this.deepUrl;
749 ComponentService.getComponent(datalet_params); 828 ComponentService.getComponent(datalet_params);
  829 + ComponentService.getComponent(datalet_params_2);
750 830
751 }, 831 },
752 /** 832 /**
@@ -762,7 +842,7 @@ Example: @@ -762,7 +842,7 @@ Example:
762 case 0: 842 case 0:
763 return true; 843 return true;
764 case 1: 844 case 1:
765 - if(this.$.data_url.value == ""){ 845 + if(this.$.data_url.value == undefined){
766 this.$.message.text = "You have to select a dataset to access to pass 2."; 846 this.$.message.text = "You have to select a dataset to access to pass 2.";
767 this.$.message.show(); 847 this.$.message.show();
768 return false; 848 return false;
@@ -771,13 +851,15 @@ Example: @@ -771,13 +851,15 @@ Example:
771 } 851 }
772 852
773 case 2: 853 case 2:
774 - if(Polymer.dom(this.$.selected_fields_container).querySelectorAll('draggable-element-controllet') == 0){ 854 + if(Polymer.dom(this.$.selectedFields_container).querySelectorAll('draggable-element-controllet') == 0){
775 this.$.message.text = "You have to select a set of fields to access to pass 3."; 855 this.$.message.text = "You have to select a set of fields to access to pass 3.";
776 this.$.message.show(); 856 this.$.message.show();
777 return false; 857 return false;
778 }else{ 858 }else{
779 return true; 859 return true;
780 } 860 }
  861 + case 3:
  862 + return true;
781 } 863 }
782 864
783 }, 865 },
@@ -802,11 +884,11 @@ Example: @@ -802,11 +884,11 @@ Example:
802 */ 884 */
803 _onNextClick : function() { 885 _onNextClick : function() {
804 886
805 - if(!this.validateCurrentPass(this.selected === 2 ? 2 : (this.selected + 1))) return; 887 + if(!this.validateCurrentPass(this.selected === 3 ? 3 : (this.selected + 1))) return;
806 888
807 this.entryAnimation = 'slide-from-right-animation'; 889 this.entryAnimation = 'slide-from-right-animation';
808 this.exitAnimation = 'slide-left-animation'; 890 this.exitAnimation = 'slide-left-animation';
809 - this.selected = this.selected === 2 ? 2 : (this.selected + 1); 891 + this.selected = this.selected === 3 ? 3 : (this.selected + 1);
810 }, 892 },
811 /** 893 /**
812 * Callback to manage InfoButton click to give user information about the selected dataset 894 * Callback to manage InfoButton click to give user information about the selected dataset
@@ -849,9 +931,9 @@ Example: @@ -849,9 +931,9 @@ Example:
849 * @param {Event} e 931 * @param {Event} e
850 */ 932 */
851 _dataletSelected : function(e){ 933 _dataletSelected : function(e){
852 - this.selected_datalet = e.detail.datalet;  
853 - this.$.selected_datalet_request.url = this.deepUrl + e.detail.datalet;  
854 - this.$.selected_datalet_request.generateRequest(); 934 + this.selectedDatalet = e.detail.datalet;
  935 + this.$.selectedDatalet_request.url = this.deepUrl + e.detail.datalet;
  936 + this.$.selectedDatalet_request.generateRequest();
855 937
856 }, 938 },
857 /** 939 /**
@@ -863,9 +945,10 @@ Example: @@ -863,9 +945,10 @@ Example:
863 */ 945 */
864 _fieldsSelected : function(e){ 946 _fieldsSelected : function(e){
865 947
866 - this.$.selected_fields_container.innerHTML = ""; 948 + this.selectedFields = e.detail.fields;
  949 + this.$.selectedFields_container.innerHTML = "";
867 for(var i=0;i<e.detail.fields.length;i++) { 950 for(var i=0;i<e.detail.fields.length;i++) {
868 - this.$.selected_fields_container.innerHTML += '<draggable-element-controllet identifier="' + e.detail.fields[i] + 951 + this.$.selectedFields_container.innerHTML += '<draggable-element-controllet identifier="' + e.detail.fields[i] +
869 '" label="' + e.detail.fields[i].split(",")[e.detail.fields[i].split(",").length -1] + 952 '" label="' + e.detail.fields[i].split(",")[e.detail.fields[i].split(",").length -1] +
870 '"></draggable-element-controllet><br>'; 953 '"></draggable-element-controllet><br>';
871 } 954 }
@@ -926,7 +1009,7 @@ Example: @@ -926,7 +1009,7 @@ Example:
926 */ 1009 */
927 _onFinish : function(e){ 1010 _onFinish : function(e){
928 1011
929 - if((this.selected_fields.length == 0) || this.selected_datalet == ""){ 1012 + if((this.selectedFields.length == 0) || this.selectedDatalet == ""){
930 this.$.message.text = "You have to map the selected fields with datalets fields(by dragging) and select a datalet to export a new visualization."; 1013 this.$.message.text = "You have to map the selected fields with datalets fields(by dragging) and select a datalet to export a new visualization.";
931 this.$.message.show(); 1014 this.$.message.show();
932 return; 1015 return;
@@ -934,9 +1017,9 @@ Example: @@ -934,9 +1017,9 @@ Example:
934 1017
935 var data = { 1018 var data = {
936 dataUrl : this.dataUrl, 1019 dataUrl : this.dataUrl,
937 - params : this.params_fields,  
938 - fields : this.selected_fields,  
939 - datalet : this.selected_datalet, 1020 + params : this.paramsFields,
  1021 + fields : this.selectedFields,
  1022 + datalet : this.selectedDatalet,
940 staticData : JSON.stringify(this.$.datalet_placeholder.children[1].behavior.data) 1023 staticData : JSON.stringify(this.$.datalet_placeholder.children[1].behavior.data)
941 } 1024 }
942 1025
controllets/data-sevc-controllet/data-sevc-controllet_.html 0 → 100644
  1 +<!--
  2 +@license
  3 + The MIT License (MIT)
  4 +
  5 + Copyright (c) 2015 Dipartimento di Informatica - Università di Salerno - Italy
  6 +
  7 + Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + of this software and associated documentation files (the "Software"), to deal
  9 + in the Software without restriction, including without limitation the rights
  10 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + copies of the Software, and to permit persons to whom the Software is
  12 + furnished to do so, subject to the following conditions:
  13 +
  14 + The above copyright notice and this permission notice shall be included in
  15 + all copies or substantial portions of the Software.
  16 +
  17 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + THE SOFTWARE.
  24 +-->
  25 +
  26 +<!--
  27 +* Developed by :
  28 +* ROUTE-TO-PA Project - grant No 645860. - www.routetopa.eu
  29 +*
  30 +-->
  31 +
  32 +<link rel="import" href="../../bower_components/polymer/polymer.html">
  33 +<link rel="import" href="../../bower_components/paper-styles/color.html">
  34 +
  35 +<link rel="import" href="../../bower_components/neon-animation/neon-animated-pages.html">
  36 +<link rel="import" href="../../bower_components/neon-animation/neon-animatable.html">
  37 +<link rel="import" href="../../bower_components/neon-animation/neon-animations.html">
  38 +
  39 +<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
  40 +<link rel="import" href="../../bower_components/paper-input/paper-input.html">
  41 +<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
  42 +<link rel="import" href="../../bower_components/paper-button/paper-button.html">
  43 +<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
  44 +<link rel="import" href="../../bower_components/paper-tabs/paper-tab.html">
  45 +<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
  46 +<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
  47 +<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
  48 +<link rel="import" href="../../bower_components/paper-item/paper-item.html">
  49 +<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
  50 +<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
  51 +<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
  52 +
  53 +<link rel="import" href="../items-slider-controllet/items-slider-controllet.html">
  54 +<link rel="import" href="../draggable-element-controllet/draggable-element-controllet.html">
  55 +<link rel="import" href="../treeview-controllet/treeview-controllet.html">
  56 +<link rel="import" href="../text-element-controllet/text-element-controllet.html">
  57 +
  58 +<!--
  59 +The `data-sevc-controllet` is a controllet to generate visualization from a dataset accessible through api. A json response is required.
  60 +It's composed by three steps. First, user have to select a datasource to access to a dataset. He can copy and paste/drag and drop an url(an api url with json response) or select
  61 +from select contextual menu an available one. Second, the user selects the fields he want to visualize from a treeview by checking on it. A table preview of selected fields will show
  62 +the currently selected values. Third, the users selects a visualization(datalet) from a slider and drags the previous selected fields in to the input data model fields area. A preview
  63 +is available every time a fields is dragged in the input data model fields area.
  64 +
  65 +Example:
  66 +
  67 + <data-sevc-controllet deep-url="http://192.168.36.128/DatalEts-Ecosystem-Provider/DEEP/"
  68 + datalets-list-url="http://192.168.36.128/DatalEts-Ecosystem-Provider/DEEP/datalets-list"
  69 + datasets='{[{name : 'dataset1', url : dataset1Urls}, ... , {name : 'datasetN', url : datasetNUrls}]'>
  70 + </data-sevc-controllet>
  71 +
  72 +
  73 +@element data-sevc-controllet
  74 +@status beta
  75 +@homepage
  76 +@group controllets
  77 +-->
  78 +
  79 +
  80 +<dom-module id="data-sevc-controllet">
  81 + <template>
  82 + <link rel="stylesheet" href="../shared_js/perfect-scrollbar/css/perfect-scrollbar.min.css">
  83 + <link rel="stylesheet" href="static/css/reset.css">
  84 +
  85 + <style is="custom-style">
  86 +
  87 + ::content body {
  88 + font-family: 'Roboto', sans-serif;
  89 + }
  90 +
  91 + .flexchild
  92 + {
  93 + @apply(--layout-flex);
  94 + }
  95 +
  96 + .flex2child
  97 + {
  98 + @apply(--layout-flex-2);
  99 + }
  100 +
  101 + .avatar
  102 + {
  103 + display: inline-block;
  104 + height: 2em;
  105 + width: 2em;
  106 + border-radius: 50%;
  107 + background: var(--paper-blue-500);
  108 + color: white;
  109 + line-height: 2em;
  110 + font-size: 1.87em;
  111 + text-align: center;
  112 + }
  113 +
  114 + .title
  115 + {
  116 + position: relative;
  117 + top: 0.60vh;
  118 + margin-left: 20px;
  119 + }
  120 +
  121 + .big
  122 + {
  123 + font-size: 1.37em;
  124 + color: var(--google-grey-500);
  125 + }
  126 +
  127 + .medium
  128 + {
  129 + font-size: 1em;
  130 + padding-bottom: 0.5em;
  131 + color : #000000;
  132 + font-weight: bold;
  133 + }
  134 +
  135 + .small
  136 + {
  137 + font-size: 0.8em;
  138 + padding-top: 10px;
  139 + color: var(--paper-blue-500);
  140 + font-weight: bold;
  141 + }
  142 +
  143 + paper-input
  144 + {
  145 + width: 80%;
  146 + }
  147 +
  148 + paper-dropdown-menu
  149 + {
  150 + text-align: left;
  151 + margin: auto;
  152 + width: 100%;
  153 + }
  154 +
  155 + ::content paper-menu-button
  156 + {
  157 + display: block;
  158 + width: 100%;
  159 + }
  160 +
  161 + #visualization_slider_area
  162 + {
  163 + min-width: 670px;
  164 + min-height: 180px;
  165 + }
  166 +
  167 + #fields_mapping_area
  168 + {
  169 + min-width: 670px;
  170 + min-height: 180px;
  171 + }
  172 +
  173 + #datalet_placeholder
  174 + {
  175 + height: 360px;
  176 + min-height: 360px;
  177 +
  178 + }
  179 +
  180 + .datalet_right_container
  181 + {
  182 + width: 100vh;
  183 + }
  184 +
  185 + .field-mapping-card
  186 + {
  187 + width: 50%;
  188 + float: left;
  189 + }
  190 +
  191 + .toolbar_button
  192 + {
  193 + --iron-icon-height: 32px;
  194 + --iron-icon-width: 32px;
  195 + }
  196 +
  197 + #finish_button
  198 + {
  199 + --iron-icon-height: 32px;
  200 + --iron-icon-width: 32px;
  201 + color: var(--paper-blue-500);
  202 + }
  203 +
  204 + .area_container
  205 + {
  206 + overflow: hidden;
  207 + margin : 0.8em;
  208 + padding : 0.8em;
  209 + border-width: 1em;
  210 + border-radius: 0.125rem;
  211 + box-shadow: 0.125em 0.125em 0.1125em 0.125em rgba(0, 0, 0, 0.25);
  212 + }
  213 +
  214 + #fields_placeholder{
  215 + width: 40%;
  216 + height: 75vh;
  217 + position: relative;
  218 + float: left;
  219 + overflow: auto;
  220 + }
  221 +
  222 + #table_fields_container{
  223 + height: 75vh;
  224 + width: 55%;
  225 + position: relative;
  226 + float: left;
  227 + overflow: auto;
  228 + }
  229 +
  230 + paper-tabs, paper-toolbar
  231 + {
  232 + background-color: var(--paper-blue-500);
  233 + color: #ffffff;
  234 + box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2);
  235 + }
  236 +
  237 + paper-toolbar paper-tabs
  238 + {
  239 + box-shadow: none;
  240 + --paper-tabs-selection-bar-color : var(--google-gray-500);
  241 + }
  242 +
  243 + paper-tabs[noink][no-bar] paper-tab.iron-selected
  244 + {
  245 + background-color: var(--google-gray-500);
  246 + }
  247 +
  248 + paper-tabs[align-bottom]
  249 + {
  250 + box-shadow: 0px -2px 6px rgba(0, 0, 0, 0.15);
  251 + }
  252 +
  253 + #idm_fields_main_container{
  254 + position: relative;
  255 + height: 50vh;
  256 + }
  257 +
  258 + #selectedFields_main_container{
  259 + position: relative;
  260 + height: 50vh;
  261 + }
  262 +
  263 + #idm_layout_main_container{
  264 + position: relative;
  265 + height: 25vh;
  266 + }
  267 +
  268 + paper-menu{
  269 + width: 100%;
  270 + }
  271 +
  272 + paper-dialog {
  273 + position: fixed;
  274 + top: 16px;
  275 + width: auto;
  276 + height: auto;
  277 + overflow: auto;
  278 + padding : 30px;
  279 + }
  280 +
  281 + </style>
  282 +
  283 + <iron-ajax
  284 + auto
  285 + id="data_request"
  286 + url={{dataUrl}}
  287 + verbose="true"
  288 + on-response="handleResponseData"
  289 + debounce-duration="300">
  290 + </iron-ajax>
  291 +
  292 + <iron-ajax
  293 + id="datales_list_request"
  294 + auto
  295 + url={{dataletsListUrl}}
  296 + handle-as="json"
  297 + on-response="handleResponseDatalets"
  298 + debounce-duration="300">
  299 + </iron-ajax>
  300 +
  301 + <iron-ajax
  302 + id="selectedDatalet_request"
  303 + url={{deepUrl}}
  304 + verbose="true"
  305 + on-response="handleSelectedDatalet"
  306 + debounce-duration="300">
  307 + </iron-ajax>
  308 +
  309 + <content>
  310 +
  311 + <neon-animated-pages id="pages" selected="[[selected]]" entry-animation="[[entryAnimation]]" exit-animation="[[exitAnimation]]">
  312 +
  313 + <neon-animatable>
  314 +
  315 + <div class="vertical justified layout">
  316 +
  317 + <div class="horizontal layout">
  318 + <div class="avatar" style="margin-left:15px">1</div>
  319 + <div class="title flex">
  320 + <div id="toolbar_title" class="big">Dataset source</div>
  321 + <div id="toolbar_description" class="small">Copy and paste/drag and drop in the textarea the url of datasource</div>
  322 + </div>
  323 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
  324 + </div>
  325 +
  326 + <div class="area_container">
  327 + <paper-tabs selected="{{DatasourceTabSelected}}">
  328 + <paper-tab>Select data source</paper-tab>
  329 + <paper-tab>Most popular</paper-tab>
  330 + <paper-tab>Search</paper-tab>
  331 + </paper-tabs>
  332 + <iron-pages selected="{{DatasourceTabSelected}}">
  333 + <div>
  334 + <div class="card-content">
  335 + <paper-dropdown-menu id="datasets-sources" label="Available datasets">
  336 + <paper-menu class="dropdown-content">
  337 + <template is="dom-repeat" items="{{datasets}}" as="dataset" index-as="index">
  338 + <paper-item id="{{index}}" on-tap="_datasourceSelected">{{dataset.name}}</paper-item>
  339 + </template>
  340 + </paper-menu>
  341 + </paper-dropdown-menu>
  342 + <paper-icon-button id="infoButton" on-click="_onInfoClick" icon="info-outline" alt="Information about selected dataset" title="info-button" style="color:#9e9e9e;"></paper-icon-button>
  343 + </div>
  344 +
  345 + <div><img src="static/images/or.png" style="position: relative;left: 50%;padding-top:20px"></div>
  346 +
  347 + <div class="card-content">
  348 + <paper-textarea id="data_url" label="Dataset api data url" floatingLabel value="{{dataUrl}}" on-dragover="_handleDatasourceDragOver"></paper-textarea>
  349 + </div>
  350 +
  351 +
  352 + </div>
  353 + <div><img src="static/images/UnderConstruction.png" style="position: relative;top: 60%;left: 25%;"></div>
  354 + <div><img src="static/images/UnderConstruction.png" style="position: relative;top: 60%;left: 25%;"></div>
  355 + </iron-pages>
  356 + </div>
  357 +
  358 + </div>
  359 +
  360 + </neon-animatable>
  361 +
  362 + <neon-animatable>
  363 +
  364 + <div class="vertical justified layout">
  365 +
  366 + <div class="horizontal layout">
  367 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  368 + <div class="avatar">2</div>
  369 + <div class="title flex">
  370 + <div id="toolbar_title" class="big">Dataset source</div>
  371 + <div id="toolbar_description" class="small">Copy and paste/drag and drop in the textarea the url of datasource</div>
  372 + </div>
  373 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
  374 + </div>
  375 +
  376 + <div class="horizontal layout">
  377 +
  378 + <div id="fields_placeholder" class="area_container flexchild" style="min-width:300px">
  379 + <treeview-controllet id="fields_treeview"></treeview-controllet>
  380 + </div>
  381 +
  382 + <div id="table_fields_container" class="area_container flex2child">
  383 + <div id="table_component_place_holder"></div>
  384 + </div>
  385 +
  386 + </div>
  387 +
  388 + </div>
  389 +
  390 + </neon-animatable>
  391 +
  392 + <neon-animatable style="height:100vh">
  393 +
  394 + <div class="vertical justified layout">
  395 +
  396 + <div class="horizontal layout">
  397 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  398 + <div class="avatar">3</div>
  399 + <div class="title flex">
  400 + <div id="toolbar_title" class="big">Data mapping</div>
  401 + <div id="toolbar_description" class="small">Select the visualization from the slider, drag and drop the selected fields in visualization parameter area, customize the visualization if you need</div>
  402 + </div>
  403 + <paper-icon-button id="finish_button" on-click="_onFinish" icon="add-circle" alt="Conforms the creation" title="finish"></paper-icon-button>
  404 + </div>
  405 +
  406 +
  407 + <div class="horizontal layout">
  408 +
  409 + <div class="">
  410 + <div id="visualization_slider_area" class="area_container"></div>
  411 + <div id="fields_mapping_area" class="area_container">
  412 +
  413 + <div id="selectedFields_main_container" class="field-mapping-card">
  414 + <div class="title">
  415 + <div class="medium">Selected fields</div>
  416 + </div>
  417 + <div id="selectedFields_container" class="area_container"></div>
  418 + </div>
  419 +
  420 + <div id="idm_fields_main_container" class="field-mapping-card">
  421 + <div class="title">
  422 + <div class="medium">Datalet fields</div>
  423 + </div>
  424 + <div id="datalet_idm_fields_container" class="area_container"></div>
  425 + </div>
  426 +
  427 + <div id="idm_layout_main_container" class="area_container">
  428 + <div class="title">
  429 + <div class="medium">Layout fields</div>
  430 + </div>
  431 + <div id="idm_layout_container" class="area_container"></div>
  432 + </div>
  433 + </div>
  434 + </div>
  435 +
  436 + <div id="datalet_placeholder" style="min-width: 43%;"></div>
  437 +
  438 + </div>
  439 +
  440 + </div>
  441 +
  442 + </neon-animatable>
  443 +
  444 + </neon-animated-pages>
  445 +
  446 + <paper-toast id="message" text=""></paper-toast>
  447 +
  448 + <paper-dialog id="infoDialog">
  449 + <h2 id="infoDialogTitle"></h2>
  450 + <paper-dialog-scrollable id="infoDialogContent">
  451 + </paper-dialog-scrollable>
  452 + </paper-dialog>
  453 +
  454 + </content>
  455 + </template>
  456 +
  457 + <script src="../shared_js/perfect-scrollbar/js/min/perfect-scrollbar.jquery.min.js"></script>
  458 + <script src="../../../DEEPCLIENT/js/deepClient.js"></script>
  459 +
  460 + <script>
  461 +
  462 + Polymer({
  463 +
  464 + is : 'data-sevc-controllet',
  465 +
  466 + /**
  467 + * Received when the user selects a datalet from slider.
  468 + *
  469 + * @event items-slider-controllet_item-selected
  470 + */
  471 +
  472 + /**
  473 + * Received when the user drags a selected fields in to one of the source input data model field
  474 + *
  475 + * @event draggable-element-controllet_content-dragged
  476 + */
  477 +
  478 + /**
  479 + * Received when the user selects one field from treeview controllet
  480 + *
  481 + * @event treeview-controllet-fileds-selected
  482 + */
  483 +
  484 + /**
  485 + * Received when the user drags a selected fields in to one of the source input data model field
  486 + *
  487 + * @event draggable-element-controllet_content-dragged
  488 + */
  489 +
  490 + /**
  491 + * Received when the user change text value of the selected datalet layout inputs
  492 + *
  493 + * @event text-element-controllet_content-changed
  494 + */
  495 +
  496 + /**
  497 + * Fired when the user press to finish button. At this event are attached all information about the visualization currently created
  498 + *
  499 + * @event data-sevc-controllet.dataletCreated
  500 + */
  501 +
  502 + listeners : {
  503 + 'items-slider-controllet_item-selected' : '_dataletSelected',
  504 + 'draggable-element-controllet_content-dragged' : '_fieldsMapped',
  505 + 'treeview-controllet_fileds-selected' : '_fieldsSelected',
  506 + 'text-element-controllet_content-changed' : '_textElementChanged'
  507 + },
  508 +
  509 + properties : {
  510 +
  511 + entryAnimation : {
  512 + type : String,
  513 + value : ""
  514 + },
  515 +
  516 + exitAnimation : {
  517 + type : String,
  518 + value : ""
  519 + },
  520 +
  521 + selected : {
  522 + type : Number,
  523 + value : 0
  524 + },
  525 +
  526 + /**
  527 + * It represents the data url from CKAN api
  528 + *
  529 + * @attribute dataUrl
  530 + * @type string
  531 + * @default 'null'
  532 + */
  533 + dataUrl : {
  534 + type : String,
  535 + value : undefined,
  536 + observer : '_dataUrlChanged'
  537 + },
  538 + /**
  539 + * It represents the DEEP url to get information about the datalets
  540 + *
  541 + * @attribute deepUrl
  542 + * @type string
  543 + * @default 'null'
  544 + */
  545 + deepUrl : {
  546 + type : String,
  547 + value : undefined
  548 + },
  549 + /**
  550 + * It's used to store the list of datalets returned from DEEP
  551 + *
  552 + * @attribute datalets_list
  553 + * @type Array
  554 + * @default empty
  555 + */
  556 + datalets_list : {
  557 + type : Array ,
  558 + value : []
  559 + },
  560 + /**
  561 + * It's used to store the selected datalet. It will be set when the controllet get the event of selection by item slider (items-slider-controllet_item-selected)
  562 + *
  563 + * @attribute selectedDatalet
  564 + * @type String
  565 + * @default ''
  566 + */
  567 + selectedDatalet : {
  568 + type : String,
  569 + value : undefined
  570 + },
  571 + /**
  572 + * It's used to store the list of selected fields by user
  573 + *
  574 + * @attribute selectedFields
  575 + * @type Array
  576 + * @default empty
  577 + */
  578 + selectedFields : {
  579 + type : Array,
  580 + value : undefined
  581 + },
  582 + /**
  583 + * It contains all attributes for the datalet preset. It'll be used when the controllet is called to modify an exsting datalet.
  584 + */
  585 + dataletPreset:{
  586 + type: Object,
  587 + value: undefined
  588 + },
  589 + /**
  590 + * It's used to store the params to give to datalet. This kind of params will not processed by selection step
  591 + *
  592 + * @attribute paramsFields
  593 + * @type Object
  594 + * @default empty
  595 + */
  596 + paramsFields:{
  597 + type: Object,
  598 + value: {}
  599 + },
  600 + /**
  601 + * It's used to store the tab index in the first pass
  602 + *
  603 + * @attribute DatasourceTabSelected
  604 + * @type Number
  605 + * @default 0
  606 + */
  607 + DatasourceTabSelected : {
  608 + type : Number,
  609 + value : 0
  610 + },
  611 + /**
  612 + * It's used to store the datasets to show in the contexual menu
  613 + *
  614 + * @attribute datasets
  615 + * @type Array
  616 + * @default empty
  617 + */
  618 + datasets :
  619 + {
  620 + type : Array,
  621 + value : []
  622 + }
  623 + },
  624 + /**
  625 + * It is called after the element’s template has been stamped and all elements inside the element’s local DOM have been configured (with values bound from parents, deserialized attributes, or else default values) and had their ready method called.
  626 + * In this phase the scrollbar will be initialized
  627 + *
  628 + * @method handleResponseData
  629 + *
  630 + * @param {Event} e
  631 + */
  632 +
  633 + ready : function(){
  634 +
  635 + $(this.$.fields_placeholder).perfectScrollbar();
  636 + $(this.$.selectedFields_main_container).perfectScrollbar();
  637 + $(this.$.idm_fields_main_container).perfectScrollbar();
  638 + $(this.$.idm_layout_main_container).perfectScrollbar();
  639 + $(this.$.table_fields_container).perfectScrollbar();
  640 +
  641 + if(this.dataletPreset != undefined)
  642 + this.$.data_url.value = this.dataletPreset['data-url'];
  643 + },
  644 +
  645 + /**
  646 + * Callback to parse the data requested when dataUrl change its value
  647 + *
  648 + * @method handleResponseData
  649 + *
  650 + * @param {Event} e
  651 + */
  652 + handleResponseData : function(e){
  653 +
  654 + this.$.fields_treeview.init(e.detail.response, this.selectedFields);
  655 +
  656 + },
  657 +
  658 + /**
  659 + * Callback to parse the components response object
  660 + *
  661 + * @method handleResponseDatalets
  662 + *
  663 + * @param {Event} e
  664 + */
  665 + handleResponseDatalets : function(e){
  666 + this.datalets_list = new Array();
  667 + for(var i=0;i < e.detail.response.length;i++){
  668 + var datalet_info = { name : e.detail.response[i].name ,
  669 + image : e.detail.response[i].url + e.detail.response[i].name + ".png"
  670 + };
  671 +
  672 + this.datalets_list.push(datalet_info);
  673 + }
  674 +
  675 + if(this.selectedDatalet == undefined)
  676 + this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +
  677 + '\'></items-slider-controllet>';
  678 + else
  679 + this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +
  680 + 'selected-card=\'' + this.selectedDatalet + '\'></items-slider-controllet>';
  681 +
  682 + },
  683 + /**
  684 + * Callback to dataset selection from list in the phase three. When a datalet is selected this function will build a bundle of box items, based on the datalet input data model,
  685 + * to allow user to drag the fields, from the selected fields box, and create a new visualization.
  686 + *
  687 + * @method handleSelectedDatalet
  688 + *
  689 + * @param {Event} e
  690 + */
  691 + handleSelectedDatalet : function(e){
  692 +
  693 + var response = e.detail.response;
  694 + this.$.datalet_idm_fields_container.innerHTML = "";
  695 + this.$.idm_layout_container.innerHTML = "";
  696 +
  697 + var layouts = jQuery.extend(true, {}, response.idm.inputs.layouts);
  698 +
  699 + if(response.idm.inputs.input.constructor == Object) {
  700 + if(response.idm.inputs.input.selection == "*")
  701 + {
  702 + var input = response.idm.inputs.input;
  703 + response.idm.inputs.input = new Array();
  704 + for(var i=0;i<this.selectedFields.length;i++){
  705 + var newInput = jQuery.extend(true, {}, input);
  706 + newInput.name = input.name + ' ' + (i + 1);
  707 + response.idm.inputs.input.push(newInput);
  708 + }
  709 + }
  710 + }
  711 +
  712 + var input;
  713 + var heading;
  714 + var id;
  715 +
  716 + for(var i =0; i < response.idm.inputs.input.length; i++) {
  717 + var html = '<draggable-element-controllet is-target="true" ';
  718 + input = response.idm.inputs.input[i];
  719 +
  720 + heading = ' heading="' + input.name + '"';
  721 + id = ' id="' + (i + 1) + '"';
  722 +
  723 + html += heading + id;
  724 + html += ' description="' + input.description + '"' +
  725 + ' number="' + (i + 1) + '"';
  726 +
  727 + if(this.selectedFields != undefined) {
  728 + if(this.selectedFields[i] != undefined) {
  729 + html += ' value="' + this.selectedFields[i] + '"' +
  730 + ' label="' + this.selectedFields[i].split(",")[this.selectedFields[i].split(",").length - 1] + '"';
  731 + }
  732 + }
  733 +
  734 + html += '></draggable-element-controllet><br>';
  735 + this.$.datalet_idm_fields_container.innerHTML += html;
  736 +
  737 + }
  738 +
  739 + if(layouts.input != undefined) {
  740 + if (layouts.input.constructor == Object) {
  741 + this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + layouts.input.name +
  742 + '" description="' + layouts.input.description +
  743 + '" value="' + this.dataletPreset[Object.keys(this.dataletPreset)[0]] +
  744 + '" number="1"></text-element-controllet>';
  745 + } else {
  746 + for (var i = 0; i < layouts.input.length; i++) {
  747 + this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + layouts.input[i].name + '" ' +
  748 + 'description="' + layouts.input[i].description + '" ' +
  749 + 'value="' + this.dataletPreset[Object.keys(this.dataletPreset)[(i + 1)]] + '" ' +
  750 + 'number="' + (i + 1) + '">' +
  751 + '</text-element-controllet>';
  752 + }
  753 +
  754 + }
  755 + }
  756 +
  757 + if(this.selectedFields != undefined) this.generateDataletPreview();
  758 +
  759 + },
  760 + /**
  761 + * Generate the datalet preview when user mapped fields. it even retrieves the value of layout inputs values.
  762 + *
  763 + * @method generateDataletPreview
  764 + */
  765 + generateDataletPreview : function(){
  766 +
  767 + var input_mapped_fields = Polymer.dom(this.$.datalet_idm_fields_container).querySelectorAll('draggable-element-controllet[is-target=true]');
  768 + this.selectedFields = Array();
  769 +
  770 + for (var i = 0; i < input_mapped_fields.length; i++) {
  771 + if (input_mapped_fields[i].value != "") {
  772 + this.selectedFields.push(input_mapped_fields[i].value);
  773 + }
  774 + }
  775 +
  776 + var input_layouts_fields = Polymer.dom(this.$.idm_layout_container).querySelectorAll('text-element-controllet');
  777 + this.paramsFields = {'data-url' : this.dataUrl};
  778 +
  779 + for (var i = 0; i < input_layouts_fields.length; i++) {
  780 + if (input_layouts_fields[i].value != "") {
  781 + this.paramsFields[input_layouts_fields[i].heading] = input_layouts_fields[i].value;
  782 + }
  783 + }
  784 +
  785 +
  786 + var datalet_params ={
  787 + component : this.selectedDatalet,
  788 + params : this.paramsFields,
  789 + fields : this.selectedFields,
  790 + placeHolder : this.$.datalet_placeholder
  791 + };
  792 +
  793 +
  794 + ComponentService.deep_url = this.deepUrl;
  795 + ComponentService.getComponent(datalet_params);
  796 +
  797 + },
  798 + /**
  799 + * Validate the current pass in order to access to next one.
  800 + *
  801 + * @method validateCurrentPass
  802 + *
  803 + * @param {Number} next_selected_pass
  804 + */
  805 + validateCurrentPass : function(next_selected_pass){
  806 +
  807 + switch(next_selected_pass){
  808 + case 0:
  809 + return true;
  810 + case 1:
  811 + if(this.$.data_url.value == undefined){
  812 + this.$.message.text = "You have to select a dataset to access to pass 2.";
  813 + this.$.message.show();
  814 + return false;
  815 + }else{
  816 + return true;
  817 + }
  818 +
  819 + case 2:
  820 + if(Polymer.dom(this.$.selectedFields_container).querySelectorAll('draggable-element-controllet') == 0){
  821 + this.$.message.text = "You have to select a set of fields to access to pass 3.";
  822 + this.$.message.show();
  823 + return false;
  824 + }else{
  825 + return true;
  826 + }
  827 + }
  828 +
  829 + },
  830 + /**
  831 + * Callback for manage the previous pass button
  832 + *
  833 + * @method _onPrevClick
  834 + *
  835 + */
  836 + _onPrevClick : function() {
  837 + if(!this.validateCurrentPass(this.selected === 0 ? 0 : (this.selected - 1))) return;
  838 +
  839 + this.entryAnimation = 'slide-from-left-animation';
  840 + this.exitAnimation = 'slide-right-animation';
  841 + this.selected = this.selected === 0 ? 0 : (this.selected - 1);
  842 + },
  843 + /**
  844 + * Callback to manage the next pass button
  845 + *
  846 + * @method _onNextClick
  847 + *
  848 + */
  849 + _onNextClick : function() {
  850 +
  851 + if(!this.validateCurrentPass(this.selected === 2 ? 2 : (this.selected + 1))) return;
  852 +
  853 + this.entryAnimation = 'slide-from-right-animation';
  854 + this.exitAnimation = 'slide-left-animation';
  855 + this.selected = this.selected === 2 ? 2 : (this.selected + 1);
  856 + },
  857 + /**
  858 + * Callback to manage InfoButton click to give user information about the selected dataset
  859 + *
  860 + */
  861 + _onInfoClick : function(){
  862 +
  863 + this.$.infoDialog.open();
  864 +
  865 + },
  866 + /**
  867 + * Callback related to datasource selection from select menu
  868 + *
  869 + * @method _datasourceSelected
  870 + *
  871 + * @param {Event} e
  872 + */
  873 + _datasourceSelected : function(e){
  874 +
  875 + this.$.data_url.value = this.datasets[parseInt(e.target.id)].url;
  876 + this.$.infoDialogTitle.innerHTML = this.datasets[parseInt(e.target.id)].name;
  877 + this.$.infoDialogContent.innerHTML = this.datasets[parseInt(e.target.id)].description;
  878 +
  879 + },
  880 + /**
  881 + * Callback related to data url change
  882 + *
  883 + * @method _dataUrlChanged
  884 + *
  885 + * @param {Event} e
  886 + */
  887 + _dataUrlChanged : function(newValue, oldValue){
  888 + this.$.data_request.generateRequest();
  889 + },
  890 + /**
  891 + * Callback related to event 'items-slider-controllet_item-selected' fired by items-slider-controllet when the user selects a datalet
  892 + *
  893 + * @method _dataletSelected
  894 + *
  895 + * @param {Event} e
  896 + */
  897 + _dataletSelected : function(e){
  898 + this.selectedDatalet = e.detail.datalet;
  899 + this.$.selectedDatalet_request.url = this.deepUrl + e.detail.datalet;
  900 + this.$.selectedDatalet_request.generateRequest();
  901 +
  902 + },
  903 + /**
  904 + * Callback related to event 'treeview-controllet-fileds-selected' fired by treeview-controllet when the user selects a field
  905 + *
  906 + * @method _fieldsSelected
  907 + *
  908 + * @param {Event} e
  909 + */
  910 + _fieldsSelected : function(e){
  911 +
  912 + this.$.selectedFields_container.innerHTML = "";
  913 + for(var i=0;i<e.detail.fields.length;i++) {
  914 + this.$.selectedFields_container.innerHTML += '<draggable-element-controllet identifier="' + e.detail.fields[i] +
  915 + '" label="' + e.detail.fields[i].split(",")[e.detail.fields[i].split(",").length -1] +
  916 + '"></draggable-element-controllet><br>';
  917 + }
  918 +
  919 + var place_holder = (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) ? this.$.table_component_place_holder : this.$.table_component_place_holder[Object.keys(this.$.table_component_place_holder)[0]];
  920 +
  921 + var table_params ={
  922 + component : "datatable-datalet",
  923 + params :{
  924 + 'data-url' : this.dataUrl
  925 + },
  926 + fields : e.detail.fields,
  927 + placeHolder : this.$.table_component_place_holder
  928 + };
  929 +
  930 + ComponentService.deep_url = this.deepUrl;
  931 + ComponentService.getComponent(table_params);
  932 +
  933 + },
  934 + /**
  935 + * Callback related to event 'draggable-element-controllet_content-dragged' fired by draggable-element-controllet when the user drags a selected field in to input data model field
  936 + *
  937 + * @method _fieldsMapped
  938 + *
  939 + * @param {Event} e
  940 + */
  941 + _fieldsMapped : function(e){
  942 +
  943 + this.generateDataletPreview();
  944 +
  945 + },
  946 + /**
  947 + * Callback related to event 'text-element-controllet_content-changed' fired by text-element-controllet when the user change the value of text
  948 + *
  949 + * @method _textElementChanged
  950 + *
  951 + * @param {Event} e
  952 + */
  953 + _textElementChanged : function(e){
  954 + this.generateDataletPreview();
  955 + },
  956 + /**
  957 + * Callback related to the drag operation in the dataUrl input area. It's used to delete previous value.
  958 + *
  959 + * @method _handleDatasourceDragOver
  960 + *
  961 + * @param {Event} e
  962 + */
  963 + _handleDatasourceDragOver : function(e){
  964 + this.$.data_url.value = "";
  965 + },
  966 + /**
  967 + * Callback related to the finish button.
  968 + *
  969 + * @method _onFinish
  970 + *
  971 + * @param {Event} e
  972 + */
  973 + _onFinish : function(e){
  974 +
  975 + if((this.selectedFields.length == 0) || this.selectedDatalet == ""){
  976 + this.$.message.text = "You have to map the selected fields with datalets fields(by dragging) and select a datalet to export a new visualization.";
  977 + this.$.message.show();
  978 + return;
  979 + }
  980 +
  981 + var data = {
  982 + dataUrl : this.dataUrl,
  983 + params : this.paramsFields,
  984 + fields : this.selectedFields,
  985 + datalet : this.selectedDatalet,
  986 + staticData : JSON.stringify(this.$.datalet_placeholder.children[1].behavior.data)
  987 + }
  988 +
  989 + this.fire('data-sevc-controllet.dataletCreated', {data : data});
  990 +
  991 + }
  992 +
  993 + });
  994 +
  995 + </script>
  996 +
  997 +</dom-module>
0 \ No newline at end of file 998 \ No newline at end of file
controllets/data-sevc-controllet/data-sevc-controllet__.html 0 → 100644
  1 +<!--
  2 +@license
  3 + The MIT License (MIT)
  4 +
  5 + Copyright (c) 2015 Dipartimento di Informatica - Università di Salerno - Italy
  6 +
  7 + Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + of this software and associated documentation files (the "Software"), to deal
  9 + in the Software without restriction, including without limitation the rights
  10 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + copies of the Software, and to permit persons to whom the Software is
  12 + furnished to do so, subject to the following conditions:
  13 +
  14 + The above copyright notice and this permission notice shall be included in
  15 + all copies or substantial portions of the Software.
  16 +
  17 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + THE SOFTWARE.
  24 +-->
  25 +
  26 +<!--
  27 +* Developed by :
  28 +* ROUTE-TO-PA Project - grant No 645860. - www.routetopa.eu
  29 +*
  30 +-->
  31 +
  32 +<link rel="import" href="../../bower_components/polymer/polymer.html">
  33 +<link rel="import" href="../../bower_components/paper-styles/color.html">
  34 +
  35 +<link rel="import" href="../../bower_components/neon-animation/neon-animated-pages.html">
  36 +<link rel="import" href="../../bower_components/neon-animation/neon-animatable.html">
  37 +<link rel="import" href="../../bower_components/neon-animation/neon-animations.html">
  38 +
  39 +<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
  40 +<link rel="import" href="../../bower_components/paper-input/paper-input.html">
  41 +<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
  42 +<link rel="import" href="../../bower_components/paper-button/paper-button.html">
  43 +<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
  44 +<link rel="import" href="../../bower_components/paper-tabs/paper-tab.html">
  45 +<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
  46 +<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
  47 +<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
  48 +<link rel="import" href="../../bower_components/paper-item/paper-item.html">
  49 +<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
  50 +<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
  51 +<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
  52 +
  53 +<link rel="import" href="../items-slider-controllet/items-slider-controllet.html">
  54 +<link rel="import" href="../draggable-element-controllet/draggable-element-controllet.html">
  55 +<link rel="import" href="../tree-view-controllet/tree-view-controllet.html">
  56 +<link rel="import" href="../text-element-controllet/text-element-controllet.html">
  57 +
  58 +<!--
  59 +The `data-sevc-controllet` is a controllet to generate visualization from a dataset accessible through api. A json response is required.
  60 +It's composed by three steps. First, user have to select a datasource to access to a dataset. He can copy and paste/drag and drop an url(an api url with json response) or select
  61 +from select contextual menu an available one. Second, the user selects the fields he want to visualize from a treeview by checking on it. A table preview of selected fields will show
  62 +the currently selected values. Third, the users selects a visualization(datalet) from a slider and drags the previous selected fields in to the input data model fields area. A preview
  63 +is available every time a fields is dragged in the input data model fields area.
  64 +
  65 +Example:
  66 +
  67 + <data-sevc-controllet deep-url="http://192.168.36.128/DatalEts-Ecosystem-Provider/DEEP/"
  68 + datalets-list-url="http://192.168.36.128/DatalEts-Ecosystem-Provider/DEEP/datalets-list"
  69 + datasets='{[{name : 'dataset1', url : dataset1Urls}, ... , {name : 'datasetN', url : datasetNUrls}]'>
  70 + </data-sevc-controllet>
  71 +
  72 +
  73 +@element data-sevc-controllet
  74 +@status beta
  75 +@homepage
  76 +@group controllets
  77 +-->
  78 +
  79 +
  80 +<dom-module id="data-sevc-controllet">
  81 + <template>
  82 + <link rel="stylesheet" href="../shared_js/perfect-scrollbar/css/perfect-scrollbar.min.css">
  83 + <link rel="stylesheet" href="static/css/reset.css">
  84 +
  85 + <style is="custom-style">
  86 +
  87 + ::content body {
  88 + font-family: 'Roboto', sans-serif;
  89 + }
  90 +
  91 + .flexchild
  92 + {
  93 + @apply(--layout-flex);
  94 + }
  95 +
  96 + .flex2child
  97 + {
  98 + @apply(--layout-flex-2);
  99 + }
  100 +
  101 + .avatar
  102 + {
  103 + display: inline-block;
  104 + height: 2em;
  105 + width: 2em;
  106 + border-radius: 50%;
  107 + background: var(--paper-blue-500);
  108 + color: white;
  109 + line-height: 2em;
  110 + font-size: 1.87em;
  111 + text-align: center;
  112 + }
  113 +
  114 + .title
  115 + {
  116 + position: relative;
  117 + top: 0.60vh;
  118 + margin-left: 20px;
  119 + }
  120 +
  121 + .big
  122 + {
  123 + font-size: 1.37em;
  124 + color: var(--google-grey-500);
  125 + }
  126 +
  127 + .medium
  128 + {
  129 + font-size: 1em;
  130 + padding-bottom: 0.5em;
  131 + color : #000000;
  132 + font-weight: bold;
  133 + }
  134 +
  135 + .small
  136 + {
  137 + font-size: 0.8em;
  138 + padding-top: 10px;
  139 + color: var(--paper-blue-500);
  140 + font-weight: bold;
  141 + }
  142 +
  143 + paper-input
  144 + {
  145 + width: 80%;
  146 + }
  147 +
  148 + paper-dropdown-menu
  149 + {
  150 + text-align: left;
  151 + margin: auto;
  152 + width: 100%;
  153 + }
  154 +
  155 + ::content paper-menu-button
  156 + {
  157 + display: block;
  158 + width: 100%;
  159 + }
  160 +
  161 + #visualization_slider_area
  162 + {
  163 + min-width: 670px;
  164 + min-height: 180px;
  165 + }
  166 +
  167 + #fields_mapping_area
  168 + {
  169 + min-width: 670px;
  170 + min-height: 180px;
  171 + }
  172 +
  173 + #datalet_placeholder
  174 + {
  175 + height: 360px;
  176 + min-height: 360px;
  177 +
  178 + }
  179 +
  180 + .datalet_right_container
  181 + {
  182 + width: 100vh;
  183 + }
  184 +
  185 + .field-mapping-card
  186 + {
  187 + width: 50%;
  188 + float: left;
  189 + }
  190 +
  191 + .toolbar_button
  192 + {
  193 + --iron-icon-height: 32px;
  194 + --iron-icon-width: 32px;
  195 + }
  196 +
  197 + #finish_button
  198 + {
  199 + --iron-icon-height: 32px;
  200 + --iron-icon-width: 32px;
  201 + color: var(--paper-blue-500);
  202 + }
  203 +
  204 + .area_container
  205 + {
  206 + overflow: hidden;
  207 + margin : 0.8em;
  208 + padding : 0.8em;
  209 + border-width: 1em;
  210 + border-radius: 0.125rem;
  211 + box-shadow: 0.125em 0.125em 0.1125em 0.125em rgba(0, 0, 0, 0.25);
  212 + }
  213 +
  214 + #fields_placeholder{
  215 + width: 40%;
  216 + height: 75vh;
  217 + position: relative;
  218 + float: left;
  219 + overflow: auto;
  220 + }
  221 +
  222 + #table_fields_container{
  223 + height: 75vh;
  224 + width: 55%;
  225 + position: relative;
  226 + float: left;
  227 + overflow: auto;
  228 + }
  229 +
  230 + paper-tabs, paper-toolbar
  231 + {
  232 + background-color: var(--paper-blue-500);
  233 + color: #ffffff;
  234 + box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2);
  235 + }
  236 +
  237 + paper-toolbar paper-tabs
  238 + {
  239 + box-shadow: none;
  240 + --paper-tabs-selection-bar-color : var(--google-gray-500);
  241 + }
  242 +
  243 + paper-tabs[noink][no-bar] paper-tab.iron-selected
  244 + {
  245 + background-color: var(--google-gray-500);
  246 + }
  247 +
  248 + paper-tabs[align-bottom]
  249 + {
  250 + box-shadow: 0px -2px 6px rgba(0, 0, 0, 0.15);
  251 + }
  252 +
  253 + #idm_fields_main_container{
  254 + position: relative;
  255 + height: 50vh;
  256 + }
  257 +
  258 + #selected_fields_main_container{
  259 + position: relative;
  260 + height: 50vh;
  261 + }
  262 +
  263 + #idm_layout_main_container{
  264 + position: relative;
  265 + height: 25vh;
  266 + }
  267 +
  268 + paper-menu{
  269 + width: 100%;
  270 + }
  271 +
  272 + paper-dialog {
  273 + position: fixed;
  274 + top: 16px;
  275 + width: auto;
  276 + height: auto;
  277 + overflow: auto;
  278 + padding : 30px;
  279 + }
  280 +
  281 + </style>
  282 +
  283 + <iron-ajax
  284 + id="data_request"
  285 + url={{dataUrl}}
  286 + verbose="true"
  287 + on-response="handleResponseData"
  288 + debounce-duration="300">
  289 + </iron-ajax>
  290 +
  291 + <iron-ajax
  292 + id="datales_list_request"
  293 + auto
  294 + url={{dataletsListUrl}}
  295 + handle-as="json"
  296 + on-response="handleResponseDatalets"
  297 + debounce-duration="300">
  298 + </iron-ajax>
  299 +
  300 + <iron-ajax
  301 + id="selected_datalet_request"
  302 + url={{deepUrl}}
  303 + verbose="true"
  304 + on-response="handleSelectedDatalet"
  305 + debounce-duration="300">
  306 + </iron-ajax>
  307 +
  308 + <content>
  309 +
  310 + <neon-animated-pages id="pages" selected="[[selected]]" entry-animation="[[entryAnimation]]" exit-animation="[[exitAnimation]]">
  311 +
  312 + <neon-animatable>
  313 +
  314 + <div class="vertical justified layout">
  315 +
  316 + <div class="horizontal layout">
  317 + <div class="avatar" style="margin-left:15px">1</div>
  318 + <div class="title flex">
  319 + <div id="toolbar_title" class="big">Dataset source</div>
  320 + <div id="toolbar_description" class="small">Copy and paste/drag and drop in the textarea the url of datasource</div>
  321 + </div>
  322 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
  323 + </div>
  324 +
  325 + <div class="area_container">
  326 + <paper-tabs selected="{{DatasourceTabSelected}}">
  327 + <paper-tab>Select data source</paper-tab>
  328 + <paper-tab>Most popular</paper-tab>
  329 + <paper-tab>Search</paper-tab>
  330 + </paper-tabs>
  331 + <iron-pages selected="{{DatasourceTabSelected}}">
  332 + <div>
  333 + <div class="card-content">
  334 + <paper-dropdown-menu id="datasets-sources" label="Available datasets">
  335 + <paper-menu class="dropdown-content">
  336 + <template is="dom-repeat" items="{{datasets}}" as="dataset" index-as="index">
  337 + <paper-item id="{{index}}" on-tap="_datasourceSelected">{{dataset.name}}</paper-item>
  338 + </template>
  339 + </paper-menu>
  340 + </paper-dropdown-menu>
  341 + <paper-icon-button id="infoButton" on-click="_onInfoClick" icon="info-outline" alt="Information about selected dataset" title="info-button" style="color:#9e9e9e;"></paper-icon-button>
  342 + </div>
  343 +
  344 + <div><img src="static/images/or.png" style="position: relative;left: 50%;padding-top:20px"></div>
  345 +
  346 + <div class="card-content">
  347 + <paper-textarea id="data_url" label="Dataset api data url" floatingLabel value="{{dataUrl}}" on-dragover="_handleDatasourceDragOver"></paper-textarea>
  348 + </div>
  349 +
  350 +
  351 + </div>
  352 + <div><img src="static/images/UnderConstruction.png" style="position: relative;top: 60%;left: 25%;"></div>
  353 + <div><img src="static/images/UnderConstruction.png" style="position: relative;top: 60%;left: 25%;"></div>
  354 + </iron-pages>
  355 + </div>
  356 +
  357 + </div>
  358 +
  359 + </neon-animatable>
  360 +
  361 + <neon-animatable>
  362 +
  363 + <div class="vertical justified layout">
  364 +
  365 + <div class="horizontal layout">
  366 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  367 + <div class="avatar">2</div>
  368 + <div class="title flex">
  369 + <div id="toolbar_title" class="big">Dataset source</div>
  370 + <div id="toolbar_description" class="small">Copy and paste/drag and drop in the textarea the url of datasource</div>
  371 + </div>
  372 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
  373 + </div>
  374 +
  375 + <div class="horizontal layout">
  376 +
  377 + <div id="fields_placeholder" class="area_container flexchild" style="min-width:300px">
  378 + <tree-view-controllet id="fields_treeview" root-name="data" opened-path="data,records"></tree-view-controllet>
  379 + </div>
  380 +
  381 + <div id="table_fields_container" class="area_container flex2child">
  382 + <div id="table_component_place_holder"></div>
  383 + </div>
  384 +
  385 + </div>
  386 +
  387 + </div>
  388 +
  389 + </neon-animatable>
  390 +
  391 + <neon-animatable style="height:100vh">
  392 +
  393 + <div class="vertical justified layout">
  394 +
  395 + <div class="horizontal layout">
  396 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  397 + <div class="avatar">3</div>
  398 + <div class="title flex">
  399 + <div id="toolbar_title" class="big">Data mapping</div>
  400 + <div id="toolbar_description" class="small">Select the visualization from the slider, drag and drop the selected fields in visualization parameter area, customize the visualization if you need</div>
  401 + </div>
  402 + <paper-icon-button id="finish_button" on-click="_onFinish" icon="add-circle" alt="Conforms the creation" title="finish"></paper-icon-button>
  403 + </div>
  404 +
  405 +
  406 + <div class="horizontal layout">
  407 +
  408 + <div class="">
  409 + <div id="visualization_slider_area" class="area_container"></div>
  410 + <div id="fields_mapping_area" class="area_container">
  411 +
  412 + <div id="selected_fields_main_container" class="field-mapping-card">
  413 + <div class="title">
  414 + <div class="medium">Selected fields</div>
  415 + </div>
  416 + <div id="selected_fields_container" class="area_container"></div>
  417 + </div>
  418 +
  419 + <div id="idm_fields_main_container" class="field-mapping-card">
  420 + <div class="title">
  421 + <div class="medium">Datalet fields</div>
  422 + </div>
  423 + <div id="datalet_idm_fields_container" class="area_container"></div>
  424 + </div>
  425 +
  426 + <div id="idm_layout_main_container" class="area_container">
  427 + <div class="title">
  428 + <div class="medium">Layout fields</div>
  429 + </div>
  430 + <div id="idm_layout_container" class="area_container"></div>
  431 + </div>
  432 + </div>
  433 + </div>
  434 +
  435 + <div id="datalet_placeholder" style="min-width: 43%;"></div>
  436 +
  437 +
  438 + </div>
  439 +
  440 + </div>
  441 +
  442 + </neon-animatable>
  443 +
  444 + </neon-animated-pages>
  445 +
  446 + <paper-toast id="message" text=""></paper-toast>
  447 +
  448 + <paper-dialog id="infoDialog">
  449 + <h2 id="infoDialogTitle"></h2>
  450 + <paper-dialog-scrollable id="infoDialogContent">
  451 + </paper-dialog-scrollable>
  452 + </paper-dialog>
  453 +
  454 + </content>
  455 + </template>
  456 +
  457 + <script src="../shared_js/perfect-scrollbar/js/min/perfect-scrollbar.jquery.min.js"></script>
  458 + <script src="../../../DEEPCLIENT/js/deepClient.js"></script>
  459 +
  460 + <script>
  461 +
  462 + Polymer({
  463 +
  464 + is : 'data-sevc-controllet',
  465 +
  466 + /**
  467 + * Received when the user selects a datalet from slider.
  468 + *
  469 + * @event items-slider-controllet_item-selected
  470 + */
  471 +
  472 + /**
  473 + * Received when the user drags a selected fields in to one of the source input data model field
  474 + *
  475 + * @event draggable-element-controllet_content-dragged
  476 + */
  477 +
  478 + /**
  479 + * Received when the user selects one field from treeview controllet
  480 + *
  481 + * @event treeview-controllet-fileds-selected
  482 + */
  483 +
  484 + /**
  485 + * Received when the user drags a selected fields in to one of the source input data model field
  486 + *
  487 + * @event draggable-element-controllet_content-dragged
  488 + */
  489 +
  490 + /**
  491 + * Received when the user change text value of the selected datalet layout inputs
  492 + *
  493 + * @event text-element-controllet_content-changed
  494 + */
  495 +
  496 + /**
  497 + * Fired when the user press to finish button. At this event are attached all information about the visualization currently created
  498 + *
  499 + * @event data-sevc-controllet.dataletCreated
  500 + */
  501 +
  502 + listeners : {
  503 + 'items-slider-controllet_item-selected' : '_dataletSelected',
  504 + 'draggable-element-controllet_content-dragged' : '_fieldsMapped',
  505 + 'treeview-controllet_fileds-selected' : '_fieldsSelected',
  506 + 'text-element-controllet_content-changed' : '_textElementChanged'
  507 + },
  508 +
  509 + properties : {
  510 +
  511 + entryAnimation : {
  512 + type : String,
  513 + value : ""
  514 + },
  515 +
  516 + exitAnimation : {
  517 + type : String,
  518 + value : ""
  519 + },
  520 +
  521 + selected : {
  522 + type : Number,
  523 + value : 0
  524 + },
  525 +
  526 + /**
  527 + * It represents the data url from CKAN api
  528 + *
  529 + * @attribute dataUrl
  530 + * @type string
  531 + * @default 'null'
  532 + */
  533 + dataUrl : {
  534 + type : String,
  535 + value : undefined,
  536 + observer : '_dataUrlChanged'
  537 + },
  538 + /**
  539 + * It represents the DEEP url to get information about the datalets
  540 + *
  541 + * @attribute deepUrl
  542 + * @type string
  543 + * @default 'null'
  544 + */
  545 + deepUrl : {
  546 + type : String,
  547 + value : ""
  548 + },
  549 + /**
  550 + * It's used to store the list of datalets returned from DEEP
  551 + *
  552 + * @attribute datalets_list
  553 + * @type Array
  554 + * @default empty
  555 + */
  556 + datalets_list : {
  557 + type : Array ,
  558 + value : []
  559 + },
  560 + /**
  561 + * It's used to store the selected datalet. It will be set when the controllet get the event of selection by item slider (items-slider-controllet_item-selected)
  562 + *
  563 + * @attribute selected_datalet
  564 + * @type String
  565 + * @default ''
  566 + */
  567 + selected_datalet : {
  568 + type : String,
  569 + value : ""
  570 + },
  571 + /**
  572 + * It's used to store the list of selected fields by user
  573 + *
  574 + * @attribute selected_fields
  575 + * @type Array
  576 + * @default empty
  577 + */
  578 + selected_fields : {
  579 + type : Array,
  580 + value : []
  581 + },
  582 + /**
  583 + * It's used to store the params to give to datalet. This kind of params will not processed by selection step
  584 + *
  585 + * @attribute params_fields
  586 + * @type Object
  587 + * @default empty
  588 + */
  589 + params_fields:{
  590 + type: Object,
  591 + value: {}
  592 + },
  593 + /**
  594 + * It's used to store the tab index in the first pass
  595 + *
  596 + * @attribute DatasourceTabSelected
  597 + * @type Number
  598 + * @default 0
  599 + */
  600 + DatasourceTabSelected : {
  601 + type : Number,
  602 + value : 0
  603 + },
  604 + /**
  605 + * It's used to store the datasets to show in the contexual menu
  606 + *
  607 + * @attribute datasets
  608 + * @type Array
  609 + * @default empty
  610 + */
  611 + datasets :
  612 + {
  613 + type : Array,
  614 + value : []
  615 + }
  616 + },
  617 + /**
  618 + * It is called after the element’s template has been stamped and all elements inside the element’s local DOM have been configured (with values bound from parents, deserialized attributes, or else default values) and had their ready method called.
  619 + * In this phase the scrollbar will be initialized
  620 + *
  621 + * @method handleResponseData
  622 + *
  623 + * @param {Event} e
  624 + */
  625 +
  626 + ready : function(){
  627 +
  628 + $(this.$.fields_placeholder).perfectScrollbar();
  629 + $(this.$.selected_fields_main_container).perfectScrollbar();
  630 + $(this.$.idm_fields_main_container).perfectScrollbar();
  631 + $(this.$.idm_layout_main_container).perfectScrollbar();
  632 + $(this.$.table_fields_container).perfectScrollbar();
  633 +
  634 + },
  635 +
  636 + /**
  637 + * Callback to parse the data requested when dataUrl change its value
  638 + *
  639 + * @method handleResponseData
  640 + *
  641 + * @param {Event} e
  642 + */
  643 + handleResponseData : function(e){
  644 +
  645 + //this.$.fields_treeview.init(e.detail.response);
  646 +
  647 + //this.$.fields_placeholder.innerHTML = '<tree-view-controllet id="fields_treeview" root-name="Data" opened-path="Data,records" json-data=\'' + JSON.stringify(e.detail.response) + '\'></tree-view-controllet>';
  648 + this.$.fields_treeview.setAttribute("json-data", JSON.stringify(e.detail.response));
  649 + this.$.fields_treeview.init();//chrome
  650 + },
  651 +
  652 + /**
  653 + * Callback to parse the components response object
  654 + *
  655 + * @method handleResponseDatalets
  656 + *
  657 + * @param {Event} e
  658 + */
  659 + handleResponseDatalets : function(e){
  660 + this.datalets_list = new Array();
  661 + for(var i=0;i < e.detail.response.length;i++){
  662 + var datalet_info = { name : e.detail.response[i].name ,
  663 + image : e.detail.response[i].url + e.detail.response[i].name + ".png"
  664 + };
  665 +
  666 + this.datalets_list.push(datalet_info);
  667 + }
  668 +
  669 + this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +
  670 + '\'></items-slider-controllet>';
  671 + },
  672 + /**
  673 + * Callback to dataset selection from list in the phase three. When a datalet is selected this function will build a bundle of box items, based on the datalet input data model,
  674 + * to allow user to drag the fields, from the selected fields box, and create a new visualization.
  675 + *
  676 + * @method handleSelectedDatalet
  677 + *
  678 + * @param {Event} e
  679 + */
  680 + handleSelectedDatalet : function(e){
  681 +
  682 + var response = e.detail.response;
  683 + this.$.datalet_idm_fields_container.innerHTML = "";
  684 + this.$.idm_layout_container.innerHTML = "";
  685 +
  686 + if(response.idm.inputs.input.constructor == Object) {
  687 + var input = response.idm.inputs.input;
  688 + if(input.selection == "*") {
  689 + var input_selected_fields = Polymer.dom(this.$.selected_fields_container).querySelectorAll('draggable-element-controllet');
  690 + for (var j = 0; j < input_selected_fields.length; j++) {
  691 + this.$.datalet_idm_fields_container.innerHTML += '<draggable-element-controllet is-target="true" heading="Field ' + (j + 1) + '" description="' + input.description + '" number="' + (j + 1) + '"></draggable-element-controllet><br>';
  692 + }
  693 + }
  694 + }else{
  695 + for(var i =0; i < response.idm.inputs.input.length; i++){
  696 + var input = response.idm.inputs.input[i];
  697 + this.$.datalet_idm_fields_container.innerHTML += '<draggable-element-controllet is-target="true" id="' + input.name + '" heading="' + input.name + '" description="' + input.description + '" number="' + (i + 1) + '"></draggable-element-controllet><br>';
  698 + }
  699 + }
  700 +
  701 + if(response.idm.inputs.layouts.input.constructor == Object) {
  702 + var input = response.idm.inputs.layouts.input;
  703 + this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + input.name + '" description="' + input.description + '" number="1"></text-element-controllet>';
  704 + }else{
  705 + for(var i =0; i < response.idm.inputs.layouts.input.length; i++){
  706 + var input = response.idm.inputs.layouts.input[i];
  707 + this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + input.name + '" ' +
  708 + 'description="' + input.description + '" ' +
  709 + 'number="' + (i+1) + '">' +
  710 + '</text-element-controllet>';
  711 + }
  712 +
  713 + }
  714 +
  715 + },
  716 + /**
  717 + * Generate the datalet preview when user mapped fields. it even retrieves the value of layout inputs values.
  718 + *
  719 + * @method generateDataletPreview
  720 + */
  721 + generateDataletPreview : function(){
  722 +
  723 + var input_mapped_fields = Polymer.dom(this.$.datalet_idm_fields_container).querySelectorAll('draggable-element-controllet[is-target=true]');
  724 + this.selected_fields = Array();
  725 +
  726 + for (var i = 0; i < input_mapped_fields.length; i++) {
  727 + if (input_mapped_fields[i].value != "") {
  728 + this.selected_fields.push(input_mapped_fields[i].value);
  729 + }
  730 + }
  731 +
  732 + var input_layouts_fields = Polymer.dom(this.$.idm_layout_container).querySelectorAll('text-element-controllet');
  733 + this.params_fields = {'data-url' : this.dataUrl};
  734 +
  735 + for (var i = 0; i < input_layouts_fields.length; i++) {
  736 + if (input_layouts_fields[i].value != "") {
  737 + this.params_fields[input_layouts_fields[i].heading] = input_layouts_fields[i].value;
  738 + }
  739 + }
  740 +
  741 +
  742 + var datalet_params ={
  743 + component : this.selected_datalet,
  744 + params : this.params_fields,
  745 + fields : this.selected_fields,
  746 + placeHolder : this.$.datalet_placeholder
  747 + };
  748 +
  749 +
  750 + ComponentService.deep_url = this.deepUrl;
  751 + ComponentService.getComponent(datalet_params);
  752 +
  753 + },
  754 + /**
  755 + * Validate the current pass in order to access to next one.
  756 + *
  757 + * @method validateCurrentPass
  758 + *
  759 + * @param {Number} next_selected_pass
  760 + */
  761 + validateCurrentPass : function(next_selected_pass){
  762 +
  763 + switch(next_selected_pass){
  764 + case 0:
  765 + return true;
  766 + case 1:
  767 + if(this.$.data_url.value == ""){
  768 + this.$.message.text = "You have to select a dataset to access to pass 2.";
  769 + this.$.message.show();
  770 + return false;
  771 + }else{
  772 + return true;
  773 + }
  774 +
  775 + case 2:
  776 + if(Polymer.dom(this.$.selected_fields_container).querySelectorAll('draggable-element-controllet') == 0){
  777 + this.$.message.text = "You have to select a set of fields to access to pass 3.";
  778 + this.$.message.show();
  779 + return false;
  780 + }else{
  781 + return true;
  782 + }
  783 + }
  784 +
  785 + },
  786 + /**
  787 + * Callback for manage the previous pass button
  788 + *
  789 + * @method _onPrevClick
  790 + *
  791 + */
  792 + _onPrevClick : function() {
  793 + if(!this.validateCurrentPass(this.selected === 0 ? 0 : (this.selected - 1))) return;
  794 +
  795 + this.entryAnimation = 'slide-from-left-animation';
  796 + this.exitAnimation = 'slide-right-animation';
  797 + this.selected = this.selected === 0 ? 0 : (this.selected - 1);
  798 + },
  799 + /**
  800 + * Callback to manage the next pass button
  801 + *
  802 + * @method _onNextClick
  803 + *
  804 + */
  805 + _onNextClick : function() {
  806 +
  807 + if(!this.validateCurrentPass(this.selected === 2 ? 2 : (this.selected + 1))) return;
  808 +
  809 + this.entryAnimation = 'slide-from-right-animation';
  810 + this.exitAnimation = 'slide-left-animation';
  811 + this.selected = this.selected === 2 ? 2 : (this.selected + 1);
  812 + },
  813 + /**
  814 + * Callback to manage InfoButton click to give user information about the selected dataset
  815 + *
  816 + */
  817 + _onInfoClick : function(){
  818 +
  819 + this.$.infoDialog.open();
  820 +
  821 + },
  822 + /**
  823 + * Callback related to datasource selection from select menu
  824 + *
  825 + * @method _datasourceSelected
  826 + *
  827 + * @param {Event} e
  828 + */
  829 + _datasourceSelected : function(e){
  830 +
  831 + this.$.data_url.value = this.datasets[parseInt(e.target.id)].url;
  832 + this.$.infoDialogTitle.innerHTML = this.datasets[parseInt(e.target.id)].name;
  833 + this.$.infoDialogContent.innerHTML = this.datasets[parseInt(e.target.id)].description;
  834 +
  835 + },
  836 + /**
  837 + * Callback related to data url change
  838 + *
  839 + * @method _dataUrlChanged
  840 + *
  841 + * @param {Event} e
  842 + */
  843 + _dataUrlChanged : function(newValue, oldValue){
  844 + this.$.data_request.generateRequest();
  845 + },
  846 + /**
  847 + * Callback related to event 'items-slider-controllet_item-selected' fired by items-slider-controllet when the user selects a datalet
  848 + *
  849 + * @method _dataletSelected
  850 + *
  851 + * @param {Event} e
  852 + */
  853 + _dataletSelected : function(e){
  854 + this.selected_datalet = e.detail.datalet;
  855 + this.$.selected_datalet_request.url = this.deepUrl + e.detail.datalet;
  856 + this.$.selected_datalet_request.generateRequest();
  857 +
  858 + },
  859 + /**
  860 + * Callback related to event 'treeview-controllet-fileds-selected' fired by treeview-controllet when the user selects a field
  861 + *
  862 + * @method _fieldsSelected
  863 + *
  864 + * @param {Event} e
  865 + */
  866 + _fieldsSelected : function(e){
  867 +
  868 + this.$.selected_fields_container.innerHTML = "";
  869 + for(var i=0;i<e.detail.fields.length;i++) {
  870 + this.$.selected_fields_container.innerHTML += '<draggable-element-controllet identifier="' + e.detail.fields[i] +
  871 + '" label="' + e.detail.fields[i].split(",")[e.detail.fields[i].split(",").length -1] +
  872 + '"></draggable-element-controllet><br>';
  873 + }
  874 +
  875 + var place_holder = (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) ? this.$.table_component_place_holder : this.$.table_component_place_holder[Object.keys(this.$.table_component_place_holder)[0]];
  876 +
  877 + var table_params ={
  878 + component : "datatable-datalet",
  879 + params :{
  880 + 'data-url' : this.dataUrl
  881 + },
  882 + fields : e.detail.fields,
  883 + placeHolder : this.$.table_component_place_holder
  884 + };
  885 +
  886 + ComponentService.deep_url = this.deepUrl;
  887 + ComponentService.getComponent(table_params);
  888 +
  889 + },
  890 + /**
  891 + * Callback related to event 'draggable-element-controllet_content-dragged' fired by draggable-element-controllet when the user drags a selected field in to input data model field
  892 + *
  893 + * @method _fieldsMapped
  894 + *
  895 + * @param {Event} e
  896 + */
  897 + _fieldsMapped : function(e){
  898 +
  899 + this.generateDataletPreview();
  900 +
  901 + },
  902 + /**
  903 + * Callback related to event 'text-element-controllet_content-changed' fired by text-element-controllet when the user change the value of text
  904 + *
  905 + * @method _textElementChanged
  906 + *
  907 + * @param {Event} e
  908 + */
  909 + _textElementChanged : function(e){
  910 + this.generateDataletPreview();
  911 + },
  912 + /**
  913 + * Callback related to the drag operation in the dataUrl input area. It's used to delete previous value.
  914 + *
  915 + * @method _handleDatasourceDragOver
  916 + *
  917 + * @param {Event} e
  918 + */
  919 + _handleDatasourceDragOver : function(e){
  920 + this.$.data_url.value = "";
  921 + },
  922 + /**
  923 + * Callback related to the finish button.
  924 + *
  925 + * @method _onFinish
  926 + *
  927 + * @param {Event} e
  928 + */
  929 + _onFinish : function(e){
  930 +
  931 + if((this.selected_fields.length == 0) || this.selected_datalet == ""){
  932 + this.$.message.text = "You have to map the selected fields with datalets fields(by dragging) and select a datalet to export a new visualization.";
  933 + this.$.message.show();
  934 + return;
  935 + }
  936 +
  937 + var data = {
  938 + dataUrl : this.dataUrl,
  939 + params : this.params_fields,
  940 + fields : this.selected_fields,
  941 + datalet : this.selected_datalet,
  942 + staticData : JSON.stringify(this.$.datalet_placeholder.children[1].behavior.data)
  943 + }
  944 +
  945 + this.fire('data-sevc-controllet.dataletCreated', {data : data});
  946 +
  947 + }
  948 +
  949 + });
  950 +
  951 + </script>
  952 +
  953 +</dom-module>
0 \ No newline at end of file 954 \ No newline at end of file
controllets/data-sevc-controllet/data-sevc-controllet_beckup.html 0 → 100644
  1 +<!--
  2 +@license
  3 + The MIT License (MIT)
  4 +
  5 + Copyright (c) 2015 Dipartimento di Informatica - Università di Salerno - Italy
  6 +
  7 + Permission is hereby granted, free of charge, to any person obtaining a copy
  8 + of this software and associated documentation files (the "Software"), to deal
  9 + in the Software without restriction, including without limitation the rights
  10 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 + copies of the Software, and to permit persons to whom the Software is
  12 + furnished to do so, subject to the following conditions:
  13 +
  14 + The above copyright notice and this permission notice shall be included in
  15 + all copies or substantial portions of the Software.
  16 +
  17 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 + THE SOFTWARE.
  24 +-->
  25 +
  26 +<!--
  27 +* Developed by :
  28 +* ROUTE-TO-PA Project - grant No 645860. - www.routetopa.eu
  29 +*
  30 +-->
  31 +
  32 +<link rel="import" href="../../bower_components/polymer/polymer.html">
  33 +<link rel="import" href="../../bower_components/paper-styles/color.html">
  34 +
  35 +<link rel="import" href="../../bower_components/neon-animation/neon-animated-pages.html">
  36 +<link rel="import" href="../../bower_components/neon-animation/neon-animatable.html">
  37 +<link rel="import" href="../../bower_components/neon-animation/neon-animations.html">
  38 +
  39 +<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
  40 +<link rel="import" href="../../bower_components/paper-input/paper-input.html">
  41 +<link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
  42 +<link rel="import" href="../../bower_components/paper-button/paper-button.html">
  43 +<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
  44 +<link rel="import" href="../../bower_components/paper-tabs/paper-tab.html">
  45 +<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
  46 +<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
  47 +<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
  48 +<link rel="import" href="../../bower_components/paper-item/paper-item.html">
  49 +<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
  50 +<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
  51 +<link rel="import" href="../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html">
  52 +
  53 +<link rel="import" href="../items-slider-controllet/items-slider-controllet.html">
  54 +<link rel="import" href="../draggable-element-controllet/draggable-element-controllet.html">
  55 +<link rel="import" href="../treeview-controllet/treeview-controllet.html">
  56 +<link rel="import" href="../text-element-controllet/text-element-controllet.html">
  57 +
  58 +<!--
  59 +The `data-sevc-controllet` is a controllet to generate visualization from a dataset accessible through api. A json response is required.
  60 +It's composed by three steps. First, user have to select a datasource to access to a dataset. He can copy and paste/drag and drop an url(an api url with json response) or select
  61 +from select contextual menu an available one. Second, the user selects the fields he want to visualize from a treeview by checking on it. A table preview of selected fields will show
  62 +the currently selected values. Third, the users selects a visualization(datalet) from a slider and drags the previous selected fields in to the input data model fields area. A preview
  63 +is available every time a fields is dragged in the input data model fields area.
  64 +
  65 +Example:
  66 +
  67 + <data-sevc-controllet deep-url="http://192.168.36.128/DatalEts-Ecosystem-Provider/DEEP/"
  68 + datalets-list-url="http://192.168.36.128/DatalEts-Ecosystem-Provider/DEEP/datalets-list"
  69 + datasets='{[{name : 'dataset1', url : dataset1Urls}, ... , {name : 'datasetN', url : datasetNUrls}]'>
  70 + </data-sevc-controllet>
  71 +
  72 +
  73 +@element data-sevc-controllet
  74 +@status beta
  75 +@homepage
  76 +@group controllets
  77 +-->
  78 +
  79 +
  80 +<dom-module id="data-sevc-controllet">
  81 + <template>
  82 + <link rel="stylesheet" href="../shared_js/perfect-scrollbar/css/perfect-scrollbar.min.css">
  83 + <link rel="stylesheet" href="static/css/reset.css">
  84 +
  85 + <style is="custom-style">
  86 +
  87 + ::content body {
  88 + font-family: 'Roboto', sans-serif;
  89 + }
  90 +
  91 + .flexchild
  92 + {
  93 + @apply(--layout-flex);
  94 + }
  95 +
  96 + .flex2child
  97 + {
  98 + @apply(--layout-flex-2);
  99 + }
  100 +
  101 + .avatar
  102 + {
  103 + display: inline-block;
  104 + height: 2em;
  105 + width: 2em;
  106 + border-radius: 50%;
  107 + background: var(--paper-blue-500);
  108 + color: white;
  109 + line-height: 2em;
  110 + font-size: 1.87em;
  111 + text-align: center;
  112 + }
  113 +
  114 + .title
  115 + {
  116 + position: relative;
  117 + top: 0.60vh;
  118 + margin-left: 20px;
  119 + }
  120 +
  121 + .big
  122 + {
  123 + font-size: 1.37em;
  124 + color: var(--google-grey-500);
  125 + }
  126 +
  127 + .medium
  128 + {
  129 + font-size: 1em;
  130 + padding-bottom: 0.5em;
  131 + color : #000000;
  132 + font-weight: bold;
  133 + }
  134 +
  135 + .small
  136 + {
  137 + font-size: 0.8em;
  138 + padding-top: 10px;
  139 + color: var(--paper-blue-500);
  140 + font-weight: bold;
  141 + }
  142 +
  143 + paper-input
  144 + {
  145 + width: 80%;
  146 + }
  147 +
  148 + paper-dropdown-menu
  149 + {
  150 + text-align: left;
  151 + margin: auto;
  152 + width: 100%;
  153 + }
  154 +
  155 + ::content paper-menu-button
  156 + {
  157 + display: block;
  158 + width: 100%;
  159 + }
  160 +
  161 + #visualization_slider_area
  162 + {
  163 + min-width: 670px;
  164 + min-height: 180px;
  165 + }
  166 +
  167 + #fields_mapping_area
  168 + {
  169 + min-width: 670px;
  170 + min-height: 180px;
  171 + }
  172 +
  173 + #datalet_placeholder
  174 + {
  175 + height: 360px;
  176 + min-height: 360px;
  177 +
  178 + }
  179 +
  180 + .datalet_right_container
  181 + {
  182 + width: 100vh;
  183 + }
  184 +
  185 + .field-mapping-card
  186 + {
  187 + width: 50%;
  188 + float: left;
  189 + }
  190 +
  191 + .toolbar_button
  192 + {
  193 + --iron-icon-height: 32px;
  194 + --iron-icon-width: 32px;
  195 + }
  196 +
  197 + #finish_button
  198 + {
  199 + --iron-icon-height: 32px;
  200 + --iron-icon-width: 32px;
  201 + color: var(--paper-blue-500);
  202 + }
  203 +
  204 + .area_container
  205 + {
  206 + overflow: hidden;
  207 + margin : 0.8em;
  208 + padding : 0.8em;
  209 + border-width: 1em;
  210 + border-radius: 0.125rem;
  211 + box-shadow: 0.125em 0.125em 0.1125em 0.125em rgba(0, 0, 0, 0.25);
  212 + }
  213 +
  214 + #fields_placeholder{
  215 + width: 40%;
  216 + height: 75vh;
  217 + position: relative;
  218 + float: left;
  219 + overflow: auto;
  220 + }
  221 +
  222 + #table_fields_container{
  223 + height: 75vh;
  224 + width: 55%;
  225 + position: relative;
  226 + float: left;
  227 + overflow: auto;
  228 + }
  229 +
  230 + paper-tabs, paper-toolbar
  231 + {
  232 + background-color: var(--paper-blue-500);
  233 + color: #ffffff;
  234 + box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.2);
  235 + }
  236 +
  237 + paper-toolbar paper-tabs
  238 + {
  239 + box-shadow: none;
  240 + --paper-tabs-selection-bar-color : var(--google-gray-500);
  241 + }
  242 +
  243 + paper-tabs[noink][no-bar] paper-tab.iron-selected
  244 + {
  245 + background-color: var(--google-gray-500);
  246 + }
  247 +
  248 + paper-tabs[align-bottom]
  249 + {
  250 + box-shadow: 0px -2px 6px rgba(0, 0, 0, 0.15);
  251 + }
  252 +
  253 + #idm_fields_main_container{
  254 + position: relative;
  255 + height: 50vh;
  256 + }
  257 +
  258 + #selected_fields_main_container{
  259 + position: relative;
  260 + height: 50vh;
  261 + }
  262 +
  263 + #idm_layout_main_container{
  264 + position: relative;
  265 + height: 25vh;
  266 + }
  267 +
  268 + paper-menu{
  269 + width: 100%;
  270 + }
  271 +
  272 + paper-dialog {
  273 + position: fixed;
  274 + top: 16px;
  275 + width: auto;
  276 + height: auto;
  277 + overflow: auto;
  278 + padding : 30px;
  279 + }
  280 +
  281 + </style>
  282 +
  283 + <iron-ajax
  284 + auto
  285 + id="data_request"
  286 + url={{dataUrl}}
  287 + verbose="true"
  288 + on-response="handleResponseData"
  289 + debounce-duration="300">
  290 + </iron-ajax>
  291 +
  292 + <iron-ajax
  293 + id="datales_list_request"
  294 + auto
  295 + url={{dataletsListUrl}}
  296 + handle-as="json"
  297 + on-response="handleResponseDatalets"
  298 + debounce-duration="300">
  299 + </iron-ajax>
  300 +
  301 + <iron-ajax
  302 + id="selected_datalet_request"
  303 + url={{deepUrl}}
  304 + verbose="true"
  305 + on-response="handleSelectedDatalet"
  306 + debounce-duration="300">
  307 + </iron-ajax>
  308 +
  309 + <content>
  310 +
  311 + <neon-animated-pages id="pages" selected="[[selected]]" entry-animation="[[entryAnimation]]" exit-animation="[[exitAnimation]]">
  312 +
  313 + <neon-animatable>
  314 +
  315 + <div class="vertical justified layout">
  316 +
  317 + <div class="horizontal layout">
  318 + <div class="avatar" style="margin-left:15px">1</div>
  319 + <div class="title flex">
  320 + <div id="toolbar_title" class="big">Dataset source</div>
  321 + <div id="toolbar_description" class="small">Copy and paste/drag and drop in the textarea the url of datasource</div>
  322 + </div>
  323 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
  324 + </div>
  325 +
  326 + <div class="area_container">
  327 + <paper-tabs selected="{{DatasourceTabSelected}}">
  328 + <paper-tab>Select data source</paper-tab>
  329 + <paper-tab>Most popular</paper-tab>
  330 + <paper-tab>Search</paper-tab>
  331 + </paper-tabs>
  332 + <iron-pages selected="{{DatasourceTabSelected}}">
  333 + <div>
  334 + <div class="card-content">
  335 + <paper-dropdown-menu id="datasets-sources" label="Available datasets">
  336 + <paper-menu class="dropdown-content">
  337 + <template is="dom-repeat" items="{{datasets}}" as="dataset" index-as="index">
  338 + <paper-item id="{{index}}" on-tap="_datasourceSelected">{{dataset.name}}</paper-item>
  339 + </template>
  340 + </paper-menu>
  341 + </paper-dropdown-menu>
  342 + <paper-icon-button id="infoButton" on-click="_onInfoClick" icon="info-outline" alt="Information about selected dataset" title="info-button" style="color:#9e9e9e;"></paper-icon-button>
  343 + </div>
  344 +
  345 + <div><img src="static/images/or.png" style="position: relative;left: 50%;padding-top:20px"></div>
  346 +
  347 + <div class="card-content">
  348 + <paper-textarea id="data_url" label="Dataset api data url" floatingLabel value="{{dataUrl}}" on-dragover="_handleDatasourceDragOver"></paper-textarea>
  349 + </div>
  350 +
  351 +
  352 + </div>
  353 + <div><img src="static/images/UnderConstruction.png" style="position: relative;top: 60%;left: 25%;"></div>
  354 + <div><img src="static/images/UnderConstruction.png" style="position: relative;top: 60%;left: 25%;"></div>
  355 + </iron-pages>
  356 + </div>
  357 +
  358 + </div>
  359 +
  360 + </neon-animatable>
  361 +
  362 + <neon-animatable>
  363 +
  364 + <div class="vertical justified layout">
  365 +
  366 + <div class="horizontal layout">
  367 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  368 + <div class="avatar">2</div>
  369 + <div class="title flex">
  370 + <div id="toolbar_title" class="big">Dataset source</div>
  371 + <div id="toolbar_description" class="small">Copy and paste/drag and drop in the textarea the url of datasource</div>
  372 + </div>
  373 + <paper-icon-button id="NextButton" class="toolbar_button" on-click="_onNextClick" icon="chevron-right" alt="arrow-forward" title="arrow-forward"></paper-icon-button>
  374 + </div>
  375 +
  376 + <div class="horizontal layout">
  377 +
  378 + <div id="fields_placeholder" class="area_container flexchild" style="min-width:300px">
  379 + <treeview-controllet id="fields_treeview"></treeview-controllet>
  380 + </div>
  381 +
  382 + <div id="table_fields_container" class="area_container flex2child">
  383 + <div id="table_component_place_holder"></div>
  384 + </div>
  385 +
  386 + </div>
  387 +
  388 + </div>
  389 +
  390 + </neon-animatable>
  391 +
  392 + <neon-animatable style="height:100vh">
  393 +
  394 + <div class="vertical justified layout">
  395 +
  396 + <div class="horizontal layout">
  397 + <paper-icon-button id="PrevButton" class="toolbar_button x-scope" on-click="_onPrevClick" icon="chevron-left" alt="arrow-back" title="arrow-back"></paper-icon-button>
  398 + <div class="avatar">3</div>
  399 + <div class="title flex">
  400 + <div id="toolbar_title" class="big">Data mapping</div>
  401 + <div id="toolbar_description" class="small">Select the visualization from the slider, drag and drop the selected fields in visualization parameter area, customize the visualization if you need</div>
  402 + </div>
  403 + <paper-icon-button id="finish_button" on-click="_onFinish" icon="add-circle" alt="Conforms the creation" title="finish"></paper-icon-button>
  404 + </div>
  405 +
  406 +
  407 + <div class="horizontal layout">
  408 +
  409 + <div class="">
  410 + <div id="visualization_slider_area" class="area_container"></div>
  411 + <div id="fields_mapping_area" class="area_container">
  412 +
  413 + <div id="selected_fields_main_container" class="field-mapping-card">
  414 + <div class="title">
  415 + <div class="medium">Selected fields</div>
  416 + </div>
  417 + <div id="selected_fields_container" class="area_container"></div>
  418 + </div>
  419 +
  420 + <div id="idm_fields_main_container" class="field-mapping-card">
  421 + <div class="title">
  422 + <div class="medium">Datalet fields</div>
  423 + </div>
  424 + <div id="datalet_idm_fields_container" class="area_container"></div>
  425 + </div>
  426 +
  427 + <div id="idm_layout_main_container" class="area_container">
  428 + <div class="title">
  429 + <div class="medium">Layout fields</div>
  430 + </div>
  431 + <div id="idm_layout_container" class="area_container"></div>
  432 + </div>
  433 + </div>
  434 + </div>
  435 +
  436 + <div id="datalet_placeholder" style="min-width: 43%;"></div>
  437 +
  438 +
  439 + </div>
  440 +
  441 + </div>
  442 +
  443 + </neon-animatable>
  444 +
  445 + </neon-animated-pages>
  446 +
  447 + <paper-toast id="message" text=""></paper-toast>
  448 +
  449 + <paper-dialog id="infoDialog">
  450 + <h2 id="infoDialogTitle"></h2>
  451 + <paper-dialog-scrollable id="infoDialogContent">
  452 + </paper-dialog-scrollable>
  453 + </paper-dialog>
  454 +
  455 + </content>
  456 + </template>
  457 +
  458 + <script src="../shared_js/perfect-scrollbar/js/min/perfect-scrollbar.jquery.min.js"></script>
  459 + <script src="../../../DEEPCLIENT/js/deepClient.js"></script>
  460 +
  461 + <script>
  462 +
  463 + Polymer({
  464 +
  465 + is : 'data-sevc-controllet',
  466 +
  467 + /**
  468 + * Received when the user selects a datalet from slider.
  469 + *
  470 + * @event items-slider-controllet_item-selected
  471 + */
  472 +
  473 + /**
  474 + * Received when the user drags a selected fields in to one of the source input data model field
  475 + *
  476 + * @event draggable-element-controllet_content-dragged
  477 + */
  478 +
  479 + /**
  480 + * Received when the user selects one field from treeview controllet
  481 + *
  482 + * @event treeview-controllet-fileds-selected
  483 + */
  484 +
  485 + /**
  486 + * Received when the user drags a selected fields in to one of the source input data model field
  487 + *
  488 + * @event draggable-element-controllet_content-dragged
  489 + */
  490 +
  491 + /**
  492 + * Received when the user change text value of the selected datalet layout inputs
  493 + *
  494 + * @event text-element-controllet_content-changed
  495 + */
  496 +
  497 + /**
  498 + * Fired when the user press to finish button. At this event are attached all information about the visualization currently created
  499 + *
  500 + * @event data-sevc-controllet.dataletCreated
  501 + */
  502 +
  503 + listeners : {
  504 + 'items-slider-controllet_item-selected' : '_dataletSelected',
  505 + 'draggable-element-controllet_content-dragged' : '_fieldsMapped',
  506 + 'treeview-controllet_fileds-selected' : '_fieldsSelected',
  507 + 'text-element-controllet_content-changed' : '_textElementChanged'
  508 + },
  509 +
  510 + properties : {
  511 +
  512 + entryAnimation : {
  513 + type : String,
  514 + value : ""
  515 + },
  516 +
  517 + exitAnimation : {
  518 + type : String,
  519 + value : ""
  520 + },
  521 +
  522 + selected : {
  523 + type : Number,
  524 + value : 0
  525 + },
  526 +
  527 + /**
  528 + * It represents the data url from CKAN api
  529 + *
  530 + * @attribute dataUrl
  531 + * @type string
  532 + * @default 'null'
  533 + */
  534 + dataUrl : {
  535 + type : String,
  536 + value : "",
  537 + observer : '_dataUrlChanged'
  538 + },
  539 + /**
  540 + * It represents the DEEP url to get information about the datalets
  541 + *
  542 + * @attribute deepUrl
  543 + * @type string
  544 + * @default 'null'
  545 + */
  546 + deepUrl : {
  547 + type : String,
  548 + value : ""
  549 + },
  550 + /**
  551 + * It's used to store the list of datalets returned from DEEP
  552 + *
  553 + * @attribute datalets_list
  554 + * @type Array
  555 + * @default empty
  556 + */
  557 + datalets_list : {
  558 + type : Array ,
  559 + value : []
  560 + },
  561 + /**
  562 + * It's used to store the selected datalet. It will be set when the controllet get the event of selection by item slider (items-slider-controllet_item-selected)
  563 + *
  564 + * @attribute selected_datalet
  565 + * @type String
  566 + * @default ''
  567 + */
  568 + selected_datalet : {
  569 + type : String,
  570 + value : ""
  571 + },
  572 + /**
  573 + * It's used to store the list of selected fields by user
  574 + *
  575 + * @attribute selected_fields
  576 + * @type Array
  577 + * @default empty
  578 + */
  579 + selected_fields : {
  580 + type : Array,
  581 + value : []
  582 + },
  583 + /**
  584 + * It's used to store the params to give to datalet. This kind of params will not processed by selection step
  585 + *
  586 + * @attribute params_fields
  587 + * @type Object
  588 + * @default empty
  589 + */
  590 + params_fields:{
  591 + type: Object,
  592 + value: {}
  593 + },
  594 + /**
  595 + * It's used to store the tab index in the first pass
  596 + *
  597 + * @attribute DatasourceTabSelected
  598 + * @type Number
  599 + * @default 0
  600 + */
  601 + DatasourceTabSelected : {
  602 + type : Number,
  603 + value : 0
  604 + },
  605 + /**
  606 + * It's used to store the datasets to show in the contexual menu
  607 + *
  608 + * @attribute datasets
  609 + * @type Array
  610 + * @default empty
  611 + */
  612 + datasets :
  613 + {
  614 + type : Array,
  615 + value : []
  616 + }
  617 + },
  618 + /**
  619 + * It is called after the element’s template has been stamped and all elements inside the element’s local DOM have been configured (with values bound from parents, deserialized attributes, or else default values) and had their ready method called.
  620 + * In this phase the scrollbar will be initialized
  621 + *
  622 + * @method handleResponseData
  623 + *
  624 + * @param {Event} e
  625 + */
  626 +
  627 + ready : function(){
  628 +
  629 + $(this.$.fields_placeholder).perfectScrollbar();
  630 + $(this.$.selected_fields_main_container).perfectScrollbar();
  631 + $(this.$.idm_fields_main_container).perfectScrollbar();
  632 + $(this.$.idm_layout_main_container).perfectScrollbar();
  633 + $(this.$.table_fields_container).perfectScrollbar();
  634 +
  635 + },
  636 +
  637 + /**
  638 + * Callback to parse the data requested when dataUrl change its value
  639 + *
  640 + * @method handleResponseData
  641 + *
  642 + * @param {Event} e
  643 + */
  644 + handleResponseData : function(e){
  645 +
  646 + this.$.fields_treeview.init(e.detail.response);
  647 +
  648 + },
  649 +
  650 + /**
  651 + * Callback to parse the components response object
  652 + *
  653 + * @method handleResponseDatalets
  654 + *
  655 + * @param {Event} e
  656 + */
  657 + handleResponseDatalets : function(e){
  658 + this.datalets_list = new Array();
  659 + for(var i=0;i < e.detail.response.length;i++){
  660 + var datalet_info = { name : e.detail.response[i].name ,
  661 + image : e.detail.response[i].url + e.detail.response[i].name + ".png"
  662 + };
  663 +
  664 + this.datalets_list.push(datalet_info);
  665 + }
  666 +
  667 + this.$.visualization_slider_area.innerHTML = '<items-slider-controllet items=\'' + JSON.stringify(this.datalets_list) + '\'' +
  668 + '\'></items-slider-controllet>';
  669 + },
  670 + /**
  671 + * Callback to dataset selection from list in the phase three. When a datalet is selected this function will build a bundle of box items, based on the datalet input data model,
  672 + * to allow user to drag the fields, from the selected fields box, and create a new visualization.
  673 + *
  674 + * @method handleSelectedDatalet
  675 + *
  676 + * @param {Event} e
  677 + */
  678 + handleSelectedDatalet : function(e){
  679 +
  680 + var response = e.detail.response;
  681 + this.$.datalet_idm_fields_container.innerHTML = "";
  682 + this.$.idm_layout_container.innerHTML = "";
  683 +
  684 + if(response.idm.inputs.input.constructor == Object) {
  685 + var input = response.idm.inputs.input;
  686 + if(input.selection == "*") {
  687 + var input_selected_fields = Polymer.dom(this.$.selected_fields_container).querySelectorAll('draggable-element-controllet');
  688 + for (var j = 0; j < input_selected_fields.length; j++) {
  689 + this.$.datalet_idm_fields_container.innerHTML += '<draggable-element-controllet is-target="true" heading="Field ' + (j + 1) + '" description="' + input.description + '" number="' + (j + 1) + '"></draggable-element-controllet><br>';
  690 + }
  691 + }
  692 + }else{
  693 + for(var i =0; i < response.idm.inputs.input.length; i++){
  694 + var input = response.idm.inputs.input[i];
  695 + this.$.datalet_idm_fields_container.innerHTML += '<draggable-element-controllet is-target="true" id="' + input.name + '" heading="' + input.name + '" description="' + input.description + '" number="' + (i + 1) + '"></draggable-element-controllet><br>';
  696 + }
  697 + }
  698 +
  699 + if(response.idm.inputs.layouts.input.constructor == Object) {
  700 + var input = response.idm.inputs.layouts.input;
  701 + this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + input.name + '" description="' + input.description + '" number="1"></text-element-controllet>';
  702 + }else{
  703 + for(var i =0; i < response.idm.inputs.layouts.input.length; i++){
  704 + var input = response.idm.inputs.layouts.input[i];
  705 + this.$.idm_layout_container.innerHTML += '<text-element-controllet heading="' + input.name + '" ' +
  706 + 'description="' + input.description + '" ' +
  707 + 'number="' + (i+1) + '">' +
  708 + '</text-element-controllet>';
  709 + }
  710 +
  711 + }
  712 +
  713 + },
  714 + /**
  715 + * Generate the datalet preview when user mapped fields. it even retrieves the value of layout inputs values.
  716 + *
  717 + * @method generateDataletPreview
  718 + */
  719 + generateDataletPreview : function(){
  720 +
  721 + var input_mapped_fields = Polymer.dom(this.$.datalet_idm_fields_container).querySelectorAll('draggable-element-controllet[is-target=true]');
  722 + this.selected_fields = Array();
  723 +
  724 + for (var i = 0; i < input_mapped_fields.length; i++) {
  725 + if (input_mapped_fields[i].value != "") {
  726 + this.selected_fields.push(input_mapped_fields[i].value);
  727 + }
  728 + }
  729 +
  730 + var input_layouts_fields = Polymer.dom(this.$.idm_layout_container).querySelectorAll('text-element-controllet');
  731 + this.params_fields = {'data-url' : this.dataUrl};
  732 +
  733 + for (var i = 0; i < input_layouts_fields.length; i++) {
  734 + if (input_layouts_fields[i].value != "") {
  735 + this.params_fields[input_layouts_fields[i].heading] = input_layouts_fields[i].value;
  736 + }
  737 + }
  738 +
  739 +
  740 + var datalet_params ={
  741 + component : this.selected_datalet,
  742 + params : this.params_fields,
  743 + fields : this.selected_fields,
  744 + placeHolder : this.$.datalet_placeholder
  745 + };
  746 +
  747 +
  748 + ComponentService.deep_url = this.deepUrl;
  749 + ComponentService.getComponent(datalet_params);
  750 +
  751 + },
  752 + /**
  753 + * Validate the current pass in order to access to next one.
  754 + *
  755 + * @method validateCurrentPass
  756 + *
  757 + * @param {Number} next_selected_pass
  758 + */
  759 + validateCurrentPass : function(next_selected_pass){
  760 +
  761 + switch(next_selected_pass){
  762 + case 0:
  763 + return true;
  764 + case 1:
  765 + if(this.$.data_url.value == ""){
  766 + this.$.message.text = "You have to select a dataset to access to pass 2.";
  767 + this.$.message.show();
  768 + return false;
  769 + }else{
  770 + return true;
  771 + }
  772 +
  773 + case 2:
  774 + if(Polymer.dom(this.$.selected_fields_container).querySelectorAll('draggable-element-controllet') == 0){
  775 + this.$.message.text = "You have to select a set of fields to access to pass 3.";
  776 + this.$.message.show();
  777 + return false;
  778 + }else{
  779 + return true;
  780 + }
  781 + }
  782 +
  783 + },
  784 + /**
  785 + * Callback for manage the previous pass button
  786 + *
  787 + * @method _onPrevClick
  788 + *
  789 + */
  790 + _onPrevClick : function() {
  791 + if(!this.validateCurrentPass(this.selected === 0 ? 0 : (this.selected - 1))) return;
  792 +
  793 + this.entryAnimation = 'slide-from-left-animation';
  794 + this.exitAnimation = 'slide-right-animation';
  795 + this.selected = this.selected === 0 ? 0 : (this.selected - 1);
  796 + },
  797 + /**
  798 + * Callback to manage the next pass button
  799 + *
  800 + * @method _onNextClick
  801 + *
  802 + */
  803 + _onNextClick : function() {
  804 +
  805 + if(!this.validateCurrentPass(this.selected === 2 ? 2 : (this.selected + 1))) return;
  806 +
  807 + this.entryAnimation = 'slide-from-right-animation';
  808 + this.exitAnimation = 'slide-left-animation';
  809 + this.selected = this.selected === 2 ? 2 : (this.selected + 1);
  810 + },
  811 + /**
  812 + * Callback to manage InfoButton click to give user information about the selected dataset
  813 + *
  814 + */
  815 + _onInfoClick : function(){
  816 +
  817 + this.$.infoDialog.open();
  818 +
  819 + },
  820 + /**
  821 + * Callback related to datasource selection from select menu
  822 + *
  823 + * @method _datasourceSelected
  824 + *
  825 + * @param {Event} e
  826 + */
  827 + _datasourceSelected : function(e){
  828 +
  829 + this.$.data_url.value = this.datasets[parseInt(e.target.id)].url;
  830 + this.$.infoDialogTitle.innerHTML = this.datasets[parseInt(e.target.id)].name;
  831 + this.$.infoDialogContent.innerHTML = this.datasets[parseInt(e.target.id)].description;
  832 +
  833 + },
  834 + /**
  835 + * Callback related to data url change
  836 + *
  837 + * @method _dataUrlChanged
  838 + *
  839 + * @param {Event} e
  840 + */
  841 + _dataUrlChanged : function(newValue, oldValue){
  842 + this.$.data_request.generateRequest();
  843 + },
  844 + /**
  845 + * Callback related to event 'items-slider-controllet_item-selected' fired by items-slider-controllet when the user selects a datalet
  846 + *
  847 + * @method _dataletSelected
  848 + *
  849 + * @param {Event} e
  850 + */
  851 + _dataletSelected : function(e){
  852 + this.selected_datalet = e.detail.datalet;
  853 + this.$.selected_datalet_request.url = this.deepUrl + e.detail.datalet;
  854 + this.$.selected_datalet_request.generateRequest();
  855 +
  856 + },
  857 + /**
  858 + * Callback related to event 'treeview-controllet-fileds-selected' fired by treeview-controllet when the user selects a field
  859 + *
  860 + * @method _fieldsSelected
  861 + *
  862 + * @param {Event} e
  863 + */
  864 + _fieldsSelected : function(e){
  865 +
  866 + this.$.selected_fields_container.innerHTML = "";
  867 + for(var i=0;i<e.detail.fields.length;i++) {
  868 + this.$.selected_fields_container.innerHTML += '<draggable-element-controllet identifier="' + e.detail.fields[i] +
  869 + '" label="' + e.detail.fields[i].split(",")[e.detail.fields[i].split(",").length -1] +
  870 + '"></draggable-element-controllet><br>';
  871 + }
  872 +
  873 + var place_holder = (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) ? this.$.table_component_place_holder : this.$.table_component_place_holder[Object.keys(this.$.table_component_place_holder)[0]];
  874 +
  875 + var table_params ={
  876 + component : "datatable-datalet",
  877 + params :{
  878 + 'data-url' : this.dataUrl
  879 + },
  880 + fields : e.detail.fields,
  881 + placeHolder : this.$.table_component_place_holder
  882 + };
  883 +
  884 + ComponentService.deep_url = this.deepUrl;
  885 + ComponentService.getComponent(table_params);
  886 +
  887 + },
  888 + /**
  889 + * Callback related to event 'draggable-element-controllet_content-dragged' fired by draggable-element-controllet when the user drags a selected field in to input data model field
  890 + *
  891 + * @method _fieldsMapped
  892 + *
  893 + * @param {Event} e
  894 + */
  895 + _fieldsMapped : function(e){
  896 +
  897 + this.generateDataletPreview();
  898 +
  899 + },
  900 + /**
  901 + * Callback related to event 'text-element-controllet_content-changed' fired by text-element-controllet when the user change the value of text
  902 + *
  903 + * @method _textElementChanged
  904 + *
  905 + * @param {Event} e
  906 + */
  907 + _textElementChanged : function(e){
  908 + this.generateDataletPreview();
  909 + },
  910 + /**
  911 + * Callback related to the drag operation in the dataUrl input area. It's used to delete previous value.
  912 + *
  913 + * @method _handleDatasourceDragOver
  914 + *
  915 + * @param {Event} e
  916 + */
  917 + _handleDatasourceDragOver : function(e){
  918 + this.$.data_url.value = "";
  919 + },
  920 + /**
  921 + * Callback related to the finish button.
  922 + *
  923 + * @method _onFinish
  924 + *
  925 + * @param {Event} e
  926 + */
  927 + _onFinish : function(e){
  928 +
  929 + if((this.selected_fields.length == 0) || this.selected_datalet == ""){
  930 + this.$.message.text = "You have to map the selected fields with datalets fields(by dragging) and select a datalet to export a new visualization.";
  931 + this.$.message.show();
  932 + return;
  933 + }
  934 +
  935 + var data = {
  936 + dataUrl : this.dataUrl,
  937 + params : this.params_fields,
  938 + fields : this.selected_fields,
  939 + datalet : this.selected_datalet,
  940 + staticData : JSON.stringify(this.$.datalet_placeholder.children[1].behavior.data)
  941 + }
  942 +
  943 + this.fire('data-sevc-controllet.dataletCreated', {data : data});
  944 +
  945 + }
  946 +
  947 + });
  948 +
  949 + </script>
  950 +
  951 +</dom-module>
0 \ No newline at end of file 952 \ No newline at end of file
controllets/draggable-element-controllet/draggable-element-controllet.html
@@ -166,7 +166,7 @@ Example: @@ -166,7 +166,7 @@ Example:
166 </div> 166 </div>
167 <div class="medium">{{description}}</div> 167 <div class="medium">{{description}}</div>
168 </div> 168 </div>
169 - <div id="target_dragged_identifier" class='draggable-card dd-content-target unselectable'></div> 169 + <div id="target_dragged_identifier" class='draggable-card dd-content-target unselectable'>{{label}}</div>
170 </div> 170 </div>
171 </template> 171 </template>
172 172
@@ -246,7 +246,7 @@ Example: @@ -246,7 +246,7 @@ Example:
246 */ 246 */
247 label : { 247 label : {
248 type : String, 248 type : String,
249 - value : "Label" 249 + value : undefined
250 }, 250 },
251 /** 251 /**
252 * It's the identifier associated to the source field element 252 * It's the identifier associated to the source field element
controllets/items-slider-controllet/items-slider-controllet.html
@@ -87,11 +87,6 @@ Example: @@ -87,11 +87,6 @@ Example:
87 float: left; 87 float: left;
88 top : 5%; 88 top : 5%;
89 margin : .5em; 89 margin : .5em;
90 -  
91 - /*height: 8em;  
92 - width: 7em;  
93 - min-width: 80px;  
94 - max-width: 115px;*/  
95 width: 15.5%; 90 width: 15.5%;
96 height: 70%; 91 height: 70%;
97 92
@@ -127,7 +122,7 @@ Example: @@ -127,7 +122,7 @@ Example:
127 display: inline-block;*/ 122 display: inline-block;*/
128 float: left; 123 float: left;
129 margin-top: 10%; 124 margin-top: 10%;
130 - width: 10px; 125 + width: 30px;
131 --iron-icon-height: 28px; 126 --iron-icon-height: 28px;
132 --iron-icon-width: 28px; 127 --iron-icon-width: 28px;
133 } 128 }
@@ -160,7 +155,7 @@ Example: @@ -160,7 +155,7 @@ Example:
160 155
161 <template is="dom-repeat" items="{{itemsPerPage}}" as="item" index-as="i"> 156 <template is="dom-repeat" items="{{itemsPerPage}}" as="item" index-as="i">
162 <template is="dom-if" if="{{getName(p, i) != 0}}"> 157 <template is="dom-if" if="{{getName(p, i) != 0}}">
163 - <div class='content-card' id="{{getName(p, i)}}" on-click="_cardClick"> 158 + <div class='content-card' id="{{getName(p, i)}}" page="{{p}}" on-click="_cardClick">
164 159
165 <div> 160 <div>
166 <div class="title"> 161 <div class="title">
@@ -239,6 +234,13 @@ Example: @@ -239,6 +234,13 @@ Example:
239 numItemsPerPage : { 234 numItemsPerPage : {
240 type: Number, 235 type: Number,
241 value : 4 236 value : 4
  237 + },
  238 + /**
  239 + * Presected card. You can pass the card title to preselect it.
  240 + */
  241 + selectedCard:{
  242 + type: String,
  243 + value: undefined
242 } 244 }
243 245
244 }, 246 },
@@ -300,6 +302,15 @@ Example: @@ -300,6 +302,15 @@ Example:
300 302
301 attached : function(){ 303 attached : function(){
302 this.selected = 1; 304 this.selected = 1;
  305 + if(this.selectedCard != undefined){
  306 + this.async(function(){
  307 + var card = document.getElementById(this.selectedCard);
  308 + card.className = "content-selected";
  309 + this.prevSelectedCard = card;
  310 + this.fire('items-slider-controllet_item-selected', {datalet: this.selectedCard + "-datalet"});
  311 + this.selected = card.page;
  312 + },1000);
  313 + }
303 } 314 }
304 }); 315 });
305 316
controllets/text-element-controllet/text-element-controllet.html
@@ -175,7 +175,9 @@ Example: @@ -175,7 +175,9 @@ Example:
175 */ 175 */
176 _valueChanged : function(oldvalue, newValue){ 176 _valueChanged : function(oldvalue, newValue){
177 clearTimeout (this.timer); 177 clearTimeout (this.timer);
178 - this.timer = setTimeout(this.fire('text-element-controllet_content-changed', {newValue: newValue}), 2000); 178 + //Firefox stuff
  179 + var _this = this;
  180 + this.timer = setTimeout(function(){_this.fire('text-element-controllet_content-changed', {newValue: newValue})}, 2000);
179 }, 181 },
180 /** 182 /**
181 * It returns the value in text area 183 * It returns the value in text area
controllets/tree-view-controllet/demo/index.html 0 → 100644
  1 +<html>
  2 +
  3 +<head>
  4 + <script src="../../js/jquery-1.11.2.min.js"></script>
  5 +
  6 + <script src="../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
  7 +
  8 + <link rel="import" href="../tree-view-controllet.html" />
  9 +</head>
  10 +
  11 +<body>
  12 +
  13 + <style>
  14 + #container {
  15 + width: 300px;
  16 + height: 100vh;
  17 + overflow: auto;
  18 + }
  19 + #fields {
  20 + height: 30px;
  21 + background-color: #2196F3;
  22 + }
  23 + </style>
  24 +
  25 + <p id="fields">&nbsp;</p>
  26 +
  27 + <div id="container">
  28 +
  29 + <tree-view-controllet id="tree" root-name="data" opened-path="data,records"></tree-view-controllet>
  30 +
  31 + </div>
  32 +
  33 + <script>
  34 + var tree = document.getElementById('tree');
  35 + var fields = document.getElementById('fields');
  36 +
  37 + $.ajax({
  38 + url: 'https://data.issy.com/api/records/1.0/search?dataset=liste-des-restaurants-a-issy-les-moulineaux&sort=type&facet=type&facet=terrasse',
  39 + dataType: "json",
  40 + success: function(data){
  41 + tree.setAttribute("json-data", JSON.stringify(data));
  42 + tree.init();//chrome
  43 + }
  44 + });
  45 +
  46 + tree.addEventListener("click", function () {
  47 + fields.innerHTML = tree.getFlatFields();
  48 + console.log(tree.getFlatFields());
  49 + console.log(tree.getFields());//firefox console.log does not recognize associative array?
  50 + });
  51 +
  52 + </script>
  53 +
  54 +</body>
  55 +
  56 +</html>
  57 +
  58 +<!--urls:-->
  59 +<!--url: 'http://ckan.routetopa.eu/api/action/datastore_search?resource_id=73e02092-85a1-434e-85fe-0c9a43aa9a52&limit=5',-->
  60 +<!--url: 'https://data.issy.com/api/records/1.0/search?dataset=liste-des-restaurants-a-issy-les-moulineaux&sort=type&facet=type&facet=terrasse',-->
  61 +<!--url: 'https://data.issy.com/api/records/1.0/search?dataset=flux-rss-des-offres-demplois-a-issy-les-moulineaux&sort=published&facet=published&refine.published=2015',-->
  62 +
controllets/tree-view-controllet/tree-view-controllet.html 0 → 100644
  1 +<link rel="import" href="../../bower_components/polymer/polymer.html" />
  2 +
  3 +<link rel="import" href="../../bower_components/iron-collapse/iron-collapse.html">
  4 +<link rel="import" href="../../bower_components/paper-menu/paper-menu.html">
  5 +<link rel="import" href="../../bower_components/paper-menu/paper-submenu.html">
  6 +<link rel="import" href="../../bower_components/paper-item/paper-item.html">
  7 +
  8 +<dom-module id="tree-view-controllet">
  9 +
  10 + <style is="custom-style">
  11 +
  12 + --paper-item {
  13 + }
  14 +
  15 + paper-item {
  16 + cursor: pointer;
  17 + }
  18 +
  19 + paper-item.menu-trigger {
  20 + font-weight: 700;
  21 + }
  22 +
  23 + paper-item:not(.menu-trigger).iron-selected {
  24 + background-color: #2196F3;
  25 + }
  26 +
  27 + .sublist {
  28 + padding-left: 20px;
  29 + padding-right: 20px;
  30 + }
  31 +
  32 + </style>
  33 +
  34 + <template>
  35 +
  36 + <paper-menu id="paper-tree"></paper-menu>
  37 +
  38 + </template>
  39 +
  40 + <script>
  41 + Polymer({
  42 +
  43 + is : 'tree-view-controllet',
  44 +
  45 + properties : {
  46 +
  47 + rootName : {
  48 + type : String,
  49 + value : "Data"
  50 + },
  51 +
  52 + jsonData : {
  53 + type : Object,
  54 + value : null
  55 + },
  56 +
  57 + selectedFields : {
  58 + type : Array,
  59 + value : []
  60 + },
  61 +
  62 + openedPath : {
  63 + type : String,
  64 + value : ""
  65 + }
  66 +
  67 + },
  68 +
  69 + listeners: {
  70 + 'iron-select': '_onSelect',
  71 + 'iron-deselect': '_onDeselect'
  72 + },
  73 +
  74 + ready : function() {
  75 + if(this.jsonData)
  76 + this.init();
  77 + },
  78 +
  79 + init : function() {
  80 + var tree = document.getElementById('paper-tree');
  81 + this.injectBoundHTML(createTree(this.rootName, this.jsonData), tree);
  82 + this.openPath();
  83 + },
  84 +
  85 + injectBoundHTML : function(html, element) {
  86 + var template = document.createElement('template');
  87 + template.innerHTML = html;
  88 + var fragment = this.instanceTemplate(template);
  89 + if (element) {
  90 + element.textContent = '';
  91 + element.appendChild(fragment);
  92 + }
  93 + return fragment;
  94 + },
  95 +
  96 + openPath : function() {
  97 + var openedPath;
  98 +
  99 + if (this.openedPath == "")
  100 + openedPath = this.rootName;
  101 + else
  102 + openedPath = this.openedPath;
  103 +
  104 + var nodes = openedPath.split(",");
  105 +
  106 + openedPath = "";
  107 +
  108 + while(nodes.length != 0) {
  109 + openedPath += nodes.splice(0,1);
  110 + var menu = document.getElementById(openedPath);
  111 + var submenu = menu.parentNode.parentNode;
  112 + submenu.setAttribute("opened", "true");
  113 + openedPath += ",";
  114 + }
  115 + },
  116 +
  117 + _onSelect : function(e) {
  118 + //this.updateSelectedFields(e);
  119 + this.fire('treeview-controllet_fileds-selected', {fields : this.getFlatFields()});
  120 +
  121 + },
  122 +
  123 + _onDeselect : function(e) {
  124 + this.updateSelectedFields(e);
  125 + this.fire('treeview-controllet_fileds-selected', {fields : this.getFlatFields()});
  126 + },
  127 +
  128 + updateSelectedFields : function(e) {
  129 + var menuId = e.target.id;
  130 + var selectedIds = [];
  131 +
  132 + var selectedItems = (e.target).selectedItems;
  133 + for(var item in selectedItems){
  134 + var id = selectedItems[item].id;
  135 + if(id != "")//submenu
  136 + selectedIds.push(id);
  137 + }
  138 +
  139 + if(selectedIds.length)
  140 + this.selectedFields[menuId] = selectedIds;
  141 + else
  142 + delete this.selectedFields[menuId];
  143 + },
  144 +
  145 + getFields : function() {
  146 + return this.selectedFields;
  147 + },
  148 +
  149 + getFlatFields : function() {
  150 + var fields = [];
  151 +
  152 + for(var A in this.selectedFields)
  153 + for(var e in this.selectedFields[A])
  154 + fields.push(this.selectedFields[A][e].replace(this.rootName + ",",""));
  155 +
  156 + return fields;
  157 + }
  158 +
  159 + });
  160 +
  161 + </script>
  162 +
  163 + <script>
  164 +
  165 + function createTree(nodeName, node){
  166 + var html = "";
  167 + if(node.constructor == Object){
  168 + var list = new Array();
  169 + for(var child in node)
  170 + list.push(createTree(nodeName+","+child, node[child]));
  171 + html = paper_submenu(nodeName, list);
  172 + }
  173 + else if (node.constructor == Array){
  174 + var list = new Array();
  175 + if(node[0].constructor == Object){
  176 + for(var child in node[0])
  177 + list.push(createTree(nodeName+","+child, node[0][child]));
  178 + html = paper_submenu(nodeName, list);
  179 + }
  180 + else{
  181 + html = nodeName;
  182 + }
  183 + }
  184 + else{
  185 + html = nodeName;
  186 + }
  187 + return html;
  188 + }
  189 +
  190 + function paper_submenu(str, list){
  191 + var submenu = "<paper-submenu>";
  192 +
  193 + submenu += "<paper-item class=\"menu-trigger\">"+getName(str)+"</paper-item>" + "<paper-menu id=\""+str+"\" class=\"menu-content sublist\" multi>";
  194 +
  195 + for(var i in list){
  196 + if(list[i].indexOf("paper-submenu") != -1)
  197 + submenu += list[i];
  198 + else
  199 + submenu += paper_item(list[i]);
  200 + }
  201 +
  202 + submenu += "</paper-menu>" + "</paper-submenu>";
  203 +
  204 + return submenu;
  205 + }
  206 +
  207 + function paper_item(str){
  208 + return "<paper-item id=\""+str+"\">"+getName(str)+"</paper-item>";
  209 + }
  210 +
  211 + function getName(str){
  212 + str = str.split(",");
  213 + return str[str.length-1];
  214 + }
  215 +
  216 + </script>
  217 +
  218 +</dom-module>
0 \ No newline at end of file 219 \ No newline at end of file
controllets/treeview-controllet/treeview-controllet.html
@@ -244,6 +244,13 @@ Example: @@ -244,6 +244,13 @@ Example:
244 fieldsMap : { 244 fieldsMap : {
245 type : Map, 245 type : Map,
246 value : null 246 value : null
  247 + },
  248 + /**
  249 + * Array of pre-selected fields. it's used to open the treeview with pre-selected checkbox checked
  250 + */
  251 + selectedFields:{
  252 + type: Array,
  253 + value: undefined
247 } 254 }
248 255
249 }, 256 },
@@ -276,6 +283,15 @@ Example: @@ -276,6 +283,15 @@ Example:
276 283
277 }, 284 },
278 /** 285 /**
  286 + * check if fields is in preselection list
  287 + */
  288 + checkIsFieldsIsSelected : function(field){
  289 + if(this.selectedFields == undefined) return false;
  290 + for(var i = 0; i < this.selectedFields.length; i++)
  291 + if(field.replace("root,","") == this.selectedFields[i]) return true;
  292 + return false;
  293 + },
  294 + /**
279 * Create the checkbox for current leaf node field. 295 * Create the checkbox for current leaf node field.
280 * 296 *
281 */ 297 */
@@ -283,7 +299,7 @@ Example: @@ -283,7 +299,7 @@ Example:
283 299
284 return '<li class="list__item">' + 300 return '<li class="list__item">' +
285 '<div class="check-awesome">' + 301 '<div class="check-awesome">' +
286 - '<input class="checkbox" type="checkbox" id="'+ id + '">' + 302 + '<input class="checkbox" type="checkbox" id="'+ id + '"' + ((this.checkIsFieldsIsSelected(id)) ? 'checked' : '') + '>' +
287 '<label for="'+ id + '" style="padding-left:10px;">' + 303 '<label for="'+ id + '" style="padding-left:10px;">' +
288 '<span></span>' + 304 '<span></span>' +
289 '<span class="check"></span>' + 305 '<span class="check"></span>' +
@@ -340,7 +356,8 @@ Example: @@ -340,7 +356,8 @@ Example:
340 * to work with async object request. 356 * to work with async object request.
341 * 357 *
342 */ 358 */
343 - init : function(data){ 359 + init : function(data, preselection){
  360 + this.selectedFields = preselection;
344 //crete root node and insert it in to shadow dom 361 //crete root node and insert it in to shadow dom
345 var mainPanel = this.createFieldsContainer("root", "Data fields"); 362 var mainPanel = this.createFieldsContainer("root", "Data fields");
346 //MATERIAL CHECKBOX UL 363 //MATERIAL CHECKBOX UL
@@ -353,6 +370,8 @@ Example: @@ -353,6 +370,8 @@ Example:
353 //call recursive analyze function for current json to get all fields user can select 370 //call recursive analyze function for current json to get all fields user can select
354 this.analyzeObject(new Array("root"), null, data); 371 this.analyzeObject(new Array("root"), null, data);
355 372
  373 + if(this.selectedFields != undefined) this.fireSelectedFields();
  374 +
356 }, 375 },
357 /** 376 /**
358 * When a user click on a checkbox it retrieves all checked fields and fire an event with this information. 377 * When a user click on a checkbox it retrieves all checked fields and fire an event with this information.
datalets/highcharts-datalet/highcharts-datalet.html
@@ -113,6 +113,8 @@ Example : @@ -113,6 +113,8 @@ Example :
113 */ 113 */
114 transformData: function () { 114 transformData: function () {
115 115
  116 + if(this.data.length == 0) return;
  117 +
116 this.properties.categories.value = this.data[0].data; 118 this.properties.categories.value = this.data[0].data;
117 119
118 for (var i = 1; i < this.data.length; i++) 120 for (var i = 1; i < this.data.length; i++)