Get Stock Chart Crosshair yAxis Price onClick - anychart

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.

Related

d3.js Tooltip do not receive data properly

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]);

How to get coordinates (x,y) from a svg and put a text tag with a value

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"))

how to capture x axis and y-axis value in anychart

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)

Getting (X,Y) point on mouse click on chart

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);
},

How to add legends in Amserial charts

I am using Amcharts in my AngularJS Application to create a simple bar chart.The following is my code in the controller:
let empChart;
let empBarGraph;
let empLine;
const writeemp = data => {
const {
total,
employees,
} = data;
empChart.dataProvider = e;
empChart.write('emp');
empChart.validateData();
};
AmCharts.handleLoad();
var configChart = function () {
empChart = new AmCharts.AmSerialChart();
empChart.categoryField = "state";
empChart.labelRotation = 90;
var yAxis = new AmCharts.ValueAxis();
yAxis.position = "left";
empChart.addValueAxis(yAxis);
empBarGraph = new AmCharts.AmGraph();
empBarGraph.valueField = "count";
empBarGraph.type = "column";
empBarGraph.fillAlphas = 1;
empBarGraph.lineColor = "#f0ab00";
empBarGraph.valueAxis = yAxis;
empChart.addGraph(empBarGraph);
empChart.write('empChart');
$http.get(hostNameService.getHostName()+"/dashboard/employees/statecount")
.then(response => writeemp(response.data));
}
Code in html:
<div class='panel-body'>
<div id="empChart"></div>
</div>
This would return me the values of State on x-axis and count on y-axis. I wanted to filter the chart based on the value of state and was not sure how to create the legends for this chart. could anyone suggest me on how to use legends. I want to create legends for the state value that is being returned.
You can add a legend using the OO-based syntax by creating a legend object through new AmCharts.AmLegend() and adding it to the class by calling the chart's addLegend method:
var legend = new AmCharts.AmLegend();
empChart.addLegend(legend);
If you want the legend to show values upon hovering over a column, you need to add a ChartCursor to your chart:
var cursor = new AmCharts.ChartCursor();
empChart.addChartCursor(cursor);
You can change what the legend displays upon column rollover by setting the valueText property. It allows for the same [shortcodes] used in fields like balloonText and labelText, e.g. legend.valueText = "[[category]]: [[value]]". You can also use set its valueFunction if you need to customize the text it returns dynamically like in your previous questions. All of the properties available in the legend object can be found in the AmLegend API documentation.
Updated:
Legends work off of graph objects only, so there isn't an out of the box method that allows you to represent each column as a legend item that toggles the other columns' visibility unless you're willing to reorganize your dataset and use different graph objects for each state. A workaround for this is to use the the legend's custom data array and add some event handling so that clicking on the custom data items adds/removes a toggle by unsetting your count valueField in the dataProvider.
The following annotated code accomplishes what you're trying to do:
//create the legend but disable it until the dataProvider is populated,
//since you're retrieving your data using AJAX
var legend = new AmCharts.AmLegend();
legend.enabled = false;
chart.addLegend(legend);
chart.toggleLegend = false;
// Callback that handles clicks on the custom data entry markers and labels
var handleLegendClick = function(legendEvent) {
//Set a custom flag so that the dataUpdated event doesn't fire infinitely
legendEvent.chart.toggleLegend = true;
// The following toggles the markers on and off.
// The only way to "hide" a column is to unset the valueField at the data index,
// so a temporary "storedCount" property is added to the dataProvider that stores the
// original value so that the value can be restored when the legend marker is toggled
// back on
if (undefined !== legendEvent.dataItem.hidden && legendEvent.dataItem.hidden) {
legendEvent.dataItem.hidden = false;
legendEvent.chart.dataProvider[legendEvent.dataItem.stateIdx].count = legendEvent.chart.dataProvider[legendEvent.dataItem.stateIdx].storedCount; //restore the value
} else {
// toggle the marker off
legendEvent.dataItem.hidden = true;
legendEvent.chart.dataProvider[legendEvent.dataItem.stateIdx].storedCount = legendEvent.chart.dataProvider[legendEvent.dataItem.stateIdx].count; //store the value
legendEvent.chart.dataProvider[legendEvent.dataItem.stateIdx].count = undefined; //set to undefined to hide the column
}
legendEvent.chart.validateData(); //redraw the chart
}
chart.addListener('dataUpdated', function(e) {
var legendDataItems; //used to store the legend's custom data array.
if (e.chart.toggleLegend === true) {
//is the user toggling a legend marker? stop here as the dataProvider will get updated in handleLegendClick
e.chart.toggleLegend = false;
return;
}
// if we're at this point, the data provider was updated.
// reconstruct the data array.
// initialize by grabbing the state, setting a color and stoing the index
// for toggline the columns later
legendDataItems = e.chart.dataProvider.map(function(dataElement, idx) {
return {
'title': dataElement.state,
'color': graph.lineColor,
'stateIdx': idx //used in toggling
}
});
// if the legend is not enabled, then we're setting this up for the first time.
// turn it on and attach the event handlers
if (e.chart.legend.enabled === false) {
e.chart.legend.enabled = true;
e.chart.legend.switchable = true;
e.chart.legend.addListener('clickMarker', handleLegendClick);
e.chart.legend.addListener('clickLabel', handleLegendClick);
}
// update the legend custom data and redraw the chart
e.chart.legend.data = legendDataItems;
e.chart.validateNow();
});
Here's a fiddle that illustrates this: http://jsfiddle.net/g254sdq5/1/

Resources