1

I want to make step chart has curved line using plotly.js. The difference between the connecting parts is felt differently depending on the size of the currently different numerical value. The thickness of the curve path is also different. And want to hide Xaxis and Yaxis divide lines. I want to make the whole chart look perfect while making it the same. Like this image.

enter image description here

<!DOCTYPE html>

<head>
  <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
  <!-- Plotly chart will be drawn inside this div -->
  <div id="plotly-div"></div>

  <body>
    <script>
      y = [0, 25, -35, -28, -10, 10, 25, 30, 35, 40, 65, 35];
      x = [0, 5, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52];
      trace = {
        line: { shape: "vh" },
        mode: "lines",
        name: "vh",
        type: "scatter",
        x: x,
        y: y,
      };
      let layout = {
        xaxis: {
          side: 'top'
        },
        showlegend: false,
        //TODO: These curves interconnect diagonal lines and horizontal lines
        shapes: [
          //Use Cubic Quadratic Curve
          {
            type: 'path',
            path: 'M 4,25 Q 4.8, 25 4.8 20',
            line: {
              color: 'black'
            },
          },
          {
            type: 'path',
            path: 'M 5.2,-30 Q 5.2, -35 5.5, -35',
            line: {
              color: 'black'
            }
          },
         

        ]
      };

      let data = [];

      for (let i = 1; i < x.length - 1; i++) {
        let _x = x.slice(i - 1, i + 1);
        // trace1 for the horizontal lines
        //TODO: horizontal lines should stop at the appropriate x and y values
        
        let bigger = y[i+1] > y[i] ? true : false
       
        let _trace1 = {
          mode: 'lines',
          x: [_x[0] + 0.5, _x[1] - 1],
          y: [y[i], y[i]],
          type: 'line+markers',
          line: {
            color: 'black',
            width: 1
          }
        };
        // trace2 for the diagonal joining lines
        //TODO: diagonal lines should cover about a percentage of the distance between the  horizontal lines. Needs corrections
        let _trace2 = {
          mode: 'lines',
          x: [x[i] - 0.2, x[i] + 0.2],
          y: bigger ? [y[i], y[i + 1] + 5] : [y[i] -5 , y[i + 1] + 5],
          type: 'line',
          line: {
            color: 'green',
            width: 1
          },
        };
        diff = y[i] - y[i - 1];
        // trace3 for the vertical lines
        //TODO: vertical lines should take into consideration correct increase or decrease
        let _trace3 = {
          mode: 'lines',
          x: [x[i - 1] + 0.5, x[i - 1] + 0.5],
          y: [1, diff],
          type: 'line',
          line: {
            color: diff > 0 ? 'black' : 'red',
            width: 5
          }
        };
        layout.shapes[2*i -2] =   {
          type: 'path',
          path: `M ${x[i]-1}, ${y[i]} Q ${x[i]-1}.8, ${y[i]} ${x[i]-1}.8 ${!bigger ? y[i]-5 : y[i]+5}`,
          line: {
            color: 'black'
          },
        }
        layout.shapes[2*i -1] =   {
          type: 'path',
          path: `M ${x[i]}.2, ${bigger ? y[i+1]-5 : y[i+1]+5} Q ${x[i]}.2, ${y[i+1]} ${x[i]}.5, ${y[i+1]}`,
          line: {
            color: 'black'
          }
        },
        
        data.push(_trace1);
        data.push(_trace2);
        data.push(_trace3);
      }

      Plotly.plot("plotly-div", {
        data: data,
        layout: layout,
      });
    </script>
  </body>

  </html>

1
  • Please trim your code to make it easier to find your problem. Follow these guidelines to create a minimal reproducible example. Commented Aug 29, 2022 at 12:22

1 Answer 1

0

Yup. I solved the issue myself. Plotly.js had solutions.

<!DOCTYPE html>

<head>
  <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
  <!-- Plotly chart will be drawn inside this div -->
  <div id="plotly-div"></div>

  <body>
    <script>
      y = [0, 25, -35, -28, -10, 10, 25, 30, 35, 40, 65, 35];
      x = [0, 5, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52];
      let shapes = [];
      let data = [];

      for (let i = 1; i < x.length - 1; i++) {
        // trace1 for the horizontal lines
        //TODO: horizontal lines should stop at the appropriate x and y values

        let bigger = y[i] > y[i - 1] ? true : false

        let _w = (Math.abs(y[i] - y[i - 1]) / 80 + 0.3)

        let _trace1 = {
          mode: 'lines',
          x: [x[i - 1], x[i] - _w],
          y: [y[i - 1], y[i - 1]],
          type: 'line+markers',
          line: {
            color: y[i - 1] < 0 ? '#EB5757' : (y[i - 1] > 50 ? '#2F80ED' : '#000000'),
            width: 1
          }
        };
        // trace2 for the diagonal joining lines
        //TODO: diagonal lines should cover about a percentage of the distance between the  horizontal lines. Needs corrections
        let _trace2 = {
          mode: 'lines',
          x: [x[i] - _w + 0.15, x[i] - 0.15],
          y: bigger ? [y[i - 1] + 1.5, y[i] - 1.5] : [y[i - 1] - 1.5, y[i] + 1.5],
          type: 'line',
          line: {
            color: y[i] < 0 || y[i - 1] < 0 ? '#EB5757' : (y[i] > 50 || y[i - 1] > 50 ? '#2F80ED ' : '#000000'),
            width: 1
          },
        };
        var diff = y[i] - y[i - 1];
        // trace3 for the vertical lines
        //TODO: vertical lines should take into consideration correct increase or decrease
        let _trace3 = {
          mode: 'lines',
          x: [x[i], x[i]],
          y: [1, diff],
          type: 'line',
          line: {
            color: diff > 0 ? '#000000' : '#EB5757',
            width: 5
          }
        };
        data.push(_trace1, _trace2, _trace3);
        shapes.push({
          type: 'path',
          path: `M ${x[i] - _w}, ${y[i - 1]} Q ${x[i] - _w + 0.1}, ${y[i - 1]} ${x[i] - _w + 0.15} ${!bigger ? y[i - 1] - 1.5 : y[i - 1] + 1.5}`,
          line: {
            color: y[i - 1] < 0 || y[i] < 0 ? '#EB5757' : (y[i] > 50 || y[i - 1] > 50 ? '#2F80ED' : '#000000'),
            width: 1
          }
        }, {
          type: 'path',
          path: `M ${x[i] - 0.15}, ${bigger ? y[i] - 1.5 : y[i] + 1.5} Q ${x[i] - 0.1}, ${y[i]} ${x[i]}, ${y[i]}`,
          line: {
            color: y[i - 1] < 0 || y[i] < 0 ? '#EB5757' : (y[i] > 50 || y[i - 1] > 50 ? '#2F80ED' : '#000000'),
            width: 1
          }
        })
      }

      layout = {
        xaxis: {
          side: 'top',
          showgrid: false,
          autotick: false,
          ticks: 'outside',
          tick0: '',
          dtick: 5,
          tickcolor: 'red',
          showline: true,
          linecolor: '#E0E0E0',
          linewidth: 1,
          tickfont: {
            size: 0,
            color: 'red',
          },
        },
        yaxis: {
          showgrid: false,
          showline: false,
          ticks: 'outside',
          tick0: 0,
          dtick: 30,
          ticklen: 4,
          tickwidth: 2,
          tickcolor: '#BDBDBD',
          automargin: false,
          tickfont: {
            family: 'Old Standard TT, serif',
            size: 12,
            color: '#828282',
          },
          zeroline: true,
          zerolinecolor: '#828282',
          zerolinewidth: 2,

        },
        showlegend: false,
        shapes: shapes,
      }

      Plotly.plot("plotly-div", {
        data: data,
        layout: layout,
      });
    </script>
  </body>

  </html>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.