ChartJS display tooltip at maximum/minimum value - coffeescript

I would like to display a tooltip at the top datapoint of a dataset in my chart. That way the user sees a value for the maximum and the minimum datapoints. That helps understanding the graph immediately.
It should look somewhat like this:
I have created a JSFiddle with the code over here: https://jsfiddle.net/h2zscw6s/1/
For reference please also find my chart config below. It's in coffeescript but I don't mind if you post answers in plain javascript.
dataWeather = [
{
label: 'January'
value: 22
}
{
label: 'February'
value: 23
}
{
label: 'March'
value: 24
}
{
label: 'May'
value: 26
}
{
label: 'June'
value: 30
}
{
label: 'July'
value: 34
}
{
label: 'August'
value: 38
}
{
label: 'September'
value: 36
}
{
label: 'October'
value: 30
}
{
label: 'November'
value: 28
}
{
label: 'December'
value: 26
}
]
dataPrices = [
{
label: 'January'
value: 5000
}
{
label: 'February'
value: 4500
}
{
label: 'March'
value: 4450
}
{
label: 'May'
value: 3700
}
{
label: 'June'
value: 3700
}
{
label: 'July'
value: 3000
}
{
label: 'August'
value: 2900
}
{
label: 'September'
value: 3100
}
{
label: 'October'
value: 3200
}
{
label: 'November'
value: 3900
}
{
label: 'December'
value: 5500
}
]
class WeatherPriceChart
setWeatherData: (weatherData)->
#weatherData = weatherData
setPriceData: (priceData)->
#priceData = priceData
minPrice: ->
_.sortBy(#priceData, (w)-> w.value)[0]?.value || 0
maxPrice: ->
_.sortBy(#priceData, (w)-> -w.value)[0]?.value || 0
minTemperature: ->
_.sortBy(#weatherData, (w)-> w.value)[0]?.value || 0
maxTemperature: ->
_.sortBy(#weatherData, (w)-> -w.value)[0]?.value || 0
isMaxTemperature: (value)->
#maxTemperature() == value
isMinTemperature: (value)->
#minTemperature() == value
isMaxPrice: (value)->
#maxPrice() == value
isMinPrice: (value)->
#minPrice() == value
getLabels: ->
_.map(#weatherData, (w)-> w.label)
getWeatherDataPoints: ->
_.map(#weatherData, (w)-> w.value)
getPriceDataPoints: ->
_.map(#priceData, (w)-> w.value)
getNormalizedWeatherDataPoints: ->
data = #weatherData
min = -10
max = 60
_.map data, (d)->
norm = d.value + (min * -1)
maxed = max + (min * -1)
norm / maxed * 100
getNormalizedPriceDataPoints: ->
data = #priceData
max = #maxPrice() * 2.5
_.map data, (d)->
d.value / max * 100
chart = new WeatherPriceChart
chart.setWeatherData(dataWeather)
chart.setPriceData(dataPrices)
ctx = document.getElementById('myChart')
myChart = new Chart(ctx,
type: 'line',
data:
xLabels: chart.getLabels(),
yLabels: [""],
datasets: [
{
label: 'Temperature'
data: chart.getWeatherDataPoints()
backgroundColor: 'rgba(239,88,42,0.2)'
borderColor: 'rgba(239,88,42,0.5)'
borderWidth: 1
},
{
label: 'Prices'
data: chart.getNormalizedPriceDataPoints()
backgroundColor: 'rgba(22,195,245,0.2)'
borderColor:'rgba(22,195,245,0.4)'
borderWidth: 1
}
]
options:
scales:
yAxes: [
{
ticks: {
beginAtZero: false,
display: false
},
display: false
},
]
legend:
display: false
)

I found an answer to this option and posted it in the linked jsfiddle. I had to add a plugin that would display all labels. That one then dynamically decided whether to show this tooltip or not.
Chart.pluginService.register
beforeRender: (chart) ->
if chart.config.options.showAllTooltips
# create an array of tooltips
# we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = []
chart.config.data.datasets.forEach (dataset, i) ->
min = _.min(dataset.data, (d)-> d)
max = _.max(dataset.data, (d)-> d)
minShown = false
maxShown = false
chart.getDatasetMeta(i).data.forEach (sector, j) ->
isMax = dataset.data[j] == max
isMin = dataset.data[j] == min
# only show the min and the max once. we can have duplicates min/maxes
if isMax && !maxShown || isMin && !minShown
minShown = true if isMin
maxShown = true if isMax
tooltip = new (Chart.Tooltip)({
_chart: chart.chart
_chartInstance: chart
_data: chart.data
_options: chart.options.tooltips
_active: [ sector ]
}, chart)
chart.pluginTooltips.push(tooltip)
return
return
# turn off normal tooltips
chart.options.tooltips.enabled = false
return
afterDraw: (chart, easing) ->
if chart.config.options.showAllTooltips
# we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if !chart.allTooltipsOnce
if easing != 1
return
chart.allTooltipsOnce = true
# turn on tooltips
chart.options.tooltips.enabled = true
Chart.helpers.each chart.pluginTooltips, (tooltip) ->
tooltip.initialize()
tooltip.update()
# we don't actually need this since we are not animating tooltips
tooltip.pivot()
tooltip.transition(easing).draw()
return
chart.options.tooltips.enabled = false
return

Related

While horizontal scrolling the datalabels of charjs is overlapping to y-axis

To show all bars I have set the horizontal scrolling to chartjs in Ionic angular project , and i have used the DataLabelsPlugin constant for bars label. and while scrolling the datalabels is overlapping with y-axis its not hiding before y-axis like bars.
and also horizontal scroll is not happening smoothly.
graph working fine as a expected output
marked with issue about - after scrolling the datalabels went over the y-axis not hide below y-axis like bars
I have tried to add and used the custom datalabels but same issue i am getting and i didnt find any css or attribute on 'https://www.chartjs.org/docs/latest/' official site or not on any other sites -> to hide the datalabels from over the y-axis.
ts file code:
createBarChart() {
const footer = (tooltipItems) => {
let sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += tooltipItem.parsed.y;
});
return this.util.getFormatValue(sum)+'%';
};
const toolLabel = (tooltipItems) => {
return "";
};
const toolTitle = (tooltipItems) => {
var string_to_array = function (str) {
return str.trim().split("#$#$");
};
var ss;
tooltipItems.forEach(function(tooltipItem) {
ss = string_to_array(tooltipItem.label.replace(/(.{40})/g, "$1#$#$"))
});
return ss;
};
let graphSize = Math.max(...this.daywise_occupancy);
if(graphSize == 0){
graphSize =1;
}
const plugin = {
id: 'customCanvasBackgroundColor',
beforeDraw: (chart, args, options) => {
const {ctx} = chart;
ctx.save();
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, chart.width, chart.height);
ctx.restore();
}
};
this.bars = new Chart(this.barchart6.nativeElement, {
type: 'bar',
data: {
labels: this.daywise_date,
datasets: [{
data: this.daywise_occupancy,
backgroundColor: function(context) {
var value = context.dataset.data[context.dataIndex];
return value <= 15 ? '#f95959'
: value > 15 && value <=60 ? '#F5A623'
: '#00ADB5'
},
borderColor: function(context) {
var value = context.dataset.data[context.dataIndex];
return value <= 15 ? '#f95959'
: value > 15 && value <=60 ? '#F5A623'
: '#00ADB5'
},
borderWidth: 1,
barThickness:30,
}]
},
plugins: [DataLabelsPlugin,plugin],
options: {
animations: {
tension: {
duration: 1000,
easing: 'linear',
from: 1,
to: 0,
loop: true
}
},
scales: {
x: {
min:0,
max:5,
ticks : {
maxRotation: 70,
minRotation: 70,
font:{
size:10,
},
callback: function(value : any, index, ticks_array) {
let characterLimit = 12;
let label = this.getLabelForValue(value);
if ( label.length >= characterLimit) {
return label.slice(0, label.length).substring(0, characterLimit -1).trim() + '..';
}
return label;
}
}
},
y: { // defining min and max so hiding the dataset does not change scale range
min: 0,
max: this.loader.getGraphsizeRound(graphSize),
title: { display: true, text: (this.titleSet)? '% of Branches Contribution' : '% of Seat Occupancy' },
beginAtZero: true,
display: true,
position: 'left',
// ticks: {
// stepSize: 6,
// },
}
},
plugins: {
legend: {
display: false
},
datalabels:{
anchor: 'end',
align: 'end',labels: {
value: {
color: '#2C3A45;',
formatter: function (value) {
// return Math.round(value) + '%';
return value + '%';
},
font:{
weight:700,
size:14
}
}
}
},
tooltip: {
callbacks: {
footer:footer,
label: toolLabel,
title:toolTitle
},
displayColors:false
}
}
}
});
this.bars.canvas.addEventListener('touchmove',(eve) => {
this.touchmove(eve,this.bars)
});
this.bars.canvas.addEventListener('touchstart',(eve) => {
this.touchstart(eve)
});
}
touchstart(e)
{
this.startX = e.touches[0].clientX;
this.startY = e.touches[0].clientY;
}
touchmove(e,chart)
{
var deltaX = e.touches[0].clientX - this.startX,
deltaY = e.touches[0].clientY - this.startY;
const dataLength = chart.data.labels.length;
let min = chart.options.scales.x.min;
if(deltaX < 0){
if( chart.options.scales.x.max >= dataLength ){
chart.options.scales.x.min = dataLength - 5;
chart.options.scales.x.max = dataLength;
}else{
chart.options.scales.x.min += 1;
chart.options.scales.x.max += 1;
}
// console.log( chart.options.scales.x.min);
// chart1line.options.scales.y.max = graphSize
}else if(deltaX > 0){
if( chart.options.scales.x.min <= 0 ){
chart.options.scales.x.min = 0;
chart.options.scales.x.max = 4;
}else{
chart.options.scales.x.min -= 1;
chart.options.scales.x.max -= 1;
}
}else{
}
chart.update();
}
HTML code:
<div class="chartWrapper">
<div class="chartAreaWrapper">
<canvas #barchart6 height="190" max-height="190" width="0"></canvas>
</div>
</div>
My expected output
horizontal scroll work smoothly.
after scrolling label should not overlap on y-axis.

change tooltip color in amchart

I want to change the background colour of the tooltip value in Amchart 5.
I mean the black background colour.
You can create an instance of Tooltip and store it in a variable. Use it in your valueAxis configuration, then modify the background color of your tooltip through its background element.
let tooltip = am5.Tooltip.new(root, {});
let valueAxis = mainPanel.yAxes.push(
am5xy.ValueAxis.new(root, {
// ...
tooltip,
// ...
})
);
tooltip.get("background").set("fill", am5.color(0x0000ff));
Full example (using this demo from the official website):
am5.ready(function() {
// Create root element
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
let root = am5.Root.new("chartdiv");
// Set themes
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([am5themes_Animated.new(root)]);
// Create a stock chart
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Instantiating_the_chart
let stockChart = root.container.children.push(
am5stock.StockChart.new(root, {})
);
// Set global number format
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/concepts/formatters/formatting-numbers/
root.numberFormatter.set("numberFormat", "#,###.00");
// Create a main stock panel (chart)
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Adding_panels
let mainPanel = stockChart.panels.push(
am5stock.StockPanel.new(root, {
wheelY: "zoomX",
panX: true,
panY: true
})
);
// Create value axis
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
let tooltip = am5.Tooltip.new(root, {});
let valueAxis = mainPanel.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
pan: "zoom"
}),
extraMin: 0.1, // adds some space for for main series
tooltip,
numberFormat: "#,###.00",
extraTooltipPrecision: 2
})
);
tooltip.get("background").set("fill", am5.color(0x0000ff));
let dateAxis = mainPanel.xAxes.push(
am5xy.GaplessDateAxis.new(root, {
baseInterval: {
timeUnit: "minute",
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {}),
tooltip: am5.Tooltip.new(root, {})
})
);
// add range which will show current value
let currentValueDataItem = valueAxis.createAxisRange(valueAxis.makeDataItem({ value: 0 }));
let currentLabel = currentValueDataItem.get("label");
if (currentLabel) {
currentLabel.setAll({
fill: am5.color(0xffffff),
background: am5.Rectangle.new(root, { fill: am5.color(0x000000) })
})
}
let currentGrid = currentValueDataItem.get("grid");
if (currentGrid) {
currentGrid.setAll({ strokeOpacity: 0.5, strokeDasharray: [2, 5] });
}
// Add series
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
let valueSeries = mainPanel.series.push(
am5xy.CandlestickSeries.new(root, {
name: "AMCH",
clustered: false,
valueXField: "Date",
valueYField: "Close",
highValueYField: "High",
lowValueYField: "Low",
openValueYField: "Open",
calculateAggregates: true,
xAxis: dateAxis,
yAxis: valueAxis,
legendValueText:
"open: [bold]{openValueY}[/] high: [bold]{highValueY}[/] low: [bold]{lowValueY}[/] close: [bold]{valueY}[/]",
legendRangeValueText: ""
})
);
// Set main value series
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Setting_main_series
stockChart.set("stockSeries", valueSeries);
// Add a stock legend
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/stock-legend/
let valueLegend = mainPanel.plotContainer.children.push(
am5stock.StockLegend.new(root, {
stockChart: stockChart
})
);
// Set main series
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/stock-chart/#Setting_main_series
valueLegend.data.setAll([valueSeries]);
// Add cursor(s)
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/
mainPanel.set(
"cursor",
am5xy.XYCursor.new(root, {
yAxis: valueAxis,
xAxis: dateAxis,
snapToSeries: [valueSeries],
snapToSeriesBy: "y!"
})
);
// Add scrollbar
// -------------------------------------------------------------------------------
// https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/
let scrollbar = mainPanel.set(
"scrollbarX",
am5xy.XYChartScrollbar.new(root, {
orientation: "horizontal",
height: 50
})
);
stockChart.toolsContainer.children.push(scrollbar);
let sbDateAxis = scrollbar.chart.xAxes.push(
am5xy.GaplessDateAxis.new(root, {
baseInterval: {
timeUnit: "minute",
count: 1
},
renderer: am5xy.AxisRendererX.new(root, {})
})
);
let sbValueAxis = scrollbar.chart.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {})
})
);
let sbSeries = scrollbar.chart.series.push(
am5xy.LineSeries.new(root, {
valueYField: "Close",
valueXField: "Date",
xAxis: sbDateAxis,
yAxis: sbValueAxis
})
);
sbSeries.fills.template.setAll({
visible: true,
fillOpacity: 0.3
});
// Data generator
let firstDate = new Date();
let lastDate;
let value = 1200;
// data
function generateChartData() {
let chartData = [];
for (var i = 0; i < 50; i++) {
let newDate = new Date(firstDate);
newDate.setMinutes(newDate.getMinutes() - i);
value += Math.round((Math.random() < 0.49 ? 1 : -1) * Math.random() * 10);
let open = value + Math.round(Math.random() * 16 - 8);
let low = Math.min(value, open) - Math.round(Math.random() * 5);
let high = Math.max(value, open) + Math.round(Math.random() * 5);
chartData.unshift({
Date: newDate.getTime(),
Close: value,
Open: open,
Low: low,
High: high
});
lastDate = newDate;
}
return chartData;
}
let data = generateChartData();
// set data to all series
valueSeries.data.setAll(data);
sbSeries.data.setAll(data);
// update data
let previousDate;
setInterval(function() {
let valueSeries = stockChart.get("stockSeries");
let date = Date.now();
let lastDataObject = valueSeries.data.getIndex(valueSeries.data.length - 1);
if (lastDataObject) {
let previousDate = lastDataObject.Date;
let previousValue = lastDataObject.Close;
value = am5.math.round(previousValue + (Math.random() < 0.5 ? 1 : -1) * Math.random() * 2, 2);
let high = lastDataObject.High;
let low = lastDataObject.Low;
let open = lastDataObject.Open;
if (am5.time.checkChange(date, previousDate, "minute")) {
open = value;
high = value;
low = value;
let dObj1 = {
Date: date,
Close: value,
Open: value,
Low: value,
High: value
};
valueSeries.data.push(dObj1);
sbSeries.data.push(dObj1);
previousDate = date;
} else {
if (value > high) {
high = value;
}
if (value < low) {
low = value;
}
let dObj2 = {
Date: date,
Close: value,
Open: open,
Low: low,
High: high
};
valueSeries.data.setIndex(valueSeries.data.length - 1, dObj2);
sbSeries.data.setIndex(sbSeries.data.length - 1, dObj2);
}
// update current value
if (currentLabel) {
currentValueDataItem.animate({ key: "value", to: value, duration: 500, easing: am5.ease.out(am5.ease.cubic) });
currentLabel.set("text", stockChart.getNumberFormatter().format(value));
let bg = currentLabel.get("background");
if (bg) {
if(value < open){
bg.set("fill", root.interfaceColors.get("negative"));
}
else{
bg.set("fill", root.interfaceColors.get("positive"));
}
}
}
}
}, 1000);
}); // end am5.ready()
#chartdiv {
width: 100%;
height: 350px;
}
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
<script src="https://cdn.amcharts.com/lib/5/stock.js"></script>
<script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
<div id="chartdiv"></div>

Changing the color in heatmap in eCharts

Is there any way to change the default colors in a calendar-based heatmap? The default heatmap runs from shades of 'yellow' to 'red', based on the value. I want to change the colors so that the color runs from 'red' to 'green'.
This is the default color scheme
With the propriety "inRange" you can change the color variation of the values.
function getVirtulData(year) {
year = year || '2017';
var date = +echarts.number.parseDate(year + '-01-01');
var end = +echarts.number.parseDate(year + '-12-31');
var dayTime = 3600 * 24 * 1000;
var data = [];
for (var time = date; time <= end; time += dayTime) {
data.push([
echarts.format.formatTime('yyyy-MM-dd', time),
Math.floor(Math.random() * 1000)
]);
}
return data;
}
option = {
visualMap: {
min: 0,
max: 1000,
inRange : {
color: ['#DD2000', '#009000' ] //From smaller to bigger value ->
}
},
calendar: {
range: '2017'
},
series: {
type: 'heatmap',
coordinateSystem: 'calendar',
data: getVirtulData(2017)
}
};
You can also use in visualMap
pieces: [
{min: 0, max: 0.5, color: 'red'},
{min: 0.5, max: 1, color: 'green'},
],
to customize even more

highcharts can't render

I use Ajax to get data, when I debug with firebug, the result shows highcharts option's data has data. But the chart can't render correctly. The charts background is rended correctely, but there is no chart.
here is my code.
// # author:wang
var chart;
var element;
var chart_type_element;
var y_title_1;
var y_title_2;
var y_title_3;
var date = new Date();
var y = date.getUTCFullYear();
var m = date.getUTCMonth();
var d = date.getUTCDate()-1;
var h = date.getUTCHours();
var minute = date.getUTCMinutes();
/**
* 返回图表的类型
*
*/
function chart_type(element){
var type;
var wind = '风向风速';
var t_h = '温湿度';
if ( element== 'wind' ){
type = wind;
} else if ( element == 't_h') {
type = t_h;
}
return type;
}
/**
*
*return y-axis title
*
*/
function y_title(element, serie){
var title;
if ( element== 'wind' ){
switch (serie){
case 1: title = '风速'; break;
case 2: title = '阵风'; break;
case 3: title = '风向'; break;
}
} else if ( element == 't_h') {
switch (serie){
case 1: title = '温度'; break;
case 2: title = '湿度'; break;
default: title = '';
}
}
return title;
}
function getLocTime(nS) {
return new Date(parseInt(nS)).toLocaleString().replace(/年|月/g, "-").replace(/日/g, " ");
}
/**
* 气压配置选项
*/
var option_p = {
chart: {
renderTo: 'station_curve',
zoomType: 'x'
},
title:{
text:'气压序列图'
},
subtitle: {
text: '信科气象台'
},
xAxis: {
type: 'datetime',
maxZoom: 3600000, // one hour
title: {
text: null
}
},
yAxis: {
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}],
min:980,
max:1040
},
tooltip: {
formatter: function() {
return getLocTime(this.x) +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'left',
x: 220,
verticalAlign: 'top',
y: 30,
floating: true,
backgroundColor: '#FFFFFF'
},
series: [{
name: '海平面气压',
color: '#4572A7',
type: 'line',
pointInterval: 60 * 1000,
pointStart: Date.UTC(y,m,d,h,minute),
marker: {
enabled: false
}
}, {
name: '甲板气压',
type: 'line',
color: '#AA4643',
pointInterval: 60 * 1000,
pointStart: Date.UTC(y,m,d,h,minute),
marker: {
enabled: false
}
}/*, {
name: '3',
color: '#89A54E',
pointInterval: 60 * 1000,
pointStart: Date.UTC(y,m,d,h,minute),
type: 'spline',
marker: {
enabled: false
}
}*/]
};
function draw_curve(platformID,element){
option.series[0].data = [];
option.series[1].data = [];
option_th.series[0].data = [];
option_th.series[1].data = [];
jQuery.getJSON('get_last_3d.php',{platformID:platformID,element:element}, function(data) {
var serie=[];
var serie1=[];
if (element == 'wind_dir'){
$.each(data,function(i,value){
serie[i]=parseInt(value.wd);
});
option.series[0].data = serie.reverse();
} else if (element == 'wind_speed'){
$.each(data,function(i,value){
serie[i]=parseInt(value.ws);
serie1[i]=parseInt(value.ws_max);
});
option_wind_speed.series[0].data = serie.reverse();
option_wind_speed.series[1].data = serie1.reverse();
} else if (element == 't_h') {
$.each(data,function(i,value){
serie[i]=parseInt(value.t);
serie1[i]=parseInt(value.h);
});
option_th.series[0].data = serie.reverse();
option_th.series[1].data = serie1.reverse();
} else if (element == 'p') {
$.each(data,function(i,value){
serie[i]=parseInt(value.sea_p);
serie1[i]=parseInt(value.deck_p);
});
option_p.series[0] = serie.reverse();
option_p.series[1] = serie1.reverse();
} else if (element == 'wave_height') {
$.each(data,function(i,value){
serie[i]=parseInt(value.wave_height);
});
option.series[0].data = serie.reverse();
} else if (element == 'visibility') {
$.each(data,function(i,value){
serie[i]=parseInt(value.visibility);
});
option.series[0].data = serie.reverse();
} else if (element == 'cloudheight') {
$.each(data,function(i,value){
serie[i]=parseInt(value.cloud_height);
});
option.series[0].data = serie.reverse();
}
switch(element){
case 'p' :
chart = new Highcharts.Chart(option_p);
break;
case 't_h':
chart = new Highcharts.Chart(option_th);
break;
case 'wind_speed':
chart = new Highcharts.Chart(option_wind_speed);
break;
default:
chart = new Highcharts.Chart(option);
}
/* old code, will be replaced with switch
if (element == 'p')
chart = new Highcharts.Chart(option_p);
else {
chart = new Highcharts.Chart(option);
}
*/
});
}
$( function(){
draw_curve(105,'t_h');
})//end of jquery function
![the chart][1]
thank you advance
The reason it doesn't work is because you didn't provide the values for y,m,d,h,minute for the Date.UTC(y,m,d,h,minute) in the pointStart property for your series. See working: http://jsfiddle.net/LzfM3/

Logarithmic chart in FLOT

Does anyone have any idea how to create a logarithmic chart in FLOT?
Basically I am trying to create a chart that looks like the one shown here (top left):
http://leto.net/plot/examples/logarithms.html
However, I have given it a try using the same options but it doesn't show the chart the same way. I think there must have been a lot of changes to FLOT since then considering that the post is quite old.
If anyone has any idea, please do let me know.
Thanks.
You can do this using the "transform" option on the yaxis.
See work here.
$(function () {
// setup plot
function sampleFunction(x1, x2, func) {
var d = [ ];
var step = (x2-x1)/300;
for (var i = x1; i < x2; i += step )
d.push([i, func( i ) ]);
return d;
}
var options1 = {
lines: { show: true },
xaxis: { ticks: 4 },
yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
transform: function(v) {return Math.log(v+0.0001); /*move away from zero*/},
tickDecimals: 3 },
grid: { hoverable: true, clickable: true, color: "#999" }
};
var data1 = sampleFunction( 0, 5, function(x){ return Math.exp(x)*Math.sin(x)*Math.sin(x) } );
var plot1 = $.plot($("#chart1"), [ { label: "exp(x)sin(x)^2", data: data1 } ], options1);
});
Full Working Code:
$(function () {
// setup plot
function sampleFunction(x1, x2, func) {
var d = [ ];
var step = (x2-x1)/300;
for (var i = x1; i < x2; i += step )
d.push([i, func( i ) ]);
return d;
}
var options1 = {
lines: { show: true },
xaxis: { ticks: 4 },
yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
transform: function(v) {return Math.log(v+0.0001); /*move away from zero*/} , tickDecimals: 3 },
grid: { hoverable: true, clickable: true , color: "#999"}
};
var data1 = sampleFunction( 0, 5, function(x){ return Math.exp(x)*Math.sin(x)*Math.sin(x) } );
var plot1 = $.plot($("#chart1"), [ { label: "exp(x)sin(x)^2", data: data1} ], options1);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
<br/><br/>
<div id="chart1" style="width:600px;height:300px;"></div>
Great work Mark
As the ticks of Y axis in Logarithmic graphs are in the format of power of 10,
I would like to share enhancement in Y axis ticks, Here it is.s
$(function () {
// setup plot
function sampleFunction(x1, x2, func) {
var d = [ ];
var step = (x2-x1)/300;
for (var i = x1; i < x2; i += step )
d.push([i, func( i ) ]);
return d;
}
var options1 = {
lines: { show: true },
xaxis: { ticks: 4 },
yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
transform: function(v) {return Math.log(v+0.0001); /*move away from zero*/} , tickDecimals: 3 ,
tickFormatter: function (v, axis) {return "10" + (Math.round( Math.log(v)/Math.LN10)).toString().sup();}
},
grid: { hoverable: true, clickable: true , color: "#999"}
};
var data1 = sampleFunction( 0, 5, function(x){ return Math.exp(x)*Math.sin(x)*Math.sin(x) } );
var plot1 = $.plot($("#chart1"), [ { label: "exp(x)sin(x)" + "2".sup(), data: data1} ], options1);
});
Please let me know if there is any better way.
Thanks.
As the other answerer said, good work Mark. There is a way to make your solution more robust.
Mark's answer will work for most cases, but the plot will not look right for values near or less than 0.0001. Also, you don't need to modify every value to move away from zero. I believe that flot tries to transform 0 to determine where the "bottom" of the plot should be. Because of this, you will not be able to make your plot axis limits dynamic. This will make your plots look very bad if your values are much greater than 0.0001. Therefore, the following modification makes Mark's solution more robust, but it requires knowing the minimum y value (ymin below) in your data.
var options1 = {
lines: { show: true },
xaxis: { ticks: 4 },
yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
transform: Function("v","return v == 0 ? Math.log("+Math.pow(10,ymin)+") : Math.log(v);"), tickDecimals: 3 },
grid: { hoverable: true, clickable: true , color: "#999"}
};
It is base 10. The approach it should not be?
transform: function (v) {
if (v == 0) v = 0.0001;
return Math.log(v) / Math.log(10);
},
inverseTransform: function (v) {
Math.pow(10, v);
},