Charts on Admin-on-rest - chart.js

I need to do a webpage to finish my uni, and im about 90% done with it, however, im struggling with getting custom Iterators and Charts to work.
Im trying to use Recharts, but i have no idea on how to make it gather the info i want (I need it to get the number of users registered and the number of vaccines they took), but all i see on the documentation is ready results, im not sure if ChartJS will make it any better, and even if it does, im confused on how custom iterators work since i took my "Analytics" one from another StackOverflow question, however that's the least of my worries, since this seems to be simplier than getting the ACTUAL charts to work.
Help would be appreciated since i have 2 weeks to deliver it and im stuck on that, and its CRUCIAL i get that to work.
Oh yes, im also very bad at Javascript so every info is welcome.
EDIT:Forgot to say i've looked around but lots of them are for simplier and static stuff instead of database counts or stuff like that.

Welcome to SO.
1) Recharts wants an array that it needs to iterate over and display. So what I usually do is make the Chart Component a child of a List component.
2) I use the Filter on the List page to select different chart components when the user selects different options from the dropdown (in case your analytics page needs to show different charts from the same page)
^^this is a bit tricky for peeps new to JS but is quite straightforward if you want to get into it.
3) For you i think the best bet will be that you make different List components and resources for each page and just display different charts on their own page.
export const AnalyticsList = (props) => {
return (
<List title="Analytics" {...props} perPage={20} sort={{ field: 'id', order: 'ASC' }}>
<Analytics />
</List>
)
}
here is how the Analytics Component is
import React from 'react';
import {BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend} from 'recharts';
export const Analytics = (props) => {
return (
<BarChart width={800} height={400} data={Object.values(props.data)} margin={{top: 5, right: 30, left: 20, bottom: 5}}>
<XAxis dataKey="name"/>
<YAxis dataKey="charLimit" />
<CartesianGrid strokeDasharray="3 3"/>
<Tooltip/>
<Legend />
<Bar dataKey="charLimit" fill="#82ca9d" />
</BarChart>
);
}
Hope this helps.

Related

Simulating a select event with Enzyme

I am a little confused because this seems to be such a trivial and easy thing, yet there is hardly any proper documentation in Enzyme on how to do this.
I want to do one of the simplest things in the world. I just want to simulate a select event in a drop down select (HTML select/combo) by selecting an option called "dogs".
When I have this option selected would like to see that the option is "selected", and I would also like to see that the select value is set to "dogs".
What am I doing wrong here?
import React from 'react';
import {shallow, mount} from "enzyme"
test(' change ', () => {
let Compoment =
<select className="sel" name="selectComp" required="">
<option value="empty">Please make your choice ...</option>
<option value="cats">feline</option>
<option value="dogs">canine</option>
</select>;
const wrapper = mount(Compoment);
let sel = wrapper.find(".sel").at(0)
sel.simulate('change', { target: { name: 'selectComp', value: "dogs" } });
expect(wrapper.find(".sel").at(0).getElement().value).toBe("dogs")
expect(wrapper.find(".sel").at(0).find("option").at(2).props().selected).toBe(true)
})
React syncs prop=>DOM property only one way.
If you set selected prop on <option> element React would write it into DOM selected property(but you actually don't use selected prop at all).
You browser(or JSDOM in case of Jest tests) also changes selected property for relevant <option> element upon user selection.
So that's why prop does not reflect change.
You can use getDOMNode to access underlying DOM node:
expect(wrapper.find(".sel").at(0).find("option").at(2).getDOMNode().selected).toBe(true)
but know what? you don't need that. This would just test browser highlights right option upon user selection. It's just a wasted time to check if browser and/or React do their job responsibly.

resetZoom in Chartjs

I need a help. I followed this tutorial https://www.dyclassroom.com/chartjs/chartjs-how-to-draw-line-graph-using-data-from-mysql-table-and-php.
I managed to start chartjs-plugin-zoom.
Now i want to add button "Reset zoom"
I fallowed this tutorial:
Add zoom event handler to charts for chartjs with chartjs-plugin-zoom
But when i add right after $.ajax({}); in app.js
$('#reset_zoom').click(function() {
mycanvas.resetZoom();
})
and press the button error is displayed:
app.js:131 Uncaught TypeError: mycanvas.resetZoom is not a function
at HTMLButtonElement.<anonymous> (app.js:131)
at HTMLButtonElement.dispatch (datatables.min.js:15)
at HTMLButtonElement.r.handle (datatables.min.js:15)
Can you give me an advice?
Kind of surprised this hasn't been answered yet. I remember running into this myself a while back. You are doing the same thing I was doing..
Effectively what you're doing is trying to run the .resetZoom() function on an HTML canvas element. You need to do this on the chart object, not the canvas element.
YouTube video walking you through it: https://www.youtube.com/watch?v=tWlENvyr9cY
Working CodePen: https://codepen.io/vpolston/pen/MWGVmrX
A couple examples of what not to do..
document.getElementById('myChart').resetZoom() // vanilla JavaScript
or even
$("#myChart").resetZoom() // jQuery
What you actually need to do is tack the .resetZoom() onto the Chart object from when you instantiated the chart. So in your code here:
const myChart = new Chart('myChart', {}
Whatever you set the variable to when you created the chart is what needs to have the .resetZoom(). So this would work:
myChart.resetZoom();
Now to make that a clickable button we can create a function. That function accepts whatever the chart Object was named.
JS
resetZoomBtn = (chart) => {
chart.resetZoom()
};
and then in our HTML we call that function and pass whatever you called the chart when you instantiated it as the parameter.
<div class="chart-container">
<canvas id="myChart"></canvas>
<button onclick="resetZoomBtn(myChart)">reset zoom</button>
</div>
Hopefully that helps anyone who views this question since it comes up at the top of the search results on Google. I know chances of it being marked 'answer' four years later are slim.
Thanks,
VP

How to render Ember component on same line

This Ember template code...
<div class="detail bedrooms">
<span>Number of bedrooms:</span> {{rental.bedrooms}}
</div>
<div class="detail temperature">
<span>Current Temperature:</span> {{city-temperature location=rental.city}}
</div>
...results in this rendering...
How could one get the "25C" text to render on the same line as "Current Temperature" in the same way that "San Francisco" is on the same line as "Location"?
I have tried getting the city-temperature component to return only text, but (secondary question here) is it even possible for a component to return only text if the text is from a remote ajax request since the promise seems to need a DOM element to append to?
This Ember app is available here on GitHub. It's a modified version of the official Ember.js tutorial app with this "Current Temperature" detail added.
The problem is that; city-temperature is a component; and by default ember components is assigned div as their tags. Due to this; the content of city-temperature starts at a new line.
What can you do? Play with css and make sure div tag of city-temperature does not start at a new line; but instead floating right within the owner div. The second option is making city-temperature component tagless; so that it does not start at a new line. To achieve that; you can just declare:
tagName: ''
within city-temperature.js. You can see the following twiddle to see the second option I mentioned.
After reading your comments; I have forked your repository and made minor modifications to achieve what you want. You can check my repository and my corresponding commit to see what I changed.
Basically; I really did not like the idea that weather service is returning a DOM element. I have changed it to return an instance of ember promise (I mean Ember.RSVP.Promise). Within city-temperature.js I just set a retrieved weather value from weather service and set it to the component instead of making DOM modification. Finally; I modified city-temperature.hbs to render weatherValue and added a simple css item in order to prevent weather-container div to insert a new line break.
I am not sure; whether you will like my solution or not; but I guess you will retrieve the visual appearance you want. You can always rely on promises for async tasks; you do not need to create DOM elements and pass them around to components and append them to somewhere within DOM tree of the corresponding component. I believe one of the reasons we are making use of a framework like Ember is to prevent such DOM modifications. Best regards.
An ember component adds a div by default. If you don't want to add this div tag, you need to set tagName to an empty string.
That's called tagless component.
Further, for your case, you can give a tagName='span' so you will not need a span in your template.
export default Ember.Component.extend({
tagName: 'span',
classNames: ['weather-container'],
weather: Ember.inject.service(),
//rest of your code...
});

Managing a list in umbraco 5

I have recently started working on an umbraco 5 project and am finding it a bit of a struggle compared with umbraco 4. What I am trying to do is have a list of items that are managed in the content section of the site where users can add items to a list, this list is then used in drop downs and page categories throughout the site.
I am looking for the best way to do this, I am currently part way through creating a property editor that manages a list of text boxes but not sure if this is the best way of doing it, and Im currently not entirely sure of how to go about doing even this. I can save one property no problem, but a dynamic list?
Can anybody give me some idea of how they would go about doing this with some code examples, theres not a huge amount of resources for 5 out there at the minute.
Many thanks to those who contribute.
UPDATE
I have now copied the multiple textstring property editor from the source code and am looking to update it to have an extra text input. Its using the knockout javascript library of which Im not too familar with, below is the code I have so far, does anyone know how I would update this to save both text values to the database?
<ul class="relatedlinks-textstring-inputs" data-bind="template: { name: 'textstringRow', foreach: textstrings }"></ul>
<script id="textstringRow" type="text/html">
<li style='width: 250px;'>Name<input type="text" data-bind="value: value" />Url<input type="text" data-bind="value: value" /></li>
</script>
#Html.HiddenFor(x => Model.Value, new Dictionary<string, object> { { "data-bind", "value: value" } })

ASP MVC4 jquery calendar

I'm working with ASP MVC4 jquery calendar. I'm new to this. I have my jquery calendar built so that it highlights particular dates which i passed through array. But now the question is, I have a table of data in database which I got into Model and then used to it retrieve information based on an 'ID' in controller and returned to VIEW. Now I can get the dates from database in the form of table but I want to know, how I can pass those particular dates to an array of JQUERY CALENDAR in VIEW.
Also I imported package:
with core and datepicker functionalities.
But when i click the next arrow or previous arrow, it doesn't show next or previous months.
I can post the code if you don't understand my question. Please help me since I have already spent more than 15 days understanding this.
well, thats an older question but I had a couple of problem myself with datepicker and took me about 3 hours of research until I found the answer ... this is only for poeple like me who'd end up on this while digging up for answers ... *
Jquery UI is already include in .net mvc4, as is datepicker, its in the bundle. you just have to call it by adding this to your layout ( in the head section )
#Scripts.Render("~/bundles/jqueryui")
#Styles.Render("~/Content/themes/base/css", "~/Content/css")
also, make sure you dont have another script render at the bottom of your body, as its by default where the jquery bundle is set (at least it was for me on the default project ) and it cause a bug with datepicker when I used it.
<input id="mydate" name="mydate" class="datepicker" type="text" value="#Model.mydate.Value.ToString("dddd, dd MMMM yyyy")" />
where mydate is the name of the parameter you'll have set in your viewModel, said parameter is a DateTime object ( or DateTimeOffSet ) (the .Value is only if you set the date as a nullable, its not necessary otherwise)
After on the bottom of your view, create a jquery section :
#section scripts{
<script>
$(".datepicker").datepicker({ dateFormat: "DD, d MM yy", altFormat: "yy-mm-dd" });
</script>
}
(dateformat and altformat are optional, give them the value you want or dont use them at all)
as for the array of date ... i'd use a viewmodel, which would contains your array as parameter, and pass this viewmodel between your view and your controller. after that define an Editor template and its should be pretty straighforward to build a table with the dates from there.