Search code examples
javascriptvue.jshighchartsvuejs3linechart

Highcharts - How to use chart.zooming.mouseWheel


According to the latest release (v11.1.0) change log:

Added support for mouse wheel zooming through chart.zooming.mouseWheel. This feature is embedded in the Highcharts Stock bundle, but requires an additional module file for the Highcharts bundle.

I'm building a line chart. I want to add this functionality to it but not exactly sure how.

I'm using Vue 3.

Here's my code:

<template>
  <h1 style="text-align: center">Facilities Analyst</h1>
  <highcharts class="chart" :options="lineChartOptions"></highcharts>
</template>


<script>
/* eslint-disable */
import { decode_jwt_token_payload } from '@/services/auth';
import spectrumDataAll from '../../spectrum_example.json';
import { tuple } from 'ant-design-vue/lib/_util/type';
const spectrumData = spectrumDataAll[0];

export default {
  data() {
    return {
      username: '',
      authority: '',
      lineChartOptions: {
        chart: {
          zooming: {
            enabled: true,
            mouseWheel: true,
            type: "x",
          },
          height: "50%",
          type: 'line',
          // zoomType: 'x',
          resetZoomButton: {
            position: {
              // align: 'right', // by default
              // verticalAlign: 'top', // by default
              x: 0,
              y: -30
            }
          },
          events: {
            selection: function (event) {
              console.log(Highcharts.version);
              console.log(event);
              if (event.resetSelection) {
                this.xAxis[0].update({ tickInterval: 100 });
              }
              else {
                // Retrieve the minimum and maximum x-values
                let xAxis = event.xAxis[0];
                let minX = this.xAxis[0].categories[Math.floor(xAxis.min)];
                let maxX = this.xAxis[0].categories[Math.ceil(xAxis.max)];
                const range = maxX - minX + 1;
                let newTickInterval = this.xAxis[0].tickInterval;
                if (range > 1000) newTickInterval = 100;
                else if (range > 500) newTickInterval = 50;
                else if (range > 100) newTickInterval = 10;
                else if (range > 50) newTickInterval = 5;
                else if (range > 10) newTickInterval = 2;
                else if (range > 5) newTickInterval = 1;
                console.log(newTickInterval);
                // Set the calculated tickInterval for the x-axis
                this.xAxis[0].update({
                  tickInterval: newTickInterval,
                });
              }
            },
          },
        },
        credits: false, // can add credits in bottom right
        title: {
          text: 'Spectrum',
          align: 'left',
          style: {
            fontFamily: 'Montserrat, Arial, sans-serif',
            fontSize: '1.3rem',
            fontWeight: '600',
            color: '#181819',
          },
        },
        subtitle: {
          text: 'bla bla bla',
          align: 'left',
          style: {
            fontFamily: 'Montserrat, Arial, sans-serif',
            fontSize: '0.9rem',
            fontWeight: '600',
            color: '#a3a3a3',
          },
        },

        xAxis: {
          title: {
            text: 'Frequency (Hz)'
          },
          tickInterval: 100,
          offset: 10,
          gridLineWidth: 1, // Set the width of the X grid lines
          gridLineColor: '#e6e6e6', // Set the color of the X grid lines
          categories: [],
          crosshair: {
            width: 1,
            color: 'black'
          },
          events: {
            setExtremes: function (event) {

            },
            afterSetExtremes: function (event) {

            },
          },
        },
        yAxis: {
          title: {
            text: 'Velocity (mm/s)'
          },
          crosshair: {
            width: 1,
            color: 'black'
          },
        },
        tooltip: {
          animation: false,
          useHTML: true,
          headerFormat: '<table><tr><th colspan="2">{series.name}</th></tr>',
          pointFormat:
            '<tr><td style="color: {series.color}">M(x): </td>' +
            '<td style="text-align: left">{point.category} Hz</td></tr>' +
            '<tr><td style="color: {series.color}">M(y): </td>' +
            '<td style="text-align: left">{point.y} mm/s</td></tr>',
          footerFormat: '</table>',
          valueDecimals: 2,
          positioner: function (labelWidth, labelHeight, point) {
            var tooltipX, tooltipY;

            tooltipX = this.chart.chartWidth - labelWidth - 10; // Adjust the offset if needed
            tooltipY = labelHeight + 40; // Adjust the offset if needed

            return {
              x: tooltipX,
              y: tooltipY
            };
          },
        },
        legend: {
          enabled: false // Disable legend
        },
        series: []
      }
    };
  },
  methods: {
    convertDate(dateString) {
      const regex = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})$/;
      const match = regex.exec(dateString);

      if (match) {
        const year = match[1];
        const month = match[2];
        const day = match[3];
        const hours = match[4];
        const minutes = match[5];
        const seconds = match[6];

        const formattedDate = `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`;
        return formattedDate;
      }
      return "";
    }
  },
  created() {
    const { username, authority } = decode_jwt_token_payload()
    this.username = username
    this.authority = authority
    console.log(spectrumData)
    // Insert X categories:
    this.lineChartOptions.xAxis.categories = Array.from({ length: spectrumData.CountX + 1 }, (_, i) => spectrumData.StartX + i * spectrumData.IncX);
    // Insert Y series:
    for (let i = 0; i < spectrumData.Measures.length; i++) {
      this.lineChartOptions.series.push({
        data: spectrumData.Measures[i].Values.map(v => parseInt(v)),
        // data: spectrumData.Measures[i].Values.map(v => parseInt(v)),
        name: this.convertDate(spectrumData.Measures[i].Date),
        visible: i < 1,
        marker: {
          enabled: false,
        }
      })
    }
  },
  mounted() {
  }

};
</script>

<style>
.chart {
  background-color: #fff;
  box-shadow: 3px 0.5px 10px rgba(119, 119, 119, 0.25);
  border-radius: 8px;
  padding: 10px;
  margin-left: 5%;
  width: 70%;
}
</style>


Solution

  • You need to import and initialize the mouse-wheel-zoom module:

    import Highcharts from "highcharts";
    import mouseWheelZoom from "highcharts/modules/mouse-wheel-zoom";
    import HighchartsVue from "highcharts-vue";
    
    mouseWheelZoom(Highcharts);
    

    and enable the feature through chart options:

      chart: {
        zooming: {
          mouseWheel: {
            enabled: true,
          }
        }
      }
    

    Live demo: https://codesandbox.io/s/wizardly-wright-pklxy-pklxyw

    Docs: https://github.com/highcharts/highcharts-vue#highcharts-vue