Skip to content

Commit

Permalink
Add the sticky positioning to center the origin axes
Browse files Browse the repository at this point in the history
  • Loading branch information
simone-panico authored and mauriciopoppe committed Jun 9, 2024
1 parent cb35cea commit 4220be7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
43 changes: 40 additions & 3 deletions src/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,6 @@ export class Chart extends EventEmitter.EventEmitter {
// (so that the functions don't overflow on zoom or drag)
const id = this.id
const defs = this.canvas.enter.append('defs')

defs
.append('clipPath')
.attr('id', 'function-plot-clip-' + id)
Expand Down Expand Up @@ -406,6 +405,7 @@ export class Chart extends EventEmitter.EventEmitter {
.select('.x.axis')
.attr('transform', 'translate(0,' + this.meta.height + ')')
.call(this.meta.xAxis)

this.canvas.merge(this.canvas.enter).select('.y.axis').call(this.meta.yAxis)
}

Expand Down Expand Up @@ -632,18 +632,55 @@ export class Chart extends EventEmitter.EventEmitter {
updateAxes() {
const instance = this
const canvas = instance.canvas.merge(instance.canvas.enter)

// center the axes
canvas.select('.x.axis').call(instance.meta.xAxis)

if (this.options.xAxis.position === 'sticky') {
const yMin = this.meta.yScale.domain()[0]
const yMax = this.meta.yScale.domain()[1]

const yMid = (yMax + yMin) / 2

const yScaleFactor = this.meta.height / (yMax - yMin)

let yTranslation = yScaleFactor * yMid + this.meta.height / 2
yTranslation = yTranslation < 0 ? 0 : yTranslation
yTranslation = yTranslation > this.meta.height ? this.meta.height : yTranslation

canvas.select('.x.axis').attr('transform', 'translate(0,' + yTranslation + ')')

canvas
.selectAll('.x.axis path, .x.axis line')
.attr('transform', 'translate(0,' + (this.meta.height / 2 - yTranslation + this.meta.height / 2) + ')')
}

canvas.select('.y.axis').call(instance.meta.yAxis)

// updates the style of the axes
if (this.options.yAxis.position === 'sticky') {
const xMin = this.meta.xScale.domain()[0]
const xMax = this.meta.xScale.domain()[1]

const xMid = (xMax + xMin) / 2

const xScaleFactor = this.meta.width / (xMin - xMax)

let xTranslation = xScaleFactor * xMid + this.meta.width / 2

xTranslation = xTranslation < 0 ? 0 : xTranslation
xTranslation = xTranslation > this.meta.width ? this.meta.width : xTranslation
canvas.select('.y.axis').attr('transform', 'translate(' + xTranslation + ',0)')

canvas.selectAll('.y.axis path, .y.axis line').attr('transform', 'translate(' + -xTranslation + ',0)')
}

canvas
.selectAll('.axis path, .axis line')
.attr('fill', 'none')
.attr('stroke', 'black')
.attr('shape-rendering', 'crispedges')
.attr('opacity', 0.1)
}

syncOptions() {
// update the original options yDomain and xDomain, this is done so that next calls to functionPlot()
// with the same object preserve some of the computed state
Expand Down
13 changes: 13 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ export interface FunctionPlotOptionsAxis {
* True to invert the direction of the axis
*/
invert?: boolean

/**
* The position of the axis
*
* - `sticky`: The axis will be in the center.
* - `left`: The axis will be positioned on the left side. (Only for the yAxis)
* - `bottom`: The axis will be positioned at the bottom. (Only for the xAxis)
*
* Default values:
* - `xAxis`: `bottom`
* - `yAxis`: `left`
*/
position?: 'sticky' | 'left' | 'bottom'
}

export interface FunctionPlotTip {
Expand Down

0 comments on commit 4220be7

Please sign in to comment.