MOBILE-2459 choice: Add custom legend to charts
parent
d813d7bcd9
commit
6dd506c326
|
@ -61,35 +61,37 @@
|
|||
</ion-card>
|
||||
|
||||
<!-- Choice results -->
|
||||
<ion-card *ngIf="canSeeResults">
|
||||
<div *ngIf="canSeeResults">
|
||||
<ion-item-divider color="light" text-center>
|
||||
{{ 'addon.mod_choice.responses' | translate }}
|
||||
</ion-item-divider>
|
||||
<ion-grid no-padding>
|
||||
<ion-row>
|
||||
<ion-col col-12 col-lg-4>
|
||||
<ion-col col-12 col-lg-5>
|
||||
<ion-item text-wrap class="core-warning-item" *ngIf="hasOffline">
|
||||
<ion-icon item-start name="warning" color="warning"></ion-icon> {{ 'addon.mod_choice.resultsnotsynced' | translate }}
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<canvas core-chart type="pie" [data]="data" [labels]="labels" height="300"></canvas>
|
||||
<core-chart type="pie" [data]="data" [labels]="labels" height="300"></core-chart>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
<ion-col *ngIf="choice.publish && results" col-12 col-lg-8>
|
||||
<ion-item text-wrap *ngFor="let result of results">
|
||||
<h2><core-format-text [text]="result.text"></core-format-text></h2>
|
||||
<p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamount} }})</p>
|
||||
<a ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseid" [userId]="user.userid" [title]="user.fullname">
|
||||
<ion-col *ngIf="choice.publish && results" col-12 col-lg-7>
|
||||
<ion-item-group *ngFor="let result of results">
|
||||
<ion-item-divider text-wrap color="light">
|
||||
<h2><core-format-text [text]="result.text"></core-format-text></h2>
|
||||
<p>{{ 'addon.mod_choice.numberofuser' | translate }}: {{ result.numberofuser }} ({{ 'core.percentagenumber' | translate: {$a: result.percentageamount} }})</p>
|
||||
</ion-item-divider>
|
||||
<a ion-item *ngFor="let user of result.userresponses" core-user-link [courseId]="courseid" [userId]="user.userid" [title]="user.fullname" text-wrap>
|
||||
<ion-avatar item-start>
|
||||
<img [src]="user.profileimageurl" [alt]="'core.pictureof' | translate:{$a: user.fullname}" core-external-content onError="this.src='assets/img/user-avatar.png'">
|
||||
</ion-avatar>
|
||||
<p>{{user.fullname}}</p>
|
||||
</a>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-card>
|
||||
</div>
|
||||
<ion-card class="core-info-card" *ngIf="!canSeeResults && !choiceNotOpenYet">
|
||||
<p>{{ 'addon.mod_choice.noresultsviewable' | translate }}</p>
|
||||
</ion-card>
|
||||
|
|
|
@ -163,7 +163,7 @@
|
|||
</ul>
|
||||
</ng-container>
|
||||
<ng-container *ngSwitchCase="'chart'">
|
||||
<canvas core-chart [type]="item.chartType" [data]="item.chartData" [labels]="item.labels" height="300"></canvas>
|
||||
<core-chart [type]="item.chartType" [data]="item.chartData" [labels]="item.labels" height="300"></core-chart>
|
||||
<p *ngIf="item.average">{{ 'addon.mod_feedback.average' | translate }}: {{item.average | number : '1.2-2'}}</p>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
|
|
|
@ -681,11 +681,6 @@ textarea {
|
|||
height: auto;
|
||||
}
|
||||
|
||||
canvas[core-chart] {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.core-circle:before {
|
||||
content: ' \25CF';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
core-chart {
|
||||
display: block;
|
||||
|
||||
canvas {
|
||||
max-width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Directive, Input, OnDestroy, OnInit, ElementRef, OnChanges } from '@angular/core';
|
||||
import { Component, Input, OnDestroy, OnInit, ElementRef, OnChanges, ViewChild } from '@angular/core';
|
||||
import { Chart } from 'chart.js';
|
||||
|
||||
/**
|
||||
|
@ -21,12 +21,13 @@ import { Chart } from 'chart.js';
|
|||
* It only supports changes on these properties: data and labels.
|
||||
*
|
||||
* Example usage:
|
||||
* <canvas core-chart [data]="data" [labels]="labels" [type]="type" [legend]="legend"></canvas>
|
||||
* <core-chart [data]="data" [labels]="labels" [type]="type" [legend]="legend"></core-chart>
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'canvas[core-chart]'
|
||||
@Component({
|
||||
selector: 'core-chart',
|
||||
templateUrl: 'core-chart.html'
|
||||
})
|
||||
export class CoreChartDirective implements OnDestroy, OnInit, OnChanges {
|
||||
export class CoreChartComponent implements OnDestroy, OnInit, OnChanges {
|
||||
// The first 6 colors will be the app colors, the following will be randomly generated.
|
||||
// It will use the same colors in the whole session.
|
||||
protected static backgroundColors = [
|
||||
|
@ -42,12 +43,13 @@ export class CoreChartDirective implements OnDestroy, OnInit, OnChanges {
|
|||
@Input() labels = []; // Labels of the data.
|
||||
@Input() type: string; // Type of chart.
|
||||
@Input() legend: any; // Legend options.
|
||||
@Input() height = 300; // Height of the chart element.
|
||||
@ViewChild('canvas') canvas: ElementRef;
|
||||
|
||||
chart: any;
|
||||
protected element: ElementRef;
|
||||
|
||||
constructor(element: ElementRef) {
|
||||
this.element = element;
|
||||
constructor() {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,8 +59,7 @@ export class CoreChartDirective implements OnDestroy, OnInit, OnChanges {
|
|||
let legend = {};
|
||||
if (typeof this.legend == 'undefined') {
|
||||
legend = {
|
||||
display: true,
|
||||
position: 'bottom',
|
||||
display: false,
|
||||
labels: {
|
||||
generateLabels: (chart): any => {
|
||||
const data = chart.data;
|
||||
|
@ -85,7 +86,7 @@ export class CoreChartDirective implements OnDestroy, OnInit, OnChanges {
|
|||
this.type = 'horizontalBar';
|
||||
}
|
||||
|
||||
const context = this.element.nativeElement.getContext('2d');
|
||||
const context = this.canvas.nativeElement.getContext('2d');
|
||||
this.chart = new Chart(context, {
|
||||
type: this.type,
|
||||
data: {
|
||||
|
@ -120,14 +121,14 @@ export class CoreChartDirective implements OnDestroy, OnInit, OnChanges {
|
|||
* @return {any[]} Array with the number of background colors requested.
|
||||
*/
|
||||
protected getRandomColors(n: number): any[] {
|
||||
while (CoreChartDirective.backgroundColors.length < n) {
|
||||
while (CoreChartComponent.backgroundColors.length < n) {
|
||||
const red = Math.floor(Math.random() * 255),
|
||||
green = Math.floor(Math.random() * 255),
|
||||
blue = Math.floor(Math.random() * 255);
|
||||
CoreChartDirective.backgroundColors.push('rgba(' + red + ', ' + green + ', ' + blue + ', 0.6)');
|
||||
CoreChartComponent.backgroundColors.push('rgba(' + red + ', ' + green + ', ' + blue + ', 0.6)');
|
||||
}
|
||||
|
||||
return CoreChartDirective.backgroundColors.slice(0, n);
|
||||
return CoreChartComponent.backgroundColors.slice(0, n);
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,8 @@
|
|||
<canvas #canvas [attr.height]="height"></canvas>
|
||||
|
||||
<ion-list *ngIf="chart" inset>
|
||||
<ion-item *ngFor="let data of chart.legend.legendItems">
|
||||
<ion-icon name="square" item-start [style.color]="data.fillStyle"></ion-icon>
|
||||
{{data.text}}
|
||||
</ion-item>
|
||||
</ion-list>
|
|
@ -32,6 +32,7 @@ import { CoreContextMenuComponent } from './context-menu/context-menu';
|
|||
import { CoreContextMenuItemComponent } from './context-menu/context-menu-item';
|
||||
import { CoreContextMenuPopoverComponent } from './context-menu/context-menu-popover';
|
||||
import { CoreCoursePickerMenuPopoverComponent } from './course-picker-menu/course-picker-menu-popover';
|
||||
import { CoreChartComponent } from './chart/chart';
|
||||
import { CoreChronoComponent } from './chrono/chrono';
|
||||
import { CoreLocalFileComponent } from './local-file/local-file';
|
||||
import { CoreSitePickerComponent } from './site-picker/site-picker';
|
||||
|
@ -66,6 +67,7 @@ import { CoreIonTabComponent } from './ion-tabs/ion-tab';
|
|||
CoreContextMenuItemComponent,
|
||||
CoreContextMenuPopoverComponent,
|
||||
CoreCoursePickerMenuPopoverComponent,
|
||||
CoreChartComponent,
|
||||
CoreChronoComponent,
|
||||
CoreLocalFileComponent,
|
||||
CoreSitePickerComponent,
|
||||
|
@ -108,6 +110,7 @@ import { CoreIonTabComponent } from './ion-tabs/ion-tab';
|
|||
CoreIconComponent,
|
||||
CoreContextMenuComponent,
|
||||
CoreContextMenuItemComponent,
|
||||
CoreChartComponent,
|
||||
CoreChronoComponent,
|
||||
CoreLocalFileComponent,
|
||||
CoreSitePickerComponent,
|
||||
|
|
|
@ -22,7 +22,6 @@ import { CoreKeepKeyboardDirective } from './keep-keyboard';
|
|||
import { CoreUserLinkDirective } from './user-link';
|
||||
import { CoreAutoRowsDirective } from './auto-rows';
|
||||
import { CoreLongPressDirective } from './long-press';
|
||||
import { CoreChartDirective } from './chart';
|
||||
import { CoreBackButtonDirective } from './back-button';
|
||||
import { CoreSupressEventsDirective } from './supress-events';
|
||||
|
||||
|
@ -37,7 +36,6 @@ import { CoreSupressEventsDirective } from './supress-events';
|
|||
CoreUserLinkDirective,
|
||||
CoreAutoRowsDirective,
|
||||
CoreLongPressDirective,
|
||||
CoreChartDirective,
|
||||
CoreBackButtonDirective,
|
||||
CoreSupressEventsDirective
|
||||
],
|
||||
|
@ -52,7 +50,6 @@ import { CoreSupressEventsDirective } from './supress-events';
|
|||
CoreUserLinkDirective,
|
||||
CoreAutoRowsDirective,
|
||||
CoreLongPressDirective,
|
||||
CoreChartDirective,
|
||||
CoreBackButtonDirective,
|
||||
CoreSupressEventsDirective
|
||||
]
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
This files describes API changes in the Moodle Mobile app,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 3.5.2 ===
|
||||
|
||||
- CoreChartDirective changed from directive to component (CoreChartComponent) and the selector to use it changed from canvas[core-chart] to core-chart.
|
Loading…
Reference in New Issue