[Chartjs]-ChartJS – Y Axis line not drawing

1👍

not sure why option zeroLineColor works for one axis, and not the other.

but we can use an array of colors for the gridlines,
setting the first as white, and the rest as transparent.

see following working snippet…

$(document).ready(function() {

  // Colors
  const squidInk = '#232F3E'; // Background and hover circle interior
  const mermaid = '#00A4B4'; // Gridlines
  const siren = '#0099D9'; // Line and points
  const darkGrey = '#3A444F'; // Fill below line - NOTE: doesn't seem to be one of main colors
  const white = '#FFF'; // Font white - in one place to change globally (sync w CSS)
  const transparent = 'transparent';

  const mobileBreakpoint = 768;

  const isMobile = window.innerWidth <= mobileBreakpoint;

  // Helper for below tooltip generation
  const getTooltipStyles = (tooltipModel, position) => ({
    opacity: 1,
    position: 'absolute',
    left: position.left + window.pageXOffset + tooltipModel.caretX + 'px',
    top: position.top + window.pageYOffset + tooltipModel.caretY + 'px',
    fontFamily: tooltipModel._bodyFontFamily,
    fontSize: tooltipModel.bodyFontSize + 'px',
    fontStyle: tooltipModel._bodyFontStyle,
    padding: tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px',
    pointerEvents: 'none'
  });

  // Chart points (y-coords; there are 20).
  // Loosely approximates the data in the designs.
  const points = [
     4,  4,  8, 19, 22,
    25, 27, 27, 28, 30,
    32, 34, 40, 44, 46,
    48, 52, 53, 55, 57
  ];

  // The value of the data key in the Chart config.
  // Contains points in the main (only) dataset,
  // and related configuration.
  const data = {
    // Years from 1997 to 2016.
    // Hide all but first and last label on mobile
    labels: points.map((_, ind) =>
      isMobile && ![0, points.length - 1].includes(ind)
        ? ''
        : 1997 + ind
    ),
    datasets: [{
      data: points,
      fill: true,
      backgroundColor: darkGrey,
      borderColor: siren,
      borderWidth: 4,
      pointHitRadius: 20,
      pointRadius: isMobile ? 0 : 2,
      pointHoverRadius: isMobile ? 0 : 10,
      pointHoverBackgroundColor: squidInk,
      pointHoverBorderWidth: 3
    }]
  };

  // Function to replace the tooltip with custom HTML.
  // NOTE: This needs to be a function, not a const, because of how
  // `this` is bound.
  function customTooltip (tooltipModel) {
    if (isMobile) {
      return '';
    }

    // Tooltip Element
    let tooltipEl = document.getElementById('chartjs-tooltip');

    // Create element on first render
    if (!tooltipEl) {
      tooltipEl = document.createElement('div');
      tooltipEl.id = 'chartjs-tooltip';
      tooltipEl.innerHTML = '<div></div>';
      document.body.appendChild(tooltipEl);
    }

    // Hide if no tooltip
    if (tooltipModel.opacity === 0) {
      tooltipEl.style.opacity = 0;
      return;
    }

    // Set caret Position
    tooltipEl.classList.remove('above', 'below', 'no-transform');
    tooltipEl.classList.add(
      tooltipModel.yAlign
        ? tooltipModel.yAlign
        : 'no-transform'
    );

    // Set Text
    if (tooltipModel.body) {
      const titleLines = tooltipModel.title || [];
      const bodyLines = tooltipModel.body.map(bodyItem => bodyItem.lines);

      // Text for hover percentages
      const percentExternal = bodyLines[0];
      const percentSellers = 100 - percentExternal;

      // These spans are styled in the CSS
      const innerHtml = `
        <span class="percent-tooltip external">${percentExternal}%</span>
        <span class="percent-tooltip sellers">${percentSellers}%</span>
      `;

      const root = tooltipEl.querySelector('div');
      root.innerHTML = innerHtml;
    }

    // `this` will be the overall tooltip
    const position = this._chart.canvas.getBoundingClientRect();

    // Apply positional styles to the tooltip (cleaned up and put above for clarity)
    const styles = getTooltipStyles(tooltipModel, position);
    Object.keys(styles).forEach(k => tooltipEl.style[k] = styles[k]);
  };

  // High-level chart options
  const options = {
    legend: {
      display: false
    },
    tooltips: {
      enabled: false,
      custom: customTooltip // Custom tooltip func (above)
    },
    scales: {
      yAxes: [{
        ticks: {
          // Include a percentage sign in the ticks.
          // Hide zero label on mobile.
          callback: value => isMobile ? (value ? `${value}%` : '') : `${value}%`,
          fontColor: white,
          max: 100,
          stepSize: isMobile ? 50 : 25
        },
        scaleLabel: {
          display: !isMobile,
          labelString: '% OF MERCHANDISE SALES',
          fontColor: white
        },
        gridLines: {
          color: mermaid,
          zeroLineColor: white,
          zeroLineWidth: 2,
          drawBorder: false
        }
      }],
      xAxes: [{
        gridLines: {
          color: points.map((_, ind) =>
            ind === 0
              ? white
              : transparent
          ),
          lineWidth: 2
        },
        ticks: {
          fontColor: white
        }
      }]
    }
  };

  // Find the div to insert the chart into
  const ctx = document.getElementById('chart').getContext('2d');

  // And generate the chart
  const chart = new Chart(ctx, {
    type: 'line',
    data,
    options,
  });

});
.container {
  /* squidInk - matches JS */
  background-color: #232F3E;
  position: relative;
  width: 100%;
}

.section-label {
  color: white;
  font-size: 20px;
  position: absolute;
}

.section-label.upper {
  left: 100px;
  top: 60px;
}

.section-label.lower {
  right: 60px;
  bottom: 60px;
}

#chartjs-tooltip div {
  position: absolute;
  left: -10px;
  top: -10px;
  cursor: pointer;
}

#chartjs-tooltip .percent-tooltip {
  font-size: 20px;
  font-weight: bold;
  display: block;
  position: absolute;
  color: white;
}

#chartjs-tooltip span.percent-tooltip.external {
  top: -30px;
}

#chartjs-tooltip span.percent-tooltip.sellers {
  top: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<div class="container">
  <span class="section-label upper">Internal</span>
  <canvas id="chart" width="300" height="150"></canvas>
  <span class="section-label lower">External</span>
</div>

Leave a comment