Related
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.
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>
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
i am trying to build a meteogram as this
In this chart there's xaxis below with values like 00,06,12,18
These are fine but how can i add the above values like satNov14, sunNov15, MonNov16
as there's multiple Yaxis but no multiple xaxis.
I am trying this , but after that am not getting the above dates in proper order
final Chart chart = new Chart()
.setBorderColor("#C7D5D5")
.setBorderWidth(3)
.setBorderRadius(0)
.setBackgroundColor("#FFFFFF")
.setChartTitleText("Meteogram")
.setSpacingTop(5)
.setChartSubtitleText("yr.no")
.setColumnPlotOptions(new ColumnPlotOptions()
.setDataLabels(new DataLabels()
.setEnabled(true)
) )
.setToolTip(new ToolTip()
.setFormatter(new ToolTipFormatter() {
public String format(ToolTipData toolTipData) {
String s;
if (toolTipData.getPointName() != null) {
s = toolTipData.getPointName() + ": " +
toolTipData.getYAsLong() + " ,";
} else {
s = toolTipData.getXAsString() + ": " +
toolTipData.getYAsLong();
}
return s;
}
})
)
.setLabelItems(
new LabelItem()
.setHtml("")
.setStyle(new Style()
.setLeft("40px")
.setTop("8px")
.setColor("black")
)
);
// Primary yAxis
chart.getYAxis(0).setGridLineWidth(1).setAxisTitleText("test")
.setAxisTitle(new AxisTitle()
.setText("")
)
.setLabels(new YAxisLabels()
//// .setStyle(new Style()
//// .setColor("#89A54E")
// )
.setFormatter(new AxisLabelsFormatter() {
public String format(AxisLabelsData axisLabelsData) {
return axisLabelsData.getValueAsLong() + "°";
}
})
);
// Secondary yAxis
chart.getYAxis(1).setGridLineWidth(2)
.setAxisTitle(new AxisTitle()
.setText("")
)
.setOpposite(true)
.setLabels(new YAxisLabels()
.setFormatter(new AxisLabelsFormatter() {
public String format(AxisLabelsData axisLabelsData) {
return axisLabelsData.getValueAsLong() + "°";
}
})
);
Point p1 = new Point(5, 5);
Marker m = new Marker();
m.setEnabled(true);
m.setOption("symbol", "url(41.png)");
p1.setMarker(m);
Point p2 = new Point(4.5, 4.5);
p2.setMarker(m);
Point p3 = new Point(4, 4);
Marker m1 = new Marker();
m1.setEnabled(true);
m1.setOption("symbol", "url(41.png)");
p3.setMarker(m1);
chart.getXAxis(1).setGridLineWidth(1).setLinkedTo(0)
.setOpposite(true)
.setCategories("Sat Nov13", "Sat Nov14", "Sat Nov15", "Sat Nov16");
chart.getXAxis(0).setGridLineWidth(1)
.setCategories("18","00","06","12","18","00","06","12","18","00","06","12","18","00","06","12","18") ;
chart.addSeries(chart.createSeries()
.setName("")
.setType(Series.Type.COLUMN)
.setPlotOptions(new ColumnPlotOptions()
.setColor("#24CBE5"))
.setPoints(new Number[]{
0,0,0,3,5,3,0,1,3,1,0,0,0,0}
)
.setYAxis(1)
);
chart.addSeries(chart.createSeries()
.setName("")
.setType(Series.Type.SPLINE)
.setPoints(new Number[]{
5,4.5,4,5,1,0,0,0,3,5,6,3,7,2 })
.setPlotOptions(new ColumnPlotOptions()
.setMarker(m1)
.setColor("#4572A7"))
);
return chart;
}
Attached is my output
Any Suggestions
Thanks
Like #Strelok said, the code is in the <script> tag if you right click the page and view source.
xAxis: [
{
type: 'datetime',
tickInterval: 6 * 3600 * 1000,
tickPosition: 'inside',
tickLength: 30,
gridLineWidth: 1,
gridLineColor: '#F0F0F0',
startOnTick: false,
endOnTick: false,
minPadding: 0,
maxPadding: 0,
offset: 30,
showLastLabel: true,
labels: {
formatter: function(){
return Highcharts.dateFormat('%H', this.value);
}
}
},
{
linkedTo: 0,
tickInterval: 24 * 3600 * 1000,
labels: {
formatter: function(){
return Highcharts.dateFormat(
'<span style="font-size: 12px; font-weight: bold">%a</span>, %b %e', this.value);
},
align: 'left',
x: 3
},
opposite: true,
tickLength: 20,
gridLineWidth: 1
}],
Top part is for bottom labels, bottom part is for top labels from the looks of it.
edit:
Give this a shot.
chart.getXAxis(1)
.setLinkedTo(0)
.setGridLineWidth(1)
.setOpposite(true)
.setTickInterval(24 * 3600 * 1000) // 24 hour tick intervals
.setCategories("Sat Nov13", "Sat Nov14", "Sat Nov15", "Sat Nov16");
chart.getXAxis(0)
.setGridLineWidth(1)
.setCategories("18","00","06","12","18","00","06","12","18","00","06","12","18","00","06","12","18");
.setTickInterval(6 * 3600 * 1000) // 6 hour tick intervals
.setTickPosition("inside")
.setStartOnTick(false)
.setEndOnTick(false)
.setOffset(30)
.setShowLastLabel(true)
in case you use unix epoch timestamps for your dates and if you need it the timestamp to be displayed in date format - just set the type of the axis to datetime
for example:
xAxis: {
type: 'datetime'
}
});
check this fiddle: http://jsfiddle.net/HnwbQ/1/
reference: http://www.highcharts.com/ref/#xAxis--type
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);
},