Here's some simple code with two charts: JSFiddle
The ticks attribute works fine with the line chart but does not with the bar chart. Interestingly it works fine when posted on Chartist website (in examples section). But I really need to have it working in my .js file.
new Chartist.Bar(
'#barChart',
{
labels: ['Week 1', 'Week 2', 'Week 3', 'Week 4', 'Week 5'],
series: [
{name: 'one', data: [5, 6, 8, 9, 5]},
{name: 'two', data: [4, 5, 6, 5, 4]},
{name: 'three', data: [2, 4, 5, 2, 1]}
]
},
{
width: 565,
height: 200,
axisY: {
type: Chartist.FixedScaleAxis,
low: 0,
high: 10,
ticks: [0, 5, 10] // the ticks don't show up
}
}
);
I was looking for the diference between your code and examples code in chartist web. And they are loading scripts/all.js js url as :
<script async="" src="scripts/all.js"></script>
So, add that code and it will work :
<script src="//gionkunz.github.io/chartist-js/scripts/all.js"></script>
It seems to be a different module (AUTO-SCALE-AXIS.JS) from the main.js
https://jsfiddle.net/g4sqzseo/4/
That is the function from github project reference chartist.js which is not working for you :
/**
* The fixed scale axis uses standard linear projection of values along an axis. It makes use of a divisor option to divide the range provided from the minimum and maximum value or the options high and low that will override the computed minimum and maximum.
* **Options**
* The following options are used by this axis in addition to the default axis options outlined in the axis configuration of the chart default settings.
* ```javascript
* var options = {
* // If high is specified then the axis will display values explicitly up to this value and the computed maximum from the data is ignored
* high: 100,
* // If low is specified then the axis will display values explicitly down to this value and the computed minimum from the data is ignored
* low: 0,
* // If specified then the value range determined from minimum to maximum (or low and high) will be divided by this number and ticks will be generated at those division points. The default divisor is 1.
* divisor: 4,
* // If ticks is explicitly set, then the axis will not compute the ticks with the divisor, but directly use the data in ticks to determine at what points on the axis a tick need to be generated.
* ticks: [1, 10, 20, 30]
* };
* ```
*
* #module Chartist.FixedScaleAxis
*/
/* global Chartist */
(function (window, document, Chartist) {
'use strict';
function FixedScaleAxis(axisUnit, data, chartRect, options) {
var highLow = Chartist.getHighLow(data.normalized, options, axisUnit.pos);
this.divisor = options.divisor || 1;
this.ticks = options.ticks || Chartist.times(this.divisor).map(function(value, index) {
return highLow.low + (highLow.high - highLow.low) / this.divisor * index;
}.bind(this));
this.range = {
min: highLow.low,
max: highLow.high
};
Chartist.FixedScaleAxis.super.constructor.call(this,
axisUnit,
chartRect,
this.ticks,
options);
this.stepLength = this.axisLength / this.divisor;
}
function projectValue(value) {
return this.axisLength * (+Chartist.getMultiValue(value, this.units.pos) - this.range.min) / (this.range.max - this.range.min);
}
Chartist.FixedScaleAxis = Chartist.Axis.extend({
constructor: FixedScaleAxis,
projectValue: projectValue
});
}(window, document, Chartist));
Related
When I create simple line plot/chart using Apache Echarts I also can add built-in data scaling mechanism: dataZoom. It reaches its main goal, but there is a question to scaled data representation, made by dataZoom. By default, dataZoom doesn't take into account the chart scale limits ticks or/and the minimum and maximum allowable values (range of a function, represented by the plot). Instead, the thumbnail of the chart is drawn on the specific value range passed to the plot in series section. In addition, everytime a small indent is added from the minimum and maximum values to the borders of the graphic element.
As a result, the representation of the visualised data looks inconsistent with reality: null is not null, max is not max (because they don't match the lower and higher bounds of the coordinate area of the thumbnail plot, respectively), the amplitude of the chart fluctuations does not correspond to the scale of real data fluctuations.
Screenshot
Is there a way (documented or undocumented) to remove the indents and force the plot to use the minimum and maximum values allowed for the yAxis ticks?
I drawn a small example, it may be pasted to Echarts online editor.
let x = [];
let y = [];
let scaled = [];
/*y = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 300,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0
];*/
for (let i = 1; i < 300; i++) {
x.push(i);
element = Math.random() * 40 + 50;
y.push(element);
scaled.push(element * 6 - 250);
}
option = {
xAxis: {
data: x
},
yAxis: {
min: 0,
max: 300
},
dataZoom: [
{
start: 50,
end: 58.5
}
],
series: [
{
name: 'Fake Data',
type: 'line',
symbol: 'none',
data: y
},
{
name: 'Simulated Scaling',
type: 'line',
symbol: 'none',
lineStyle: {
opacity: 0.3
},
data: scaled
}
]
};
As you can see, the magnitude of the fluctuations of the graph, drawn by dataZoom doesn't correspond rather to the main data, but to some kind of artificial transformation of them (light green graph). Then try to comment 11st line and uncomment lines from 4 to 7. At the start of the plot you'll see main graph touching y zero line, but not on the thumbnail.
I didn't find any params for dataZoom that make them to look like expected.
Using marker:{color:x} in javascript plotly (http://jsfiddle.net/d8bt1qof/), I can color-code my
data:
But how can I change the colorscale?
Different colorscales seems to be available (https://plotly.com/javascript/colorscales/), but the usage is only explained for heatmap plots. And adding colorscale: 'Portland' seems not to work.
scattergl trace markers can also have a colorschale. I found a reference for it in the documentation here:
colorscale
Parent: data[type=scattergl].marker
Type: colorscale
Sets the colorscale. Has an effect only if in marker.coloris set to a numerical array. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, [[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]. To control the bounds of the colorscale in color space, usemarker.cmin and marker.cmax. Alternatively, colorscale may be a palette name string of the following list: Greys,YlGnBu,Greens,YlOrRd,Bluered,RdBu,Reds,Blues,Picnic,Rainbow,Portland,Jet,Hot,Blackbody,Earth,Electric,Viridis,Cividis.
So an example based on your fiddle you could look like this:
var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var trace1 = {
x: x,
y: x,
mode: 'markers',
marker: {
size: 20,
color: x,
colorscale: 'Greens'
},
};
Plotly.newPlot('myDiv', [trace1], {});
Here is an implementation for a custom colorscale based on the viridis colour scale R users will be familiar with.
var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var y = vector_normalise(x);
var trace1 = {
x: x,
y: x,
mode: 'markers',
marker: {
colorscale: [
[0.000, "rgb(68, 1, 84)"],
[0.111, "rgb(72, 40, 120)"],
[0.222, "rgb(62, 74, 137)"],
[0.333, "rgb(49, 104, 142)"],
[0.444, "rgb(38, 130, 142)"],
[0.556, "rgb(31, 158, 137)"],
[0.667, "rgb(53, 183, 121)"],
[0.778, "rgb(109, 205, 89)"],
[0.889, "rgb(180, 222, 44)"],
[1.000, "rgb(253, 231, 37)"]
],
color: y,
size: 20,
},
};
Plotly.newPlot('myDiv', [trace1], {});
Below is my normalisation function, I have left it verbose to help with understanding. The input vec could be overwritten and returned to reduce local variables if desired.
function vector_normalise(vec) {
var vmin = Math.min(...vec);
var vmax = Math.max(...vec);
// calculate the delta to save time with big arrays
var vdelta = vmax - vmin;
// create an empty array to return
var vec_ret = [];
// push doesn't seem to like inline functions
var vnorm;
// iterate over the array/vector
vec.forEach(value => {
vnorm = (value - vmin) / vdelta;
vec_ret.push(vnorm);
})
return vec_ret
}
Edit: Turns out Viridis is one of the existing available palettes... 😉
I working on a project that needs me to use graph csv file inputs. I've been using plotly and so far it seems to be working very well.
However, when I try to change the color of the graphs (lines and markers) it doesn't work. I am posting excerpts of my code since the color is overall a small portion of the code and I don't want to dump everything here.
//There's multiple charts so changing color is important
var r = Math.random() * 256
var g = Math.random() * 256
var b = Math.random() * 256
...
//used these as a vars so I can change things to test easily (multiple time series being used)
var color='rgb('+r+', '+g+', '+b+')'
var colora='rgba('+r+', '+g+', '+b+', '+'0.14'+')'
...
//layout of markers
{
x: time,
y: time,
z: data1,
line: {
reversescale: false,
//color: "'"+color+"'"
color: "'rgb("+r+', ' +g+', '+ b+")'",
},
//mode: 'lines',
marker: {
//color: "'"+color+"'",
color: "'rgb("+r+', ' +g+', '+ b+")'",
size: 3,
line: {
//color: "'"+colora+"'",
color: "'rgb("+r+', ' +g+', '+ b+")'",
width: 0.1
},
opacity: 0.8
},
type: 'scatter3d'
}
Both the attempts just give me the standard black dots. When I tried constants that worked fine (something like color:'rgb(100,100,240)'). Is there something I'm missing here? I've console.logged this thing and it doesn't seem to be an issue with the structure of my vars.
You have too many quotation marks around your rgb strings. In order to avoid confusion when concatenating strings, you could also use template strings.
See the working fiddle below.
const r = 0;
const g = 255;
const b = 0;
const color = 'rgb(' + r + ',' + g + ',' + b + ')';
const colorTemplate = `rgb(${r},${g},${b})`;
var trace1 = {
x: [1, 2, 3, 4],
y: [10, 15, 13, 17],
type: 'scatter',
marker: {
color: color
}
};
var trace2 = {
x: [1, 2, 3, 4],
y: [16, 5, 11, 9],
type: 'scatter',
marker: {
color: colorTemplate
}
};
var data = [trace1, trace2];
Plotly.newPlot('myDiv', data);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
The problem with my code is that I'm using vars. By switching to consts, I can fix the thing. I didn't catch the color not changing because for some reason the legend was displaying the right colors, but the markers and lines don't accept it.
I'm trying to build some chart like this one:
Chart Visual
But the main struggle is to add two different series that complement each other.
I really appreciate any help that someone could give me.
Many thanks in advance.
You can achieve it, but the process of implementation is not so easy. I prepared the example which shows how to do that, and I will try to explain what I did, step by step.
First, you need to define your data array just like that:
var data = [40, 30, 10, 20]
Then define your chart configuration, and inside of chart.events.load function handler put whole logic of creating desired effect.
Next step is iterate on all data positions, and create its own specific point, series, yAxis and pane, basing on calculations like below:
load() {
var chart = this,
series = [],
panes = [],
yAxes = [],
radius = 112,
innerRadius = 88,
pointAngle,
prevPointAngle = 0,
pointPadding = (radius - innerRadius) / 4,
colors = Highcharts.getOptions().colors,
additionalPointPadding = 2;
data.forEach(function(p, i) {
pointAngle = (p * 360) / 100 // Calculate point angle
// Prepare pane for each point
panes.push({
startAngle: prevPointAngle + pointPadding + additionalPointPadding,
endAngle: (pointAngle + prevPointAngle) - pointPadding - additionalPointPadding,
background: [{
backgroundColor: '#fff',
borderWidth: 0
}]
})
// Prepare yAxis for specific pane
yAxes.push({
min: 0,
max: 100,
lineWidth: 0,
tickPositions: [],
pane: i
})
// Prepare series with specific point
series.push({
name: 'Exercise ' + i,
data: [{
color: colors[i],
radius: radius + '%',
innerRadius: innerRadius + '%',
y: 100,
percents: p
}],
yAxis: i
})
prevPointAngle += pointAngle
})
And finally, update our chart by new objects:
chart.update({
pane: panes,
yAxis: yAxes,
series: series
},true, true)
Last thing you have to know, that your chart configuration should have the same amount of empty objects in pane array, like the data positions, e.g:
var data = [10, 80, 10]
(...)
pane: [{},{},{}]
Here is the example which shows the final effect: https://jsfiddle.net/yamu5z9r/
Kind regards!
I want to limit my y-axis to the range from -43 to 43. I also want my chart to not display space/area/anything under or over those values. Here is what my axis options look like
yAxis: {
tickInterval: 1,
minorTickInterval: null,
endOnTick: false,
min: -41,
max: 43,
title: {
text: 'Y Coordinate'
},
gridLineColor: 'transparent'
}
However, in the following image you can clearly see that highcharts is displaying space for values below my limit and down to -45. I want these hard limits so my background image lines up perfectly with the coordinate grid system.
I read that setting my tickInverval to 1 and endOnTick to false would produce the desired result, however it seems that is not so.
Any ideas?
Tick positions determine start and end axis values. You can use tickPositions in order to pass your positions or create a function which returns tick positions based on your min and max value and pass it as positioner.
const random = () => Math.round((Math.random() * 200) - 100)
const options = {
yAxis: {
min: -99,
max: 99,
// tickPositions: [-99, 99],
tickPositioner () {
const axis = this
return axis.tickPositions.map((pos) => {
if (pos <= axis.max && pos >= axis.min) return pos // If between range
else if (pos > axis.max) return axis.max
else if (pos < axis.min) return axis.min
})
}
},
series: [{
data: [...Array(10)].map(random),
type: 'column'
}]
}
const chart = Highcharts.chart('container', options)
Live example:
https://jsfiddle.net/918zb76r/