I've always use flot.js for common charting requirements, but I'd like to explore new ways to visualize data that might be beyond this charting library. I'd appreciate any advice or recommendations as to how others might programmatically render the custom display chart below. Maybe CSS?
I know you probably weren't looking for an answer spelling out how to implement this in flot, but it was a fun exercise.
Getting creative with hiding and stacking bars with the stack plugin allows you to represent your bounds. For each set of bounds, you'll need to create a hidden bar with your lower bound value and then create a visible bar with your upper bound value (and stack the two). Specifying which bars should stack on each other is easy by setting the stack option to the same key.
Once the bars are setup, the next step is to set the options of the chart. A grid marking handles displaying the current value. Hiding both axes effectively hides the grid.
The rest comes down to creating methods to append div elements to placeholder to show the bar values, labels, and marking value.
This is a basic implementation of your example image that really focuses on the flot component of the chart. With a bit more time, the extra appended div elements could be styled in such a way to more closely match your example.
This JSFiddle contains the code below for easier review.
$(function() {
var data = [{
data: [ [0, 21.51] ],
lines: { show: false },
bars: { show: false },
stack: 0,
label: 'Hidden'
},{
data: [ [1, 32.50] ],
lines: { show: false },
bars: { show: false },
stack: 1,
label: 'Hidden'
},{
data: [ [2, 47.14] ],
lines: { show: false },
bars: { show: false },
stack: 2,
label: 'Hidden'
},{
data: [ [0, 37.77] ],
stack: 0,
label: 'Last Year'
},{
data: [ [1, 24.65] ],
stack: 1,
label: 'Last Month'
}, {
data: [ [2, 7.67] ],
stack: 2,
label: 'Last Week'
}];
var options = {
series: {
bars: { show: true },
points: { show: false }
},
xaxis: { show: false },
yaxis: { show: false },
grid: {
show: true,
borderWidth: 0,
backgroundColor: null,
markings: [{
xaxis: { from: 0, to: 3 },
yaxis: { from: 48.01, to: 48.01 },
color: "#000000"
}]
},
legend: { show: false }
};
var plot = $.plot($('#graph'), data, options);
var plotData = plot.getData();
var markings = plot.getOptions().grid.markings;
displayBarValues(plotData);
displayBarLabels(plotData);
displayMarkingValues(markings);
// display values next to bars
function displayBarValues(plotData) {
$.each(plotData, function(i, data) {
var stackedValue = data.data[0][1];
if (data.bars.show) {
stackedValue = findStackedValue(plotData, data.stack);
}
var offset = plot.pointOffset({x: data.data[0][0], y: stackedValue});
$('<div class="data-point-value">-- $' + stackedValue + '</div>').css( {
left: offset.left + 30,
top: offset.top - 8,
}).appendTo(plot.getPlaceholder());
});
}
function findStackedValue(dataSeries, stackNumber) {
var stackedValue = 0;
for (var i =0; i < dataSeries.length; i++) {
if (dataSeries[i].stack === stackNumber) {
stackedValue = stackedValue + dataSeries[i].data[0][1];
}
}
return stackedValue;
}
// display a marking value
function displayMarkingValues(markings) {
$.each(markings, function(i, marking) {
var offset = plot.pointOffset({x: marking.xaxis.to, y: marking.yaxis.to });
$('<div class="data-point-value">------ $' + marking.yaxis.to + '</div>').css( {
left: offset.left,
top: offset.top - 8,
}).appendTo(plot.getPlaceholder());
});
}
function displayBarLabels(plotData) {
$.each(plotData, function(i, data) {
if (data.bars.show) {
var stackedValue = findStackedValue(plotData, data.stack);
var offset = plot.pointOffset({x: data.data[0][0], y: stackedValue});
$('<div class="data-point-label">' + data.label + '</div>').css({
left: offset.left - 35,
top: offset.top + 50,
}).appendTo(plot.getPlaceholder());
}
});
}
});
#graph {
margin: 0 auto;
text-align: center;
width: 100px;
height: 600px;
}
.data-point-value {
position: absolute;
white-space: nowrap;
font-size: 11px;
}
.data-point-label {
position: absolute;
white-space: nowrap;
width: 100px;
font-size: 11px;
text-align: right;
-webkit-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.js"></script>
<script src="https://rawgit.com/emmerich/flot-orderBars/master/js/jquery.flot.orderBars.js"></script>
<script src="https://rawgit.com/flot/flot/master/source/jquery.flot.stack.js"></script>
<div id="graph"></div>
I have used Fusion Charts. Its pretty easy to customize and it works well in all browsers. Also have a look at Chart JS. Its pretty cool and its open source
I'v been using Chart.js for a while. While it is sweet at first glance, and you really can do super awesome stuff with it out of the box, it can be really limiting later on when you come across the need to do some simple/custom details that are not in documentation. For example: label outside the chart; turning off background for bar chart, doughnut bar with 1 value (for example - i have doughnut chart, with value 20%, i want the difference to be colored - you cant do that).
Of course all these stuff can be addressed and made with customizing .js file, and extending it but if you don't have time for that and you want out of the box solution, you can be stuck on simple detail so i suggest reading full docs to see if it is up to your expetations.
I would recommend D3.js with the caveat the the learning curve is steep; let me try to explain:
In something like chart.js, chartist,etc you provide the data, chart type and some configuration and you have your chart. In D3, it is a bit more complicated in the sense that D3 provides the framework for displaying and interacting with data via the Dom elements you design and specify.( Mostly svg's although you can also use divs,spans etc)
While it feels daunting at first and the documentation is basically an API Reference, there are hundreds of examples you can use as base or inspiration.
I'v been using (ChartJS, Morris, Inline Charts) for dashboard. It may help you much to customize the chart
I would recommend Chartist.js. It is fully responsive with great flexibility and DPI dependent.
you're able to style your charts with CSS in #media queries and lot of animation options. they have given examples for line chart, bar chart, pie chart with code. So it will definitely help you.
I like amCharts.
Can do all kinds of stuff and is free to use.
Google gives you an interesting charting library.
May want to try that but it requires you to be connected to Google for it to work (can't run it offline).
Here's a shot at it with HighCharts. I adapted the 'Stacked and grouped column' example at http://www.highcharts.com/demo/column-stacked-and-grouped.
Obviously there's work to be done in getting the labels and axes right, but I think this is a good start.
jsFiddle at http://jsfiddle.net/saevj2n4/1/
HTML:
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
JavaScript
$(function () {
Highcharts.chart('container', {
chart: {
type: 'column',
width: 200,
height: 1000
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Profit']
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal',
//groupPadding: .45,
pointPadding: 0,
//pointWidth: 40,
}
},
series: [{
name: 'Min',
data: [59.28 - 21.58 ],
stack: 'Last Year',
color: "#919191"
}, {
name: 'Max',
data: [21.58 ],
stack: 'Last Year',
color: "transparent"
}, {
name: 'Min',
data: [ 57.15 - 32.5 ],
stack: 'Last Month',
color: "#6095c9"
}, {
name: 'Max',
data: [32.50],
stack: 'Last Month',
color: "transparent"
}, {
name: 'Min',
data: [54.81 - 47.14 ],
stack: 'Last Week',
color: "#745f8e"
}, {
name: 'Max',
data: [47.14],
stack: 'Last Week',
color: "transparent"
}]
});
});
Related
I am trying to plot some heavy data on zing Chart. Zing charts are normally plot inside a div but for my case my page became leggy after loading 200k points inside zing chart div-tag. In the doc it says to load large data in Canvas.
In the performance documentation of zing chart; in the end of document there is Render type, it says to load in canvas but its not working. according to doc
Render Type
The render method is where you can define the output, which can either render Canvas or SVG. If you are rendering a large dataset, the performance of Canvas will benefit you because DOM explosion happens when rendering in SVG.
Here is my code any suggestion or help.
function chart_timeFreq_ff_fh(timeArray, frequency_array_ff, frequency_array_fh) {
zingchart.DEV.SORTTOKENS = 0;
zingchart.DEV.PLOTSTATS = 0;
zingchart.DEV.RESOURCES = 0;
zingchart.DEV.KEEPSOURCE = 0;
zingchart.DEV.COPYDATA = 0;
zingchart.DEV.MEDIARULES = 0;
zingchart.SYNTAX = 'dashed';
$('#lineChart_f').remove();
$('#canvas_div_f').append(
'<canvas id="lineChart_f" style="min-height: 400px; height: 550px; max-height: 500px; max-width: 100%;"></canvas>'
);
let configTimeAndAngle = {
"type": "line",
plot: {
mode: 'fast',
'hint-ts': true
},
legend: {
layout: "1x2", //row x column // items means in one two we added two items as legends
x: "35%",
y: "6%",
},
"preview":{
"live":true
},
'scale-x': {
zooming: true,
labels: timeArray,
'max-items':8,
transform: {
type: 'date'
},
item: {
'font-size':10
}
},
'scale-y': {
'auto-fit': true,
guide: {
'line-style': "solid"
},
item: {
'font-size':10
}
},
tooltip: {
// text: 'Time : %kt (X) Freq : %%node-value (Y).',
text: 'Time : %kt (X) Freq : %v (Y).',
alpha: 0.9,
backgroundColor: '#F44336',
borderColor: '#B71C1C',
borderRadius: 2,
borderWidth: 1,
padding: '5 10'
},
gui: {
behaviors: [
{
id: 'ViewDataTable',
enabled: 'none'
},
{
id: 'ViewSource',
enabled: 'none'
},
{
id: 'CrosshairHide',
enabled: 'all'
}
]
},
"series": [
{
"values": frequency_array_ff,
'line-color': "#3366ff",
'background-color': "#3366ff",
text: "Centeral Frequency"
},
{
"values": frequency_array_fh,
'line-color': "#00cc99",
'background-color': "#00cc99",
text: "Frequency Hopping"
}
]
};
zingchart.render({
id: 'lineChart_cob_f',
data: configTimeAndAngle,
height: "100%",
width: "100%",
output: "canvas"
});
}
Updated
I have tried to plot like this but still issue. Above chart is also updated and we i need to change how I pass time ? my time format is like 2022-10-10 23:24:03 an array of time like this so in the 'scale-x': { labels: timeArray} i add time like this
"series": [
{
values: [],
'line-color': "#3366ff",
'background-color': "#3366ff",
text: "Centeral Frequency"
},
{
values: [],
'line-color': "#00cc99",
'background-color': "#00cc99",
text: "Frequency Hopping"
}
]
configTimeAndAngle.series[0].values.push([frequency_array_ff]);
configTimeAndAngle.series[1].values.push([frequency_array_fh]);
configTimeAndAngle.series[0]=values.[frequency_array_ff];
configTimeAndAngle.series[1]=values[frequency_array_fh];
configTimeAndAngle.series[0]=frequency_array_ff;
configTimeAndAngle.series[1]=frequency_array_fh];
I've managed to create you a demo in a studio application with over 200k nodes, maybe you can use this setup with canvas in the render method for reference and see how it goes. I hope this helps.
To be honest I also had the same issue all day, then I saw this and I have found the issue on your question. you have use canvas instead use div and while rendering use
// this is your code
$('#canvas_div_f').append(
'<canvas id="lineChart_f" style="min-height: 400px; height: 550px; max-height: 500px; max-width: 100%;"></canvas>'
);
instead just use
$('#canvas_div_f').append(
'<div id="lineChart_f" style="min-height: 400px; height: 550px; max-height: 500px; max-width: 100%;"></div>'
);
and while render set output to canvas.
zingchart.render({
id: 'lineChart_cob_f',
data: configTimeAndAngle,
height: "100%",
width: "100%",
output: "canvas"
});
I have line-time-series chart (in ECharts). I need to keep a constant number of points, which moves from left to right with new data. However, when I add data using setOption, there is no shift, but each point just changes its position in the y direction.
Can someone please advise me what I'm doing wrong?
This example does exactly what I need. I think I have it the same, but it still behaves differently.
Thank you
<script src="https://unpkg.com/vue#2.6.12/dist/vue.js"></script>
<script src="https://unpkg.com/echarts#4.9.0/dist/echarts.js"></script>
<div id="app" style="width: 700px; height: 400px;">
<div ref="echart" style="width: 100%; height: 100%;" ></div>
<button type="button" #click="onClick"> Push data < /button></div>
new Vue({
el: '#app',
mounted() {
this.chart_data=[
['2020-09-01 15:14:13.0', 1],
['2020-09-01 15:14:14.0', 1.5],
['2020-09-01 15:14:15.0', 0.7],
['2020-09-01 15:14:16.0', 0.8],
['2020-09-01 15:14:17.0', 1.7]
]
this.chart=echarts.init(this.$refs.echart)
var option={
color: '#3283bb',
xAxis: {
type: 'time',
splitLine: {
show: false
}
},
yAxis: {
type: 'value',
splitLine: {
show: false
}
},
series: [{
showSymbol: false,
type: 'line',
areaStyle: {
opacity: 0.2
},
lineStyle: {
width: 1.5
},
data: this.chart_data,
hoverAnimation: false
}]
}
this.chart.setOption(option)
},
methods: {
onClick: function() {
this.chart_data.shift()
this.chart_data.shift()
this.chart_data.push(['2020-09-01 15:14:18.0', 2.5])
this.chart_data.push(['2020-09-01 15:14:19.0', 2.0])
this.chart.setOption({
series: [{
data: this.chart_data
}]
})
}
},
})
JSFiddle example
I was able to find out the answer directly from the ECharts developers. Therefore, if someone has a similar problem, the solution is as follows:
ECharts performs animates "shift" if it recognizes part of the old data in the newly added data. Currently, this can be done by adding a unique name to each value. Each value is then an object with a name and value property.
{name: '2020-09-01 15:14:18.0', value: ['2020-09-01 15:14:18.0', 2.5]}
I am attaching a modified jsfiddle https://jsfiddle.net/Clyde256/b2d4juzt/44/ from the previous post, where the shift already works.
I would like to add, that if you are using dataset functionality, you need to name your dimension and then in the series property use the encode block and set itemId to any dimension name that has unique values like so:
dataset: {
dimensions: ['value', 'ts'],
source: [],
},
series: [
{
name: 'some line',
type: 'line',
encode: {
x: 'ts',
y: 'value',
itemId: 'ts',
},
},
],
Then the chart renders with correct 'shift left' animation when new values are added and old ones are removed.
I am using a javascript library called Highcharts https://www.highcharts.com/
to plot JSON data on a stock/line graph.
Reference the image below to get an understanding of the terms I am using in this post.
https://www.highcharts.com/images/docs/understanding_highstock.png
So everything works fine when clicking on the range selector buttons to zoom in. But when I use the navigator to specify a huge range (years), the final line plot is incorrect. I have created some images to help you understand what I mean.
Using the range selector buttons to specify a smaller range works perfectly when trying to plot [1519162460000,246.39649367343821] as my final price:
But now, let me resize the navigator in order to show the entire price history:
If you look carefully at the image you should be able to see that the last plot on the chart is incorrect and shows $230.72 when it should display $246.40 246.39649367343821 <- rounded
As you can probably tell, this is a major issue for someone who is trying to display relevant price information on my website.
If I do not restrict the width of the chart div or resize the browser window the plots display fine but I still dont know the issue. (note: what I just described does not work in codepen because the viewport width is restricted so the plots mess up regardless when I navigate a big enough range)
Below is a snippet of my js and html along with a link to the codepen I created.
JS
Highcharts.setOptions({
lang: {
thousandsSep: ","
}
});
Highcharts.stockChart("chart", {
chart: {
width: 290,
padding: [5, 5, 5, 5]
},
title: {
text: "Litecoin Price" // make dynamic
},
series: [
{
name: "Price",
data: JSON.parse(data)["stats"],
tooltip: {
valueDecimals: 2,
valuePrefix: "$",
valueSuffix: " USD"
}
}
],
responsive: {
rules: [
{
condition: {
maxWidth: 500
},
chartOptions: {
chart: {
zoomType: "none"
},
credits: {
enabled: false
},
scrollbar: {
enabled: false
} //,
//navigator: {
//enabled: false
//},
//rangeSelector: {
//enabled: false
//}
}
}
]
},
scrollbar: {
liveRedraw: false
},
rangeSelector: {
allButtonsEnabled: false,
buttons: [
{
type: "month",
count: 1,
text: "1m"
},
{
type: "month",
count: 3,
text: "3m"
},
{
type: "month",
count: 6,
text: "6m"
},
{
type: "year",
count: 1,
text: "1y"
},
{
type: "ytd",
count: 1,
text: "YTD"
}
],
selected: 4,
inputEnabled: true,
enabled: true,
inputStyle: {
color: "#757575"
},
labelStyle: {
color: "#757575"
}
}
});
HTML
<div class="card" style="padding: 10px; min-width: 330px;">
<div class="card chart-card" style="height: 350px; overflow: hidden; width: 300px;">
<div id="chart" style="height: 350px; min-width: 300px;">
<div id="highcharts-loading">
<div style="display: block; margin: 0 auto; position: absolute; top: calc(50% - 24px); left: calc(50% - 24px);"><span class="loading1"></span></div>
</div>
<div id="highcharts-nodata" style="display:none; text-align: center;">No chart data found</div>
</div>
</div>
</div>
That's because when you zoom out enough, Highcharts groups the data and displays the average value. If you look at the tooltip it says "Week from Monday, Feb 19, 2018", which means the value that is being displayed is the average for that week. I believe there are some settings that allow you to disable that grouping, but at the expense of the graph interaction possibly becoming laggy due to rendering so many data points.
Data grouping is the concept of sampling the data values into larger
blocks in order to ease readability and increase performance of the
JavaScript charts. Highstock by default applies data grouping when the
points become closer than a certain pixel value, determined by the
groupPixelWidth option.
The settings for data grouping on line charts are here: series.line.dataGrouping
I'm attempting to combine a couple of different chart demos from Highcharts.
My examples are: Data classes and popup and Small US with data labels
I want the map from the first with the popup feature of the second. I need to connect the map to my own google spreadsheet but for now I'm just trying to get the data from the first example to work.
This is what I have so far but can't seem to get any data in the map. I thought I had a joinBy problem, and I may still, but when I set joinBy to null I thought "the map items are joined by their position in the array", yet nothing happened.
https://jsfiddle.net/9eq6mydv/
$(function () {
// Load the data from a Google Spreadsheet
// https://docs.google.com/a/highsoft.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0AoIaUO7wH1HwdFJHaFI4eUJDYlVna3k5TlpuXzZubHc&output=html
Highcharts.data({
googleSpreadsheetKey: '0AoIaUO7wH1HwdDFXSlpjN2J4aGg5MkVHWVhsYmtyVWc',
googleSpreadsheetWorksheet: 1,
// custom handler for columns
parsed: function (columns) {
// Make the columns easier to read
var keys = columns[0],
names = columns[1],
percent = columns[10],
// Initiate the chart
options = {
chart : {
renderTo: 'container',
type: 'map',
borderWidth : 1
},
title : {
text : 'US presidential election 2008 result'
},
subtitle: {
text: 'Source: <a href="http://en.wikipedia.org/wiki/United_States_presidential_election,' +
'_2008#Election_results">Wikipedia</a>'
},
mapNavigation: {
enabled: true,
enableButtons: false
},
legend: {
align: 'right',
verticalAlign: 'top',
x: -100,
y: 70,
floating: true,
layout: 'vertical',
valueDecimals: 0,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || 'rgba(255, 255, 255, 0.85)'
},
colorAxis: {
dataClasses: [{
from: -100,
to: 0,
color: '#C40401',
name: 'McCain'
}, {
from: 0,
to: 100,
color: '#0200D0',
name: 'Obama'
}]
},
series : [{
data : data,
dataLabels: {
enabled: true,
color: '#FFFFFF',
format: '{point.code}',
style: {
textTransform: 'uppercase'
}
},
mapData: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']),
joinBy: keys,
name: 'Democrats margin',
point: {
events: {
click: pointClick
}
},
tooltip: {
ySuffix: ' %'
},
cursor: 'pointer'
}, {
type: 'mapline',
data: Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small'], 'mapline'),
color: 'silver'
}]
};
/**
* Event handler for clicking points. Use jQuery UI to pop up
* a pie chart showing the details for each state.
*/
function pointClick() {
var row = this.options.row,
$div = $('<div></div>')
.dialog({
title: this.name,
width: 400,
height: 300
});
window.chart = new Highcharts.Chart({
chart: {
renderTo: $div[0],
type: 'pie',
width: 370,
height: 240
},
title: {
text: null
},
series: [{
name: 'Votes',
data: [{
name: 'Obama',
color: '#0200D0',
y: parseInt(columns[3][row], 10)
}, {
name: 'McCain',
color: '#C40401',
y: parseInt(columns[4][row], 10)
}],
dataLabels: {
format: '<b>{point.name}</b> {point.percentage:.1f}%'
}
}]
});
}
// Read the columns into the data array
var data = [];
$.each(keys, function (i, key) {
data.push({
key: key,//.toUpperCase(),
value: parseFloat(percent[i]),
name: names,
row: i
});
});
// Initiate the chart
window.chart = new Highcharts.Map(options);
},
error: function () {
$('#container').html('<div class="loading">' +
'<i class="icon-frown icon-large"></i> ' +
'Error loading data from Google Spreadsheets' +
'</div>');
}
});
});
UPDATE:
I wanted to share with everyone my final solution. Although Ondkloss did a magnificent job answering my question the popup feature still didn't work and this is because I forgot to include the jQuery for the .dialog call. Once I included that I had an empty popup with a highchart error 17, this is because the highmaps.js code doesn't include the pie chart class. So I had to add the highcharts.js code and include map.js module afterward. You can see my final jsfiddle here.
Thanks again to Ondkloss for the excellent answer!
The problem here mostly comes down to the use of joinBy. Also to correct it there are some required changes to your data and mapData.
Currently your joinBy is an array of strings, like ["al", "ak", ...]. This is quite simply not an accepted format of the joinBy option. You can read up on the details in the API documentation, but the simplest approach is to have a attribute in common in data and mapData and then supply a string in joinBy which then joins those two arrays by that attribute. For example:
series : [{
data : data,
mapData: mapData,
joinBy: "hc-key",
]
Here the "hc-key" attribute must exist in both data and mapData.
Here's how I'd create the data variable in your code:
var data = [];
$.each(keys, function (i, key) {
if(i != 0)
data.push({
"hc-key": "us-"+key,
code: key.toUpperCase(),
value: parseFloat(percent[i]),
name: names[i],
row: i
});
});
This skips the first key, which is just "Key" (the title of the column). Here we make the "hc-key" fit the format of the "hc-key" in our map data. An example would be "us-al". The rest is just metadata that will be joined in. Note that you were referencing your data in the options prior to filling it with data, so this has to be moved prior to this.
This is how I'd create the mapData variable in your code:
var mapData = Highcharts.geojson(Highcharts.maps['countries/us/custom/us-small']);
// Process mapdata
$.each(mapData, function () {
var path = this.path,
copy = { path: path };
// This point has a square legend to the right
if (path[1] === 9727) {
// Identify the box
Highcharts.seriesTypes.map.prototype.getBox.call(0, [copy]);
// Place the center of the data label in the center of the point legend box
this.middleX = ((path[1] + path[4]) / 2 - copy._minX) / (copy._maxX - copy._minX);
this.middleY = ((path[2] + path[7]) / 2 - copy._minY) / (copy._maxY - copy._minY);
}
// Tag it for joining
this.ucName = this.name.toUpperCase();
});
The first part is your "standard map data". The rest is to correctly center the labels for the popout states, and gotten directly from the example.
And voila, see this JSFiddle demonstration to witness your map in action.
I suggest doing some console.log-ing to see how data and mapData have the hc-key in common and that leads to the joining of the data in the series.
I have a column chart with two series, one of which I want to go down and the other up, like this:
However both of the series have positive y-values, which I can't change, e.g.
blue = [1746181, 1884428, 2089758, 2222362, 2537431, 2507081, 2443179,
2664537, 3556505, 3680231, 3143062, 2721122, 2229181, 2227768,
2176300, 1329968, 836804, 354784, 90569, 28367, 3878];
grey = [1656154, 1787564, 1981671, 2108575, 2403438, 2366003, 2301402, 2519874,
3360596, 3493473, 3050775, 2759560, 2304444, 2426504, 2568938, 1785638,
1447162, 1005011, 330870, 130632, 21208];
Using highcharts options, is it possible to have a chart like this? The example I used for the screenshot is this jsFiddle if it's useful to anyone, however it has a series with negative values which is not an option for me. Instead my data is more like this fiddle
I would try to use two separate yAxes: http://jsfiddle.net/zares7x9/2/, where one of them is reversed:
yAxis: [{
title: {
text: null
},
top: '5%',
height: '45%',
labels: {
formatter: function () {
return (Math.abs(this.value) / 1000000) + 'M';
}
},
min: 0,
max: 4000000
}, {
title: {
text: null
},
labels: {
formatter: function () {
return (Math.abs(this.value) / 1000000) + 'M';
}
},
offset: 0,
showFirstLabel: false, // hide 0-value
reversed: true, //reverse
top: '50%',
height: '45%',
min: 0,
max: 4000000
}],
Setting top and height allows you to render axes like one. Note, that you need to set for one of the series yAxis: 1, to inform Highcharts which series belongs to which axis.