Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touch events are surpressed to charts that does not have zoom added as plugin #311

Closed
AllanOricil opened this issue Jan 12, 2020 · 7 comments · Fixed by #429
Closed

Touch events are surpressed to charts that does not have zoom added as plugin #311

AllanOricil opened this issue Jan 12, 2020 · 7 comments · Fixed by #429

Comments

@AllanOricil
Copy link

I have 3 charts on my web app. After adding the plugin to a Line chart I noticed the other 2 charts started to supress any touch event. The result is that I cant scrooll down or up when I touch any area of those other two charts. I can only scroll if I touch a area that is not on the canvas of the other two charts. The code bellow is how I added the plugin. The plugin is only in the last chart component (line).

import Vue from 'vue'
import Chart from 'chart.js'
import { Bar, Doughnut, generateChart } from 'vue-chartjs'
import zoom from 'chartjs-plugin-zoom'

Chart.defaults.LineWithLine = Chart.defaults.line
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
  draw(ease) {
    Chart.controllers.line.prototype.draw.call(this, ease)

    if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
      const activePoint = this.chart.tooltip._active[0]
      const ctx = this.chart.ctx
      const x = activePoint.tooltipPosition().x
      const topY = this.chart.scales['y-axis-0'].top
      const bottomY = this.chart.scales['y-axis-0'].bottom

      const y = activePoint.tooltipPosition().y
      const leftX = this.chart.scales['x-axis-0'].left
      const rightX = this.chart.scales['x-axis-0'].right

      // draw line
      ctx.save()
      ctx.beginPath()
      ctx.moveTo(x, topY)
      ctx.lineTo(x, bottomY)
      ctx.lineWidth = 2
      ctx.strokeStyle = 'rgb(119, 122, 124)'
      ctx.setLineDash([5, 5])
      ctx.color = 'white'
      ctx.stroke()
      ctx.restore()

      // draw line
      ctx.save()
      ctx.beginPath()
      ctx.moveTo(leftX, y)
      ctx.lineTo(rightX, y)
      ctx.lineWidth = 2
      ctx.strokeStyle = 'rgb(119, 122, 124)'
      ctx.setLineDash([5, 5])
      ctx.color = 'white'
      ctx.stroke()
      ctx.restore()
    }
  }
})

const CustomLine = generateChart('custom-line', 'LineWithLine')

Vue.component('barChart', {
  extends: Bar,
  props: {
    data: {
      type: Object,
      default: () => {}
    },
    options: {
      type: Object,
      default: () => {}
    }
  },
  mounted() {
    this.renderChart(this.data, this.options)
  }
})

Vue.component('doughnutChart', {
  extends: Doughnut,
  props: {
    data: {
      type: Object,
      default: () => {}
    },
    options: {
      type: Object,
      default: () => {}
    }
  },
  mounted() {
    this.addPlugin({
      id: 'kwhWeek',
      afterDatasetDraw(chart) {
        const width = chart.chart.width
        const height = chart.chart.height
        const ctx = chart.chart.ctx

        ctx.restore()
        ctx.font = '2em Roboto'
        ctx.fillStyle = 'white'
        ctx.textBaseline = 'middle'

        const text =
          'R$ ' +
          chart.config.data.datasets[0].data
            .reduce((total, value) => total + parseFloat(value), 0)
            .toFixed(0)

        const div = document.createElement('div')
        div.innerHTML = text
        div.style.position = 'absolute'
        div.style.top = '-9999px'
        div.style.left = '-9999px'
        div.style.fontFamily = 'Roboto'
        div.style.fontWeight = 'bold'
        div.style.fontSize = '10pt' // or 'px'
        document.body.appendChild(div)
        const size = [div.offsetWidth, div.offsetHeight]
        document.body.removeChild(div)

        const textX = Math.round((width - ctx.measureText(text).width) / 2)
        const textY = height / 2 + 2 * size[1]

        ctx.fillText(text, textX, textY)
        ctx.save()
      }
    })
    this.renderChart(this.data, this.options)
  }
})

Vue.component('lineChart', {
  extends: CustomLine,
  props: {
    data: {
      type: Object,
      default: () => {}
    },
    options: {
      type: Object,
      default: () => {}
    }
  },

  mounted() {
    this.addPlugin(zoom)
    this.renderChart(this.data, this.options)
  }
})
@jledentu
Copy link
Collaborator

@AllanOricil It's quite difficult to reproduce your issue. It would be so great if you could provide a minimal example in a codepen or jsfiddle... If you can't, I'll set up myself a project with Vue, vue-chartjs and your code but it will take more time.

@AllanOricil
Copy link
Author

There are two problems.
The first one can be seen in this fiddle

http://jsfiddle.net/jyougo/sv2n4zdh/2/

Click on Enable zoom. Reduce the size of the window until the chart is covering the entire Width of the available space. After that, try to scroll down the page placing the mouse anywhere inside the Canvas. It will not let you scroll down because the scroll is being captured by the canvas. Now imagine that I have this chart expanded in the entire area of a phone. How would the user scroll down to check info that is bellow the chart canvas? He would not, because he can't scroll down. This is what is happening.

Another problem is that somehow when I apply zoom for one Chart, I cant scroll down in any other chart. Can we make a call so I can show it to you? I'm not good with jsfiddle.

@ndrake
Copy link

ndrake commented Jan 15, 2020

@AllanOricil your jsfiddle is using older versions of chart.js and the zoom plugin. I made the same mistake with my codepen on #289. Even with the latest versions of both, I am still seeing the issue you describe.

@AllanOricil
Copy link
Author

Yes. I can confirm that I'm also using the latest versions on my project. The fiddle was just to evidence the problems. I think its related to the way you implemented the hammer js.

@jledentu
Copy link
Collaborator

jledentu commented Jan 15, 2020

About the charts - without zoom enabled - capturing the touch events, I reopened #289
About the charts with zoom enabled, a solution would be to allow a modifier key (alt, ctrl...) as discussed in #308

@AllanOricil
Copy link
Author

I will test the modifier key

@jacopotediosi
Copy link
Contributor

jacopotediosi commented Feb 27, 2021

I have the same problem. I noticed chartjs-plugin-zoom adds "touch-action: none;" to the style attribute of all canvas even for charts that don't implement zoom plugin.

@kurkle kurkle linked a pull request Mar 9, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants