How to add period selector in AmSerialChart? - javascript

I am new to amCharts. Does anyone know how to add period selector in AmSerialChart.
I have tried this:
var periodSelector = new AmCharts.PeriodSelector();
periodSelector.position = "left";
periodSelector.periods = [{
period: "DD",
count: 10,
label: "10 days"
}, {
period: "MM",
selected: true,
count: 1,
label: "1 month"
}, {
period: "YYYY",
count: 1,
label: "1 year"
}, {
period: "YTD",
label: "YTD"
}, {
period: "MAX",
label: "MAX"
}];
chart.periodSelector = periodSelector;
It doesn't create any change.

Period Selector is an exclusive feature of the JavaScript Stock Chart, and is not available in regular serial charts.
There are two ways to go about it:
1) Implement your own external HTML controls to select periods. Then use chart's zoomToDates() method to set specific time range.
OR
2) Switch to Stock Chart and get Period Selector out-of-the-box. Stock Chart can be configured to look exactly like Serial chart. The biggest difference is that you will need to define panels (in your case just one) as well as data sets (again just one).
If you could update your question with the code and data you have so far, I could update mine with a similar Stock Chart.

Related

How to create a threshold in Observable Plot in JavaScript / TypeScript

I am trying to create a grouped bar chart using Observable's Plot.plot in JavaScript (code is in TypeScript).
The problem is that the x-axis is showing each specific date, however I want the dates to show dynamic months or weeks, not specific dates.
This is the code:
const chart = Plot.plot({
x: { axis: null, domain: ["Add", "Remove"], },
y: { tickFormat: "s", label: "↑ Access Requests", grid: true },
color: {
legend: true,
type: "categorical",
domain: ["Add", "Remove"],
range: redGreenColorRange,
},
style: {
background: "transparent",
},
width: 1350,
caption: "in 2 week increments",
facet: {
data: groupedAddRemove,
label: "Created Date",
x: "createdDate",
// thresholds: d3.utcWeeks,
// ^ this doesn't work, but a similar structure has worked in other projects I've seen
},
marks: [
Plot.barY(groupedAddRemove, {
x: "type",
y: "count",
fill: "type",
}),
Plot.ruleY([0]),
],
});
and this is what it looks like:
I want the x-axis marks to show a dynamic version of Months, like:
My data structure either could show the "Date" as a string, or a TypeScript typeof Date object
data structure with date with a type of string
data structure with date with a type of Date
This is the data structure type:
The 'groupedAddRemove' is an array of this type
( AddRemoveBarChartType[] )
type AddRemoveBarChartType = {
createdDate: Date;
count: number;
type: "Add" | "Remove";
};
the "Type" can either be "Add" or "Remove". I had a boolean for this value previously, but the "Add" and "Remove" fit better to automatically have the legend say "Add" and "Remove". It could be changed back to a boolean if there is a better way to display it that way.
The data could be changed in other ways too, if that will simplify things. I am also open to using a D3.js implementation instead of Plot.plot.
I'm very new to Observable Plot.plot so any help is appreciated, thank you!

FullCalendar - Can I achieve this view (see images)

I have downloaded and been experimenting with FullCalendar and it does almost everything I need for a resource scheduling app I am developing for my company's use. I just need to try and get it to display the events a bit differently and was hoping someone might be able to help.
I currently have it configured to display like this:
However, I am ultimately need it to display like this (side by side):
This is for a sequential process and it is important to convey the order of events and if one event (blue) extends into another day then the next day's event(s) (purple) have to wait until that one is done. This is not as clear in the top image as the bottom one.
Is this something that can be configured or will this require me to modify the source or intercept the event render and manipulate it there?
Thanks!
[EDIT] Added code snippets:
TEMPLATE:
<FullCalendar ref="fullCalendar"
default-view="resourceTimelineMonth"
:plugins="calendarPlugins"
:events="calEvents"
:resources="calResources"
:weekends="true"
:editable="true"
:event-overlap="false"
:slot-width="100"/>
SCRIPT:
data () {
return {
...
calendarPlugins: [ interactionPlugin, resourceTimelinePlugin ],
calEvents: [
{ resourceId: "101", title: 'WO123', start: '2019-11-01T07:00:00', end: '2019-11-01T12:00:00', backgroundColor: 'red' },
{ resourceId: "101", title: 'WO127', start: '2019-11-01T12:00:00', end: '2019-11-01T18:00:00', backgroundColor: 'green' },
{ resourceId: "101", title: 'WO144', start: '2019-11-01T18:00:00', end: '2019-11-02T03:00:00', backgroundColor: 'blue' },
{ resourceId: "101", title: 'WO145', start: '2019-11-02T03:00:00', end: '2019-11-02T10:00:00', backgroundColor: 'purple' }
],
calResources: [
{id: "101", title: "KM101"},
{id: "102", title: "KM102"},
{id: "103", title: "KM103"},
{id: "104", title: "KM104"},
{id: "105", title: "KM105"},
],
...
}
As I hinted at in the comments above, the reason you don't see what you're hoping for is because when you compress each slot to a single day, fullCalendar appears to switch to an "all-day" mode of display, where it ceases to take the specific times of day into account, and simply indicates the day(s) in which the event occurs.
The way to get a display the way (or close to the way) you want is to reduce the slot duration to half a day (which clearly creates the least division of the day you can do), and also modify the slot labels slightly to suit. Once the slot duration involves hours, fullCalendar will start taking the time component of the event into account again when it renders.
I don't know vue.js syntax and can't make a demo of it, so I've done the code and demo below in vanilla JS, but hopefully you can translate that into the syntax used by the vue plugin without any difficulty.
Options to add to your calendar config:
slotDuration: { hours: 12 },
slotLabelFormat: [
{ weekday: "short" },
{ hour: "2-digit", },
],
Live demo: https://codepen.io/ADyson82/pen/VwwXowr
See https://fullcalendar.io/docs/date-display for relevant documentation.

How to change randomised data used for graph values with my input data? D3js donut graph

I am fairly new to coding and I need to use d3js library to make graphs. While I get the basics, I don't yet comprehend the whole thing...
So, I found this graph in D3js examples that i want to use. but don't know how to change data showing in graph. I want donut chart to have my input data instead of randomised data as it is shown in example
http://bl.ocks.org/dbuezas/9306799
This is a graph I want to use.
the key function is change(), just replace randomData() to getYourData()
function getYourData() {
let yourData = [
{
label: 'label1',
value: 12,
},
{
label: 'label2',
value: 6,
}
]
return yourData;
}
change(getYourData());
Hopefully you can understand this syntax more easily
change([ { label: "Label 1", value: 10 },
{ label: "Label 2", value: 20 },
{ label: "Label 3", value: 30 } ])
The function change takes an array of objects, each object is a segment of the pie graph.

Adjust Highcharts data grouping based on range selector

Depending on the value of the highcharts range selector, I would like to change the data grouping. In my column chart, if one week is selected, there should be 7 bars, if one day is selected, there should be 24 bars, if one month is selected, there should be a bar for each day of the month.
There doesnt seem to be any way to supply a function inside the highchart configs to accomplish this, but I may be missing something.
My current plan was to handle a click event on the range selector to update the series data to contain the correct amount of points. But there may be a better way.
Thanks
There certainly are a bunch of options available in highstock for data grouping.
The primary one that you should look at is units. Here you can specify what kind of groups are allowed.
Top this up with groupPixelWidth and you have what you need, this width defines how small can a point in your chart be, if the number of points on the chart goes higher, the width per point decreases, once it goes below this threshold highcharts would force grouping. Keep this large enough to force grouping of next level, given you want not more than ~30 points on the screen.
dataGrouping: {
units: [
['hour', [1]],
['day', [1]],
['month', [1]],
['year', null]
],
groupPixelWidth: 100
}
#jsFiddle
Instead of using events you can combine range selector buttons with data grouping.
See: "Data grouping by buttons" in the API https://api.highcharts.com/highstock/rangeSelector.buttons
Example: https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/stock/rangeselector/datagrouping/
rangeSelector: {
allButtonsEnabled: true,
buttons: [{
type: 'month',
count: 3,
text: 'Day',
dataGrouping: {
forced: true,
units: [['day', [1]]]
}
}, {
type: 'year',
count: 1,
text: 'Week',
dataGrouping: {
forced: true,
units: [['week', [1]]]
}
}, {
type: 'all',
text: 'Month',
dataGrouping: {
forced: true,
units: [['month', [1]]]
}
}]
},
We tried a Hack around this, where we used Highstock's (Splinechart) RangeSelector, Event and DataGrouping. On click of weekly rangeselectorButton we catch this event through setExtremes. Post catching the event approximate it to "sum". If you are using two series than iterate the object.
events: {
setExtremes: function (e) {
if (e.rangeSelectorButton != undefined) {
var triger = e.rangeSelectorButton;
if (triger.type == 'week') {
$.each(this.series, function (index, obj) {
obj.options.dataGrouping.units[0] = ['week', [1]];
});
} else if (triger.type == 'day') {
$.each(this.series, function (index, obj) {
obj.options.dataGrouping.units[0] = ['day', [1]];
});
}
}
}
},
#fiddle

HighStock Grouping Daily and Monthly with columns

I have a HighStock chart (type column) that contains a value for each day. What I would like to do looks very simple, however I cannot manage to achieve it. I would like my data to appear day by day when we display one month and month by month when we display more than one month. I have 3 buttons for range selector :
buttons: [{
type: 'month',
count: 1,
text: 'Vue par mois'
}, {
type: 'year',
count: 1,
text: 'Annee'
}, {
type: 'all',
text: 'Tout'
}]
I tried to play with de datagrouping options but the problem is that the default value group my data by week instead of month. I tried many solutions but nothing works :
units:
[[
'month',
[1]
],
[
'day',
[1]
]
]
The solution above for example group the data by month, even if we display for one month, resulting in a big column block on the graph.
I feel like I'm missing something but what ? I hope my explanations are understandable. Any help would really be appreciated.
Thanks in advance !
Milene

Categories