Highcharts: Auto-scale rendered shape along with chart? - javascript

I've placed a box shape on the chart using chart.renderer.rect(). I want that box to get skinnier (the same way the chart does) when I resize the page horizontally.
I can see in the inspector that the width attribute of all the SVG chart elements is getting changed as I resize the page but not my rendered box shape. How are they doing this? Is there some property I have to add to my rendered box shape?
I also noticed the add() method takes a parent but I can't figure out how to get the SVGElement from the chart I'm adding it to and I'm not sure setting the parent would give me the auto-scaling I want anyway.

You can store reference to an element and edit it's attributes, for example based on axis values. Example:
chart: {
events: {
render: function() {
const chart = this;
const xAxis = chart.xAxis[0];
const yAxis = chart.yAxis[0];
const startX = xAxis.toPixels(1);
const startY = yAxis.toPixels(7);
const width = xAxis.toPixels(6) - startX;
const height = yAxis.toPixels(4) - startY;
if (!chart.customRect) {
chart.customRect = chart.renderer.rect().attr({
'stroke-width': 2,
stroke: 'red',
fill: 'yellow'
}).add();
}
chart.customRect.attr({
x: startX,
y: startY,
width,
height
});
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/p6743jam/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement#attr
https://api.highcharts.com/class-reference/Highcharts.Axis#toPixels

Related

Can I animate plotbands and put more than one label to each plotband using the Highstock API?

I am using the highstock API, and I want to draw some plotBands on a chart. I would like to know if there is any way to animate the plotband while it is being drawed, like CSS transitions applied to html elements when their width change. I also want to know if I can assign more than one label to one plotband. I have seen a lot of examples in jsfiddle where a plotband has only one label, but I would like to put two labels for each plotband in order to show its start point and its end point.
Thanks in advance.
You can use the Renderer.rect and trigger animate() function on rendered object, instead of using plotbands. As a result new shape is animated.
var yAxis = chart.yAxis[0],
xAxis = chart.xAxis[0],
start = 1,
end = 2,
x1 = xAxis.toPixels(start),
x2 = xAxis.toPixels(end);
var plotBand = chart.renderer.rect(x1, chart.plotTop, 0, chart.plotHeight)
.attr({
fill: 'yellow',
zIndex: 0
})
.add();
plotBand.animate({
width: x2 - x1
});
Example:
http://jsfiddle.net/qvt5mvdL/

How to style images in highcharts flags?

In my chart, I show the user pictures for their comment date, so the users can read the comments in a tooltip using these icons. It seems like soundcloud charts. I did it using flags type and I set the shape variables as user picture url for each data item.
But I want to add also colorized border for each icons. I know, there is lineWidth and lineColor config in flags type but it doesn't work with images, it works only with default shapes flag, circlepin or squarepin.
I tried to use shape as flag and to add user images as background image, but It doesn't work.
In SVG you can not set border for the images, you need to create rect around the image: http://jsfiddle.net/xuL76rkL/1/
For example you can use load and redraw events to manage those rects, code:
var H = Highcharts;
function drawBorder() {
var chart = this;
H.each(chart.series[1].points, function(p) {
var bbox,
rect,
fontSize = 13, // it's used as default font size offet, even for the images
dim = 32; //width and height for the image
if(p.graphic) {
if(p.rectangle) {
p.rectangle.destroy();
}
bbox = p.graphic.getBBox();
rect = chart.renderer.rect(p.plotX - dim/2, p.plotY - dim/2 - fontSize, dim, dim).attr({
"stroke": "black",
"stroke-width": 2,
"fill": "transparent"
}).add(chart.series[1].markerGroup);
p.rectangle = rect;
}
});
}
$('#container').highcharts('StockChart', {
chart: {
events: {
load: drawBorder,
redraw: drawBorder
}
},
...
});
You can set an image with the shape option:
Example: shape: "url(/assets/my_image.svg)"
Documentation available here: https://api.highcharts.com/highstock/series.flags.shape

Bar Chart outside bounds and mouseover event issue

Here is my dimple.js code, the bar chart that it produces is outside the bounds and touching Y-axis.
Mouseover event is not changing the color of the bars.
Below is the image
var myChart2 = new dimple.chart(svg,data);
myChart2.setBounds(750,50,550,250);
var x = myChart2.addTimeAxis( "x", "date", "%m/%d/%Y", "%d-%b");
x.floatingBarWidth = 21;
var y2= myChart2.addMeasureAxis("y","callperorder");
var y1= myChart2.addMeasureAxis("y","calls");
var bars = myChart2.addSeries("or", dimple.plot.bar,[x,y2]);
var lines= myChart2.addSeries("cl", dimple.plot.line,[x,y1]);
lines.lineMarkers= true;
myChart2.addLegend(750, 20, 300, 20, "right");
myChart2.assignColor("cl","rgb(99,39,29)");
myChart2.assignColor("or","rgb(99,89,219)");
myChart2.draw();
\\MOUSEOVER EVENT
bars.addEventHandler("mouseover", function( {d3.select(this).style("fill","green")});
You need to add the event handler before calling draw if you want to use the dimple method. Alternatively you could use the d3 method after draw.
bars.shapes.on("mouseover", function () {...});
NB. There's also a typo in your event declaration, it's missing the closing bracket after function (.
In order to avoid overlapping the edge of the chart you will need to manually set the x bounds:
x.overrideMin = d3.time.format("%m/%d/%Y").parse("12/31/2014");
x.overrideMax = d3.time.format("%m/%d/%Y").parse("01/11/2015");
Using whatever values you want of course;

Finding the Y axis value for a plot line in HIghCharts.js

I am trying to size a background image on a HighCharts line chart dynamically depending on the position of the top plot line. The image I am trying to size is the bell curve in the image below.
I can't set the height of the image as a static value because the size of the screen can change and the top plot line also changes over time.
At the moment I am setting the position of the plot lines with external functions like this:
plotLines: [
value: upperControl3()}, {
color: '#ccc',
zIndex: 3,
width: 1,
label: {
text: '-2s',
x: 520,
y: 3
}
The closest thing to the y value of the top plot line I have been able to find is a dataMax value but this stays the same on every chart load.
I have been trying to overlay and size the image with a function at the end of the chart like this:
function(chart) {
console.log(chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis);
var h = chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis.dataMax;
var y = chart.yAxis[0].axisTitle.y + extra;
// X, Y, Width, Height
chart.renderer.image('images/bell.jpg', 60, y, 200, h).add();
}
Is the any way to find the coordinates of a plot line in highcharts?
You can use plotLinesAndBands object, where plotlines are kept. In the options you have value, whcih can be translated into pixels value by toPixels function.
var $button = $('#button'),
$report = $('#report'),
chart = $('#container').highcharts();
$button.click(function () {
chart.xAxis[0].addPlotLine({
value: 5.5,
color: 'red',
width: 2,
id: 'plot-line-1'
});
var plotline = chart.xAxis[0].plotLinesAndBands[0];
$report.html('Value: ' + plotline.options.value + ' Pixels: ' + chart.xAxis[0].toPixels(plotline.options.value));
});
http://jsfiddle.net/HhP39/1/
If you know which plot line (by index) it is, you can do this:
chart.yAxis[0].plotLinesAndBands[0].options.value
Of course, you need to make sure your data is actually normally distributed, or else that normal curve means nothing :)
And zero-bounded data is not usually normally distributed.

how to change size of raphael icons?

how I can change the width and the height of icons from free Raphael icons ?
I tried to use attr, tried to use % , like this var paper = Raphael("canvas", 100%, 100%);.
I need to do this: if I change the size of the parent block, the size of my icon changes too.
upd: i tried use "scale" and "transform", but icon resize from centre and not fit into the parent correctly
According to the Raphael.js documentation
var el = paper.rect(10, 20, 300, 200);
// translate 100, 100, rotate 45°, translate -100, 0
el.transform("t100,100r45t-100,0");
// if you want you can append or prepend transformations
el.transform("...t50,50");
el.transform("s2...");
// or even wrap
el.transform("t50,50...t-50-50");
// to reset transformation call method with empty string
el.transform("");
// to get current value call it without parameters
console.log(el.transform());
Check this Fiddle:
Demonstration of all the transformations
var icon = paper.rect(100,200,100,100);
var anim = Raphael.animation({
"10%":{transform:'t100,0'}, //transform on x-axis
"20%":{transform:'...t0,100'},//transform on y-axis
"30%":{transform:'...t-100,0'},//transform on x-axis(negative)
"40%":{transform:'...t0,-100'},//transform on y-axis(negative)
"50%":{transform:'...t200,200'},//transform diagonally
"60%":{transform:'...t-100,-100'},//transform diagonally(negative)
"70%":{transform:'...s1,1.5'},//scale y-axis
"80%":{transform:'...s1.5,1'},//scale x-axis
"90%":{transform:'...s2'},//scale in both direction
"100%":{transform:'...r45'},//rotate
},5000);
icon.animate(anim.delay(1000));
So in your case you'll have to do this:
var somename = paper.path("path coordinates").transform('s2,3');
where 2 is for width & 3 is for height.

Categories