jQuery Flotcharts.js - zoom error? - javascript

I have this error with my plot when i add zoom in options:
Uncaught TypeError: Cannot read property 'apply' of undefined | jquery.flot.navigate.js:105
My code:
function plotSetUp(XTYPE_) {
console.log('plotSetup')
XTYPE = XTYPE_;
var V = [];
var PRK = [];
var r = 0;
if (!MONIT[CAR.id].route || MONIT[CAR.id].route.err) {
V.push([0, 0]);
} else {
for (var i = 0; i < PTS.length; i++) {
if (XTYPE == 'points') {
V.push([i, PTS[i].v]);
(PTS[i].key) ? PRK.push([i, null]): PRK.push([i, 100]);
} else if (XTYPE == 'time') {
V.push([getMsFromDate(PTS[i].dt), PTS[i].v]);
(PTS[i].key) ? PRK.push([getMsFromDate(PTS[i].dt), -20]): PRK.push([getMsFromDate(PTS[i].dt), 255]);
} else if (XTYPE == 'road') {
log(PTS[i].rgps);
V.push([PTS[i].rtah, PTS[i].v]);
}
}
}
var mode = null;
if (XTYPE == 'time') mode = 'time';
var options = {
grid: {
clickable: true,
hoverable: true
},
series: {
lines: {
show: true,
fill: true,
lineWidth: 0,
fillColor: {
colors: [{
opacity: 1
}, {
opacity: 1
}]
},
},
},
colors: ["rgba(41, 150, 206, 0.9)", "rgba(67, 90, 110, 0.4)", ],
crosshair: {
mode: "x",
color: "#323232",
lineWidth: 1,
},
xaxis: {
mode: mode,
show: true,
position: "bottom",
color: "#323232",
font: {
size: 10,
lineHeight: 15,
},
labelHeight: 15,
},
yaxis: {
show: true,
position: "left",
color: "#323232",
labelWidth: 20,
font: {
size: 10,
},
max: 150,
min: 0,
},
pan: {
interactive: true,
cursor: "move",
frameRate: 60,
},
zoom: {
interactive: true
},
tooltip: true,
tooltipOpts: {
id: 'flotTip',
content: '%x : %y km/h',
shifts: {
x: 10,
y: 20,
},
defaultTheme: true,
lines: {
track: false,
threshold: 0.05,
},
}
};
This is happen when i scroll over flot. How to fix it?
PS: Need to add more text, cos its mostly code but explained well :o
and more and more

Related

How to draw ApexCharts crosshair line from the marker (y value) to the bottom?

Using apexchart
const data = [45, 52, 78, 45, 69, 23, 30, 45, 52, 88]
const dataXCategories = ["10.12", "11.12", "12.12", "13.12", "14.12", "15.12", "16.12", "17.12", "18.12", "19.12"]
new ApexCharts(chart, {
chart: {
height: 165,
type: "area",
toolbar: {
show: false
}
},
stroke: {
show: true,
curve: 'smooth',
lineCap: 'butt',
colors: undefined,
width: 2,
dashArray: 0,
},
colors: ["#00f"],
dataLabels: {
enabled: false
},
series: [{
name: "Series 1",
data: data
}],
fill: {
type: "gradient",
gradient: {
shadeIntensity: 1,
opacityFrom: .7,
opacityTo: .9,
stops: [0, 90, 100]
}
},
xaxis: {
categories: dataXCategories,
labels: {
show: true,
format: 'dd/MM',
style: {
fontSize: "11px",
fontWeight: 400,
fontFamily: "Inter",
colors: ["#999", "#999", "#999", "#999", "#999", "#999", "#999", "#999", "#999", "#999"],
}
},
crosshairs: {
show: true,
opacity: 1,
position: 'front',
stroke: {
color: '#4A3AFF',
width: 2,
dashArray: 0
}
}
},
yaxis: {
min: 0,
max: 100,
tickAmount: 4,
labels: {
show: true,
offsetX: -12,
style: {
fontSize: "11px",
fontWeight: 400,
fontFamily: "Inter",
colors: ["#999"],
},
formatter: function(value) {
return `${value}%`;
}
},
},
grid: {
show: true,
borderColor: '#EDEDED',
strokeDashArray: 0,
position: 'back',
xaxis: {
lines: {
show: true
}
},
yaxis: {
lines: {
show: true
}
},
row: {
colors: undefined,
opacity: .5
},
column: {
colors: undefined,
opacity: .5
},
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
},
},
markers: {
colors: '#4A3AFF',
hover: {
size: undefined,
sizeOffset: 7
}
}
}).render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart" class="apex-charts" dir="ltr"></div>
Now the blue line is equal to the height of the graph
Please tell me how to make the line start from the marker to the bottom line x
I will be glad for any help
I do not think you can do this with simple configuration. However, since ApexCharts is based on SVG, you can manipulate the DOM yourself quite easily.
As I said previously in other answers, because I have already used this technique several times, what I am going to show you is more experimental than official.
It works, though.
In your case, the idea is to put some code in the mouseMove event callback. The use of a MutationObserver is recommended to watch for changes in the DOM. When a marker (which is a circle) is hovered, its r, cx and cy attributes are updated. In particular, cy is the most interesting because it gives us the vertical position of the active marker. r is also useful to adjust the offset of crosshairs.
Here is the main part of the code:
chart: {
// ...
events: {
mouseMove: () => {
let crosshairs = document.querySelector('.apexcharts-xcrosshairs'),
marker = document.querySelector('.apexcharts-marker');
let settings = { attributes: true },
observer = new MutationObserver(() => {
crosshairs.setAttribute('y1', `${marker.cy.baseVal.value + marker.r.baseVal.value + 1}`);
});
observer.observe(marker, settings);
}
}
},
Here is the full code:
const data = [45, 52, 78, 45, 69, 23, 30, 45, 52, 88];
const dataXCategories = ["10.12", "11.12", "12.12", "13.12", "14.12", "15.12", "16.12", "17.12", "18.12", "19.12"];
new ApexCharts(chart, {
chart: {
height: 165,
type: 'area',
toolbar: {
show: false
},
events: {
mouseMove: () => {
let crosshairs = document.querySelector('.apexcharts-xcrosshairs'),
marker = document.querySelector('.apexcharts-marker');
let settings = { attributes: true },
observer = new MutationObserver(() => {
crosshairs.setAttribute('y1', `${marker.cy.baseVal.value + marker.r.baseVal.value + 1}`);
});
observer.observe(marker, settings);
}
}
},
stroke: {
show: true,
curve: 'smooth',
lineCap: 'butt',
colors: undefined,
width: 2,
dashArray: 0,
},
colors: ['#00f'],
dataLabels: {
enabled: false
},
series: [{
name: 'Series 1',
data: data
}],
fill: {
type: 'gradient',
gradient: {
shadeIntensity: 1,
opacityFrom: .7,
opacityTo: .9,
stops: [0, 90, 100]
}
},
xaxis: {
categories: dataXCategories,
labels: {
show: true,
format: 'dd/MM',
style: {
fontSize: '11px',
fontWeight: 400,
fontFamily: 'Inter',
colors: ['#999', '#999', '#999', '#999', '#999', '#999', '#999', '#999', '#999', '#999']
}
},
crosshairs: {
show: true,
opacity: 1,
position: 'front',
stroke: {
color: '#4A3AFF',
width: 2,
dashArray: 0
}
}
},
yaxis: {
min: 0,
max: 100,
tickAmount: 4,
labels: {
show: true,
offsetX: -12,
style: {
fontSize: '11px',
fontWeight: 400,
fontFamily: 'Inter',
colors: ['#999']
},
formatter: value => `${value}%`
},
},
grid: {
show: true,
borderColor: '#EDEDED',
strokeDashArray: 0,
position: 'back',
xaxis: {
lines: {
show: true
}
},
yaxis: {
lines: {
show: true
}
},
row: {
colors: undefined,
opacity: .5
},
column: {
colors: undefined,
opacity: .5
},
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0
},
},
markers: {
colors: '#4A3AFF',
hover: {
size: undefined,
sizeOffset: 7
}
}
}).render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart" class="apex-charts" dir="ltr"></div>

E-charts Needle Color

Anyone here can help me how to change the color of a needle in my speedometer chart? I copied this chart in Apache E-charts.
This is the script:
var dom = document.getElementById('performance-chart');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
option = {
series: [
{
type: 'gauge',
progress: {
show: true,
width: 18,
itemStyle: {
borderWidth: 10,
color: '#8D7CDB'
}
},
axisLine: {
lineStyle: {
width: 18
}
},
axisTick: {
show: false
},
splitLine: {
length: 5,
lineStyle: {
width: 1,
color: '#8D7CDB'
}
},
axisLabel: {
distance: 25,
color: '#8D7CDB',
fontSize: 9
},
anchor: {
show: true,
showAbove: true,
size: 25,
color: '#8D7CDB',
itemStyle: {
borderWidth: 8,
borderColor: '#8D7CDB'
}
},
title: {
show: false
},
detail: {
valueAnimation: true,
fontSize: 20,
color: '#8D7CDB',
formatter: "{value}%",
offsetCenter: [0, '70%']
},
data: [
{
value: 5.85
}
]
}
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
The 'needle' is represented by the pointer parameter. Like most of echarts items, you can change the pointer style with itemStyle.
series: [
{
type: 'gauge',
... // the rest of the config
pointer: {
itemStyle: {
color: 'red'
}
},
},
]

Add second series to highchart master detail

I'm using highcharts to create a master-detail chart, could you help me how to add another series type area to the chart? i have used example from official site, but i cant imagine how to add second area to this chart
const priceChart1 = Highcharts.getJSON(
'https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/usdeur.json',
data => {
let detailChart;
// create the detail chart
function createDetail(masterChart) {
// prepare the detail chart
var detailData = [],
detailStart = data[0][0];
masterChart.series[0].data.forEach(point => {
if (point.x >= detailStart) {
detailData.push(point.y);
}
});
// create a detail chart referenced by a global variable
detailChart = Highcharts.chart('detail-container', {
chart: {
zoomType: "x",
spacingLeft: 10,
spacingRight: -20,
borderRadius: 10,
backgroundColor: "#F3F3F3",
borderColor: "#335cad",
height: priceChartHeight,
style: { fontFamily: "Manrope" },
style: {
position: 'absolute'
},
resetZoomButton: {
position: {
// align: 'right', // by default
// verticalAlign: 'top', // by default
x: -40,
y: 5
},
theme: {
fill: '#377DED',
stroke: 'transparent',
r: 0,
style: {
color: 'white',
borderRadius: 10
},
states: {
hover: {
fill: '#41739D',
style: {
color: 'white'
},
},
},
},
},
marginBottom: 90,
reflow: false,
marginLeft: 10,
style: {
position: 'absolute'
}
},
credits: {
enabled: false
},
title: {
text: null,
align: 'left'
},
subtitle: {
text: null,
align: 'left'
},
xAxis: {
type: 'datetime',
visible: false,
},
yAxis: {
title: {
text: null,
},
opposite: true,
gridLineColor: "rgba(87, 87, 87, 0.15)",
gridLineDashStyle: "dash",
left: -40
},
tooltip: {
formatter: function () {
var point = this.points[0];
return '' + '<br/>' + ' <span style="font-weight: 700;font-size: 14px; line-height: 19px; color: #377DED;"> ' + Highcharts.numberFormat(point.y, 2) + '</span> ' + '<span style="font-size: 9px; font-weight: 300; line-height: 12px; color: rgba(51,51,51, 0.25)">Nominal</span>' + '<br/> ' + '<span style="font-size: 9px; font-weight: 300; line-height: 12px; color: rgba(51,51,51, 0.25)">' + Highcharts.dateFormat('%e %B %Y', this.x) + '</span>' },
shared: true,
borderRadius: 5,
borderColor: 'transparent',
shadow: false,
backgroundColor: '#fff'
},
legend: {
enabled: false
},
plotOptions: {
series: {
marker: {
enabled: false,
states: {
hover: {
enabled: true,
radius: 3
}
}
}
}
},
series: [
{
name: 'Nominal',
data: detailData,
type: 'area',
},
],
exporting: {
enabled: false
}
}); // return chart
}
// create the master chart
function createMaster() {
Highcharts.chart('master-container', {
chart: {
reflow: false,
borderWidth: 0,
backgroundColor: null,
spacingLeft: 10,
spacingRight: 30,
borderRadius: 10,
zoomType: 'x',
events: {
// listen to the selection event on the master chart to update the
// extremes of the detail chart
selection: function (event) {
var extremesObject = event.xAxis[0],
min = extremesObject.min,
max = extremesObject.max,
detailData = [],
xAxis = this.xAxis[0];
// reverse engineer the last part of the data
this.series[0].data.forEach(point => {
if (point.x > min && point.x < max) {
detailData.push([point.x, point.y]);
}
});
// move the plot bands to reflect the new detail span
xAxis.removePlotBand('mask-before');
xAxis.addPlotBand({
id: 'mask-before',
from: data[0][0],
to: min,
color: 'rgba(0, 0, 0, 0)'
});
xAxis.removePlotBand('mask-after');
xAxis.addPlotBand({
id: 'mask-after',
from: max,
to: data[data.length - 1][0],
color: 'rgba(0, 0, 0, 0)'
});
xAxis.addPlotBand({
id: 'mask-after',
from: min,
to: max,
color: 'rgba(255, 255, 255, 1)',
borderColor: "#377DED",
borderWidth: 2
});
detailChart.series[0].setData(detailData);
console.log(min)
console.log(max)
return false;
}
}
},
title: {
text: null
},
accessibility: {
enabled: false
},
xAxis: {
type: "datetime",
labels: { format: '{value:%b %e }' },
crosshair: {
color: '#377DED80'
},
lineWidth: 0, minorGridLineWidth: 0, lineColor: 'transparent', minorTickLength: 0, tickLength: 0,
top: -5,
showLastTickLabel: true,
maxZoom: 14 * 24 * 3600000, // fourteen days
plotBands: [{
id: 'mask-before',
from: data[0][0],
to: data[data.length - 1][0],
color: 'rgba(0, 0, 0, 0)'
}],
title: {
text: null
},
},
yAxis: {
gridLineWidth: 0,
labels: {
enabled: false
},
title: {
text: null
},
min: 0.6,
showFirstLabel: false
},
tooltip: {
borderRadius: 50,
borderColor: 'red'
},
legend: {
enabled: false
},
credits: {
enabled: false
},
plotOptions: {
series: {
fillColor: {
linearGradient: [0, 0, 0, 70],
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, 'rgba(255,255,255,0)']
]
},
lineWidth: 1,
marker: {
enabled: false
},
shadow: false,
states: {
hover: {
lineWidth: 1
}
},
enableMouseTracking: false
}
},
series: [{
type: 'area',
name: 'USD to EUR',
pointInterval: 24 * 3600 * 1000,
pointStart: data[0][0],
data: data
}],
exporting: {
enabled: false
}
}, masterChart => {
createDetail(masterChart);
}); // return chart instance
}
// make the container smaller and add a second container for the master chart
const container = document.getElementById('price-chart-main');
container.style.position = 'relative';
container.innerHTML += '<div id="detail-container" style="height: 100%"></div><div id="master-container" style="height: 90px; position: absolute; bottom: 0; width: 100%"></div>';
// create master and in its callback, create the detail chart
createMaster();
}
);
there is example that i used https://www.highcharts.com/demo/dynamic-master-detail
Adding a new series to a master-detail chart is very simple. You need to only add a new data set and connect it to the right series. For example:
var detailData = [
[],
[]
],
detailStart = data1[0][0];
masterChart.series.forEach((s, index) => {
s.points.forEach(point => {
if (point.x >= detailStart) {
detailData[index].push(point.y);
}
});
});
// create a detail chart referenced by a global variable
detailChart = Highcharts.chart('detail-container', {
chart: {
type: 'area',
...
},
...,
series: [{
data: detailData[0]
}, {
data: detailData[1]
}]
});
Live demo: https://jsfiddle.net/BlackLabel/97dxakfe/
API Reference: https://api.highcharts.com/highcharts/series

ui-jq flot chart on lazy load

I have the following html:
<div id="test" ui-jq="plot" ui-options="
[
{ data: {{line}}, points: { show: true, radius: 6}, splines: { show: true, tension: 0.45, lineWidth: 5, fill: 0 }, label: 'Akademi' },
],
{
colors: ['{{app.color.info}}', '{{app.color.success}}'],
series: { shadowSize: 3 },
xaxis:{
font: { color: '#ccc' },
position: 'bottom',
ticks: {{categories}}
},
yaxis:{ font: { color: '#ccc' } },
grid: { hoverable: true, clickable: true, borderWidth: 0, color: '#ccc' },
tooltip: true,
tooltipOpts: { content: '%x.1 is %y.4', defaultTheme: false, shifts: { x: 0, y: 20 } },
redrawOverlayInterval: 60
}
" style="height:240px">
</div>
The data for this chart is being loaded by a $http get request:
$http.get(api.getUrl('latestActivityByTeamAndModule', [$scope.team_id, $scope.module_id]))
.success(function(response){
var i = 0;
$scope.line = [];
$scope.categories = [];
response.forEach(function(y){
var log_date = y.date.substr(0, y.date.indexOf('T'));
var date = new Date(log_date);
var logg_date = moment(date).fromNow();
$scope.categories.push(logg_date);
$scope.line.push(y.num_taken);
});
});
Sadly when i force reload (F5) the chart is empty. HOWEVER the html is correctly updated:
From inspecting the element in chrome:
<div id="test" ui-jq="plot" ui-options="[
{ data: [4], points: { show: true, radius: 6}, splines: { show: true, tension: 0.45, lineWidth: 5, fill: 0 }, label: 'Akademi' },
],
{
colors: ['#23b7e5', '#27c24c'],
series: { shadowSize: 3 },
xaxis:{
font: { color: '#ccc' },
position: 'bottom',
ticks: ["21 hours ago"]
},
yaxis:{ font: { color: '#ccc' } },
grid: { hoverable: true, clickable: true, borderWidth: 0, color: '#ccc' },
tooltip: true,
tooltipOpts: { content: '%x.1 is %y.4', defaultTheme: false, shifts: { x: 0, y: 20 } },
redrawOverlayInterval: 60
}" style="height: 240px; padding: 0px; position: relative;">
im guessing its because of the lazy load so that it does not redraw on the data change?
Try adding ui-refresh
<div id="test" ui-jq="plot" ui-refresh="line" ui-options="[{ data: {{line}}, ... }, ... ]"></div>
Where ui-refresh value is the literal name of ui-options data value name.

Hide Series on Click with jQuery Flot

I have a Flot graph which I am trying to make it so that when you click a particular legend item it makes that data disappear from the chart.
I am having limited success in getting this to work. I've gotten as far as being able to click a legend item and a series line is removed, but not the points, and it appears to be the wrong line data as well.
Any help on this would be really appreciated :)
var Graphs = function () {
return {
//main function
initCharts: function () {
if (!jQuery.plot) {
return;
}
function showChartTooltip(x, y, xValue, yValue) {
$('<div id="tooltip" class="chart-tooltip">' + yValue + '<\/div>').css({
position: 'absolute',
display: 'none',
top: y - 40,
left: x - 40,
border: '0px solid #ccc',
padding: '2px 6px',
'background-color': '#fff'
}).appendTo("body").fadeIn(200);
}
if ($('#site_revenue').size() != 0) {
//site revenue
var previousPoint2 = null;
var plot_statistics = null;
var data = [];
togglePlot = function(seriesIdx)
{
var previousPoint2 = plot_statistics.getData();
previousPoint2[seriesIdx].lines.show = !previousPoint2[seriesIdx].lines.show;
plot_statistics.setData(previousPoint2);
plot_statistics.draw();
}
$('#site_revenue_loading').hide();
$('#site_revenue_content').show();
var data = [{
label: "Gross Revenue",
color: ['#44b5b1'],
points: {
fillColor: "#44b5b1"
},
data: [
['Sep', 264.41],
['Aug', 6653.98],
['Jul', 921.35],
['Jun', 937.00],
['May', 1839.25],
['Apr', 1561.96],
['Mar', 2289.62],
['Feb', 2661.91],
['Jan', 6021.44],
['Dec', 4129.21],
['Nov', 0.00],
['Oct', 2865.28],
],
idx:1
},{
label: "Tax",
color: ['#8fc2ed'],
points: {
fillColor: "#8fc2ed"
},
data: [
['Sep', 0.00],
['Aug', 2865.28],
['Jul', 2661.91],
['Jun', 6653.98],
['May', 6021.44],
['Apr', 0.00],
['Mar', 2289.62],
['Feb', 1561.96],
['Jan', 921.35],
['Dec', 937.00],
['Nov', 1839.25],
['Oct', 4129.21]
],
idx: 2
}];
var plot_statistics = $.plot($("#site_revenue"), data, {
series: {
lines: {
show: true,
fill: 0.2,
lineWidth: 0,
fill: false,
lineWidth: 3
},
shadowSize: 1,
points: {
show: true,
fill: true,
radius: 4,
lineWidth: 2
},
},
xaxis: {
tickLength: 0,
tickDecimals: 0,
mode: "categories",
min: 0,
font: {
lineHeight: 18,
style: "normal",
variant: "small-caps",
color: "#6F7B8A"
}
},
yaxis: {
ticks: 5,
tickDecimals: 0,
tickColor: "#eee",
font: {
lineHeight: 14,
style: "normal",
variant: "small-caps",
color: "#6F7B8A"
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#eee",
borderColor: "#eee",
borderWidth: 1
},
legend: {
show: true,
placement: 'outsideGrid',
container: $('#site_revenue_legend'),
labelFormatter: function(label, series){
return ''+label+'';
}
}
});
$("#site_revenue").bind("plothover", function (event, pos, item) {
$("#x").text(pos.x.toFixed(2));
$("#y").text(pos.y.toFixed(2));
if (item) {
if (previousPoint2 != item.dataIndex) {
previousPoint2 = item.dataIndex;
$("#tooltip").remove();
var x = item.datapoint[0].toFixed(2),
y = item.datapoint[1].toFixed(2);
showChartTooltip(item.pageX, item.pageY, item.datapoint[0], '$' + item.datapoint[1]);
}
}
});
$('#site_revenue').bind("mouseleave", function () {
$("#tooltip").remove();
});
}
}
};
}();
jQuery(document).ready(function() {
Graphs.initCharts(); // init index page's custom scripts
});
JSFiddle: http://jsfiddle.net/fxc4vyg3/
You must be tired, you just have an off-by-one error, and you only called the update for the lines, not the points.
togglePlot = function(seriesIdx)
{
var previousPoint2 = plot_statistics.getData();
seriesIdx--; // ***HERE***
previousPoint2[seriesIdx].points.show = // ***AND HERE***
previousPoint2[seriesIdx].lines.show = !previousPoint2[seriesIdx].lines.show;
plot_statistics.setData(previousPoint2);
plot_statistics.draw();
}
Here's the fixed fiddle: http://jsfiddle.net/it_turns_out/fxc4vyg3/3/

Categories

Resources