I am using react Chartjs's scatter chart to plot a line chart for a set of X,Y points.
I am trying to get the X and Y points when user right clicks anywhere on the chart by passing following function to onClick.
options={
...
onClick: function(event) {
let activeElement = Ref.current.chartInstance.getElementAtEvent(
event
);
let res =
Ref.current.chartInstance.data.datasets[
activeElement[0]._datasetIndex
].data[activeElement[0]._index];
}
}
But this only works when I click on plotted line on the existing point and not when I click anywhere in the chart. If I click anywhere else other the line, returned activeElement will be empty list.
How can I get X and Y regardless of where I click in chart area?
onClick: (e) => {
const canvasPosition = Chart.helpers.getRelativePosition(e, chart);
// replace .x. and .y. with the id of your axes below
const dataX = chart.scales.x.getValueForPixel(canvasPosition.x);
const dataY = chart.scales.y.getValueForPixel(canvasPosition.y);
},
Related
I have d3 line chart with two lines full with events and made a html tooltip to show some data from these events on mousemove. Its working fine until the moment when you switch to show only one line, than the tooltip doesnt receive any data. Ive log the data and it is coming to the tooltip, but tooltip is not receiving it for some reason. Check the code bellow:
const tooltip = d3.select('.Tooltip')
.style('visibility', 'hidden')
.style('pointer-events', 'none')
function mousemove (event) {
// recover coordinate we need
const mouse = d3.pointer(event, this)
const [xm, ym] = (mouse)
const mouseWindows = d3.pointer(event, d3.select(this))
const [xmw, ymw] = (mouseWindows)
const i = d3.least(I, i => Math.hypot(xScale(X[i]) - xm, yScale(Y[i]) - ym)) // closest point
path.style('stroke-width', ([z]) => Z[i] === z ? strokeWidthHovered : strokeWidth).filter(([z]) => Z[i] === z).raise()
dot.attr('transform', `translate(${xScale(X[i])},${yScale(Y[i])})`)
// console.log(O[i]) <-- this is the data for the current selected event and its fine after
changing the line shown
tooltip
.data([O[i]])
.text(d => console.log(d)) <-- here i log what is coming from data and doesn`t return anything
.style('left', `${tooltipX(xScale(X[i]), offSetX)}px `)
.style('top', `${tipY}px`)
.style('visibility', 'visible')
.attr('class', css.tooltipEvent)
.html(d => chartConfig.options.tooltip.pointFormat(d))
When you call tooltip.data([0[i]]), d3 returns a selection of elements already associated with your data, which does not make sense for your tooltip. If you already computed the value you want to show (I assume it is O[i]), then simply set the text or the html of the tooltip:
tooltip.html(chartConfig.options.tooltip.pointFormat(O[i]);
I have a stock chart and I would like to get the value shown in the yAxis label that the crosshairs create when clicking in a plot. Essentially I want to know what the price is on the yAxis for the current location of my mouse when I click. So lets say the crosshairs yAxis label is showing 20, when I click, I want to put that 20 into a variable. So how can I "get" the crosshair's yAxis value? Thanks
const yAxis = plot.yAxis();
plot.listen('click', function (e) {
console.log(e)
//this will get the first label on the y Axis, this is 12
//I dont want the yAxis of the chart labels, I want the crosshair yAxis label
const value = yAxis.scale().ticks().get()[0];
console.log(value)
//prints 12
var value = chart.crosshair().yLabel()
//I dont know what to query to get the "value" of the label
console.log(value)
});
Yes, it is possible to get yAxis label value.
You can do so by acessing the plot's crosshair object.
//Create variable for label value
let yAxisLabelValue = 0;
//Handling click event
plot.listen("click", (e) => {
let label = plot.crosshair().yLabel();
let labelValue = label.text();
//Asigning current value to a variable
yAxisLabelValue = labelValue;
});
Feel free to try out on the playground how to interact with a crosshair object.
Hello and thank you for reading this question.
I'm struggling to deal with the onclick event on canvas with React.
I am currently building a component that has to draw bounding boxes on an image and make those boxes fire a onclick event with its coordinates and/or metadata.
I am using the following react-bounding-box component (https://www.npmjs.com/package/react-bounding-box) with a bit of customization.
The idea is that my component receive the following data :
an image
a JSON with a list of items that contains coordinates of bounding boxes and other data related to those boxes.
Once the JSON is loaded, my code iterates on the list of items and draws the bounding boxes on the image using canvas.
My component definition looks like that (I omitted useless lines of code) :
[...]
import BoundingBox from 'react-bounding-box'
[...]
export const ComicImageDrawer = (props) => {
const [boundingBoxesItems, setBoundingBoxesItems] = useState(Array<any>());
const [selectedBoxItem, setSelectedBoxItem] = useState({})
const [selectedBoxIndex, setSelectedBoxIndex] = useState<Number>(-1);
const [currentImageBoxes, setCurrentImageBoxes] = useState(Array<any>())
useEffect(() => {
[...] // loading data
}, [])
// That function is fired when a box is hovered
// param value is the index of the box
// I would like to do the same but with the `onclick` event
function onOver(param) {
[...] // don't care
}
const params = {
[...] // don't care
}
};
return (
<BoundingBox
image={currentImage}
boxes={currentImageBoxes}
options={params.options}
onSelected={onOver}
drawBox={drawBoxCustom}
drawLabel={() => {}}
/>
)
}
The redefined the component drawBox() function to add some customization. So that function definition looks like this :
function drawBoxCustom(canvas, box, color, lineWidth) {
if(!box || typeof box === 'undefined')
return null;
const ctx = canvas.getContext('2d');
const coord = box.coord ? box.coord : box;
let [x, y, width, height] = [0, 0, 0, 0]
[...] // removed useless lines of codes
ctx.lineWidth = lineWidth;
ctx.beginPath();
[...] // drawing element definition
ctx.stroke();
};
I haved tried the following stuff to make the canvas fire an onclick event but it never fires (i also tried other event like mouseover) :
// Listen for mouse moves
canvas.addEventListener('onmouseover', function (event) {
console.log('click event', event);
});
What I would like to obtain is to fire a function in my React component that looks like that. The idea is to determine which box has been clicked :
const handleCanvasClick = (event, box) => {
console.log('event', event);
console.log('box', box);
}
Any help or suggestion would be appreciated.
Thanks.
I'm trying to do a web app on React to write guitar tabs, i'm doing the tabs with SVG. I think i know how to get the coords but the problem is i don't know how to put that text tag with a value, because it doesn't have a value attribute (i think so)
my function:
// Doesn't work
// Suppose that i want to add a 2
const clicked = (evt) =>{
const { currentTarget: svg, pageX, pageY } = evt
const coords = svg.getBoundingClientRect() //<----- get the coords
const text = document.createElementNS('http://www.w3.org/2000/svg','text') //<--- create the svg
text.setAttribute('x', `$pageX - coords.x`) //<----- set the attributes X and Y with the mouse coords
text.setAttribute('y', `$pagey - coords.y`)
text.setAttribute('value', "2") //<----- It doesn't work
svg.appendChild(text)
}
heres other function, but to put circles:
//IT WORKS
clicked(evt) {
const {currentTarget: svg, pageX, pageY} = evt;
const coords = svg.getBoundingClientRect();
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
circle.setAttribute('cx', `${pageX - coords.x}`);
circle.setAttribute('cy', `${pageY - coords.y}`);
circle.setAttribute('r', '5');
svg.appendChild(circle);
}
Text is not an attribute, it's content so you want to replace
text.setAttribute('value', "2")
with
text.appendChild(document.createTextNode("2"))
I want to capture the x-axis and y-axis values when I click on axes in the console I want to show the values when I click on axes.
example this way :
chart.listen("click",function(){
chart.xAxis("{%value}");
console.log(xAxis.value(0));
});
It's not showing any value in the console I just want to get value when I click on xAxis or yAxis.
You can setup a click handler for individual labels, e.g.:
const xAxis = chart.xAxis();
xAxis.labels().listen('click', function (e) {
const labelIndex = e.labelIndex;
const label = this.getLabel(labelIndex);
const value = xAxis.scale().ticks().get()[labelIndex];
console.log(value);
});
You can see it in action in this playground (click on any xAxis label and its value will be logged to the console)