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