I'm using highcharts to build my charts that shows the values that comes from a sensor placed into my garage: all of these values are numeric values, so, i have no problem to build a graph like the following one JSFIDDLE
As i've said, all of the values that comes from the sensor are numeric, except one: the "status", this value is a string value type and it's not a fixed string, it can be:
Transmitting
Standby
Active
Alarm
Or any free string
So, my intention is - and i don't know if that can be feasible - to draw a graph with a fixed serie value (e.g.: 1...maybe i have to use a javascript function that maps the "status" to a given value?) and show that string as fixed datalabels as shown in the fiddle that i've posted.
Final Remarks:
The data that comes from the sensor is a time-series value, like the following:
{"datetime": 1566730095, "status": "transmitting"}
{"datetime": 1566730162, "status": "hello! i'm here"}
This chart will be a separate chart instead the numeric charts, in order to simplify the build and management.
The final goal can be something like that (the following graph is a pure graphical example):
To achieve it you can map data like that:
series: [{
dataLabels: {
enabled: true,
format: '{point.name}',
rotation: -45,
align: 'left',
y: -8
},
data: data.map(item => {
return {
x: item.datetime,
y: 1,
name: item.status
};
})
}]
Demo:
https://jsfiddle.net/BlackLabel/840tv6mz/
To change the way data is exported to CSV you can use this wrapper (edit it as needed):
(function(H) {
H.wrap(H.Chart.prototype, 'getDataRows', function(proceed, multiLevelHeaders) {
var rows = proceed.call(this, multiLevelHeaders);
rows[0][0] = 'Time';
rows[0][1] = 'Status';
rows = rows.map(row => {
if (row.x) {
row[0] = H.dateFormat('%H:%M:%S.%L', row.x);
row[1] = row.name;
}
return row;
});
return rows;
});
}(Highcharts));
Demo:
https://jsfiddle.net/BlackLabel/to92mbu0/
Related
Good morning.
I need to do the following: Update a stacked line chart using a function in javascript that takes a 2d array ([[0,1],[0,2],...]).
My page is running in a Java fx webview so I can dynamically update my data. All the examples I've seen so far create a predefined X axis and pass the y values accordingly, I wanted to pass the two values together to plot a line on the chart.
How could I make this function? It's the first time I use echarts so I'm lost.
I even managed to do something similar but when plotting the chart it was all wrong.
Char Image
var option = {
xAxis: {
type: "value",
},
yAxis: {
type: "value",
},
series: [
{
type: "line",
data: [],
},
],
};
vibrationStackedLineChart.setOption(option);
function updateEchart(dataArray) {
// Parse the JSON string back into a 2D int array
var data = JSON.parse("[" + dataArray + "]");
// Update the chart with the new data
vibrationStackedLineChart.setOption({
series: [
{
data: data,
},
],
});
}
Java function with array 2d
So I have 6 series I'm using in a single highcharts treemap chart where each series is it's own, smaller tree map. I can't get each of the names of the series to appear in the legend because the showInLegend property is a level above the data property.
I've tried two different configurations. First: series is set to my chartData variable, which looks like:
[{
name: key,
stack: key,
id: key,
showInLegend: true,
color: colors[key],
data: sliced
},
{...}]
And so forth. This gives me a single treemap chart with each series underneath the previous, aka they are stacked on top of each other.
If I combine them all into a single data array, I can get the proper chart format I'm looking for, where each individual series is grouped by color/parent and so forth. This was done using data-less data points, like so:
{
name,
id,
showInLegend,
color
}
and each of the other points then would be:
{
name
parent
value
}
This large data array is then given to a series array that looks like:
[{
type: 'treemap',
layoutAlgorithm: 'squarified',
data: dataArray from above,
}]
Again, I want the chart to be multiple tree maps, not one jammed on top of the other. But i also need the legend to show all of those series' names
You can use unofficial legendType: 'point' property and remove unnecessary elements in afterGetAllItems legend event:
var H = Highcharts;
H.addEvent(H.Legend, 'afterGetAllItems', function(e) {
e.allItems.splice(2, 6);
});
H.chart('container', {
series: [{
legendType: 'point',
showInLegend: true,
...
}]
});
Live demo: https://jsfiddle.net/BlackLabel/gp2qmvac/
API Reference: https://api.highcharts.com/highcharts/series.treemap.showInLegend
Docs: https://www.highcharts.com/docs/extending-highcharts
I have a page where I can put in two timeintervals and after posting these two timeintervals I get the amount of sold tickets between these two dates.
i get back multiple data depending on how far back I go.
My problem:
If I go as far back as to the first insert of the database.
I will get a high value of for example 200 tickets and after that I calculate the difference between each row in the database which gives me a chart like this:
As you see in the image I would like to reduce the space between the y-axis points in order to see the smaller values better.
In the example above I have a bar that is 160 and other bars that are for example 1 or 2 and I can hardly see them on the chart
Code for this:
buildCharts: function (target, chartData, chartEnum) {
$(target).highcharts({
chart: {
type: 'column',
height: 300,
},
title: {
text: chartEnum.name
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: chartEnum.text
}
},
series: [{
name: 'SystemInfo',
showInLegend: false,
colorByPoint: false,
data: chartData,
turboThreshold: chartData.length + 500
}],
});
}
How can I reduce space between y-axis points?
Using the "tickInterval" attribute is the easiest way to go about this (see http://api.highcharts.com/highcharts#xAxis.tickInterval).
If you wanted to set this based upon the total number of tickets you're viewing (assuming from your question that you can choose the point in time you want to start), what you could do is set that tickInterval based on the length of your series data (for example, if the data more than 100 items, set a tickInterval of 4; otherwise, set a tickInterval of 2 or 1). Do this by creating the chart's options, and then changing the value in the options after you grab your data, but before drawing/redrawing the chart.
I'm creating a line chart using n3 line chart in my angular app.
My data is array of dates and counts.
This is the result I get:
As you can see, the X axis values are inconsistent.
It has a tick every 12 hours, but each tick has different format. I'm trying to keep the format the same for every tick, i.e:
This is how I include the chart in my html:
<linechart class="linechart" data="data" options="options"></linechart>
This is my axes options:
$scope.options = {
axes: {
x: {
key: "from",
type: "date",
innerTicks: false,
grid: false,
ticksInterval: d3.time.days
},
y: {
ticks: 6,
ticksFormatter: $scope. formatNumber
}
}
I've tried to use diffent values for ticks and ticksInterval but with no success.
Any way to achieve this?
Thank you.
I had the same problem today.
I solved it using thickFormat and the d3.time.format() function.
axes : {
x : {
key : "date",
type : 'date',
tickFormat : d3.time.format("%x %X")
}
}
I looked up Highcharts' API references and couldn't find a particular function to select a time range.
My purpose is to bind a function to an input button. When I click on it, it will choose a range.
I found that in Highstock there's a range selector with built-in buttons.
Is there any existing function to do that in Highcharts? Or how can I do it with custom javascript?
If you want something simple, like a preset range requiring no interaction from user by selecting over the graph area, you can use what is explained in this link.
Improving a bit, the idea is that your button handles the values needed for the range and supply them to the function below. When it runs, the graph gets redrawn, reflecting the new range.
function renderGraph(xmin, xmax, ymin, ymax){
var chart = new Highcharts.Chart({
xAxis: {
min: xmin,
max: xmax
},
yAxis: {
min: ymin,
max: ymax
},
chart: {
renderTo: "graph-container",
},
title: { text: null },
credits: { enabled: false}
});
}
Hope it helps.
if you're able to use the built-in range selector, try specifying the selected option (api reference), like this:
rangeSelector: {
enabled:true,
buttons: [
{type: 'week', count: 6, text: '6w'},
{type: 'week', count: 12, text: '12w'}
],
selected: 1 // uses a zero-based index
},
if this doesn't suit your needs, and if you're reading the chart data from json, then you could try something like the following:
$('#button_id_value').click(function() {
buildChart(some_hardcoded_time_value_selection); // you will have to specify a value that matches your json data
});
function buildChart(selected_time_value){
d3.json("/path/to/your/data.json", function(error, json_data) {
if (error) return console.warn(error);
chart_series = json_data.filter(function(d, i){
return (selected_time_value == d["time_value"]);
});
$('#container').highcharts({
chart: {type: 'column'},
// ... more chart options ...
series: chart_series,
// ... more chart options ...
});
});
});
fyi - this last solution requires d3 and jquery.