mirror of
https://gitlab.com/freepascal.org/fpc/pas2js.git
synced 2025-04-05 05:27:47 +02:00
156 lines
4.3 KiB
ObjectPascal
156 lines
4.3 KiB
ObjectPascal
program demoscriptablebubble;
|
|
|
|
{$MODE OBJFPC}
|
|
{$MODESWITCH EXTERNALCLASS}
|
|
|
|
uses
|
|
JS,
|
|
Web,
|
|
SysUtils,
|
|
Math,
|
|
ChartJS;
|
|
|
|
const
|
|
COLORS: array[0..8] of string = ('#4dc9f6', '#f67019', '#f53794', '#537bc4',
|
|
'#acc236', '#166a8f', '#00a950', '#58595b', '#8549ba');
|
|
|
|
function rand(min, max: Integer): Integer;
|
|
begin
|
|
Result := RandomRange(min, max);
|
|
end;
|
|
|
|
function ftos(const f: Double): string;
|
|
begin
|
|
Result := FloatToStrF(f, ffNumber, 15, 1);
|
|
end;
|
|
|
|
const
|
|
DATA_COUNT = 16;
|
|
MIN_XY = -150;
|
|
MAX_XY = 100;
|
|
|
|
function generateData: TJSArray;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := TJSArray.new;
|
|
for i := 0 to Pred(DATA_COUNT) do
|
|
begin
|
|
Result.push(TChartXYVData.new(rand(MIN_XY, MAX_XY), rand(MIN_XY, MAX_XY),
|
|
rand(0, 1000)));
|
|
end;
|
|
end;
|
|
|
|
function colorize(opaque: Boolean; context: TChartOptionsContext): JSValue;
|
|
var
|
|
value: TChartXYVData;
|
|
x, y, r, g, b, a: Double;
|
|
begin
|
|
value := TChartXYVData(
|
|
TChartBubbleDataset(context.dataset).data_[context.dataIndex]);
|
|
x := value.x_ / 100;
|
|
y := value.y_ / 100;
|
|
r := IfThen((x < 0) and (y < 0), 250, IfThen(x < 0, 150, IfThen(y < 0, 50, 0)));
|
|
g := IfThen((x < 0) and (y < 0), IfThen(x < 0, 50, IfThen(y < 0, 150, 250)));
|
|
b := IfThen((x < 0) and (y < 0), 0, IfThen((x > 0) and (y > 0), 250, 150));
|
|
a := IfThen(opaque, 1, 0.5 * value.v_ / 1000);
|
|
Result := 'rgba(' + ftos(r) + ',' + ftos(g) + ',' + ftos(b) + ',' +
|
|
ftos(a) + ')';
|
|
end;
|
|
|
|
function color(index: NativeInt): string;
|
|
begin
|
|
Result := COLORS[index mod Length(COLORS)];
|
|
end;
|
|
|
|
var
|
|
chart: TChart;
|
|
config: TChartConfiguration;
|
|
options: TChartOptions;
|
|
data: TChartData;
|
|
dataset: TChartBubbleDataset;
|
|
begin
|
|
data := TChartData.new;
|
|
data.datasets_ := TJSArray.new;
|
|
dataset := TChartBubbleDataset.new;
|
|
dataset.data_ := generateData;
|
|
data.datasets_.push(dataset);
|
|
dataset := TChartBubbleDataset.new;
|
|
dataset.data_ := generateData;
|
|
data.datasets_.push(dataset);
|
|
|
|
options := TChartOptions.new;
|
|
options.aspectRatio := 1;
|
|
options.legend_ := False;
|
|
options.tooltips_ := False;
|
|
options.elements := TChartElementsConfiguration.new;
|
|
options.elements.point := TChartElementPoint.new;
|
|
options.elements.point.backgroundColor_ := TJSFunction(@colorize).bind(nil, False);
|
|
options.elements.point.borderColor_ := TJSFunction(@colorize).bind(nil, True);
|
|
options.elements.point.borderWidth_ :=
|
|
function(context: TChartOptionsContext): JSValue
|
|
begin
|
|
Result := Min(Max(1, context.datasetIndex + 1), 8);
|
|
end;
|
|
options.elements.point.hoverBackgroundColor := 'transparent';
|
|
options.elements.point.hoverBorderColor_ :=
|
|
function(context: TChartOptionsContext): JSValue
|
|
begin
|
|
Result := color(context.datasetIndex);
|
|
end;
|
|
options.elements.point.hoverBorderWidth_ :=
|
|
function(context: TChartOptionsContext): JSValue
|
|
var
|
|
value: TChartXYVData;
|
|
begin
|
|
value := TChartXYVData(
|
|
TChartBubbleDataset(context.dataset).data_[context.dataIndex]);
|
|
Result := Round(8 * value.v_ / 1000);
|
|
end;
|
|
options.elements.point.radius_ :=
|
|
function(context: TChartOptionsContext): JSValue
|
|
var
|
|
value: TChartXYVData;
|
|
size: NativeUInt;
|
|
base: Double;
|
|
begin
|
|
value := TChartXYVData(TChartBubbleDataset(
|
|
context.dataset).data_[context.dataIndex]);
|
|
size := context.chart.width;
|
|
base := Abs(value.v_) / 1000;
|
|
Result := (size / 24) * base;
|
|
end;
|
|
config := TChartConfiguration.new;
|
|
config.type_ := 'bubble';
|
|
config.data := data;
|
|
config.options := options;
|
|
chart := TChart.new('chart-0', config);
|
|
|
|
document.getElementById('randomize').addEventListener('click',
|
|
procedure
|
|
begin
|
|
chart.config.data.datasets_.forEach(
|
|
function(element: JSValue; index: NativeInt; arr: TJSArray): Boolean
|
|
begin
|
|
TChartBubbleDataset(element).data_ := generateData;
|
|
end);
|
|
chart.update;
|
|
end);
|
|
document.getElementById('addDataset').addEventListener('click',
|
|
procedure
|
|
var
|
|
dataset: TChartBubbleDataset;
|
|
begin
|
|
dataset := TChartBubbleDataset.new;
|
|
dataset.data_ := generateData;
|
|
chart.config.data.datasets_.push(dataset);
|
|
chart.update;
|
|
end);
|
|
document.getElementById('removeDataset').addEventListener('click',
|
|
procedure
|
|
begin
|
|
chart.config.data.datasets_.shift;
|
|
chart.update;
|
|
end);
|
|
end.
|