Skip to content

Commit

Permalink
add built in window resize handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Spacarar committed Jan 11, 2022
1 parent a4ab07e commit 69ed16d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
20 changes: 19 additions & 1 deletion src/components/dc-bar-chart/dc-bar-chart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ export default {
data() {
return {
scaleChart: null,
top: 0
top: 0,
hasReplacedRenderFunc: false
}
},
methods: {
createChart() {
this.hasReplacedRenderFunc = false
let { elastic, scrollable, minScrollable, scrollHeight, groupAll, valueAccessor, label, filterFunction, mouseZoom, barPadding, barGap, outerBarPadding } =
this.computedOptions
this.$options.dimension = this.createDimension()
Expand Down Expand Up @@ -185,6 +187,22 @@ export default {
render() {
this.$super(BaseChartMixin).render()
if (this.canScroll) {
if (!this.hasReplacedRenderFunc) {
// Calling `dc.renderAll()` messed up mouse zooming with this chart
// so this fixes things when using the window resize handler which calls dc.renderAll() to resize the charts
// rewriting this function without `this._configureMouseZoom()` seems to work?
// http://dc-js.github.io/dc.js/docs/html/base_coordinate-grid-mixin.js.html#sunlight-1-line-1150
// https://github.com/dc-js/dc.js/issues/1857
this.chart._doRender = function () {
this.resetSvg();
this._preprocessData();
this._generateG();
this._generateClipPath();
this._drawChart(true);
return this
}
this.hasReplacedRenderFunc = true
}
this.scaleChart?.render()
const maxEnd = Math.floor(this.top / Math.min(8, Math.ceil(this.top / 12)))
this.chart.focus([-1, maxEnd])
Expand Down
7 changes: 5 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import { DcPlugin, dc, d3, crossfilter } from './plugins/dc.plugin.js'
import { DcBarChart, DcChecklist, DcCompositeLineChart, DcDateChart, DcPieChart, DcRowChart, DcStackedBarChart } from './components'

const defaultOptions = {
registerComponents: true // Vue.component(everything) by default? will use dc-chart-name for prefixes
// defaultColors: for dc plugin, array of string colors (or I think there is a function definition as well)
registerComponents: true, // Vue.component(everything) by default? will use dc-chart-name for prefixes
// defaultColors: for dc.defaultOptions.defaultColors
// useWindowResize: window.addEventListener(resize => dc.renderAll())
// resizeTimeout how long to wait before calling the renderAll. prevents glitchy re-rendering if lots of resize events fire
}

const VueDc = {
Expand All @@ -25,6 +27,7 @@ const VueDc = {
}

// register $dc, $d3, $crossfilter
// also set up window resize watcher if specified
Vue.use(DcPlugin, options)

// register out of the box components
Expand Down
5 changes: 3 additions & 2 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Vue from 'vue'
import App from './App.vue'
import dcPlugin from './plugins/dc.plugin'
import { DcPlugin } from './plugins/dc.plugin'

import router from './router'

Vue.config.productionTip = false
Expand All @@ -17,7 +18,7 @@ Vue.prototype.$super = function (options) {
})
}

Vue.use(dcPlugin)
Vue.use(DcPlugin)

new Vue({
router,
Expand Down
26 changes: 24 additions & 2 deletions src/plugins/dc.plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,43 @@ require('dc/dist/style/dc.min.css')

dc.AxisChart = AxisChart

const defaultOptions = {
// defaultColors: string[] of colors for ordinal charts
useWindowResize: true, // on window resize, resize the charts to best fit their space
resizeTimeout: 100 // wait at least this many ms to resize the charts (prevents glitching when slowly resizing the window)
}

/**
* import DcPlugin from 'this.file'
* Vue.use(DcPlugin)
*
* binds dc, d3, and crossfilter to vue via $dc, $d3, $crossfilter
*/
const DcPlugin = {
install(Vue, options) {
install(Vue, _options) {
const options = Object.assign({}, defaultOptions, _options)
if (options?.defaultColors) {
dc.config.defaultColors = options.defaultColors
dc.config.defaultColors(options.defaultColors)
}

Vue.prototype.$dc = dc
Vue.prototype.$d3 = d3
Vue.prototype.$crossfilter = crossfilter

if (options.useWindowResize) {
let resizeTimeout = null
// I don't think there's really any way for us to know when/how to destroy this, so I'm assuming vue will figure it out
// most likely this is only destroyed when you leave the page and everything is destroyed anyway
window.addEventListener('resize', () => {
if (resizeTimeout) {
clearTimeout(resizeTimeout)
}
resizeTimeout = setTimeout(() => {
dc.renderAll()
resizeTimeout = null
}, options.resizeTimeout)
})
}
}
}

Expand Down

0 comments on commit 69ed16d

Please sign in to comment.