0

Based on this question I made up a chart. There are two texts inputs where there can be introduced values which will re-generate the Y-axis based on their values.

The text inputs are one for min and one for max. There must be shown on the chart some messages if some conditions are fulfilled:

  • if it is introduced a value in the max input which is smaller than the actual min, on the top left corner of the chart it should be shown this message: "value smaller than y min"
  • if it is introduced a value in the min input which is bigger than the actual max, on the bottom left corner of the chart it should be shown this message: "value bigger than y max"
  • if there are introduced other values which are still fulfilling these conditions, the message(s) should remain on the chart
  • if there are introduced values (min < max) the message(s) should disappear

In my code it works well when there are introduced the first values for min and max that make the message(s) visible. If these values are changed but still the condition is true, they disappear (which shouldn't be). They must disappear only when min < max.

If I remove from the first two ifs the this.lineView.chart.ygrids.remove() calls it will rewrite over again the messages one over the other, there should be maximum one messages for each (min or max).

This is my code:

(which is min if there was introduced a value into the min input and it is max if it happened for max input)

updateChart(which) {
    this.lineView.chart.axis.range({max: {y: this.myChart.max}, min: {y: this.myChart.min}});

    if(this.myChart.min > this.myChart.max) {
        if (which === 'max'){
            this.lineView.chart.ygrids.remove(
                {value: this.myChart.max, text: "value smaller than y min", position: "start", class: "max-message"}
            );
            this.lineView.chart.ygrids.add(
                    {value: this.myChart.max, text: "value smaller than y min", position: "start", class: "max-message"}
                );
        }
        if (which === 'min') {
            this.lineView.chart.ygrids.remove(
                {value: this.myChart.min, text: "value bigger than y max", position: "start", class: "min-message"}
            );
            this.lineView.chart.ygrids.add(
                    {value: this.myChart.min, text: "value bigger than y max", position: "start", class: "min-message"}
                );
        }
    }
    if(this.myChart.min < this.myChart.max) {
        this.lineView.chart.ygrids.remove();
    }
}

I added translateY to the messages because otherwise they would be positioned outside the (visible) chart:

.min-message {
    transform: translateY(-40px);
}
.max-message {
    transform: translateY(40px);
}
.min-message line, .max-message line {
    display: none;
}
.min-message text, .max-message text {
    font-size: 15px;
} 

I guess that the problem comes from remove and add called one after the other.

Is it true that after removing ygrids it is not possible to add it back?

Any suggestions would be appreciated.

Leo Messi
  • 5,157
  • 14
  • 63
  • 125

1 Answers1

1

It's because adding & removal of grids is done with the transition. So, if you want add and remove grids sequentially executed, run them with some determined time gaps.

var chart = bb.generate({
  data: {
   columns: [
    ["data1", 30, 200, 100, 400, 150, 250],
    ["data2", 130, 250, 140, 200, 150, 50],
    ["data3", 100, 200, 340, 300, 250, 250],
    ["data4", 80, 230, 240, 100, 350, 150]
   ],
   type: "bar"
  },
  grid: {
   y: {
    lines: [
     {value: 100, text: 'Label 1'}
    ]
   }
  },
  transition: {
   duration: 0
  }
 });

 function toggle(remove, add) {
  setTimeout(function() {
   chart.ygrids.remove({
    value: remove, text: "value bigger than y max", position: "start", class: "min-message"
   })
  }, 0);
  
  setTimeout(function() {
   chart.ygrids.add({
    value: add, text: "value bigger than y max", position: "start", class: "min-message"
   });
  }, 100);
 }
#chart {width:400px; height:250px; }
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.min.css" />
    <script src="https://cdn.jsdelivr.net/npm/billboard.js/dist/billboard.pkgd.min.js"></script>
    <title>billboard.js</title>
</head>
<body>
<div id="chart"></div>

<button onclick="toggle(100, 300)">one</button>
<button onclick="toggle(300, 100)">two</button>
</body>
</html>
Jae Sung Park
  • 900
  • 6
  • 9