I know it is weird but I want to customize step line chart like horizontal step is thicker and vertical step is thinner, is there any way to achieve this?
Thanks in advance
You can render other lines in the same positions as the horizontal ones. Please check the below solution:
chart: {
events: {
render: function() {
const points = this.series[0].points;
points.forEach(point => {
const nextPoint = points[point.index + 1];
if (nextPoint) {
const d = [
'M',
point.plotX + this.plotLeft - 1,
point.plotY + this.plotTop,
'L',
nextPoint.plotX + this.plotLeft + 1,
point.plotY + this.plotTop
];
if (point.customPath) {
point.customPath.attr({
d
});
} else {
point.customPath = this.renderer
.path([])
.attr({
d,
stroke: 'red',
'stroke-width': 7
})
.add();
}
}
});
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/wc5zrax9/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#path
Related
How can I change Chart Js's bar chart shape to have pointy top and bottom like this picture?
One way to get the triangles is to do a stacked chart, and add a line graph on top. To keep it reactive you would need to dynamically resize the pointRadius on the line data.
https://jsfiddle.net/0mcd5s13/3/
Or on line 4640 of chart.js you can change element_rectangle draw function to this:
draw: function() {
var ctx = this._chart.ctx;
var vm = this._view;
var rects = boundingRects(vm);
var outer = rects.outer;
var inner = rects.inner;
//ctx.fillStyle = vm.backgroundColor;
//ctx.fillRect(outer.x, outer.y, outer.w, outer.h);
if (outer.w === inner.w && outer.h === inner.h) {
return;
}
let offset = outer.w / 2;
ctx.save();
ctx.beginPath();
ctx.moveTo(outer.x, outer.y);
ctx.lineTo(outer.x, outer.y + outer.h);
ctx.lineTo(outer.x + offset, outer.y + outer.h + offset);
//ctx.lineTo(outer.x + offset, outer.y + outer.h);
ctx.lineTo(outer.x + outer.w, outer.y + outer.h);
ctx.lineTo(outer.x + outer.w, outer.y);
ctx.lineTo(outer.x + offset, outer.y - offset);
ctx.lineTo(outer.x, outer.y);
ctx.stroke();
//ctx.rect(outer.x, outer.y, outer.w, outer.h);
ctx.clip();
ctx.fillStyle = vm.borderColor;
// ctx.rect(inner.x, inner.y, inner.w, inner.h);
ctx.fill('evenodd');
ctx.restore();
},
which yields this:
more likely to import chart.js from a source, you will need make your own type of chart as an extension of bar chart.
(function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.triBar = {
hover: {
mode: "label"
},
dataset: {
categoryPercentage: 0.8,
barPercentage: 0.9
},
scales: {
xAxes: [{
type: "category",
// grid line settings
gridLines: {
offsetGridLines: true
}
}],
yAxes: [{
type: "linear"
}]
}
};
Chart.controllers.triangleBar = Chart.controllers.bar.extend({
//
// extend element_rectangle draw function here
//
});
}).call(this, Chart);
I want to display legend for a line series at the top and colorAxis for heatmap at the right side in a chart. There is a global option to position the legend but no separate option for each series.
Highcharts Version: v4.3.1
That feature is not yet implemented in Highcharts core, but it should be available soon: https://github.com/highcharts/highcharts/issues/11309
For now you can move colorAxis from the legend to another place on the chart in this way:
(function(H) {
H.wrap(H.ColorAxis.prototype, 'drawLegendSymbol', function(proceed) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
this.legendItemWidth = 0;
this.legendItemHeight = 0;
});
}(Highcharts));
Highcharts.chart('container', {
chart: {
marginRight: 80,
events: {
load: function() {
var chart = this,
colorAxis = chart.colorAxis[0].axisParent.element,
mainSVG = chart.container.children[0],
xPos = chart.plotLeft + chart.plotWidth + 10,
yPos = chart.plotTop;
mainSVG.appendChild(colorAxis);
colorAxis.setAttribute(
'transform', 'translate(' + xPos + ', ' + yPos + ')'
)
}
}
},
series: [{
...,
showInLegend: true
}, {
...,
showInLegend: true
}],
colorAxis: {
layout: 'vertical'
}
});
Live demo: http://jsfiddle.net/BlackLabel/0c9fkvwp/
API Reference: https://api.highcharts.com/highcharts/chart.events
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
I need two labels for a column, one above to show the score and one below to show if it is a "test" or a "retest". How do I go about doing it?
I assume complicated calculation is needed, something like this? http://jsfiddle.net/72xym/4/ (but I can't really understand)
I got other diagrams need to achieve this as well. Basically I need to do this:
My code is inside here: http://jsfiddle.net/kscwx139/6/
I did this for the part to add the label:
..., function() {
var i = 0, j = 0, len_i, len_j, self = this, labelBBox, labels=[];
for(i=0; i<this.series.length; i++) {
labels[i] = [];
for(j=0; j<this.series[i].data.length; j++) {
labels[i][j] = this.renderer.label(self.series[i].name)
.css({
width: '100px',
color: '#000000',
fontSize: '12px'
}).attr({
zIndex: 100
}).add();
labelBBox = labels[i][j].getBBox();
labels[i][j].attr({
x: 100, //1) what to put here?
y: 100 //2) what to put here?
});
}
}
}
I would do something like this:
var chart2 = new Highcharts.Chart(options2, function() {
var i = 0, j = 0, len_i, len_j, self = this, labelBBox, labels=[], point;
for(i=0; i<this.series.length; i++) {
labels[i] = [];
for(j=0; j<this.series[i].data.length; j++) {
labels[i][j] = this.renderer.label(self.series[i].name)
.css({
width: '100px',
color: '#000000',
fontSize: '12px'
}).attr({
zIndex: 100,
align: "center"
}).add();
point = this.series[i].data[j];
labelBBox = labels[i][j].getBBox();
labels[i][j].attr({
x: point.plotX + this.plotLeft + point.series.pointXOffset + point.shapeArgs.width / 2,
y: this.plotTop + this.plotHeight - labelBBox.height
});
}
}
});
Demo: http://jsfiddle.net/kscwx139/7/
Note: I would suggest using chart.redraw event to update labels position (label[i][j].animate({ x: ..., y: ... });) when resizing browser, updating data, etc.
Short explanation:
point.plotX - x-position in the plotting area (center of the point's shape)
this.plotLeft - left offset for left yAxis (labels, title)
point.series.pointXOffset - offset for multiple columns in the same category
this.plotTop - the same as plotLeft but from top ;)
this.plotHeight - height of the plotting area
labelBBox.height - height of the label to place it above the xAxis line
I need to respond to a click event on each slice in a Raphael Pie Chart. I tried it this way, but it does not seem to do it. My code is just two lines commented as "My code" in the below code, which comes directly from the demo Pie Chart of RaphaelJS...
<script>
var u = "";
var r = "";
window.onload = function () {
r = Raphael("holder"),
pie = r.piechart(320, 240, 100, [25, 20, 13, 32, 5, 21, 14, 10,41,16,12,18,16,14,12,13],
{ legend: ["%%.%% - Enterprise Users", "IE Users"],
legendpos: "west", href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]
}
);
r.text(320, 100, "Interactive Pie Chart").attr({ font: "20px sans-serif" });
pie.hover(function () {
u = this; // My Code
u.onclick = clickEvent; // hook to the function
this.sector.stop();
this.sector.scale(1.1, 1.1, this.cx, this.cy); // Scale slice
if (this.label) { // Scale button and bolden text
this.label[0].stop();
this.label[0].attr({ r: 7.5 });
this.label[1].attr({ "font-weight": 800 });
}
}, function () {
this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
if (this.label) {
this.label[0].animate({ r: 5 }, 1500, "bounce");
this.label[1].attr({ "font-weight": 400 });
}
});
};
function clickEvent(){
console.log("Clicked!")
}
</script>
Raphaels syntax is a little different.
Check this documentation
Your code should be as below:
u.click(clickEvent);
I have created the BBox on a Average line. i have created the BBox by the following code
$('#container').highcharts({
chart: {
zoomType: 'x',
},
.
.
.
.
}, function(chart){
if(chart.series[0].data[1])
{
var point = chart.series[0].data[1],
text = chart.renderer.text(
'Average='+Math.ceil(point.y)+" s",
point.plotX + chart.plotLeft - 45,
point.plotY + chart.plotTop - 13
).attr({
zIndex: 5
}).add(),
box = text.getBBox();
chart.renderer.rect(box.x - 5, box.y - 5, box.width + 10, box.height + 10, 5)
.attr({
fill: '#FFFFEF',
stroke: 'gray',
'stroke-width': 1,
zIndex: 4
})
.add();
}
});
the box have been created
I want to change the BBox location according to average line when the zoom property in role.
How can i do this ..Thanks in Advance
You need to use your code in the redraw() event in highcahrts. Take care about destroy (old rendered object) and create new one, or translate it.
Example:
http://jsfiddle.net/be2ebcg2/1/