How to position nodes sequentially nz-graph? - ng-zorro-antd

How to make node a be placed at the level of its neighbor node b?
{
nodes: [
{id: `enter`, width: 100, height: 100},
{id: `a`, width: 100, height: 100},
{id: `b`, width: 100, height: 100},
{id: `c`, width: 100, height: 100},
{id: `exit`, width: 100, height: 100},
],
edges: [
{v: `enter`, w: `a`},
{v: `a`, w: `c`},
{v: `c`, w: `exit`},
{v: `enter`, w: `b`},
{v: `b`, w: `exit`},
]
}

{
nodes: [
{id: `enter`, width: 100, height: 100},
{id: `a`, width: 100, height: 100},
{id: `b`, width: 100, height: 100},
{id: `c`, width: 100, height: 100},
{id: `exit`, width: 100, height: 100},
],
edges: [
{v: `enter`, w: `a`},
{v: `a`, w: `c`},
{v: `c`, w: `exit`},
{v: `enter`, w: `c`},
{v: `b`, w: `exit`},
]
}

Related

How control how the layout manage the drag and drop 'displacements' of the cells with react-grid-layout

This code creates a 10x1 layout with react-grid-layout . All the elements can move.
But I need it when I move one column to another only column don't add an extra row in the 10x1. I need all the movements to happen only in the 10x1.
How I can say this to the Grid ?
I have this code :
import '/node_modules/react-grid-layout/css/styles.css'
import '/node_modules/react-resizable/css/styles.css'
import GridLayout from "react-grid-layout";
export function MyFirstGrid () {
const widthCell=1;
const heightCell=1;
const layout = [
{ i: "0000", x: 0, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0100", x: 1, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0200", x: 2, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0300", x: 3, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0400", x: 4, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0500", x: 5, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0600", x: 6, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0700", x: 7, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0800", x: 8, y: 0, w: widthCell, h: heightCell,isResizable:false},
{ i: "0900", x: 9, y: 0, w: widthCell, h: heightCell,isResizable:false}
];
const getLayouts = () => {
const savedLayouts = localStorage.getItem("grid-layout");
return savedLayouts ? JSON.parse(savedLayouts) : layout;
};
const handleLayoutChange = (layout) => {
localStorage.setItem("grid-layout", JSON.stringify(layout));
};
const borderAdditive="border"
return (<div>
<GridLayout
layout={getLayouts()}
className="layout"
cols={10}
rowHeight={50}
width={1200}
onLayoutChange={handleLayoutChange}
margin={[1,1]}
>
<div className={borderAdditive} key="0000">0000</div>
<div className={borderAdditive} key="0100">0100</div>
<div className={borderAdditive} key="0200">0200</div>
<div className={borderAdditive} key="0300">0300</div>
<div className={borderAdditive} key="0400">0400</div>
<div className={borderAdditive} key="0500">0500</div>
<div className={borderAdditive} key="0600">0600</div>
<div className={borderAdditive} key="0700">0700</div>
<div className={borderAdditive} key="0800">0800</div>
<div className={borderAdditive} key="0900">0900</div>
</GridLayout>
</div>
);
}
To be graphical on a 10x10 layout now this happens :
I moved the element 0000 to 0100 and an extra row is added .
I want to move from 0000 to 0001 and those cells interchange the position. Something like that :
I know this solution is not perfect. But I want to share if anyone can use this.
// These get a array with only the X and Y of the updated Layout
function GetXYArray(layout){
let XYArray=[];
layout.map(item=>{XYArray.push({x:item.x,y:item.y})})
return XYArray
}
// This get what the cell spaces
function AvailableCoordinates(ChangedLayout,MaxValueX,MaxValueY){
let ArrayAvailableCoordinates=[];
let MaxValueColumn=MaxValueY+1;
for (let xCheck=0;xCheck<=MaxValueX;xCheck++){
let tempLayOut=ChangedLayout.filter(item=>{return item.x===xCheck})
if(ChangedLayout.filter(item=>{return item.x===xCheck}).length<MaxValueColumn){
for (let yCheck=0;yCheck<=MaxValueY;yCheck++){
if (tempLayOut.filter(item=>{return item.y===yCheck}).length===0){
ArrayAvailableCoordinates.push({x:xCheck,y:yCheck})
}
}
}
}
return ArrayAvailableCoordinates;
}
const handleOnDragStop=(layout)=>{
const MaxArrayYValue=9;
const MaxValueX=9;
const MaxValueY=9;
let VarAvailableCoordinates=AvailableCoordinates(GetXYArray(layout),MaxValueX,MaxValueY);
const itemsValueGreaterThanMaxArrayYValue=layout.filter(function (item){return item.y > MaxArrayYValue})
// This part reallocate the cells outside of the array and use the spaces Available. For one only one cell , this part can be improved
// on the user case a element have more than 1x1 cell
itemsValueGreaterThanMaxArrayYValue.map(GTMaxArrayYValue=>(layout.map(item=>{if (item.i===GTMaxArrayYValue.i) { item.x=VarAvailableCoordinates[0].x;
item.y=VarAvailableCoordinates[0].y}})))
}
The layout for testing is :
const layout = [
{ i: "0000", x: 0, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0100", x: 1, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0200", x: 2, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0300", x: 3, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0400", x: 4, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0500", x: 5, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0600", x: 6, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0700", x: 7, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0800", x: 8, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0900", x: 9, y: 0, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0001", x: 0, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0101", x: 1, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0201", x: 2, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0301", x: 3, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0401", x: 4, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0501", x: 5, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0601", x: 6, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0701", x: 7, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0801", x: 8, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0901", x: 9, y: 1, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0002", x: 0, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0102", x: 1, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0202", x: 2, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0302", x: 3, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0402", x: 4, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0502", x: 5, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0602", x: 6, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0702", x: 7, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0802", x: 8, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0902", x: 9, y: 2, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0003", x: 0, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0103", x: 1, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0203", x: 2, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0303", x: 3, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0403", x: 4, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0503", x: 5, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0603", x: 6, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0703", x: 7, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0803", x: 8, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0903", x: 9, y: 3, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0004", x: 0, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0104", x: 1, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0204", x: 2, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0304", x: 3, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0404", x: 4, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0504", x: 5, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0604", x: 6, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0704", x: 7, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0804", x: 8, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0904", x: 9, y: 4, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0005", x: 0, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0105", x: 1, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0205", x: 2, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0305", x: 3, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0405", x: 4, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0505", x: 5, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0605", x: 6, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0705", x: 7, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0805", x: 8, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0905", x: 9, y: 5, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0006", x: 0, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0106", x: 1, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0206", x: 2, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0306", x: 3, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0406", x: 4, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0506", x: 5, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0606", x: 6, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0706", x: 7, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0806", x: 8, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0906", x: 9, y: 6, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0007", x: 0, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0107", x: 1, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0207", x: 2, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0307", x: 3, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0407", x: 4, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0507", x: 5, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0607", x: 6, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0707", x: 7, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0807", x: 8, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0907", x: 9, y: 7, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0008", x: 0, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0108", x: 1, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0208", x: 2, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0308", x: 3, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0408", x: 4, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0508", x: 5, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0608", x: 6, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0708", x: 7, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0808", x: 8, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0908", x: 9, y: 8, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0009", x: 0, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0109", x: 1, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0209", x: 2, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0309", x: 3, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0409", x: 4, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0509", x: 5, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0609", x: 6, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0709", x: 7, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0809", x: 8, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag},
{ i: "0909", x: 9, y: 9, w: widthCell, h: heightCell,isResizable:false,isBounded:BoundedFlag}
];

How do I create larger polygons out of a smaller polygons

I would like to transform the following list of polygons:
[
%{height: 32, width: 32, x: 0, y: 0},
%{height: 32, width: 32, x: 32, y: 0},
%{height: 32, width: 32, x: 64, y: 0},
%{height: 32, width: 32, x: 256, y: 0},
%{height: 32, width: 32, x: 288, y: 0}
]
Into a list where the adjacent polygons are joined as follows:
[
%{height: 32, width: 96, x: 0, y: 0},
%{height: 32, width: 64, x: 256, y: 0}
]
I've tried using Enum.reduce_while as follows:
Enum.reduce_while(polys, 0, fn poly, max_x ->
if poly.x - max_x <= 32, do: {:cont, max_x + 32}, else: {:halt, max_x}
end)
That works to give me the first polygon, but how do I get the subsequent polygons and is it possible to get all of them in 1 pass?
This would be a perfect use-case for Enum.chunk_while/4:
input = [
%{height: 32, width: 32, x: 0, y: 0},
%{height: 32, width: 32, x: 32, y: 0},
%{height: 32, width: 32, x: 64, y: 0},
%{height: 32, width: 32, x: 256, y: 0},
%{height: 32, width: 32, x: 288, y: 0}
]
chunk_fun = fn
i, [] -> {:cont, i}
%{width: iw, x: ix}, %{height: ah, width: aw, x: ax, y: ay}
when ax + aw == ix ->
{:cont, %{height: ah, width: aw + iw, x: ax, y: ay}}
%{height: ih, y: iy}, %{height: ah, width: aw, x: ax, y: ay}
when ay + ah == iy ->
{:cont, %{height: ah + ih, width: aw, x: ax, y: ay}}
i, acc -> {:cont, acc, i}
end
after_fun = fn
[] -> {:cont, []}
acc -> {:cont, acc, []}
end
input
|> Enum.chunk_while([], chunk_fun, after_fun)
|> IO.inspect()
#⇒ [%{height: 32, width: 96, x: 0, y: 0},
# %{height: 32, width: 64, x: 256, y: 0}]
Please note, that the example above also handles the y-axis joins. The example is interesting due to the unusual use of a map instance as an accumulator.
I'd use Enum.reduce here. Enum.reduce_while is meant for cases when you want to stop processing the list further based on some condition. You do want to process the whole list in this case.
What I do is collect polygons in the accumulator, starting with a list with only the first polygon. Then, in each reduction, I check whether the previous polygon's x + width is the same as the new polygon's x. If it is, I merge the polygons by adding the widths, if not I prepend the polygon.
The list is collected in reverse so I use Enum.reverse after the reduction.
[
%{height: 32, width: 32, x: 0, y: 0},
%{height: 32, width: 32, x: 32, y: 0},
%{height: 32, width: 32, x: 64, y: 0},
%{height: 32, width: 32, x: 256, y: 0},
%{height: 32, width: 32, x: 288, y: 0}
]
|> Enum.reduce(nil, fn
x, nil ->
[x]
x, [h | t] ->
if h.x + h.width == x.x do
[%{h | width: x.width + h.width} | t]
else
[x, h | t]
end
end)
|> Enum.reverse()
|> IO.inspect()
Output:
[%{height: 32, width: 96, x: 0, y: 0}, %{height: 32, width: 64, x: 256, y: 0}]

How to prevent first/last bars from being cut off in a chart with time scale

How do I prevent the first and last bars from being cut off (showing half)?
I need to show the short month names on the x-axis. I've tried playing around with various min/max settings, but I can't seem to get it right.
var graphData = {
dates: [
'2016-06-01',
'2016-07-01',
'2016-08-01',
'2016-09-01',
'2016-10-01',
'2016-11-01',
'2016-12-01',
'2017-01-01',
'2017-02-01',
'2017-03-01',
'2017-04-01',
'2017-05-01'
],
wins: [23, 5, 13, 24, 8, 11, 23, 5, 13, 24, 8, 11],
draws: [2, 1, 2, 0, 2, 2, 3, 1, 2, 4, 0, 1],
losses: [3, 1, 2, 10, 8, 8, 3, 1, 2, 10, 8, 8],
winRates: [50, 40, 72, 30, 46, 80, 50, 40, 72, 30, 46, 80]
};
var winsMax = Math.max.apply(Math, graphData.wins);
var lossesMax = Math.max.apply(Math, graphData.losses);
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: "bar",
data: {
labels: graphData.dates.map((date) => moment(date)),
datasets: [
{
type: "bar",
backgroundColor: "green",
hoverBackgroundColor: "green",
data: graphData.wins,
yAxisID: "winsAndLosses"
},
{
type: "bar",
backgroundColor: "red",
hoverBackgroundColor: "red",
data: graphData.losses.map((i) => -i),
yAxisID: "winsAndLosses"
},
{
type: "line",
data: graphData.winRates,
fill: true,
backgroundColor: "gray",
pointRadius: 0,
pointHoverRadius: 0,
yAxisID: "winRate"
}
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
type: "time",
time: {
unit: "month",
displayFormats: {
month: "MMM"
}
},
stacked: true,
gridLines: {
display: false
},
ticks: {
callback: (label) => label.toUpperCase(),
fontSize: 10
}
}],
yAxes: [
{
id: "winsAndLosses",
stacked: true,
ticks: {
min: (lossesMax + 10) * -1,
max: winsMax + 10,
callback: (label) => Math.abs(label) // TODO: Localization (number formatting).
},
display: false
},
{
id: "winRate",
ticks: {
min: 0,
max: 100,
stepSize: 10,
callback: (label) => label + "%", // TODO: Localization (number formatting).
fontSize: 10
}
}
]
}
}
});
.myChartDiv {
max-width: 800px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js#latest/dist/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="800" height="400"></canvas>
</div>
</body>
</html>
There's a setting called offset which seems to work for me:
xAxes: [{
offset: true
}]
var graphData = {
dates: [
'2016-06-01',
'2016-07-01',
'2016-08-01',
'2016-09-01',
'2016-10-01',
'2016-11-01',
'2016-12-01',
'2017-01-01',
'2017-02-01',
'2017-03-01',
'2017-04-01',
'2017-05-01'
],
wins: [23, 5, 13, 24, 8, 11, 23, 5, 13, 24, 8, 11],
draws: [2, 1, 2, 0, 2, 2, 3, 1, 2, 4, 0, 1],
losses: [3, 1, 2, 10, 8, 8, 3, 1, 2, 10, 8, 8],
winRates: [50, 40, 72, 30, 46, 80, 50, 40, 72, 30, 46, 80]
};
var winsMax = Math.max.apply(Math, graphData.wins);
var lossesMax = Math.max.apply(Math, graphData.losses);
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: "bar",
data: {
labels: graphData.dates.map((date) => moment(date)),
datasets: [
{
type: "bar",
backgroundColor: "green",
hoverBackgroundColor: "green",
data: graphData.wins,
yAxisID: "winsAndLosses"
},
{
type: "bar",
backgroundColor: "red",
hoverBackgroundColor: "red",
data: graphData.losses.map((i) => -i),
yAxisID: "winsAndLosses"
},
{
type: "line",
data: graphData.winRates,
fill: true,
backgroundColor: "gray",
pointRadius: 0,
pointHoverRadius: 0,
yAxisID: "winRate"
}
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
type: "time",
time: {
unit: "month",
displayFormats: {
month: "MMM"
}
},
stacked: true,
gridLines: {
display: false
},
ticks: {
callback: (label) => label.toUpperCase(),
fontSize: 10
},
offset:true
}],
yAxes: [
{
id: "winsAndLosses",
stacked: true,
ticks: {
min: (lossesMax + 10) * -1,
max: winsMax + 10,
callback: (label) => Math.abs(label) // TODO: Localization (number formatting).
},
display: false
},
{
id: "winRate",
ticks: {
min: 0,
max: 100,
stepSize: 10,
callback: (label) => label + "%", // TODO: Localization (number formatting).
fontSize: 10
}
}
]
}
}
});
.myChartDiv {
max-width: 800px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js#latest/dist/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="800" height="400"></canvas>
</div>
</body>
</html>

How do I draw line after receiving data - Route from GPS Trace

I just started using Here Maps. Before I used Google Direction, I want to try use 'Here Maps' API. This is example JSON result. After I got this result, How do I implement this into Polyline or Direction (MAP Here)? Thanks
{
RouteLinks: [
{
linkId: 25664478,
functionalClass: 5,
shape: "51.1017723 0.3934907 51.1018066 0.3933491 51.1018295 0.39326",
linkLength: 15.575699313408467
},
{
linkId: 25664473,
functionalClass: 4,
shape: "51.1018295 0.39326 51.1022491 0.39348",
linkLength: 44.17562556306323
},
{
linkId: 25664459,
functionalClass: 4,
shape: "51.1022491 0.39348 51.1022987 0.39351",
linkLength: 5.305684979980019
},
{
linkId: 781742854,
functionalClass: 4,
shape: "51.1022987 0.39351 51.1025505 0.39365",
linkLength: 26.670487136749067
},
{
linkId: 781742855,
functionalClass: 4,
shape: "51.1025505 0.39365 51.1027794 0.39378",
linkLength: 24.302012297623005
},
{
linkId: 25664450,
functionalClass: 4,
shape: "51.1027794 0.39378 51.1030807 0.39403",
linkLength: 33.974229462422905
},
{
linkId: 25664444,
functionalClass: 4,
shape: "51.1030807 0.39403 51.103241 0.39413",
linkLength: 17.215963662407898
},
{
linkId: 25664440,
functionalClass: 4,
shape: "51.103241 0.39413 51.1033783 0.39421 51.1035385 0.39433 51.1036797 0.39445",
linkLength: 48.32839625333388
},
{
linkId: 25664427,
functionalClass: 4,
shape: "51.1036797 0.39445 51.1038017 0.39454",
linkLength: 13.445306290244636
},
{
linkId: 860272608,
functionalClass: 4,
shape: "51.1038017 0.39454 51.1039391 0.39465",
linkLength: 15.378381014646559
},
{
linkId: 860272609,
functionalClass: 4,
shape: "51.1039391 0.39465 51.1041908 0.39484",
linkLength: 27.85427285471891
},
{
linkId: 781742870,
functionalClass: 4,
shape: "51.1041908 0.39484 51.1043282 0.39494 51.1045609 0.39506",
linkLength: 39.56626207722863
},
{
linkId: 781742871,
functionalClass: 4,
shape: "51.1045609 0.39506 51.1047287 0.39515 51.1050262 0.3953021",
linkLength: 48.951382959921716
}
],
TracePoints: [
{
confidenceValue: 1, linkIdMatched: 25664478, matchDistance: 1.46,
routeLinkSeqNrMatched: 0, lat: 51.10177, lon: 0.39349,
elevation: 0, speedMps: 0, headingDegreeNorthClockwise: 10000,
latMatched: 51.10178065190155, lonMatched: 0.3934977183445852,
timestamp: 0, headingMatched: 114.46568884011239,
minError: 1.3027890756593314
},
{
confidenceValue: 1, linkIdMatched: 25664478, matchDistance: 1.57,
routeLinkSeqNrMatched: 0, lat: 51.10181, lon: 0.39335,
elevation: 0, speedMps: 0, headingDegreeNorthClockwise: 10000,
latMatched: 51.10182, lonMatched: 0.39336,
timestamp: 0, headingMatched: -65.53429247174023,
minError: 1000000
},
{
confidenceValue: 1, linkIdMatched: 781742854, matchDistance: 1,
routeLinkSeqNrMatched: 4, lat: 51.10255, lon: 0.39366,
elevation: 0, speedMps: 0, headingDegreeNorthClockwise: 10000,
latMatched: 51.102547928304084, lonMatched: 0.3936687569824506,
timestamp: 0, headingMatched: 20.644254301899522,
minError: 0.6541474931313044
},
{
confidenceValue: 1, linkIdMatched: 860272608, matchDistance: 4.59,
routeLinkSeqNrMatched: 10, lat: 51.10398, lon: 0.39466,
elevation: 0, speedMps: 0, headingDegreeNorthClockwise: 10000,
latMatched: 51.10394, lonMatched: 0.39465,
timestamp: 0, headingMatched: 25.217234923243595,
minError: 1.2405405512432781
},
{
confidenceValue: 1, linkIdMatched: 1022687693, matchDistance: 1.33,
routeLinkSeqNrMatched: 14, lat: 51.10501, lon: 0.39533,
elevation: 0, speedMps: 0, headingDegreeNorthClockwise: 10000,
latMatched: 51.105012239590245, lonMatched: 0.39531827230152644,
timestamp: 0, headingMatched: 16.91643828307876,
minError: 0.8568378930601925
}
],
Warnings: [
{
"tracePointSeqNum": -1,
"routeLinkSeqNum": 3,
"category": 3,
"text": "Entering link 781742854 into forbidden driving direction"
}
],
MapVersion: "2013Q4" }
*linkId,shape is like that trip points which is given by Heremap api step1.
You just draw route by polyline function.
addPolylineToMap(map,linkId);
function addPolylineToMap(map,linkId) {
for (j = 0; j < (shape.length - 1); j = j + 2) {
var strip = new H.geo.Strip();
strip.pushPoint({lat: shape[j],lng: shape[j+1]});
}
}

highcharts, four aeraranges with linear gradients

I'm trying to create chart in Highcharts with four arearanges and one line. I'm doing my best to get something like on image:
arearanges
I'v managed to do something like this:
$(function () {
var rangesHI = [
[1246406400000, 90, 75],
[1248998400000, 90, 75]
],
rangesME = [
[1246406400000, 75, 60],
[1248998400000, 75, 60]
],
rangesNO = [
[1246406400000, 60, 35],
[1248998400000, 60, 35]
],
rangesLO = [
[1246406400000, 35, 15],
[1248998400000, 35, 15]
],
averages = [
[1246406400000, 31.5],
[1246492800000, 32.1],
[1246579200000, 33],
[1246665600000, 33.8],
[1246752000000, 31.4],
[1246838400000, 31.3],
[1246924800000, 38.3],
[1247011200000, 35.4],
[1247097600000, 36.4],
[1247184000000, 47.7],
[1247270400000, 47.5],
[1247356800000, 37.6],
[1247443200000, 47.7],
[1247529600000, 46.8],
[1247616000000, 47.7],
[1247702400000, 46.3],
[1247788800000, 47.8],
[1247875200000, 48.1],
[1247961600000, 57.2],
[1248048000000, 54.4],
[1248134400000, 53.7],
[1248220800000, 55.7],
[1248307200000, 54.6],
[1248393600000, 55.3],
[1248480000000, 45.3],
[1248566400000, 55.8],
[1248652800000, 65.2],
[1248739200000, 74.8],
[1248825600000, 44.4],
[1248912000000, 55],
[1248998400000, 43.6]
];
$('#container').highcharts({
title: {
text: null
},
xAxis: {
type: 'datetime'
},
yAxis: {
max:90,
min:20,
title: {
text: null
}
},
series: [{
name: 'RH',
data: averages,
zIndex: 1
}, {
data: rangesHI,
type: 'arearange',
lineWidth: 0,
fillColor: {
linearGradient: [0, 0, 0, 300],
stops: [
[0, 'rgba(255,0,0, 0.2)'],
[1, 'rgba(255,0,0, 1)']
]
},
zIndex: 0
}, {
data: rangesME,
type: 'arearange',
lineWidth: 0,
fillColor: {
linearGradient: [300, 0, 300, 400],
stops: [
[0, 'rgba(237,230,126, 0.2)'],
[1, 'rgba(237,230,126, 1)']
]
},
zIndex: 0
}, {
data: rangesNO,
type: 'arearange',
lineWidth: 0,
fillColor: {
linearGradient: [500, 0, 500, 600],
stops: [
[0, 'rgba(104,217,91, 0.2)'],
[1, 'rgba(104,217,91, 0.7)']
]
},
zIndex: 0
}, {
data: rangesLO,
type: 'arearange',
lineWidth: 0,
fillColor: {
linearGradient: [0, 0, 0, 220],
stops: [
[0, 'rgba(91,187,217, 0.2)'],
[1, 'rgba(91,187,217, 0.7)']
]
},
zIndex: 0
}]
}, function (chart) {
chart.renderer.text('EKSTREMALNA', 80, 95).css({
fontSize: '16pt',
color: 'rgba(255,0,0, 1)'
}).add();
chart.renderer.text('WYSOKA', 80, 145).css({
fontSize: '16pt',
color: 'rgba(237,230,126, 1)'
}).add();
chart.renderer.text('KOMFORTOWA', 80, 225).css({
fontSize: '16pt',
color: 'rgba(104,217,91, 01)'
}).add();
chart.renderer.text('NISKA', 80, 305).css({
fontSize: '16pt',
color: 'rgba(91,187,217, 1)'
}).add();
});
http://jsfiddle.net/qazopap4/1/ but this is far from what I'v expected.
I can't make linear gradient for each arearange separately.
You can use plotBands which allows you to apply gradients.
yAxis: {
plotBands: [{
from: 60,
to: 90,
color: {
linearGradient: [0, 0, 0, 300],
stops: [
[0, 'rgba(255,0,0, 0.2)'],
[1, 'rgba(255,0,0, 1)']
]
}
}],
max: 90,
min: 20,
title: {
text: null
}
},
Example: http://jsfiddle.net/pag5qgsm

Resources