Source: main.js

const selectElement = document.querySelector('#chart-type');
const selectedNameElement = document.querySelector('#selected-chart-type');
const resizer = document.querySelector(".resizer"), sidebar = document.querySelector(".sidebar");
const handle = document.querySelector('.ui-resizable-s');
const inputfield = document.querySelector('#ember29');
const editor = document.querySelector('.ace-editor-container textarea');
const content = document.querySelector('.content');
const twoChart_resizer = document.querySelector('.twoChart-resizer');


let colors = [
  "red", 
  "blue", 
  "teal", 
  "navy", 
  "maroon", 
  "purple", 
  "fuchsia", 
  "indigo", 
  "black", 
  "gray", 
  "silver", 
  "olive", 
  "lime", 
  "green", 
  "aqua", 
  "teal", 
  "navy", 
  "purple", 
  "fuchsia", 
  "indigo"
];
let curr_color = "#325296";
let curr_dataset = null;
let view = null;
let curr_strokeWidth = 3;
let curr_projection = false;


const divObservers = {};


    function debounce(func, wait) {
      let timeout;
      return function (...args) {
        const context = this;
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
      };
    }
    
    /**
     * This function takes an object as an parameter and parses it to get the necessary parameters such as size and input data, 
     * which are then passed to the appropriate rendering functions such as changeToLineChart() or changeToScatterPlot(). 
     * The function also uses the Observer API to monitor whether the size of the div elements in which the charts are rendered changes. 
     * If a change is detected, the function will re-render the charts with the updated size.
     * 
     * @param {object} willRenderObj Parameter format{ main_chart: {name:"main-chart",type: bar-chart, dataset: []}
        }
     */
    function graphSizeControl(willRenderObj) {

      Object.values(willRenderObj).forEach(obj => {
        const div = document.getElementById(obj.name);
        if (divObservers.hasOwnProperty(div.id)) {
          divObservers[div.id].disconnect();
        }
      });

      Object.values(willRenderObj).forEach(obj => {
        const div = document.getElementById(obj.name);
        const resizeObserver = new ResizeObserver(
          debounce(
          entries => {
            for (const entry of entries){
              if (entry.contentBoxSize){
                // const entry = entries[0];
                const type = obj.type;

                  var width = div.clientWidth -30 ;
                  var height = div.clientHeight;
                  console.log("Dectet size change:");
                  if (type === "bar-chart") {
                    changeToBarChart(obj.dataset, div.id, width, height);
                    console.log("changeToBarChart---size controal",width);
                  } else if (type === "line-chart") {
                    changeToLineChart(obj.dataset, div.id , width, height);
                    console.log("changeToLineChart -- size control",width,"height:",height);
                  }else if (type === "scatter-plot-detailView") {
                    changeToScatterPlot(obj.dataset, div.id , width, height);
                    console.log("changeToScatterPlot -- size control",width,height);
                  }else if (type === "line-chart-detailView") {
                    changeToLineChart_Detail_View(obj.dataset, div.id , width, height);
                    console.log("changeToLineChart_Detail_View -- size control",width);
                  }
              }
            }
            
            
          }
          ,100)
          );
          divObservers[div.id] = resizeObserver;
          resizeObserver.observe(div,{ box : 'border-box' });
      });
    }

    /**
     * This function is responsible for creating a color control panel for the line chart. 
     * It determines the number of datasets to be displayed on the chart and creates a corresponding color control for each one.
     * Users can click on the colored circles to open a color picker to change the color of each line. 
     * This function gets called when a line chart is rendered.
     */
    function controlLineColor(){
      const datasetCount = [...new Set(curr_dataset.map(item => item.c))].length;
      document.getElementById("linechart-control-color").innerHTML = '';   //avoid overlapping with the old content.
      for (let i = 0; i < datasetCount; i++) {
        const div = document.createElement('div');
        div.classList.add('dataset-' + i);
        div.style.backgroundColor = '#e8e7e1';
        div.style.padding = '10px';
        div.style.marginBottom = '5px';

        div.style.display = 'flex';           
        div.style.alignItems = 'center';
        div.style.justifyContent = 'left';
        div.style.borderRadius = '10px';

        const circle = document.createElement('div');
        circle.style.backgroundColor = colors[i];
        circle.classList.add('circle');
        circle.onclick = toggleColorPicker;

        const colorPicker = document.createElement('input');
        colorPicker.type = 'color';
        colorPicker.classList.add('color-picker');
        colorPicker.onchange = setColor;
      
        const lineLabel = document.createElement('span'); // Added span element
        lineLabel.textContent = `Line-${i}`; // Set the text content to "line-?"
        lineLabel.style.marginLeft = '10px';

        circle.appendChild(colorPicker);
        div.appendChild(circle);
        div.appendChild(lineLabel);
        
        document.getElementById("linechart-control-color").appendChild(div);
      }

      function toggleColorPicker(event) {
        const circle = event.currentTarget;
        const colorPicker = circle.querySelector('.color-picker');
        colorPicker.click();
      }

      function setColor(event) {
        const colorPicker = event.target;
        const circle = colorPicker.parentElement;
        const datasetDiv = circle.parentElement;
        circle.style.backgroundColor = colorPicker.value;
        
        const parentDiv = document.getElementById('linechart-control-color');
        const index = Array.prototype.indexOf.call(parentDiv.children, datasetDiv);
        colors[index] = colorPicker.value;
        
        
        view.signal('colors',colors.slice());
        view.runAsync();
      }
    }

    /**
     * This function is responsible for creating a color control panel for the bar chart. 
     * It creates a color picker element and sets up an event listener for it. 
     * When the user clicks on the color box, the color picker opens, allowing the user to select a color for the bar chart. 
     * This function gets called when a bar chart is rendered.
     */
    function controlBarChartColor(){
      const color_box_div = document.getElementById('color-box');
      const color_box_div_colorPicker = document.getElementById('colorPicker-barchart');
      // Add a change event listener to the colorPicker element
      color_box_div_colorPicker.addEventListener('change', () => {
        // Get the current value of the colorPicker element
        const color = color_box_div_colorPicker.value;
        color_box_div.style.backgroundColor = color;
      });

      // Add a click event listener to the div
      color_box_div.addEventListener('click', () => {
        color_box_div_colorPicker.click();
      });
    }

    /**
     * This function is used to render line charts controlled by the two Vega View APIs.
     * They parse the data passed to them and use Vega chart specifications defined in JSON files fetched using the Fetch API, 
     * and it also sets various values for the charts such as axis labels, colors, stroke widths, and chart size.
     * 
     * @param {object} myData User's input data
     * @param {string} willRenderDivId The ID of the DOM element where the chart will be rendered.
     * @param {number} width Viewable width of an element in pixels, including padding, but not the border, scrollbar or margin.
     * @param {number} height Viewable height of an element in pixels, including padding, but not the border, scrollbar or margin.
     */
    function changeToLineChart(myData,willRenderDivId,width,height){
      let renderedDiv;
      if(willRenderDivId === "main-chart"){
        renderedDiv = "#main-chart"
      }else if(willRenderDivId === "projection-chart"){
        renderedDiv = "#projection-chart"
      }
      
      
      fetch('./JSON/lineChart.json')
      .then(res => res.json())
      .then(spec => render(spec))
      .catch(err => console.error(err));

      function render(spec) {
          view = new vega.View(vega.parse(spec), {
          renderer:  'svg',  // renderer (canvas or svg)
          container: renderedDiv,   // parent DOM container
          hover:     true 
          })
          .insert("chartData", myData)
          let xscale = Object.keys(myData[0])[0];
          let yscale = Object.keys(myData[0])[1];
          // let str = xscale.toString();
          view.signal('xAxis',xscale);
          view.signal('yAxis',yscale);
          view.signal("width",width);
          view.signal("height",height);
          view.signal("graphSize",[height-30,width-35]);    //There is bug in json file, i don't why have to set -30,
          view.signal("strokeWidth",curr_strokeWidth);
          view.signal("colors",colors);
          view.runAsync();

          if(willRenderDivId === "main-chart" &&  curr_projection){
            let existedFilteredData = [];
            view.addSignalListener("detailDomain", (_, domain) => {
              if(domain != null && domain.length >= 1){   //return when user selects avavilable data, at least one element
                filteredData = filterDataByRange(myData, domain[0], domain[1]);
                if(filteredData !== null && filteredData.length >= 1 && !arraysAreEqual(existedFilteredData,filteredData)){
                  existedFilteredData = filteredData;
                  // graphSizeControl([myDiv,projectionCharts],{"main-chart": "line-chart", "projection-chart": "line-chart" },dataset);
                  let willRenderObj = {
                    projection_chart: {name:"projection-chart" , type: "line-chart", dataset: filteredData}
                  };
                  graphSizeControl(willRenderObj);
                  console.log(filteredData);
                }
              }
            });
          }
          
      }

      

    };

    /**
     * This function is used to render scatter plot using the Vega view API. 
     * They parse the data passed to them and use Vega chart specifications defined in JSON files fetched using the Fetch API, 
     * and it also sets various values for the charts such as axis labels, colors, stroke widths, and chart size.
     * 
     * @param {object} myData User's input data
     * @param {string} willRenderDivId The ID of the DOM element where the chart will be rendered.
     * @param {number} width Viewable width of an element in pixels, including padding, but not the border, scrollbar or margin.
     * @param {number} height Viewable height of an element in pixels, including padding, but not the border, scrollbar or margin.
     */
    function changeToScatterPlot(myData,willRenderDivId,width,height){
      let renderedDiv;
      if(willRenderDivId === "main-chart"){
        renderedDiv = "#main-chart"
      }else if(willRenderDivId === "projection-chart"){
        renderedDiv = "#projection-chart"
      }
      
      fetch('./JSON/scatter_plot.json')
      .then(res => res.json())
      .then(spec => render(spec))
      .catch(err => console.error(err));

      function render(spec) {
          view = new vega.View(vega.parse(spec), {
          renderer:  'svg',  // renderer (canvas or svg)
          container: renderedDiv,   // parent DOM container
          hover:     true 
          })
          .insert("chartData", myData)
          // return view.runAfter(
          //   console.log(view.signal('xAxis'))
          // )
          let xscale = Object.keys(myData[0])[0];
          let yscale = Object.keys(myData[0])[1];
          // let str = xscale.toString();
          view.signal('xAxis',xscale);
          view.signal('yAxis',yscale);
          view.signal("width",width);
          view.signal("height",height);
          view.signal("graphSize",[height,width-80]);    //There is bug in json file, i don't know why have to set -30,
          view.signal("classification","c");
          view.runAsync();

          if(willRenderDivId === "main-chart" &&  !curr_projection){// if there is only one chart show up in screen
            let existedFilteredData = [];     //Avoid rendering duplicate content.
            view.addSignalListener("detailDomainXY", (_, domain) => {
              if(domain[0] != null && domain[1] != null){   //when user selects a region with included data, 
                let filteredData = filterDataByTwoRanges(myData, domain[0], domain[1]);
                if(filteredData !== null && filteredData.length >= 1 && !arraysAreEqual(existedFilteredData,filteredData)){
                  existedFilteredData = filteredData;
                  console.log(filteredData);
                }
              }
            });
          }
      }
    };

    /**
     * This function is used to render bar charts using the Vega view API. 
     * They parse the data passed to them and use Vega chart specifications defined in JSON files fetched using the Fetch API, 
     * and it also sets various values for the charts such as axis labels, colors, stroke widths, and chart size.
     * 
     * @param {object} myData User's input data
     * @param {string} willRenderDivId The ID of the DOM element where the chart will be rendered.
     * @param {number} width Viewable width of an element in pixels, including padding, but not the border, scrollbar or margin.
     * @param {number} height Viewable height of an element in pixels, including padding, but not the border, scrollbar or margin.
     */
    function changeToBarChart(myData,willRenderDivId,width,height){
      let renderedDiv;
      if(willRenderDivId === "main-chart"){
        renderedDiv = "#main-chart"
      }else if(willRenderDivId === "projection-chart"){
        renderedDiv = "#projection-chart"
      }
      
      
      fetch('./JSON/barChart.json')
      .then(res => res.json())
      .then(spec => render(spec))
      .catch(err => console.error(err));

      function render(spec) {
          view = new vega.View(vega.parse(spec), {
          renderer:  'svg',  // renderer (canvas or svg)
          container: renderedDiv,   // parent DOM container
          hover:     true 
          })
          .insert("table", myData)
          let xscale = Object.keys(myData[0])[0];
          let yscale = Object.keys(myData[0])[1];
          view.signal('xAxis',xscale);
          view.signal('yAxis',yscale);
          view.signal("width",width);
          view.signal("height",height-20);
          view.signal("fillColor",curr_color);
          view.runAsync();
          controlBarChartColor()
      }

    };
  
    /**
     * This function is used to render line charts using the Vega view API. 
     * They parse the data passed to them and use Vega chart specifications defined in JSON files fetched using the Fetch API, 
     * and it also sets various values for the charts such as axis labels, colors, stroke widths, and chart size.
     * 
     * @param {object} myData User's input data
     * @param {string} willRenderDivId The ID of the DOM element where the chart will be rendered.
     * @param {number} width Viewable width of an element in pixels, including padding, but not the border, scrollbar or margin.
     * @param {number} height Viewable height of an element in pixels, including padding, but not the border, scrollbar or margin.
     */
    function changeToLineChart_Detail_View(myData,willRenderDivId,width,height){
      let renderedDiv;
      if(willRenderDivId === "main-chart"){
        renderedDiv = "#main-chart"
      }else if(willRenderDivId === "projection-chart"){
        renderedDiv = "#projection-chart"
      }

      fetch('./JSON/lineChart_two.json')
      .then(res => res.json())
      .then(spec => render(spec))
      .catch(err => console.error(err));

      function render(spec) {

          view = new vega.View(vega.parse(spec), {
          renderer:  'svg',  // renderer (canvas or svg)
          container: renderedDiv,   // parent DOM container
          hover:     true 
          })
          .insert("chartData", myData)
          let xscale = Object.keys(myData[0])[0];
          let yscale = Object.keys(myData[0])[1];
          view.signal('xAxis',xscale);
          view.signal('yAxis',yscale);
          view.signal('colors',colors);
          view.signal("graphSize",[height,width-30]);
          view.signal("width",width);
          view.signal("height",height);
          view.signal("strokeWidth",curr_strokeWidth);
          view.runAsync();
          controlLineColor();
          
          let existedFilteredData = []; 
          view.addSignalListener("detailDomain", (_, domain) => {
            if(domain != null && domain.length >= 1){   //return when user selects avavilable data
              filteredData = filterDataByRange(myData, domain[0], domain[1]);
              if(filteredData !== null && filteredData.length >= 1 && !arraysAreEqual(existedFilteredData,filteredData)){
                existedFilteredData = filteredData;
                console.log(filteredData);
              }
            }
          });

          console.log(view);
      }
    }

    /**
     * This function is responsible for retrieving the user's input data and preferences from the form, parsing the input data, 
     * and updating the current dataset and visualization options accordingly. 
     * It then creates an object that encapsulates the relevant information, including the selected chart type, input data, 
     * and the div element where the chart will be rendered. Finally, this object is passed as an argument to the graphSizeControl() function,
     * which calculates the appropriate dimensions for the chart and uses them to render the chart.
      *
      * @param {Object[]} dataset - The dataset for the chart.
      * @param {string} type - The type of the chart.
      * @param {string} color - The color to use for the chart.
      * @param {boolean} projection - Flag indicating whether a projection chart is needed.
      *
     */
    function updateGraph(dataset,type,color,projection){
      const myDiv = document.getElementById('main-chart');
      const projectionCharts = document.getElementById("projection-chart");
      const twoChart_resizer = document.getElementById("twoChart-resizer");
      const content = document.getElementById("content");
      console.log("updateGraph function is called");

      // if(type === "line-chart"){
      //   console.log("changeToLineChart() is called")
      //   if(Object.keys(dataset[0]).length !== 3){
      //     alert("The array format you entered cannot be converted to line chart")
      //   }else{
      //     changeToLineChart(dataset,"main-chart",curr_width,curr_height);
      //   }
      // }else if(type === "bar-chart"){
      //   console.log("changeToBarChart() is called")
      //   if(Object.keys(dataset[0]).length !== 2){
      //     alert("The array format you entered cannot be converted to Bar chart")
      //   }else{
      //     changeToBarChart(dataset);
      //   }
      // }else if(type === "multiple-line-chart"){
      //   console.log("changeToMultiLineChart() is called")
      //   if(Object.keys(dataset[0]).length !== 3){
      //     alert("The array format you entered cannot be converted to multiple line chart")
      //   }else{
      //     changeToMultiLineChart(dataset,"#main-chart",curr_width,curr_height);
      //   }
        
      // }else if(type === "area-chart"){
      //   console.log("AreaChart() is called")
      //   if(Object.keys(dataset[0]).length <= 2){
      //     alert("The array format you entered cannot be converted to multiple line chart")
      //   }else{
      //     changeToAreaChart();
      //   }
        
      // }else if(type === "multiple-line-chart-two"){
      //   console.log("multiple-line-chart-two() is called")
      //   if(Object.keys(dataset[0]).length != 3){
      //     alert("The array format you entered cannot be converted to multiple line projection chart")
      //   }else{
      //     changeToMultiLineProjection(dataset,"#main-chart");
      //   }
      // }

      if(projection){
        projectionCharts.style.display = "block";
        twoChart_resizer.style.display = "block";
        myDiv.style.height = "10%";                 //这里删除会出现无限渲染的bug
        let willRenderObj = {
          main_chart: {name:"main-chart"  , type: type, dataset: dataset},
          projection_chart: {name:"projection-chart" , type: "line-chart", dataset: dataset}
        };
        graphSizeControl(willRenderObj);
        contorlAdjacentDiv(twoChart_resizer);
      }else{
        projectionCharts.style.display = "none";
        twoChart_resizer.style.display = "none";
        let willRenderObj = {
          main_chart: {name:"main-chart"  , type: type, dataset: dataset}
        };
        graphSizeControl(willRenderObj);
      }

      if(color != ""){
        curr_color = color;
      }
      
      
    };

/**
 * Initializes a function to handle the resizing of a sidebar and content area with a draggable resizer.
 * This function has internal handlers for mousedown, mousemove, and mouseup events to control the resizing process.
 * 
 * The mousedown handler tracks the initial mouse position and sets up event listeners for mouse movement and release.
 * The mousemove handler adjusts the sidebar width based on the change in mouse position.
 * The mouseup handler removes event listeners for mouse movement and release once the resizing action is done.
 *
 * @param {HTMLElement} resizer - The HTML element used as a handle to resize the sidebar and content area.
 * @param {HTMLElement} sidebar - The HTML element representing the sidebar, which will be resized.
 * @param {HTMLElement} content - The HTML element representing the content area, which will be resized indirectly.
 *
 * @function
 * @name initResizerFn
 */
  function initResizerFn( resizer, sidebar , content) {

    // track current mouse position in x var
    var x, w, contentW;

    function rs_mousedownHandler( e ) {

      x = e.clientX;

      var sbWidth = window.getComputedStyle( sidebar ).width;
      w = parseInt( sbWidth, 10 );
      var contentWidth = window.getComputedStyle( content ).width;
      contentW = parseInt( contentWidth, 10 );

      document.addEventListener("mousemove", rs_mousemoveHandler);
      document.addEventListener("mouseup", rs_mouseupHandler);
    }

    function rs_mousemoveHandler( e ) {
      var dx = e.clientX - x;
      var cw = w + dx; // complete width
      const newLeftWidth = ((w + dx) * 100) / resizer.parentNode.getBoundingClientRect().width;;
      
      if ( newLeftWidth > 5 && newLeftWidth < 70) {
        sidebar.style.width = `${newLeftWidth}%`;
      }
    }


    function rs_mouseupHandler() {
      // remove event mousemove && mouseup
      document.removeEventListener("mouseup", rs_mouseupHandler);
      document.removeEventListener("mousemove", rs_mousemoveHandler);
    }

    

    resizer.addEventListener("mousedown", rs_mousedownHandler);

  };
  initResizerFn( resizer, sidebar , content);           
    

  /**
   * Controls the size of an input field based on mouse movement.
   *
   * This function adds event listeners to a specified handle element to allow resizing of an input field.
   * The 'mousedown' event on the handle initiates the resizing process, activating 'mousemove' and 'mouseup' events.
   * The 'mousemove' event dynamically adjusts the input field's height based on the cursor's vertical displacement.
   * The 'mouseup' event finalizes the resizing and removes the 'mousemove' and 'mouseup' event listeners.
   * The maximum height of the input field is capped at 500 pixels.
   *
   * @param {HTMLElement} inputfield - The HTML element representing the input field to be resized.
   * @param {HTMLElement} editor - The HTML element representing the editor area, which will be resized along with the input field.
   * @param {HTMLElement} handle - The HTML element used as a handle to resize the input field and editor area.
   *
   * @function
   * @name controlSizeOfInputField
   */
  function contorlSizeOfInputField(inputfield,editor,handle){

    handle.addEventListener('mousedown', function(e) {
      startY = e.clientY;
      startHeight = parseInt(getComputedStyle(inputfield).height);
      document.addEventListener('mousemove', handleResize);
      document.addEventListener('mouseup', stopResize);
    });
    function handleResize(e) {
      var diffY = e.clientY - startY;
      var newHeight = startHeight + diffY;
      if(newHeight < 500){      // set the sidebar maximum height of inpout field to 500
        editor.style.height = (newHeight) + 'px'; // adjust for padding/margin
        inputfield.style.height = newHeight + 'px';
      }
    }
    function stopResize() {
      document.removeEventListener('mousemove', handleResize);
      document.removeEventListener('mouseup', stopResize);
    }

  }
  contorlSizeOfInputField(inputfield,editor,handle);    


  //general resizer function, only available use when user resize "height"
  function contorlAdjacentDiv(resizer){
    const prevSibling = resizer.previousElementSibling;
    const nextSibling = resizer.nextElementSibling;
    resizer.addEventListener('mousedown', function(e) {
      x = e.clientX;
      y = e.clientY;
      prevSiblingHeight = prevSibling.getBoundingClientRect().height;
      console.log(prevSiblingHeight);
      document.addEventListener('mousemove', handleResize);
      document.addEventListener('mouseup', stopResize);
    });
    function handleResize(e) {
      resizer.style.cursor = 'col-resize';
      document.body.style.cursor = 'col-resize';
      prevSibling.style.userSelect = 'none';
      prevSibling.style.pointerEvents = 'none';
      nextSibling.style.userSelect = 'none';
      nextSibling.style.pointerEvents = 'none';

      const dx = e.clientX - x;
      const dy = e.clientY - y;
      const newPrevSiblingHeight = ((prevSiblingHeight + dy) * 100) / resizer.parentNode.getBoundingClientRect().height;
      if(newPrevSiblingHeight > 3 && newPrevSiblingHeight < 97){
        prevSibling.style.height = `${newPrevSiblingHeight}%`;
      }
    }
    function stopResize() {
      resizer.style.removeProperty('cursor');
      document.body.style.removeProperty('cursor');
      prevSibling.style.removeProperty('user-select');
      prevSibling.style.removeProperty('pointer-events');
      nextSibling.style.removeProperty('user-select');
      nextSibling.style.removeProperty('pointer-events');
      document.removeEventListener('mousemove', handleResize);
      document.removeEventListener('mouseup', stopResize);
    }
  }      

/**
 * Sets up an event listener for a form submission.
 * Prevents the default form submission action and extracts the form data.
 * The data is then processed and used to update a graph.
 * Alerts the user if the input format is invalid.
 * 
 * @listens submit - The event that triggers the function.
 * @event 
 *
 * @param {Event} event - The submit event object.
 * @returns {undefined}
 *
 * @throws {SyntaxError} If JSON.parse fails to parse the input data.
 *
 * @property {FormData} formData - The form's data, extracted using the FormData interface.
 * @property {Array} data - The parsed input data, expected to be an array of objects.
 * @property {string} type - The type of chart to be generated.
 * @property {string} stroke - The stroke input from the form.
 * @property {string} color - The color input for the bar chart from the form.
 * @property {boolean} projection - The projection status, converted to boolean.
 */
const form = document.querySelector('#my-form');
form.addEventListener('submit', function(event) {
  event.preventDefault(); // prevent the default form submission behavior
  
  // Do something with the form data, such as sending it to a server
  const formData = new FormData(form);
  
  var data;
  try {
    data = JSON.parse(formData.get('myInput'));
  } catch (error) {
    alert("Invalid input format, please enter the text as following format:            [{'x': '3', 'y': 21},{'x': '5', 'y': 32}]     ");
  }

  curr_dataset = data;
  const type = formData.get('chart-type');
  // const min = formData.get('domain-min');
  // const max = formData.get('domain-max');
  // const color = formData.get('color-input');
  const stroke = formData.get('stroke-input');
  curr_strokeWidth = stroke;
  const color = formData.get("bar-chart-color");
  const projection = formData.get("project");
  curr_projection = Boolean(projection);
  console.log("submit",curr_projection);
  updateGraph(data,type,color,curr_projection);
  
});


/**
 * Sets up a 'change' event listener for a chart type selector.
 *
 * When the chart type selector's value changes, this listener checks the new value and adjusts
 * the display properties of the bar chart color selector, step selector, and line chart color selector.
 * Different chart types require different selectors to be visible.
 *
 * @listens change - The event that triggers the function.
 * @event
 *
 * @property {HTMLElement} chartTypeSelect - The HTML select element for choosing the chart type.
 * @property {HTMLElement} colorSelect - The HTML element representing the barchart color selector, which is shown or hidden based on the chart type.
 * @property {HTMLElement} stepSelect - The HTML element representing the step selector, which is shown or hidden based on the chart type.
 * @property {HTMLElement} lineChartColorSelect - The HTML element representing the line chart color selector, which is shown or hidden based on the chart type.
 */
const chartTypeSelect = document.getElementById('chart-type');
const colorSelect = document.getElementById('color-change');
const stepSelect = document.getElementById('step-change');
const lineChartColorSelect = document.getElementById('linechart-control-color');

chartTypeSelect.addEventListener('change', function() {
  const selectedOptionValue = this.value;
  
  if (selectedOptionValue === 'bar-chart') {
    colorSelect.style.display = "block";      // color seletor for barchart
    stepSelect.style.display = "none";        // line width for linechart
    lineChartColorSelect.style.display = "none";    // color seletor for linechart
  }else if (selectedOptionValue === 'line-chart' || selectedOptionValue === 'line-chart-detailView') {
    colorSelect.style.display = "none";
    stepSelect.style.display = "block";
    lineChartColorSelect.style.display = "block";
  }else if(selectedOptionValue === 'scatter-plot-detailView'){
    colorSelect.style.display = "none";
    stepSelect.style.display = "none";
    lineChartColorSelect.style.display = "none";
  }else{
    colorSelect.style.display = "none";
    colorSelect.style.display = "none";
    stepSelect.style.display = "none";
  }
});