Skip to content

Commit

Permalink
refactor: Replace Raphael with Chart.js for pie chart
Browse files Browse the repository at this point in the history
  • Loading branch information
arildm committed May 28, 2024
1 parent 5515f80 commit 20a0ccf
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 402 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [Unreleased]

### Changed

- Replaced Raphael library with Chart.js, used in the pie chart over corpus distribution in statistics

## [9.6.0] - 2024-05-27

### Added
Expand Down
1 change: 0 additions & 1 deletion app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ require("angular-filter/index.js")

require("./lib/jquery.tooltip.pack.js")

require("./scripts/pie-widget.js")
require("./scripts/widgets.js")
require("./scripts/main.js")
require("./scripts/app.js")
Expand Down
65 changes: 65 additions & 0 deletions app/scripts/components/corpus-distribution-chart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/** @format */
import angular, { IController, IRootScopeService } from "angular"
import { Chart } from "chart.js"
import { html } from "@/util"

const defaultMode: Mode = "relative"

angular.module("korpApp").component("corpusDistributionChart", {
template: html`
<div class="flex flex-col gap-2 items-center">
<canvas id="distribution-chart"></canvas>
<div id="statistics_switch">
<a data-mode="relative" href="javascript:"> {{ 'statstable_relfigures' | loc }} </a>
<a data-mode="absolute" href="javascript:"> {{ 'statstable_absfigures' | loc }} </a>
</div>
</div>
`,
bindings: {
row: "<",
},
controller: [
"$rootScope",
function ($rootScope: IRootScopeService) {
const $ctrl = this as CorpusDistributionChartController
let chart: Chart<"pie">

const getValues = (mode: Mode) => $ctrl.row.map((corpus) => corpus.values[mode == "relative" ? 1 : 0])

$ctrl.$onInit = () => {
chart = new Chart("distribution-chart", {
type: "pie",
data: {
labels: $ctrl.row.map((corpus) => corpus.title),
datasets: [{ data: getValues(defaultMode) }],
},
options: {
locale: $rootScope["lang"],
plugins: {
legend: {
display: false,
},
},
},
})

setTimeout(() => {
const radioList = ($("#statistics_switch") as any).radioList({
selected: defaultMode,
change: () => {
const mode = radioList.radioList("getSelected").attr("data-mode")
chart.data.datasets[0].data = getValues(mode)
chart.update()
},
})
})
}
},
],
})

type CorpusDistributionChartController = IController & {
row: { title: string; values: [number, number] }[]
}

type Mode = "relative" | "absolute"
4 changes: 2 additions & 2 deletions app/scripts/components/corpus_chooser/corpus-time-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import angular, { IRootScopeService } from "angular"
import range from "lodash/range"
import { Chart } from "chart.js/auto"
import { getLang, loc } from "@/i18n"
import { loc } from "@/i18n"
import {
calculateYearTicks,
getSeries,
Expand Down Expand Up @@ -94,7 +94,7 @@ angular.module("korpApp").component("corpusTimeGraph", {
minBarLength: 2,
},
},
locale: getLang(),
locale: $rootScope["lang"],
plugins: {
legend: {
display: false,
Expand Down
106 changes: 24 additions & 82 deletions app/scripts/components/statistics.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/** @format */
import angular from "angular"
import _ from "lodash"
import "components-jqueryui/ui/widgets/dialog.js"
import settings from "@/settings"
import { formatRelativeHits, html } from "@/util"
import { html } from "@/util"
import { loc, locObj } from "@/i18n"
import { getCqp } from "../../config/statistics_config.js"
import { expandOperators } from "@/cqp_parser/cqp.js"
import "@/components/corpus-distribution-chart"

angular.module("korpApp").component("statistics", {
template: html`
Expand Down Expand Up @@ -166,15 +166,18 @@ angular.module("korpApp").component("statistics", {
},
controller: [
"$rootScope",
"$scope",
"$uibModal",
"searches",
"backend",
function ($rootScope, searches, backend) {
function ($rootScope, $scope, $uibModal, searches, backend) {
const $ctrl = this

$ctrl.noRowsError = false
$ctrl.doSort = true
$ctrl.sortColumn = null
$ctrl.mapRelative = true
$scope.row = null

$ctrl.$onInit = () => {
$(window).resize(
Expand Down Expand Up @@ -446,88 +449,27 @@ angular.module("korpApp").component("statistics", {
}

function showPieChart(rowId) {
let statsSwitchInstance
const pieChartCurrentRowId = rowId
const row = $ctrl.data.find((row) => row.rowId == rowId)

const getDataItems = (rowId, valueType) => {
const dataItems = []
if (valueType === "relative") {
valueType = 1
} else {
valueType = 0
}
for (let row of $ctrl.data) {
if (row.rowId === rowId) {
for (let corpus of $ctrl.searchParams.corpora) {
const freq = row[corpus + "_value"][valueType]
const freqStr = formatRelativeHits(freq.toString(), $rootScope.lang)
const title = locObj(settings.corpora[corpus.toLowerCase()]["title"])
dataItems.push({
value: freq,
caption: `${title}: ${freqStr}`,
shape_id: rowId,
})
}
break
}
}
return dataItems
}
$scope.rowData = $ctrl.searchParams.corpora.map((corpus) => ({
title: locObj(settings.corpora[corpus.toLowerCase()]["title"]),
values: row[corpus + "_value"], // [absolute, relative]
}))

$("#dialog").remove()

const relHitsString = loc("statstable_relfigures_hits")
$("<div id='dialog'></div>")
.appendTo("body")
.append(
html`<div id="pieDiv">
<div id="statistics_switch" class="text-center my-2">
<a href="javascript:" rel="localize[statstable_relfigures]" data-mode="relative">
Relativa frekvenser
</a>
<a href="javascript:" rel="localize[statstable_absfigures]" data-mode="absolute">
Absoluta frekvenser
</a>
</div>
<div id="chartFrame" class="h-[340px] mx-auto" />
<p id="hitsDescription" class="text-center my-2" rel="localize[statstable_absfigures_hits]">
${relHitsString}
</p>
</div>`
)
.dialog({
width: 400,
height: 500,
close() {
return $("#pieDiv").remove()
},
})
.css("opacity", 0)
.parent()
.find(".ui-dialog-title")
.localeKey("statstable_hitsheader_lemgram")

$("#dialog").fadeTo(400, 1)
$("#dialog").find("a").blur() // Prevents the focus of the first link in the "dialog"

const stats2Instance = $("#chartFrame").pie_widget({
container_id: "chartFrame",
data_items: getDataItems(rowId, "relative"),
})
statsSwitchInstance = $("#statistics_switch").radioList({
change: () => {
let loc
const typestring = statsSwitchInstance.radioList("getSelected").attr("data-mode")
stats2Instance.pie_widget("newData", getDataItems(pieChartCurrentRowId, typestring))
if (typestring === "absolute") {
loc = "statstable_absfigures_hits"
} else {
loc = "statstable_relfigures_hits"
}
return $("#hitsDescription").localeKey(loc)
},
selected: "relative",
const modal = $uibModal.open({
template: html`
<div class="modal-header">
<h3 class="modal-title !w-full">{{ 'statstable_distribution' | loc }}</h3>
</div>
<div class="modal-body">
<corpus-distribution-chart row="$parent.rowData"></corpus-distribution-chart>
</div>
`,
scope: $scope,
windowClass: "!text-base",
})
// Ignore rejection from closing the modal
modal.result.catch(() => {})
}

$ctrl.resizeGrid = (resizeColumns) => {
Expand Down
Loading

0 comments on commit 20a0ccf

Please sign in to comment.