highcharts can set yAxis formatter function to change yAxis format,but
using highcharts-export-server to generate image, yAxis formatter does not work.
the demo code is like this:
const exporter = require("highcharts-export-server");
const fs = require("fs");
const options = {
"xAxis": {
"categories": ['1', '2', '3', '4']
},
"yAxis": {
title: {
text: 'times'
},
plotLines: [
{
value: 0,
width: 1,
color: "#808080"
}
],
labels: {
enabled: true,
formatter: function () {
return this.value * 100
},
},
},
"series": [{
"data": [1, 3, 2, 4],
"type": "line"
}, {
"data": [5, 3, 4, 2],
"type": "line"
}]
}
const exportSettings = {type: 'png',options}
//Set up a pool of PhantomJS workers
exporter.initPool();
//Perform an export
exporter.export(exportSettings, function (err, res) {
var dataBuffer = new Buffer(res.data, 'base64');
fs.writeFile("out.png", dataBuffer, function (err) {
if (err) {
console.log(err);
} else {
console.log("save success!");
}
});
exporter.killPool();
});
any one have some suggestions?thanks!
the result:
demo result
There's a bug associated with this problem: https://github.com/highcharts/node-export-server/issues/70
However you can use the formatter function in callback export parameter like this:
{
"type": "Png",
callback: `function(chart) {
chart.yAxis[0].update({
labels: {
enabled: true,
formatter: function() {
return this.value * 100
}
}
});
}`,
options: {
"xAxis": {
"categories": ['1', '2', '3', '4', '5']
(...)
Notice that the whole function is a String.
Related
I am trying to display a custom tooltip on a react highcharts network chart that includes the node id as well as the title and other fields in the JSON data I am feeding it. However I am not able to get this to work using the formatted function specified in the API.
My simplified code is as follows:
import React, { useState, useEffect, useRef } from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import networkgraph from "highcharts/modules/networkgraph";
networkgraph(Highcharts);
const NetworkChart = () => {
const chartComponent = useRef(null); // reference to chart obj
const [nodeData, setNodeData] = useState([
{ 'id': 'A', title:'ABC', other:'X', dataLabels: { enabled: true }, marker: { radius: 11, fillColor: 'red' } },
{ 'id': 'P', title:'CDE', other:'Y', dataLabels: { enabled: true } },
{ 'id': 'K', title:'EDF', other:'X', dataLabels: { enabled: true } },
{ 'id': 'S', title:'DFG', other:'Z', dataLabels: { enabled: true } },
{ 'id': 'D', title:'SDF', other:'Y', dataLabels: { enabled: true } },
]);
const [linkData, setLinkData] = useState([
{ 'from': 'D', 'to': 'A' },
{ 'from': 'S', 'to': 'A' },
{ 'from': 'K', 'to': 'A' },
{ 'from': 'P', 'to': 'A' }
]);
const [chartOptions, setChartOptions] = useState({
chart: {
type: 'networkgraph',
plotBorderWidth: 1,
},
title: {
text: 'Phrasal verbs'
},
subtitle: {
text: 'Integration: ' + 'euler'
},
credits: false,
plotOptions: {
networkgraph: {
layoutAlgorithm: {
enableSimulation: false,
integration: 'euler',
linkLength: 25,
},
keys: ['from', 'to'],
marker: {
radius: 5,
lineWidth: 1
}
},
series: {
point: {
events: {
click: function () {
// click function
},
}
}
}
},
series: [{
allowPointSelect: true,
nodes: nodeData,
data: linkData,
}]
});
return (
<div>
<HighchartsReact
highcharts={Highcharts}
options={chartOptions}
containerProps={{ style: { height: 700 } }}
allowChartUpdate = {true}
ref={chartComponent}
/>
</div>
)
};
export default NetworkChart;
Currently all I see is node id on hover. What I want to see is node id, title and other field values when I hover on each node in the chart.
You can get the required propeerties through: this.point.options
tooltip: {
formatter: function() {
const { title, other } = this.point.options;
return 'Title: ' + title + ' Other: ' + other
}
}
Live demo: http://jsfiddle.net/BlackLabel/4zgrnqc2/
API Reference: https://api.highcharts.com/highcharts/tooltip.formatter
i'm trying to make a stacked column chart based on the following values
[
{
"date": "2019-06-08",
"profileId": "2978",
"likes": "48",
"source": "text",
"brand": "Pepsi",
"comments": "8",
"followers": "23443",
"ER": "1.00439"
},
{
"date": "2019-06-10",
"profileId": "6456",
"likes": "93",
"source": "media",
"brand": "pepsi",
"comments": "3",
"followers": "54482",
"ER": "0.99969"
},
{
"date": "2019-06-10",
"profileId": "6215",
"likes": "457",
"source": "media",
"brand": "pepsi",
"comments": "11",
"followers": "233113",
"ER": "1.00818"
}
]
and here's the chart object
const brandsValueChartOptions = {
chart: {
type: 'column',
}
credits: {
enabled: false,
},
xAxis: {
title: {
text: 'Date',
},
categories: brandsValue.x,
labels: {
formatter: function() {
return moment(this.value).format('Do MMM')
},
},
crosshair: true,
grouping: true
},
yAxis: {
min: 0,
title: {
text: 'Value (in USD)',
},
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span>',
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,
stacking: 'normal',
},
},
series: {
stacking: 'true'
}
},
series: brandsValue.y,
}
and here how i process the data on the structure the results object to be used in the chart object above.
const brandsValue = {
x: [],
y: [],
}
let colorIndex = 0
_.chain(data)
.map(brand => {
return {
...brand,
day: brand.date,
brand: _.capitalize(brand.brand.toLowerCase()),
}
})
.forEach(brand => brandsValue.x.push(brand.day))
.groupBy(brand => brand.brand)
.forEach(items => {
if (values.mediaTypeSelected === 'posts') {
items.forEach(item => {
let followersCount = parseInt(item.followers)
let er = parseFloat(item.ER)
item.finalCost = 100 * er
item.date = new Date(item.date).getTime()
return item
})
}
})
.forEach(item => {
let sorted = _.sortBy(item, i => moment(i.date))
let values = {
name: item[0].brand,
color: "#cccccc",
data: [],
}
sorted.forEach(i => {
if (this.state.mediaTypeSelected === 'posts') {
values.data.push([
moment(i.date).format('Do MMM'),
parseInt(i.finalCost),
i.profileId,
])
}
})
brandsValue.y.push(values)
})
.value()
The problem here, is that the x-axis values aren't grouped/stacked based on the date, i've tried several solutions with no luck,
here's how the chart results looks like
I was developing a vue app using vue advanced webpack template and I didn't took much attention to IE browser but today I tried and I'm getting very odd errors.
I have a several sparkline charts rendered with Highcharts in the mount function of a component and I think the point where I have this error is here:
options = Highcharts.merge(defaultOptions, options);
I use babel-polyfill and my .babelrc configuration is this one:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": [
"Chrome >= 52",
"FireFox >= 44",
"Safari >= 7",
"Explorer 11",
"last 4 Edge versions"
]
},
"useBuiltIns": true,
"debug": true
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs",
"dynamic-import-node"]
}
}
}
In webpack.base.config.js I have this loader configured:
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('i18n'), resolve('test'),
resolve('node_modules/webpack-dev-server/client')]
},
Any help will be appreciated, thanks!
Relevant Source of List.vue:
import createSmallCharts from './smallChart';
function refreshCharts(elements) {
createSmallCharts(elements);
}
...
mounted() {
const elements = this.$refs['currency-table-
body'].querySelectorAll('.table__price-graph');
refreshCharts(elements);
},
And the source for createSmallCharts
import * as Highcharts from 'highcharts/highcharts';
// Creating 153 sparkline charts is quite fast in modern browsers, but IE8 and mobile
// can take some seconds, so we split the input into chunks and apply them in timeouts
// in order avoid locking up the browser process and allow interaction.
function createSmallCharts(elements) {
const time = +new Date();
let stringdata;
let data;
let n = 0;
for (let i = 0; i < elements.length; i += 1) {
const element = elements[i];
stringdata = element.getAttribute('data-sparkline');
data = stringdata.split(', ').map(dataEl => parseFloat(dataEl));
Highcharts.SparkLine(element, {
series: [{
data,
pointStart: 1,
pointInterval: 24 * 3600 * 1000,
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1,
},
},
}],
plotOptions: {
series: {
marker: {
enabled: false,
states: {
hover: {
enabled: true,
radius: 3,
},
},
},
},
},
tooltip: {
formatter: () => false,
},
});
// If the process takes too much time, run a timeout to allow interaction with the browser
if (new Date() - time > 500) {
elements.splice(0, i + 1);
setTimeout(createSmallCharts, 0);
break;
}
}
}
export { createSmallCharts as default };
Finnaly the definition of SparkLine:
import Highcharts from 'highcharts/highcharts';
Highcharts.SparkLine = function SparkLine(...params) {
const hasRenderToArg = typeof a === 'string' || params[0].nodeName;
let options = params[hasRenderToArg ? 1 : 0];
const defaultOptions = {
chart: {
renderTo: (options.chart && options.chart.renderTo) || this,
backgroundColor: null,
borderWidth: 0,
type: 'area',
margin: [2, 0, 2, 0],
width: 120,
height: 20,
style: {
overflow: 'visible',
},
// small optimalization, saves 1-2 ms each sparkline
skipClone: true,
},
title: {
text: '',
},
credits: {
enabled: false,
},
xAxis: {
labels: {
enabled: false,
},
title: {
text: null,
},
startOnTick: false,
endOnTick: false,
tickPositions: [],
},
yAxis: {
endOnTick: false,
startOnTick: false,
labels: {
enabled: false,
},
title: {
text: null,
},
tickPositions: [0],
},
legend: {
enabled: false,
},
tooltip: {
backgroundColor: null,
borderWidth: 0,
shadow: false,
useHTML: true,
hideDelay: 0,
shared: true,
padding: 0,
positioner(w, h, point) {
return {
x: point.plotX - (w / 2),
y: point.plotY - h,
};
},
},
plotOptions: {
series: {
animation: false,
lineWidth: 1,
shadow: false,
states: {
hover: {
lineWidth: 1,
},
},
marker: {
radius: 1,
states: {
hover: {
radius: 2,
},
},
},
fillOpacity: 0.25,
},
column: {
negativeColor: '#910000',
borderColor: 'silver',
},
},
};
options = Highcharts.merge(defaultOptions, options); // I think ERROR is here
return hasRenderToArg ?
new Highcharts.Chart(params[0], options, params[2]) :
new Highcharts.Chart(options, params[1]);
};
Try to import it at the top of your main.js file like this:
import 'babel-polyfill'
At least this fixed this issue for me.
i can see 2 y axes but how can i scale the second? Where i have to put code? I get data from database using json.php which i don't include because i am sure i get results...as i said i can see lines........
function InitHighChart()
{
$("#chart").html("Wait, Loading graph...");
var options = {
chart: {
renderTo: 'chart',
borderColor: '#a1a1a1',
borderWidth: 2,
borderRadius: 13,
alignTicks: false,
height: 550
},
credits: {
enabled: false
},
title: {
text: 'Ενεργός Ισχύς / Τάση',
x: -20
},
xAxis: {
categories: [{}],
labels: {
step: 15,
rotation: -75
}
},
yAxis: [{ // Primary yAxis
labels: {
format: '{value} MWatt',
},
title: {
text: 'Ενεργός Ισχύς',
}
}, { // Secondary yAxis
title: {
text: 'Τάση',
},
labels: {
format: '{value} V',
},
opposite: true
}],
tooltip: {
formatter: function() {
var s = '<b>'+ this.x +'</b>';
$.each(this.points, function(i, point) {
s += '<br/>'+point.series.name+': '+point.y;
});
return s;
},
shared: true
},
series: [{},{}]
};
$.ajax({
url: "json.php",
data: 'show=impression',
type:'post',
dataType: "json",
success: function(data){
options.xAxis.categories = data.datetime;
options.series[0].name = '...';
options.series[0].data = data.ActiveData;
options.series[1].name = '...';
options.series[1].data = data.VoltageData;
var chart = new Highcharts.Chart(options);
},
});
}
Have you assigned any series to second y axis? That might be the problem.
API: http://api.highcharts.com/highcharts#series.yAxis
series: [{
data: [1, 2, 3, 4, 5, 3, 5]
}, {
data: [3, 3, 5, 4, 6, 6, 3, 3, 4, 6],
yAxis: 1
}]
jsFiddle: http://jsfiddle.net/boog4dpe/
in your code you should add line in
$.ajax({
url: "json.php",
data: 'show=impression',
type:'post',
dataType: "json",
success: function(data){
options.xAxis.categories = data.datetime;
options.series[0].name = '...';
options.series[0].data = data.ActiveData;
options.series[1].name = '...';
options.series[1].data = data.VoltageData;
options.series[1].yAxis = 1; //added line
var chart = new Highcharts.Chart(options);
},
});
I'm trying to retrieve from a JSON formatted file this series name and data
[
{ "name":"gfs00", "data": [ [1359676800000, 30], [1359687600000, 32]]
},
{ "name":"gfs06", "data": [ [1359676800000, 28], [1359687600000, 29]]
}
]
Here's the highchart code:
var data_temp;
$.getJSON('dati/performance_gfs/precipitazioni/pioggia_live_data.php',
{ run: runs_gfs} ,function(data_temp){
for (var i = 0; i <data_temp.length ;i++){
chart.addSeries({
data:data_temp,
});
}
});
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container_temperatura_windchill_heatindex',
defaultSeriesType: 'line',
zoomType: 'x',
},
title: {
text: 'Ensemble'
},
xAxis: {
type: 'datetime'
},
yAxis: [{ // Primary yAxis
id:0,
labels: {
formatter: function() {
return this.value +'°C';
},
style: {
color: '#89A54E'
}
},
title: {
text: 'Temperature',
style: {
color: '#89A54E'
}
}
}],
plotOptions: {
line: {
lineWidth: 1,
states: {
hover: {
lineWidth: 2
}
},
marker: {
enabled: false,
states: {
hover: {
enabled: true,
symbol: 'circle',
radius: 5,
lineWidth: 1
}
}
},
pointInterval: 24 * 3600000, // one hour
pointStart: Date.UTC(2012, 9, 6, 0, 0, 0)
}
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%d-%m-%Y %H:%M', this.x)+'<br/>'+
this.y;
}
},
series: []
});
});
}
As can be seen I don't know how to assign the series names and data from the JSON file which is correct what I need is something like http://jsfiddle.net/vXdxv/1/
Try the following:
for (var i = 0; i <data_temp.length ;i++){
chart.addSeries(data_temp[i], false);
});
chart.redraw();