Crosshair
Basic configuration
The Crosshair component is a special tooltip designed to work in an XYContainer.
When a user is interacting with the XYContainer and a crosshair is provided, the Crosshair will appear as a vertical line and render circles on the corresponding y
values in the dataset.
- React
- Angular
- Svelte
- TypeScript
import { VisXYContainer, VisLine, VisAxis, VisAxis, VisCrosshair } from '@unovis/react'
function Component(props) {
const data: DataRecord[] = props.data
const x = (d: DataRecord) => d.x
const y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
return (
<VisXYContainer data={data}>
<VisLine x={x} y={y}/>
<VisAxis type="x"/>
<VisAxis type="y"/>
<VisCrosshair/>
</VisXYContainer>
)
}
@Component({
templateUrl: 'template.html'
})
export class Component {
@Input data: DataRecord[];
x = (d: DataRecord) => d.x
y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
}
<vis-xy-container [data]="data">
<vis-line [x]="x" [y]="y"></vis-line>
<vis-axis type="x"></vis-axis>
<vis-axis type="y"></vis-axis>
<vis-crosshair></vis-crosshair>
</vis-xy-container>
<script lang='ts'>
import { VisXYContainer, VisLine, VisAxis, VisAxis, VisCrosshair } from '@unovis/svelte'
export let data: DataRecord[]
const x = (d: DataRecord) => d.x
const y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
</script>
<VisXYContainer {data}>
<VisLine {x} {y}/>
<VisAxis type="x"/>
<VisAxis type="y"/>
<VisCrosshair/>
</VisXYContainer>
import { XYContainer, Line, Axis, Crosshair } from '@unovis/ts'
import { data, DataRecord } from './data'
const x = (d: DataRecord) => d.x
const y = [
(d: DataRecord) => d.y,
(d: DataRecord) => d.y1,
(d: DataRecord) => d.y2
]
const crosshair = new Crosshair<DataRecord>({ })
const container = new XYContainer<DataRecord>(node, {
components: [new Line({ x, y })],
xAxis: new Axis({ type: "x" }),
yAxis: new Axis({ type: "y" }),
crosshair
}, data)
X and Y accessors
Like other components in you can supply x
and y
accessors to the Crosshair component to control where it appears in your container.
There's also a dedicated yStacked
property for dealing with stacked values.
By default, Crosshair automatically takes the x
, y
and yStacked
settings from XYContainer.
But as soon as you manually specify any of them, the component will expect the rest to be provided as well. For example, if you supply
the x
accessor function to your crosshair you'll also have to supply the y
or yStacked
settings depending on your chart configuration.
See the following example which moves the position of the crosshair line to the right of each bar.
const x: ((d: DataRecord) => number) = d.x + 0.5
const yStacked: ((d: DataRecord) => number)[] = [d => d.y, d => d.y1, d => d.y2]
- React
- Angular
- Svelte
- TypeScript
<VisCrosshair x={x} yStacked={yStacked}/>
<vis-crosshair [x]="x" [yStacked]="yStacked"></vis-crosshair>
<VisCrosshair {x} {yStacked}/>
const crosshair = new Crosshair<DataRecord>({ x, yStacked })
Hiding the crosshair
By default, the Crosshair component will render if the cursor is within a certain distance in pixels from a valid x
value.
You can disable this feature using the hideWhenFarFromPointer
attribute.
- React
- Angular
- Svelte
- TypeScript
<VisCrosshair hideWhenFarFromPointer={true}/>
<vis-crosshair [hideWhenFarFromPointer]="true"></vis-crosshair>
<VisCrosshair hideWhenFarFromPointer={true}/>
const crosshair = new Crosshair<DataRecord>({ hideWhenFarFromPointer: true })
hideWhenFarFromPointerDistance
Use the hideWhenFarFromPointerDistance
attribute with a length (in pixels) that represents the minimum horizontal distance the cursor must be from a datapoint before hiding.
- React
- Angular
- Svelte
- TypeScript
<VisCrosshair hideWhenFarFromPointerDistance={50}/>
<vis-crosshair [hideWhenFarFromPointerDistance]="50"></vis-crosshair>
<VisCrosshair hideWhenFarFromPointerDistance={50}/>
const crosshair = new Crosshair<DataRecord>({ hideWhenFarFromPointerDistance: 50 })
Custom Color
Provide a string
or color accessor function to the color
attribute to customize the crosshair's point color:
- React
- Angular
- Svelte
- TypeScript
function Component(props) {
const data: DataRecord[] = props.data
const color = (d: DataRecord, i: number) => ['red','green','blue'][i]
return (
<VisCrosshair color={color}/>
)
}
@Component({
template: '<vis-crosshair [color]="color"></vis-crosshair>'
})
export class Component {
@Input data: DataRecord[];
color = (d: DataRecord, i: number) => ['red','green','blue'][i]
}
<script lang='ts'>
import { VisXYContainer, VisCrosshair } from '@unovis/svelte'
export let data: DataRecord[]
const color = (d: DataRecord, i: number) => ['red','green','blue'][i]
</script>
<VisCrosshair {color}/>
const crosshair = new Crosshair<DataRecord>({
color: (d: DataRecord, i: number) => ['red','green','blue'][i]
})
Displaying Custom Content
You can render text content for your Crosshair component by providing it with a template
property and a Tooltip component within the same container.
- React
- Angular
- Svelte
- TypeScript
import { VisXYContainer, VisScatter, VisTooltip, VisAxis, VisAxis, VisCrosshair } from '@unovis/react'
function Component(props) {
const data: DataRecord[] = props.data
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
const template = (d: DataRecord) => [d.x,d.y].join(', ')
return (
<VisXYContainer data={data}>
<VisScatter x={x} y={y}/>
<VisTooltip/>
<VisAxis type="x"/>
<VisAxis type="y"/>
<VisCrosshair template={template}/>
</VisXYContainer>
)
}
@Component({
templateUrl: 'template.html'
})
export class Component {
@Input data: DataRecord[];
x = (d: DataRecord) => d.x
y = (d: DataRecord) => d.y
template = (d: DataRecord) => [d.x,d.y].join(', ')
}
<vis-xy-container [data]="data">
<vis-scatter [x]="x" [y]="y"></vis-scatter>
<vis-tooltip></vis-tooltip>
<vis-axis type="x"></vis-axis>
<vis-axis type="y"></vis-axis>
<vis-crosshair [template]="template"></vis-crosshair>
</vis-xy-container>
<script lang='ts'>
import { VisXYContainer, VisScatter, VisTooltip, VisAxis, VisAxis, VisCrosshair } from '@unovis/svelte'
export let data: DataRecord[]
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
const template = (d: DataRecord) => [d.x,d.y].join(', ')
</script>
<VisXYContainer {data}>
<VisScatter {x} {y}/>
<VisTooltip/>
<VisAxis type="x"/>
<VisAxis type="y"/>
<VisCrosshair {template}/>
</VisXYContainer>
import { XYContainer, Scatter, Tooltip, Axis, Crosshair } from '@unovis/ts'
import { data, DataRecord } from './data'
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
const crosshair = new Crosshair<DataRecord>({
template: (d: DataRecord) => [d.x,d.y].join(', ')
})
const container = new XYContainer<DataRecord>(node, {
components: [new Scatter({ x, y })],
tooltip: new Tooltip({ }),
xAxis: new Axis({ type: "x" }),
yAxis: new Axis({ type: "y" }),
crosshair
}, data)
Additional Styling: CSS Variables
The Crosshair component supports additional styling via CSS variables that you can define for your visualization container. For example:
.visualization-container-div {
--vis-crosshair-line-stroke-color: #f88080;
--vis-crosshair-circle-stroke-color: #000000;
}
All supported CSS variables and their default values
--vis-crosshair-line-stroke-color: #888;
--vis-crosshair-circle-stroke-color: #fff;
Name | Type | Description |
---|---|---|
* required property |